1 /*
2 * This file is part of Dune Legacy.
3 *
4 * Dune Legacy is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * Dune Legacy is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Dune Legacy. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef DRAWINGRECTHELPER_H
19 #define DRAWINGRECTHELPER_H
20
21 #include <SDL.h>
22
23 extern SDL_Renderer* renderer;
24
25 enum class HAlign {
26 Left,
27 Center,
28 Right,
29 };
30
31 enum class VAlign {
32 Top,
33 Center,
34 Bottom,
35 };
36
37 /**
38 Returns the width of this surface
39 \param pSurface the surface to consider
40 \return the width of pSurface
41 */
getWidth(SDL_Surface * pSurface)42 inline int getWidth(SDL_Surface *pSurface) {
43 return pSurface->w;
44 }
45
46 /**
47 Returns the height of this surface
48 \param pSurface the surface to consider
49 \return the height of pSurface
50 */
getHeight(SDL_Surface * pSurface)51 inline int getHeight(SDL_Surface *pSurface) {
52 return pSurface->h;
53 }
54
55 /**
56 Returns the width of this texture
57 \param pTexture the surface to consider
58 \return the width of pTexture
59 */
getWidth(SDL_Texture * pTexture)60 inline int getWidth(SDL_Texture *pTexture) {
61 int w;
62 SDL_QueryTexture(pTexture, nullptr, nullptr, &w, nullptr);
63 return w;
64 }
65
66 /**
67 Returns the height of this texture
68 \param pTexture the surface to consider
69 \return the height of pTexture
70 */
getHeight(SDL_Texture * pTexture)71 inline int getHeight(SDL_Texture *pTexture) {
72 int h;
73 SDL_QueryTexture(pTexture, nullptr, nullptr, nullptr, &h);
74 return h;
75 }
76
77 /**
78 Calculates the source rect for drawing the sprite at (row, col) in pSurface.
79 \param pSurface the surface to calculate the rect for
80 \param col the zero-based column index of the sprite
81 \param numCols the number of sprites per row in pSurface
82 \param row the zero-based row index of the sprite (default is 0)
83 \param numRows the number of sprites per column in pSurface (default is 1)
84 \return the rectangle for drawing the specified sprite from pSurface when passed to SDL_BlitSurface
85 */
86 inline SDL_Rect calcSpriteSourceRect(SDL_Surface *pSurface, int col, int numCols, int row = 0, int numRows = 1) {
87 SDL_Rect rect = { col * (pSurface->w/numCols), row * (pSurface->h/numRows), pSurface->w/numCols, pSurface->h/numRows };
88 return rect;
89 }
90
91 /**
92 Calculates the source rect for drawing the sprite at (row, col) in pTexture.
93 \param pTexture the texture to calculate the rect for
94 \param col the zero-based column index of the sprite
95 \param numCols the number of sprites per row in pTexture
96 \param row the zero-based row index of the sprite (default is 0)
97 \param numRows the number of sprites per column in pTexture (default is 1)
98 \return the rectangle for drawing the specified sprite from pTexture when passed to SDL_RenderCopy
99 */
100 inline SDL_Rect calcSpriteSourceRect(SDL_Texture *pTexture, int col, int numCols, int row = 0, int numRows = 1) {
101 int w;
102 int h;
103 SDL_QueryTexture(pTexture, nullptr, nullptr, &w, &h);
104 SDL_Rect rect = { col * (w/numCols), row * (h/numRows), w/numCols, h/numRows };
105 return rect;
106 }
107
108 /**
109 Calculates the drawing rectangle for drawing a sprite from pSurface at (x,y). The parameters halign and valign determine which coordinate in the sprite
110 is drawn at (x,y), e.g. if they are HAlign::Right and VAlign::Bottom the bottom right corner of the sprite is drawn at position (x,y)
111 \param pSurface the surface to calculate the rect for
112 \param x the x-coordinate
113 \param y the y-coordinate
114 \param numCols the number of sprites in each column
115 \param numRows the number of sprites in each row (default is 1)
116 \param halign the horizontal alignment of pSurface (default is HAlign::Left)
117 \param valign the vertical alignment of pSurface (default is VAlign::Top)
118 \return the rectangle for drawing pSurface at the specified position when passed to SDL_BlitSurface
119 */
120 inline SDL_Rect calcSpriteDrawingRect(SDL_Surface* pSurface, int x, int y, int numCols, int numRows = 1, HAlign halign = HAlign::Left, VAlign valign = VAlign::Top) {
121 SDL_Rect rect = { x, y, pSurface->w/numCols, pSurface->h/numRows };
122
123 switch(halign) {
124 case HAlign::Left: /*nothing*/ break;
125 case HAlign::Center: rect.x -= rect.w/2; break;
126 case HAlign::Right: rect.x -= rect.w-1; break;
127 }
128
129 switch(valign) {
130 case VAlign::Top: /*nothing*/ break;
131 case VAlign::Center: rect.y -= rect.h/2; break;
132 case VAlign::Bottom: rect.y -= rect.h-1; break;
133 }
134
135 return rect;
136 }
137
138 /**
139 Calculates the drawing rectangle for drawing a sprite from pTexture at (x,y). The parameters halign and valign determine which coordinate in the sprite
140 is drawn at (x,y), e.g. if they are HAlign::Right and VAlign::Bottom the bottom right corner of the sprite is drawn at position (x,y)
141 \param pTexture the texture to calculate the rect for
142 \param x the x-coordinate
143 \param y the y-coordinate
144 \param numCols the number of sprites in each column
145 \param numRows the number of sprites in each row (default is 1)
146 \param halign the horizontal alignment of pTexture (default is HAlign::Left)
147 \param valign the vertical alignment of pTexture (default is VAlign::Top)
148 \return the rectangle for drawing pTexture at the specified position when passed to SDL_RenderCopy
149 */
150 inline SDL_Rect calcSpriteDrawingRect(SDL_Texture* pTexture, int x, int y, int numCols, int numRows = 1, HAlign halign = HAlign::Left, VAlign valign = VAlign::Top) {
151 SDL_Rect rect = { x, y, 0, 0 };
152 SDL_QueryTexture(pTexture, nullptr, nullptr, &rect.w, &rect.h);
153
154 rect.w /= numCols;
155 rect.h /= numRows;
156
157 switch(halign) {
158 case HAlign::Left: /*nothing*/ break;
159 case HAlign::Center: rect.x -= rect.w/2; break;
160 case HAlign::Right: rect.x -= rect.w-1; break;
161 }
162
163 switch(valign) {
164 case VAlign::Top: /*nothing*/ break;
165 case VAlign::Center: rect.y -= rect.h/2; break;
166 case VAlign::Bottom: rect.y -= rect.h-1; break;
167 }
168
169 return rect;
170 }
171
172 /**
173 Calculates the drawing rectangle for drawing pSurface at (x,y). The parameters halign and valign determine which coordinate in pSurface
174 is drawn at (x,y), e.g. if they are HAlign::Right and VAlign::Bottom the bottom right corner of pSurface is drawn at position (x,y)
175 \param pSurface the surface to calculate the rect for
176 \param x the x-coordinate
177 \param y the y-coordinate
178 \param halign the horizontal alignment of pSurface (default is HAlign::Left)
179 \param valign the vertical alignment of pSurface (default is VAlign::Top)
180 \return the rectangle for drawing pSurface at the specified position when passed to SDL_BlitSurface
181 */
182 inline SDL_Rect calcDrawingRect(SDL_Surface* pSurface, int x, int y, HAlign halign = HAlign::Left, VAlign valign = VAlign::Top) {
183 return calcSpriteDrawingRect(pSurface, x, y, 1, 1, halign, valign);
184 }
185
186 /**
187 Calculates the drawing rectangle for drawing pTexture at (x,y). The parameters halign and valign determine which coordinate in pTexture
188 is drawn at (x,y), e.g. if they are HAlign::Right and VAlign::Bottom the bottom right corner of pTexture is drawn at position (x,y)
189 \param pTexture the texture to calculate the rect for
190 \param x the x-coordinate
191 \param y the y-coordinate
192 \param halign the horizontal alignment of pTexture (default is HAlign::Left)
193 \param valign the vertical alignment of pTexture (default is VAlign::Top)
194 \return the rectangle for drawing pTexture at the specified position when passed to SDL_RenderCopy
195 */
196 inline SDL_Rect calcDrawingRect(SDL_Texture* pTexture, int x, int y, HAlign halign = HAlign::Left, VAlign valign = VAlign::Top) {
197 return calcSpriteDrawingRect(pTexture, x, y, 1, 1, halign, valign);
198 }
199
200 /**
201 Returns size of the rendering target.
202 \return the rectangle describing the size (w,h) of the rendering target (x and y are always zero)
203 */
getRendererSize()204 inline SDL_Rect getRendererSize() {
205 SDL_Rect rect = {0, 0, 0, 0};
206 SDL_RenderGetLogicalSize(renderer, &rect.w, &rect.h);
207 if(rect.w == 0 || rect.h == 0) {
208 SDL_GetRendererOutputSize(renderer, &rect.w, &rect.h);
209 }
210 return rect;
211 }
212
213 /**
214 Returns the width of the rendering target.
215 \return the width of the rendering target
216 */
getRendererWidth()217 inline int getRendererWidth() {
218 return getRendererSize().w;
219 }
220
221 /**
222 Returns the height of the rendering target.
223 \return the height of the rendering target
224 */
getRendererHeight()225 inline int getRendererHeight() {
226 return getRendererSize().h;
227 }
228
229 /**
230 Calculates the drawing rectangle for drawing pSurface at the edge or in the center of rect.
231 The parameters halign and valign determine at which edge pSurface is drawn, e.g. HAlign::Left and VAlign::Top draws pSurface in the
232 top left corner.
233 \param pSurface the surface to calculate the rect for
234 \param rect the rect to center around
235 \param halign the horizontal alignment of pSurface (default is HAlign::Center)
236 \param valign the vertical alignment of pSurface (default is VAlign::Center)
237 \return the rectangle for drawing pSurface at the specified position when passed to SDL_BlitSurface
238 */
239 inline SDL_Rect calcAlignedDrawingRect(SDL_Surface* pSurface, const SDL_Rect& rect, HAlign halign = HAlign::Center, VAlign valign = VAlign::Center) {
240 int x = 0;
241 int y = 0;
242
243 switch(halign) {
244 case HAlign::Left: x = 0; break;
245 case HAlign::Center: x = rect.w/2; break;
246 case HAlign::Right: x = rect.w-1; break;
247 }
248
249 switch(valign) {
250 case VAlign::Top: y = 0; break;
251 case VAlign::Center: y = rect.h/2; break;
252 case VAlign::Bottom: y = rect.h-1; break;
253 }
254
255 return calcDrawingRect(pSurface, x, y, halign, valign);
256 }
257
258 /**
259 Calculates the drawing rectangle for drawing pSurface at the edge or in the center of the current rendering target (usually the screen).
260 The parameters halign and valign determine at which edge pSurface is drawn, e.g. HAlign::Left and VAlign::Top draws pSurface in the
261 top left corner.
262 \param pSurface the surface to calculate the rect for
263 \param halign the horizontal alignment of pSurface (default is HAlign::Center)
264 \param valign the vertical alignment of pSurface (default is VAlign::Center)
265 \return the rectangle for drawing pSurface at the specified position when passed to SDL_BlitSurface
266 */
267 inline SDL_Rect calcAlignedDrawingRect(SDL_Surface* pSurface, HAlign halign = HAlign::Center, VAlign valign = VAlign::Center) {
268 return calcAlignedDrawingRect(pSurface, getRendererSize(), halign, valign);
269 }
270
271 /**
272 Calculates the drawing rectangle for drawing pSurface at the edge or in the center of pBaseSurface.
273 The parameters halign and valign determine at which edge pSurface is drawn, e.g. HAlign::Left and VAlign::Top draws pSurface in the
274 top left corner.
275 \param pSurface the surface to calculate the rect for
276 \param pBaseSurface the rect to center around
277 \param halign the horizontal alignment of pSurface (default is HAlign::Center)
278 \param valign the vertical alignment of pSurface (default is VAlign::Center)
279 \return the rectangle for drawing pSurface at the specified position when passed to SDL_BlitSurface
280 */
281 inline SDL_Rect calcAlignedDrawingRect(SDL_Surface* pSurface, SDL_Surface* pBaseSurface, HAlign halign = HAlign::Center, VAlign valign = VAlign::Center) {
282 SDL_Rect rect = {0, 0, pBaseSurface->w, pBaseSurface->h};
283 return calcAlignedDrawingRect(pSurface, rect, halign, valign);
284 }
285
286 /**
287 Calculates the drawing rectangle for drawing pTexture at the edge or in the center of rect.
288 The parameters halign and valign determine at which edge pTexture is drawn, e.g. HAlign::Left and VAlign::Top draws pTexture in the
289 top left corner.
290 \param pTexture the texture to calculate the rect for
291 \param rect the rect to center around
292 \param halign the horizontal alignment of pTexture (default is HAlign::Center)
293 \param valign the vertical alignment of pTexture (default is VAlign::Center)
294 \return the rectangle for drawing pTexture at the specified position when passed to SDL_RenderCopy
295 */
296 inline SDL_Rect calcAlignedDrawingRect(SDL_Texture* pTexture, const SDL_Rect& rect, HAlign halign = HAlign::Center, VAlign valign = VAlign::Center) {
297 int x = 0;
298 int y = 0;
299
300 switch(halign) {
301 case HAlign::Left: x = 0; break;
302 case HAlign::Center: x = rect.w/2; break;
303 case HAlign::Right: x = rect.w-1; break;
304 }
305
306 switch(valign) {
307 case VAlign::Top: y = 0; break;
308 case VAlign::Center: y = rect.h/2; break;
309 case VAlign::Bottom: y = rect.h-1; break;
310 }
311
312 return calcDrawingRect(pTexture, x, y, halign, valign);
313 }
314
315 /**
316 Calculates the drawing rectangle for drawing pTexture at the edge or in the center of the current rendering target (usually the screen).
317 The parameters halign and valign determine at which edge pTexture is drawn, e.g. HAlign::Left and VAlign::Top draws pTexture in the
318 top left corner.
319 \param pTexture the texture to calculate the rect for
320 \param halign the horizontal alignment of pTexture (default is HAlign::Center)
321 \param valign the vertical alignment of pTexture (default is VAlign::Center)
322 \return the rectangle for drawing pTexture at the specified position when passed to SDL_RenderCopy
323 */
324 inline SDL_Rect calcAlignedDrawingRect(SDL_Texture* pTexture, HAlign halign = HAlign::Center, VAlign valign = VAlign::Center) {
325 return calcAlignedDrawingRect(pTexture, getRendererSize(), halign, valign);
326 }
327
328
329 #endif // DRAWINGRECTHELPER_H
330