1 /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2 /* If you are missing that file, acquire a complete release at teeworlds.com. */
5 #include <engine/console.h>
6 #include <engine/graphics.h>
9 #include <game/generated/client_data.h>
10 #include <game/client/render.h>
11 #include <game/localization.h>
13 CLayerQuads::CLayerQuads()
15 m_Type
= LAYERTYPE_QUADS
;
16 str_copy(m_aName
, "Quads", sizeof(m_aName
));
20 CLayerQuads::~CLayerQuads()
24 void CLayerQuads::Render()
26 Graphics()->TextureSet(-1);
27 if(m_Image
>= 0 && m_Image
< m_pEditor
->m_Map
.m_lImages
.size())
28 Graphics()->TextureSet(m_pEditor
->m_Map
.m_lImages
[m_Image
]->m_TexID
);
30 m_pEditor
->RenderTools()->RenderQuads(m_lQuads
.base_ptr(), m_lQuads
.size(), LAYERRENDERFLAG_OPAQUE
|LAYERRENDERFLAG_TRANSPARENT
, m_pEditor
->EnvelopeEval
, m_pEditor
);
33 CQuad
*CLayerQuads::NewQuad()
35 m_pEditor
->m_Map
.m_Modified
= true;
37 CQuad
*q
= &m_lQuads
[m_lQuads
.add(CQuad())];
41 q
->m_PosEnvOffset
= 0;
42 q
->m_ColorEnvOffset
= 0;
44 q
->m_aPoints
[0].x
= x
;
45 q
->m_aPoints
[0].y
= y
;
46 q
->m_aPoints
[1].x
= x
+64;
47 q
->m_aPoints
[1].y
= y
;
48 q
->m_aPoints
[2].x
= x
;
49 q
->m_aPoints
[2].y
= y
+64;
50 q
->m_aPoints
[3].x
= x
+64;
51 q
->m_aPoints
[3].y
= y
+64;
53 q
->m_aPoints
[4].x
= x
+32; // pivot
54 q
->m_aPoints
[4].y
= y
+32;
56 for(int i
= 0; i
< 5; i
++)
58 q
->m_aPoints
[i
].x
<<= 10;
59 q
->m_aPoints
[i
].y
<<= 10;
63 q
->m_aTexcoords
[0].x
= 0;
64 q
->m_aTexcoords
[0].y
= 0;
66 q
->m_aTexcoords
[1].x
= 1<<10;
67 q
->m_aTexcoords
[1].y
= 0;
69 q
->m_aTexcoords
[2].x
= 0;
70 q
->m_aTexcoords
[2].y
= 1<<10;
72 q
->m_aTexcoords
[3].x
= 1<<10;
73 q
->m_aTexcoords
[3].y
= 1<<10;
75 q
->m_aColors
[0].r
= 255; q
->m_aColors
[0].g
= 255; q
->m_aColors
[0].b
= 255; q
->m_aColors
[0].a
= 255;
76 q
->m_aColors
[1].r
= 255; q
->m_aColors
[1].g
= 255; q
->m_aColors
[1].b
= 255; q
->m_aColors
[1].a
= 255;
77 q
->m_aColors
[2].r
= 255; q
->m_aColors
[2].g
= 255; q
->m_aColors
[2].b
= 255; q
->m_aColors
[2].a
= 255;
78 q
->m_aColors
[3].r
= 255; q
->m_aColors
[3].g
= 255; q
->m_aColors
[3].b
= 255; q
->m_aColors
[3].a
= 255;
83 void CLayerQuads::BrushSelecting(CUIRect Rect
)
85 // draw selection rectangle
86 IGraphics::CLineItem Array
[4] = {
87 IGraphics::CLineItem(Rect
.x
, Rect
.y
, Rect
.x
+Rect
.w
, Rect
.y
),
88 IGraphics::CLineItem(Rect
.x
+Rect
.w
, Rect
.y
, Rect
.x
+Rect
.w
, Rect
.y
+Rect
.h
),
89 IGraphics::CLineItem(Rect
.x
+Rect
.w
, Rect
.y
+Rect
.h
, Rect
.x
, Rect
.y
+Rect
.h
),
90 IGraphics::CLineItem(Rect
.x
, Rect
.y
+Rect
.h
, Rect
.x
, Rect
.y
)};
91 Graphics()->TextureSet(-1);
92 Graphics()->LinesBegin();
93 Graphics()->LinesDraw(Array
, 4);
94 Graphics()->LinesEnd();
97 int CLayerQuads::BrushGrab(CLayerGroup
*pBrush
, CUIRect Rect
)
100 CLayerQuads
*pGrabbed
= new CLayerQuads();
101 pGrabbed
->m_pEditor
= m_pEditor
;
102 pGrabbed
->m_Image
= m_Image
;
103 pBrush
->AddLayer(pGrabbed
);
105 //dbg_msg("", "%f %f %f %f", rect.x, rect.y, rect.w, rect.h);
106 for(int i
= 0; i
< m_lQuads
.size(); i
++)
108 CQuad
*q
= &m_lQuads
[i
];
109 float px
= fx2f(q
->m_aPoints
[4].x
);
110 float py
= fx2f(q
->m_aPoints
[4].y
);
112 if(px
> Rect
.x
&& px
< Rect
.x
+Rect
.w
&& py
> Rect
.y
&& py
< Rect
.y
+Rect
.h
)
117 for(int p
= 0; p
< 5; p
++)
119 n
.m_aPoints
[p
].x
-= f2fx(Rect
.x
);
120 n
.m_aPoints
[p
].y
-= f2fx(Rect
.y
);
123 pGrabbed
->m_lQuads
.add(n
);
127 return pGrabbed
->m_lQuads
.size()?1:0;
130 void CLayerQuads::BrushPlace(CLayer
*pBrush
, float wx
, float wy
)
132 CLayerQuads
*l
= (CLayerQuads
*)pBrush
;
133 for(int i
= 0; i
< l
->m_lQuads
.size(); i
++)
135 CQuad n
= l
->m_lQuads
[i
];
137 for(int p
= 0; p
< 5; p
++)
139 n
.m_aPoints
[p
].x
+= f2fx(wx
);
140 n
.m_aPoints
[p
].y
+= f2fx(wy
);
145 m_pEditor
->m_Map
.m_Modified
= true;
148 void CLayerQuads::BrushFlipX()
152 void CLayerQuads::BrushFlipY()
156 void Rotate(vec2
*pCenter
, vec2
*pPoint
, float Rotation
)
158 float x
= pPoint
->x
- pCenter
->x
;
159 float y
= pPoint
->y
- pCenter
->y
;
160 pPoint
->x
= x
* cosf(Rotation
) - y
* sinf(Rotation
) + pCenter
->x
;
161 pPoint
->y
= x
* sinf(Rotation
) + y
* cosf(Rotation
) + pCenter
->y
;
164 void CLayerQuads::BrushRotate(float Amount
)
167 GetSize(&Center
.x
, &Center
.y
);
171 for(int i
= 0; i
< m_lQuads
.size(); i
++)
173 CQuad
*q
= &m_lQuads
[i
];
175 for(int p
= 0; p
< 5; p
++)
177 vec2
Pos(fx2f(q
->m_aPoints
[p
].x
), fx2f(q
->m_aPoints
[p
].y
));
178 Rotate(&Center
, &Pos
, Amount
);
179 q
->m_aPoints
[p
].x
= f2fx(Pos
.x
);
180 q
->m_aPoints
[p
].y
= f2fx(Pos
.y
);
185 void CLayerQuads::GetSize(float *w
, float *h
)
189 for(int i
= 0; i
< m_lQuads
.size(); i
++)
191 for(int p
= 0; p
< 5; p
++)
193 *w
= max(*w
, fx2f(m_lQuads
[i
].m_aPoints
[p
].x
));
194 *h
= max(*h
, fx2f(m_lQuads
[i
].m_aPoints
[p
].y
));
199 extern int gs_SelectedPoints
;
201 int CLayerQuads::RenderProperties(CUIRect
*pToolBox
)
210 CProperty aProps
[] = {
211 {"Image", m_Image
, PROPTYPE_IMAGE
, -1, 0},
215 static int s_aIds
[NUM_PROPS
] = {0};
217 int Prop
= m_pEditor
->DoProperties(pToolBox
, aProps
, s_aIds
, &NewVal
);
219 m_pEditor
->m_Map
.m_Modified
= true;
221 if(Prop
== PROP_IMAGE
)
224 m_Image
= NewVal
%m_pEditor
->m_Map
.m_lImages
.size();
233 void CLayerQuads::ModifyImageIndex(INDEX_MODIFY_FUNC Func
)
238 void CLayerQuads::ModifyEnvelopeIndex(INDEX_MODIFY_FUNC Func
)
240 for(int i
= 0; i
< m_lQuads
.size(); i
++)
242 Func(&m_lQuads
[i
].m_PosEnv
);
243 Func(&m_lQuads
[i
].m_ColorEnv
);