SDL  2.0
SDL_rotate.c
Go to the documentation of this file.
1 /*
2 
3 SDL_rotate.c: rotates 32bit or 8bit surfaces
4 
5 Shamelessly stolen from SDL_gfx by Andreas Schiffler. Original copyright follows:
6 
7 Copyright (C) 2001-2011 Andreas Schiffler
8 
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any damages
11 arising from the use of this software.
12 
13 Permission is granted to anyone to use this software for any purpose,
14 including commercial applications, and to alter it and redistribute it
15 freely, subject to the following restrictions:
16 
17  1. The origin of this software must not be misrepresented; you must not
18  claim that you wrote the original software. If you use this software
19  in a product, an acknowledgment in the product documentation would be
20  appreciated but is not required.
21 
22  2. Altered source versions must be plainly marked as such, and must not be
23  misrepresented as being the original software.
24 
25  3. This notice may not be removed or altered from any source
26  distribution.
27 
28 Andreas Schiffler -- aschiffler at ferzkopp dot net
29 
30 */
31 #include "../../SDL_internal.h"
32 
33 #if defined(__WIN32__)
34 #include "../../core/windows/SDL_windows.h"
35 #endif
36 
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #include "SDL.h"
41 #include "SDL_rotate.h"
42 
43 /* ---- Internally used structures */
44 
45 /* !
46 \brief A 32 bit RGBA pixel.
47 */
48 typedef struct tColorRGBA {
53 } tColorRGBA;
54 
55 /* !
56 \brief A 8bit Y/palette pixel.
57 */
58 typedef struct tColorY {
60 } tColorY;
61 
62 /* !
63 \brief Returns maximum of two numbers a and b.
64 */
65 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
66 
67 /* !
68 \brief Number of guard rows added to destination surfaces.
69 
70 This is a simple but effective workaround for observed issues.
71 These rows allocate extra memory and are then hidden from the surface.
72 Rows are added to the end of destination surfaces when they are allocated.
73 This catches any potential overflows which seem to happen with
74 just the right src image dimensions and scale/rotation and can lead
75 to a situation where the program can segfault.
76 */
77 #define GUARD_ROWS (2)
78 
79 /* !
80 \brief Returns colorkey info for a surface
81 */
82 static Uint32
84 {
85  Uint32 key = 0;
86  SDL_GetColorKey(src, &key);
87  return key;
88 }
89 
90 
91 /* !
92 \brief Internal target surface sizing function for rotations with trig result return.
93 
94 \param width The source surface width.
95 \param height The source surface height.
96 \param angle The angle to rotate in degrees.
97 \param dstwidth The calculated width of the destination surface.
98 \param dstheight The calculated height of the destination surface.
99 \param cangle The sine of the angle
100 \param sangle The cosine of the angle
101 
102 */
103 void
105  int *dstwidth, int *dstheight,
106  double *cangle, double *sangle)
107 {
108  /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */
109  int angle90 = (int)(angle/90);
110  if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */
111  angle90 %= 4;
112  if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
113  if(angle90 & 1) {
114  *dstwidth = height;
115  *dstheight = width;
116  *cangle = 0;
117  *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */
118  } else {
119  *dstwidth = width;
120  *dstheight = height;
121  *cangle = angle90 == 0 ? 1 : -1;
122  *sangle = 0;
123  }
124  } else {
125  double x, y, cx, cy, sx, sy;
126  double radangle;
127  int dstwidthhalf, dstheighthalf;
128  /*
129  * Determine destination width and height by rotating a centered source box
130  */
131  radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */
132  *sangle = SDL_sin(radangle);
133  *cangle = SDL_cos(radangle);
134  x = (double)(width / 2);
135  y = (double)(height / 2);
136  cx = *cangle * x;
137  cy = *cangle * y;
138  sx = *sangle * x;
139  sy = *sangle * y;
140 
141  dstwidthhalf = MAX((int)
142  SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1);
143  dstheighthalf = MAX((int)
144  SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1);
145  *dstwidth = 2 * dstwidthhalf;
146  *dstheight = 2 * dstheighthalf;
147  }
148 }
149 
150 /* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */
151 static void
152 computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy,
153  int *sincx, int *sincy, int *signx, int *signy)
154 {
155  int pitch = flipy ? -src->pitch : src->pitch;
156  if (flipx) {
157  bpp = -bpp;
158  }
159  switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
160  case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break;
161  case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break;
162  case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break;
163  case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break;
164  }
165  if (flipx) {
166  *signx = -*signx;
167  }
168  if (flipy) {
169  *signy = -*signy;
170  }
171 }
172 
173 /* Performs a relatively fast rotation/flip when the angle is a multiple of 90 degrees. */
174 #define TRANSFORM_SURFACE_90(pixelType) \
175  int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy; \
176  Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de; \
177  \
178  computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \
179  if (signx < 0) sp += (src->w-1)*sizeof(pixelType); \
180  if (signy < 0) sp += (src->h-1)*src->pitch; \
181  \
182  for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \
183  if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \
184  SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \
185  sp += dst->w*sizeof(pixelType); \
186  dp += dst->w*sizeof(pixelType); \
187  } else { \
188  for (de = dp + dst->w*sizeof(pixelType); dp != de; sp += sincx, dp += sizeof(pixelType)) { \
189  *(pixelType*)dp = *(pixelType*)sp; \
190  } \
191  } \
192  }
193 
194 static void
195 transformSurfaceRGBA90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy)
196 {
198 }
199 
200 static void
201 transformSurfaceY90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy)
202 {
204 }
205 
206 #undef TRANSFORM_SURFACE_90
207 
208 /* !
209 \brief Internal 32 bit rotozoomer with optional anti-aliasing.
210 
211 Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
212 parameters by scanning the destination surface and applying optionally anti-aliasing
213 by bilinear interpolation.
214 Assumes src and dst surfaces are of 32 bit depth.
215 Assumes dst surface was allocated with the correct dimensions.
216 
217 \param src Source surface.
218 \param dst Destination surface.
219 \param cx Horizontal center coordinate.
220 \param cy Vertical center coordinate.
221 \param isin Integer version of sine of angle.
222 \param icos Integer version of cosine of angle.
223 \param flipx Flag indicating horizontal mirroring should be applied.
224 \param flipy Flag indicating vertical mirroring should be applied.
225 \param smooth Flag indicating anti-aliasing should be used.
226 */
227 static void
228 _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
229 {
230  int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
231  tColorRGBA c00, c01, c10, c11, cswap;
232  tColorRGBA *pc, *sp;
233  int gap;
234 
235  /*
236  * Variable setup
237  */
238  xd = ((src->w - dst->w) << 15);
239  yd = ((src->h - dst->h) << 15);
240  ax = (cx << 16) - (icos * cx);
241  ay = (cy << 16) - (isin * cx);
242  sw = src->w - 1;
243  sh = src->h - 1;
244  pc = (tColorRGBA*) dst->pixels;
245  gap = dst->pitch - dst->w * 4;
246 
247  /*
248  * Switch between interpolating and non-interpolating code
249  */
250  if (smooth) {
251  for (y = 0; y < dst->h; y++) {
252  dy = cy - y;
253  sdx = (ax + (isin * dy)) + xd;
254  sdy = (ay - (icos * dy)) + yd;
255  for (x = 0; x < dst->w; x++) {
256  dx = (sdx >> 16);
257  dy = (sdy >> 16);
258  if (flipx) dx = sw - dx;
259  if (flipy) dy = sh - dy;
260  if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) {
261  sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx;
262  c00 = *sp;
263  sp += 1;
264  c01 = *sp;
265  sp += (src->pitch/4);
266  c11 = *sp;
267  sp -= 1;
268  c10 = *sp;
269  if (flipx) {
270  cswap = c00; c00=c01; c01=cswap;
271  cswap = c10; c10=c11; c11=cswap;
272  }
273  if (flipy) {
274  cswap = c00; c00=c10; c10=cswap;
275  cswap = c01; c01=c11; c11=cswap;
276  }
277  /*
278  * Interpolate colors
279  */
280  ex = (sdx & 0xffff);
281  ey = (sdy & 0xffff);
282  t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
283  t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
284  pc->r = (((t2 - t1) * ey) >> 16) + t1;
285  t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
286  t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
287  pc->g = (((t2 - t1) * ey) >> 16) + t1;
288  t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
289  t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
290  pc->b = (((t2 - t1) * ey) >> 16) + t1;
291  t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
292  t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
293  pc->a = (((t2 - t1) * ey) >> 16) + t1;
294  }
295  sdx += icos;
296  sdy += isin;
297  pc++;
298  }
299  pc = (tColorRGBA *) ((Uint8 *) pc + gap);
300  }
301  } else {
302  for (y = 0; y < dst->h; y++) {
303  dy = cy - y;
304  sdx = (ax + (isin * dy)) + xd;
305  sdy = (ay - (icos * dy)) + yd;
306  for (x = 0; x < dst->w; x++) {
307  dx = (sdx >> 16);
308  dy = (sdy >> 16);
309  if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
310  if(flipx) dx = sw - dx;
311  if(flipy) dy = sh - dy;
312  *pc = *((tColorRGBA *)((Uint8 *)src->pixels + src->pitch * dy) + dx);
313  }
314  sdx += icos;
315  sdy += isin;
316  pc++;
317  }
318  pc = (tColorRGBA *) ((Uint8 *) pc + gap);
319  }
320  }
321 }
322 
323 /* !
324 
325 \brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing.
326 
327 Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
328 parameters by scanning the destination surface.
329 Assumes src and dst surfaces are of 8 bit depth.
330 Assumes dst surface was allocated with the correct dimensions.
331 
332 \param src Source surface.
333 \param dst Destination surface.
334 \param cx Horizontal center coordinate.
335 \param cy Vertical center coordinate.
336 \param isin Integer version of sine of angle.
337 \param icos Integer version of cosine of angle.
338 \param flipx Flag indicating horizontal mirroring should be applied.
339 \param flipy Flag indicating vertical mirroring should be applied.
340 */
341 static void
342 transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
343 {
344  int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay;
345  tColorY *pc;
346  int gap;
347 
348  /*
349  * Variable setup
350  */
351  xd = ((src->w - dst->w) << 15);
352  yd = ((src->h - dst->h) << 15);
353  ax = (cx << 16) - (icos * cx);
354  ay = (cy << 16) - (isin * cx);
355  pc = (tColorY*) dst->pixels;
356  gap = dst->pitch - dst->w;
357  /*
358  * Clear surface to colorkey
359  */
360  SDL_memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h);
361  /*
362  * Iterate through destination surface
363  */
364  for (y = 0; y < dst->h; y++) {
365  dy = cy - y;
366  sdx = (ax + (isin * dy)) + xd;
367  sdy = (ay - (icos * dy)) + yd;
368  for (x = 0; x < dst->w; x++) {
369  dx = (sdx >> 16);
370  dy = (sdy >> 16);
371  if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
372  if (flipx) dx = (src->w-1)-dx;
373  if (flipy) dy = (src->h-1)-dy;
374  *pc = *((tColorY *)src->pixels + src->pitch * dy + dx);
375  }
376  sdx += icos;
377  sdy += isin;
378  pc++;
379  }
380  pc += gap;
381  }
382 }
383 
384 
385 /* !
386 \brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
387 
388 Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface.
389 'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set
390 then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit
391 surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes).
392 The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE
393 mode will set the BLEND mode on the 'dst' surface. The MOD mode either generates a white 'dst'
394 surface and sets the colorkey or fills the it with the colorkey before copying the pixels.
395 When using the NONE and MOD modes, color and alpha modulation must be applied before using this function.
396 
397 \param src The surface to rotozoom.
398 \param angle The angle to rotate in degrees.
399 \param centerx The horizontal coordinate of the center of rotation
400 \param zoomy The vertical coordinate of the center of rotation
401 \param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
402 \param flipx Set to 1 to flip the image horizontally
403 \param flipy Set to 1 to flip the image vertically
404 \param dstwidth The destination surface width
405 \param dstheight The destination surface height
406 \param cangle The angle cosine
407 \param sangle The angle sine
408 \return The new rotated surface.
409 
410 */
411 
412 SDL_Surface *
413 SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle)
414 {
415  SDL_Surface *rz_dst;
416  int is8bit, angle90;
417  int i;
418  SDL_BlendMode blendmode;
419  Uint32 colorkey = 0;
420  int colorKeyAvailable = SDL_FALSE;
421  double sangleinv, cangleinv;
422 
423  /* Sanity check */
424  if (src == NULL)
425  return NULL;
426 
427  if (SDL_GetColorKey(src, &colorkey) == 0) {
428  colorKeyAvailable = SDL_TRUE;
429  }
430 
431  /* This function requires a 32-bit surface or 8-bit surface with a colorkey */
432  is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable;
433  if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask)))
434  return NULL;
435 
436  /* Calculate target factors from sin/cos and zoom */
437  sangleinv = sangle*65536.0;
438  cangleinv = cangle*65536.0;
439 
440  /* Alloc space to completely contain the rotated surface */
441  rz_dst = NULL;
442  if (is8bit) {
443  /* Target surface is 8 bit */
444  rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
445  if (rz_dst != NULL) {
446  for (i = 0; i < src->format->palette->ncolors; i++) {
447  rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
448  }
449  rz_dst->format->palette->ncolors = src->format->palette->ncolors;
450  }
451  } else {
452  /* Target surface is 32 bit with source RGBA ordering */
453  rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32,
454  src->format->Rmask, src->format->Gmask,
455  src->format->Bmask, src->format->Amask);
456  }
457 
458  /* Check target */
459  if (rz_dst == NULL)
460  return NULL;
461 
462  /* Adjust for guard rows */
463  rz_dst->h = dstheight;
464 
465  SDL_GetSurfaceBlendMode(src, &blendmode);
466 
467  if (colorKeyAvailable == SDL_TRUE) {
468  /* If available, the colorkey will be used to discard the pixels that are outside of the rotated area. */
469  SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey);
470  SDL_FillRect(rz_dst, NULL, colorkey);
471  } else if (blendmode == SDL_BLENDMODE_NONE) {
472  blendmode = SDL_BLENDMODE_BLEND;
473  } else if (blendmode == SDL_BLENDMODE_MOD) {
474  /* Without a colorkey, the target texture has to be white for the MOD blend mode so
475  * that the pixels outside the rotated area don't affect the destination surface.
476  */
477  colorkey = SDL_MapRGBA(rz_dst->format, 255, 255, 255, 0);
478  SDL_FillRect(rz_dst, NULL, colorkey);
479  /* Setting a white colorkey for the destination surface makes the final blit discard
480  * all pixels outside of the rotated area. This doesn't interfere with anything because
481  * white pixels are already a no-op and the MOD blend mode does not interact with alpha.
482  */
483  SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey);
484  }
485 
486  SDL_SetSurfaceBlendMode(rz_dst, blendmode);
487 
488  /* Lock source surface */
489  if (SDL_MUSTLOCK(src)) {
490  SDL_LockSurface(src);
491  }
492 
493  /* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce
494  * the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near
495  * multiples of 90 degrees.
496  */
497  angle90 = (int)(angle/90);
498  if (angle90 == angle/90) {
499  angle90 %= 4;
500  if (angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
501  } else {
502  angle90 = -1;
503  }
504 
505  if (is8bit) {
506  /* Call the 8-bit transformation routine to do the rotation */
507  if(angle90 >= 0) {
508  transformSurfaceY90(src, rz_dst, angle90, flipx, flipy);
509  } else {
510  transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
511  flipx, flipy);
512  }
513  } else {
514  /* Call the 32-bit transformation routine to do the rotation */
515  if (angle90 >= 0) {
516  transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy);
517  } else {
518  _transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
519  flipx, flipy, smooth);
520  }
521  }
522 
523  /* Unlock source surface */
524  if (SDL_MUSTLOCK(src)) {
525  SDL_UnlockSurface(src);
526  }
527 
528  /* Return rotated surface */
529  return rz_dst;
530 }
#define SDL_UnlockSurface
#define SDL_ceil
Uint8 y
Definition: SDL_rotate.c:59
GLenum GLenum dst
#define SDL_MapRGBA
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
#define SDL_fabs
#define GUARD_ROWS
Definition: SDL_rotate.c:77
static void computeSourceIncrements90(SDL_Surface *src, int bpp, int angle, int flipx, int flipy, int *sincx, int *sincy, int *signx, int *signy)
Definition: SDL_rotate.c:152
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
static void transformSurfaceRGBA90(SDL_Surface *src, SDL_Surface *dst, int angle, int flipx, int flipy)
Definition: SDL_rotate.c:195
Uint8 a
Definition: SDL_rotate.c:52
uint32_t Uint32
Definition: SDL_stdinc.h:181
GLenum src
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
#define SDL_GetSurfaceBlendMode
GLuint64 key
Definition: gl2ext.h:2192
void * pixels
Definition: SDL_surface.h:75
#define SDL_GetColorKey
uint8_t Uint8
Definition: SDL_stdinc.h:157
Uint8 BitsPerPixel
Definition: SDL_pixels.h:319
#define SDL_cos
static void transformSurfaceY(SDL_Surface *src, SDL_Surface *dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
Definition: SDL_rotate.c:342
#define SDL_SetColorKey
static void transformSurfaceY90(SDL_Surface *src, SDL_Surface *dst, int angle, int flipx, int flipy)
Definition: SDL_rotate.c:201
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:164
SDL_Color * colors
Definition: SDL_pixels.h:307
SDL_PixelFormat * format
Definition: SDL_surface.h:72
Uint8 r
Definition: SDL_rotate.c:49
#define SDL_LockSurface
#define TRANSFORM_SURFACE_90(pixelType)
Definition: SDL_rotate.c:174
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
#define SDL_CreateRGBSurface
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
#define SDL_SetSurfaceBlendMode
#define SDL_FillRect
GLfloat angle
static Uint32 _colorkey(SDL_Surface *src)
Definition: SDL_rotate.c:83
#define MAX(a, b)
Definition: SDL_rotate.c:65
SDL_Palette * palette
Definition: SDL_pixels.h:318
SDL_Surface * SDLgfx_rotateSurface(SDL_Surface *src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle)
Definition: SDL_rotate.c:413
void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle)
Definition: SDL_rotate.c:104
Uint8 b
Definition: SDL_rotate.c:51
Uint8 g
Definition: SDL_rotate.c:50
#define SDL_memset
static void _transformSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
Definition: SDL_rotate.c:228
#define SDL_sin