SDL  2.0
SDL_rotate.c File Reference
#include "../../SDL_internal.h"
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#include "SDL_rotate.h"
+ Include dependency graph for SDL_rotate.c:

Go to the source code of this file.

Data Structures

struct  tColorRGBA
 
struct  tColorY
 

Macros

#define MAX(a, b)   (((a) > (b)) ? (a) : (b))
 
#define GUARD_ROWS   (2)
 
#define VALUE_LIMIT   0.001
 

Functions

static Uint32 _colorkey (SDL_Surface *src)
 
void SDLgfx_rotozoomSurfaceSizeTrig (int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle)
 
static void _transformSurfaceRGBA (SDL_Surface *src, SDL_Surface *dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
 
static void transformSurfaceY (SDL_Surface *src, SDL_Surface *dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
 
SDL_SurfaceSDLgfx_rotateSurface (SDL_Surface *src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle)
 

Macro Definition Documentation

#define GUARD_ROWS   (2)

Definition at line 77 of file SDL_rotate.c.

Referenced by SDLgfx_rotateSurface().

#define MAX (   a,
  b 
)    (((a) > (b)) ? (a) : (b))

Definition at line 65 of file SDL_rotate.c.

Referenced by SDLgfx_rotozoomSurfaceSizeTrig().

#define VALUE_LIMIT   0.001

Definition at line 82 of file SDL_rotate.c.

Function Documentation

static Uint32 _colorkey ( SDL_Surface src)
static

Definition at line 88 of file SDL_rotate.c.

References SDL_GetColorKey.

Referenced by SDLgfx_rotateSurface(), and transformSurfaceY().

89 {
90  Uint32 key = 0;
91  SDL_GetColorKey(src, &key);
92  return key;
93 }
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
#define SDL_GetColorKey
static void _transformSurfaceRGBA ( SDL_Surface src,
SDL_Surface dst,
int  cx,
int  cy,
int  isin,
int  icos,
int  flipx,
int  flipy,
int  smooth 
)
static

Definition at line 159 of file SDL_rotate.c.

References tColorRGBA::a, tColorRGBA::b, tColorRGBA::g, SDL_Surface::h, SDL_Surface::pitch, SDL_Surface::pixels, tColorRGBA::r, and SDL_Surface::w.

Referenced by SDLgfx_rotateSurface().

160 {
161  int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
162  tColorRGBA c00, c01, c10, c11, cswap;
163  tColorRGBA *pc, *sp;
164  int gap;
165 
166  /*
167  * Variable setup
168  */
169  xd = ((src->w - dst->w) << 15);
170  yd = ((src->h - dst->h) << 15);
171  ax = (cx << 16) - (icos * cx);
172  ay = (cy << 16) - (isin * cx);
173  sw = src->w - 1;
174  sh = src->h - 1;
175  pc = (tColorRGBA*) dst->pixels;
176  gap = dst->pitch - dst->w * 4;
177 
178  /*
179  * Switch between interpolating and non-interpolating code
180  */
181  if (smooth) {
182  for (y = 0; y < dst->h; y++) {
183  dy = cy - y;
184  sdx = (ax + (isin * dy)) + xd;
185  sdy = (ay - (icos * dy)) + yd;
186  for (x = 0; x < dst->w; x++) {
187  dx = (sdx >> 16);
188  dy = (sdy >> 16);
189  if (flipx) dx = sw - dx;
190  if (flipy) dy = sh - dy;
191  if ((unsigned)dx < (unsigned)sw && (unsigned)dy < (unsigned)sh) {
192  sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx;
193  c00 = *sp;
194  sp += 1;
195  c01 = *sp;
196  sp += (src->pitch/4);
197  c11 = *sp;
198  sp -= 1;
199  c10 = *sp;
200  if (flipx) {
201  cswap = c00; c00=c01; c01=cswap;
202  cswap = c10; c10=c11; c11=cswap;
203  }
204  if (flipy) {
205  cswap = c00; c00=c10; c10=cswap;
206  cswap = c01; c01=c11; c11=cswap;
207  }
208  /*
209  * Interpolate colors
210  */
211  ex = (sdx & 0xffff);
212  ey = (sdy & 0xffff);
213  t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
214  t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
215  pc->r = (((t2 - t1) * ey) >> 16) + t1;
216  t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
217  t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
218  pc->g = (((t2 - t1) * ey) >> 16) + t1;
219  t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
220  t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
221  pc->b = (((t2 - t1) * ey) >> 16) + t1;
222  t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
223  t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
224  pc->a = (((t2 - t1) * ey) >> 16) + t1;
225  }
226  sdx += icos;
227  sdy += isin;
228  pc++;
229  }
230  pc = (tColorRGBA *) ((Uint8 *) pc + gap);
231  }
232  } else {
233  for (y = 0; y < dst->h; y++) {
234  dy = cy - y;
235  sdx = (ax + (isin * dy)) + xd;
236  sdy = (ay - (icos * dy)) + yd;
237  for (x = 0; x < dst->w; x++) {
238  dx = (sdx >> 16);
239  dy = (sdy >> 16);
240  if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
241  if(flipx) dx = sw - dx;
242  if(flipy) dy = sh - dy;
243  *pc = *((tColorRGBA *)((Uint8 *)src->pixels + src->pitch * dy) + dx);
244  }
245  sdx += icos;
246  sdy += isin;
247  pc++;
248  }
249  pc = (tColorRGBA *) ((Uint8 *) pc + gap);
250  }
251  }
252 }
Uint8 a
Definition: SDL_rotate.c:52
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
void * pixels
Definition: SDL_surface.h:75
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
Uint8 r
Definition: SDL_rotate.c:49
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
Uint8 b
Definition: SDL_rotate.c:51
Uint8 g
Definition: SDL_rotate.c:50
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 at line 340 of file SDL_rotate.c.

References _colorkey(), _transformSurfaceRGBA(), SDL_PixelFormat::Amask, tColorRGBA::b, SDL_PixelFormat::BitsPerPixel, blendMode, SDL_PixelFormat::Bmask, SDL_Palette::colors, SDL_Surface::flags, SDL_Surface::format, tColorRGBA::g, SDL_PixelFormat::Gmask, GUARD_ROWS, SDL_Surface::h, i, SDL_Palette::ncolors, NULL, SDL_PixelFormat::palette, tColorRGBA::r, SDL_PixelFormat::Rmask, SDL_BYTEORDER, SDL_ConvertSurfaceFormat, SDL_CreateRGBSurface, SDL_FillRect, SDL_FreeSurface, SDL_GetRGB, SDL_GetSurfaceAlphaMod, SDL_GetSurfaceBlendMode, SDL_GetSurfaceColorMod, SDL_LIL_ENDIAN, SDL_LockSurface, SDL_MapRGB, SDL_MasksToPixelFormatEnum, SDL_MUSTLOCK, SDL_RLEACCEL, SDL_SetColorKey, SDL_SetSurfaceAlphaMod, SDL_SetSurfaceBlendMode, SDL_SetSurfaceColorMod, SDL_SWSURFACE, SDL_TRUE, SDL_UnlockSurface, and transformSurfaceY().

Referenced by SW_RenderCopyEx().

341 {
342  SDL_Surface *rz_src;
343  SDL_Surface *rz_dst;
344  int is32bit;
345  int i;
346  Uint8 r,g,b;
347  Uint32 colorkey = 0;
348  int colorKeyAvailable = 0;
349  double sangleinv, cangleinv;
350 
351  /*
352  * Sanity check
353  */
354  if (src == NULL)
355  return (NULL);
356 
357  if (src->flags & SDL_TRUE/* SDL_SRCCOLORKEY */)
358  {
359  colorkey = _colorkey(src);
360  SDL_GetRGB(colorkey, src->format, &r, &g, &b);
361  colorKeyAvailable = 1;
362  }
363  /*
364  * Determine if source surface is 32bit or 8bit
365  */
366  is32bit = (src->format->BitsPerPixel == 32);
367  if ((is32bit) || (src->format->BitsPerPixel == 8)) {
368  /*
369  * Use source surface 'as is'
370  */
371  rz_src = src;
372  } else {
375  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
376 #else
377  0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
378 #endif
379  );
380  rz_src = SDL_ConvertSurfaceFormat(src, format, src->flags);
381  is32bit = 1;
382  }
383 
384 
385  /* Determine target size */
386  /* _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, &dstwidth, &dstheight, &cangle, &sangle); */
387 
388  /*
389  * Calculate target factors from sin/cos and zoom
390  */
391  sangleinv = sangle*65536.0;
392  cangleinv = cangle*65536.0;
393 
394  /*
395  * Alloc space to completely contain the rotated surface
396  */
397  rz_dst = NULL;
398  if (is32bit) {
399  /*
400  * Target surface is 32bit with source RGBA/ABGR ordering
401  */
402  rz_dst =
403  SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
404  rz_src->format->Rmask, rz_src->format->Gmask,
405  rz_src->format->Bmask, rz_src->format->Amask);
406  } else {
407  /*
408  * Target surface is 8bit
409  */
410  rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
411  }
412 
413  /* Check target */
414  if (rz_dst == NULL)
415  return NULL;
416 
417  /* Adjust for guard rows */
418  rz_dst->h = dstheight;
419 
420  if (colorKeyAvailable == 1){
421  colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
422 
423  SDL_FillRect(rz_dst, NULL, colorkey );
424  }
425 
426  /*
427  * Lock source surface
428  */
429  if (SDL_MUSTLOCK(rz_src)) {
430  SDL_LockSurface(rz_src);
431  }
432 
433  /*
434  * Check which kind of surface we have
435  */
436  if (is32bit) {
437  /*
438  * Call the 32bit transformation routine to do the rotation (using sw_64)
439  */
440  _transformSurfaceRGBA(rz_src, rz_dst, centerx, centery,
441  (int) (sangleinv), (int) (cangleinv),
442  flipx, flipy,
443  smooth);
444  /*
445  * Turn on source-alpha support
446  */
447  /* SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); */
448  SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src));
449  } else {
450  /*
451  * Copy palette and colorkey info
452  */
453  for (i = 0; i < rz_src->format->palette->ncolors; i++) {
454  rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
455  }
456  rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
457  /*
458  * Call the 8bit transformation routine to do the rotation
459  */
460  transformSurfaceY(rz_src, rz_dst, centerx, centery,
461  (int) (sangleinv), (int) (cangleinv),
462  flipx, flipy);
463  SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src));
464  }
465 
466  /* copy alpha mod, color mod, and blend mode */
467  {
469  Uint8 alphaMod, cr, cg, cb;
470  SDL_GetSurfaceAlphaMod(src, &alphaMod);
471  SDL_GetSurfaceBlendMode(src, &blendMode);
472  SDL_GetSurfaceColorMod(src, &cr, &cg, &cb);
473  SDL_SetSurfaceAlphaMod(rz_dst, alphaMod);
474  SDL_SetSurfaceBlendMode(rz_dst, blendMode);
475  SDL_SetSurfaceColorMod(rz_dst, cr, cg, cb);
476  }
477 
478  /*
479  * Unlock source surface
480  */
481  if (SDL_MUSTLOCK(rz_src)) {
482  SDL_UnlockSurface(rz_src);
483  }
484 
485  /*
486  * Cleanup temp surface
487  */
488  if (rz_src != src) {
489  SDL_FreeSurface(rz_src);
490  }
491 
492  /*
493  * Return destination surface
494  */
495  return (rz_dst);
496 }
#define SDL_GetRGB
#define SDL_ConvertSurfaceFormat
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
#define SDL_UnlockSurface
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
#define SDL_SWSURFACE
Definition: SDL_surface.h:52
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
#define SDL_MasksToPixelFormatEnum
#define GUARD_ROWS
Definition: SDL_rotate.c:77
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
#define SDL_LIL_ENDIAN
Definition: SDL_endian.h:37
Uint32 flags
Definition: SDL_surface.h:71
#define SDL_GetSurfaceBlendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
GLboolean GLboolean g
#define SDL_FreeSurface
#define SDL_SetSurfaceColorMod
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
Uint8 BitsPerPixel
Definition: SDL_pixels.h:303
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:273
#define SDL_SetColorKey
#define SDL_GetSurfaceAlphaMod
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:42
#define NULL
Definition: begin_code.h:143
SDL_Color * colors
Definition: SDL_pixels.h:291
SDL_PixelFormat * format
Definition: SDL_surface.h:72
#define SDL_LockSurface
#define SDL_CreateRGBSurface
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
#define SDL_GetSurfaceColorMod
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
#define SDL_SetSurfaceBlendMode
#define SDL_FillRect
#define SDL_MapRGB
static Uint32 _colorkey(SDL_Surface *src)
Definition: SDL_rotate.c:88
SDL_Palette * palette
Definition: SDL_pixels.h:302
GLenum src
GLboolean GLboolean GLboolean b
#define SDL_BYTEORDER
#define SDL_SetSurfaceAlphaMod
#define SDL_RLEACCEL
Definition: SDL_surface.h:54
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:159
void SDLgfx_rotozoomSurfaceSizeTrig ( int  width,
int  height,
double  angle,
int *  dstwidth,
int *  dstheight,
double *  cangle,
double *  sangle 
)

Definition at line 109 of file SDL_rotate.c.

References M_PI, MAX, SDL_ceil, SDL_cos, SDL_fabs, and SDL_sin.

Referenced by SW_RenderCopyEx().

112 {
113  double x, y, cx, cy, sx, sy;
114  double radangle;
115  int dstwidthhalf, dstheighthalf;
116 
117  /*
118  * Determine destination width and height by rotating a centered source box
119  */
120  radangle = angle * (M_PI / 180.0);
121  *sangle = SDL_sin(radangle);
122  *cangle = SDL_cos(radangle);
123  x = (double)(width / 2);
124  y = (double)(height / 2);
125  cx = *cangle * x;
126  cy = *cangle * y;
127  sx = *sangle * x;
128  sy = *sangle * y;
129 
130  dstwidthhalf = MAX((int)
131  SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1);
132  dstheighthalf = MAX((int)
133  SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1);
134  *dstwidth = 2 * dstwidthhalf;
135  *dstheight = 2 * dstheighthalf;
136 }
#define SDL_ceil
#define SDL_fabs
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
#define SDL_cos
#define M_PI
Definition: SDL_stdinc.h:436
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
GLfloat angle
#define MAX(a, b)
Definition: SDL_rotate.c:65
#define SDL_sin
static void transformSurfaceY ( SDL_Surface src,
SDL_Surface dst,
int  cx,
int  cy,
int  isin,
int  icos,
int  flipx,
int  flipy 
)
static

Definition at line 273 of file SDL_rotate.c.

References _colorkey(), SDL_Surface::h, SDL_Surface::pitch, SDL_Surface::pixels, SDL_memset, and SDL_Surface::w.

Referenced by SDLgfx_rotateSurface().

274 {
275  int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay;
276  tColorY *pc;
277  int gap;
278 
279  /*
280  * Variable setup
281  */
282  xd = ((src->w - dst->w) << 15);
283  yd = ((src->h - dst->h) << 15);
284  ax = (cx << 16) - (icos * cx);
285  ay = (cy << 16) - (isin * cx);
286  pc = (tColorY*) dst->pixels;
287  gap = dst->pitch - dst->w;
288  /*
289  * Clear surface to colorkey
290  */
291  SDL_memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h);
292  /*
293  * Iterate through destination surface
294  */
295  for (y = 0; y < dst->h; y++) {
296  dy = cy - y;
297  sdx = (ax + (isin * dy)) + xd;
298  sdy = (ay - (icos * dy)) + yd;
299  for (x = 0; x < dst->w; x++) {
300  dx = (sdx >> 16);
301  dy = (sdy >> 16);
302  if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
303  if (flipx) dx = (src->w-1)-dx;
304  if (flipy) dy = (src->h-1)-dy;
305  *pc = *((tColorY *)src->pixels + src->pitch * dy + dx);
306  }
307  sdx += icos;
308  sdy += isin;
309  pc++;
310  }
311  pc += gap;
312  }
313 }
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
void * pixels
Definition: SDL_surface.h:75
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
static Uint32 _colorkey(SDL_Surface *src)
Definition: SDL_rotate.c:88
#define SDL_memset