--- Begin Message ---
Hi,
I patched SDL-gfx to support vertical and horizontal flipping. I tryed
to keep old API to don't brake compatibility and do a patch as small as
possible :-).
You may add some #define (or change API version ?) to aware programs
that the new API support rotozoom and zoomSurface with flipping.
To use flipping, just use negative zoom ;-) E.g. zoom=(-1, 1) means
vertical flipping.
TODO :
- Test it :-(
- Write smooth version
- Optimize it ??? (a if statement in double for isn't the fastest way to
do a flipping :-()
I tested :
- zoomSurfaceRGBA without smooth with 32 bits surface (RGBA)
- transformSurfaceRGBA without smooth with 32 bits surface (RGBA)
Bye, Haypo
--- SDL_gfx-2.0.12/SDL_rotozoom.h 2004-06-01 18:20:57.000000000 +0200
+++ SDL_gfx-haypo/SDL_rotozoom.h 2004-10-03 04:16:23.000000000 +0200
@@ -67,12 +67,18 @@
DLLINTERFACE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
+ DLLINTERFACE SDL_Surface *rotozoomSurfaceXY
+ (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
/* Returns the size of the target surface for a rotozoomSurface() call */
DLLINTERFACE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
int *dstheight);
+ DLLINTERFACE void rotozoomSurfaceSizeXY
+ (int width, int height, double angle, double zoomx, double zoomy,
+ int *dstwidth, int *dstheight);
+
/*
zoomSurface()
--- SDL_gfx-2.0.12/SDL_rotozoom.c 2004-06-01 18:20:57.000000000 +0200
+++ SDL_gfx-haypo/SDL_rotozoom.c 2004-10-03 04:38:33.000000000 +0200
@@ -25,12 +25,12 @@
*/
-int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth)
+int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth)
{
int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep;
tColorRGBA *c00, *c01, *c10, *c11;
tColorRGBA *sp, *csp, *dp;
- int sgap, dgap;
+ int dgap;
/*
* Variable setup
@@ -63,6 +63,12 @@
/*
* Precalculate row increments
*/
+ sp = csp = (tColorRGBA *) src->pixels;
+ dp = (tColorRGBA *) dst->pixels;
+
+ if (flipx) csp += (src->w-1);
+ if (flipy) csp = (tColorRGBA*)( (Uint8*)csp + src->pitch*(src->h-1) );
+
csx = 0;
csax = sax;
for (x = 0; x <= dst->w; x++) {
@@ -80,12 +86,6 @@
csy += sy;
}
- /*
- * Pointer setup
- */
- sp = csp = (tColorRGBA *) src->pixels;
- dp = (tColorRGBA *) dst->pixels;
- sgap = src->pitch - src->w * 4;
dgap = dst->pitch - dst->w * 4;
/*
@@ -176,7 +176,9 @@
* Advance source pointers
*/
csax++;
- sp += (*csax >> 16);
+ sstep = (*csax >> 16);
+ if (flipx) sstep = -sstep;
+ sp += sstep;
/*
* Advance destination pointer
*/
@@ -186,7 +188,10 @@
* Advance source pointer
*/
csay++;
- csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
+ sstep = (*csay >> 16) * src->pitch;
+ if (flipy) sstep = -sstep;
+ csp = (tColorRGBA *) ((Uint8 *) csp + sstep);
+
/*
* Advance destination pointers
*/
@@ -212,7 +217,7 @@
*/
-int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
+int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy)
{
Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
Uint8 *sp, *dp, *csp;
@@ -327,7 +332,7 @@
*/
-void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int smooth)
+void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
{
int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
tColorRGBA c00, c01, c10, c11;
@@ -460,6 +465,8 @@
for (x = 0; x < dst->w; x++) {
dx = (short) (sdx >> 16);
dy = (short) (sdy >> 16);
+ if (flipx) dx = (src->w-1)-dx;
+ if (flipy) dy = (src->h-1)-dy;
if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
sp += dx;
@@ -542,7 +549,7 @@
/* Local rotozoom-size function with trig result return */
-void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight,
+void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight,
double *canglezoom, double *sanglezoom)
{
double x, y, cx, cy, sx, sy;
@@ -555,8 +562,8 @@
radangle = angle * (M_PI / 180.0);
*sanglezoom = sin(radangle);
*canglezoom = cos(radangle);
- *sanglezoom *= zoom;
- *canglezoom *= zoom;
+ *sanglezoom *= zoomx;
+ *canglezoom *= zoomx;
x = width / 2;
y = height / 2;
cx = *canglezoom * x;
@@ -574,18 +581,33 @@
/* Publically available rotozoom-size function */
-void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
+void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight)
{
double dummy_sanglezoom, dummy_canglezoom;
- rotozoomSurfaceSizeTrig(width, height, angle, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+ rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
}
+/* Publically available rotozoom-size function */
+
+void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
+{
+ double dummy_sanglezoom, dummy_canglezoom;
+
+ rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+}
/* Publically available rotozoom function */
SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth)
{
+ return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth);
+}
+
+/* Publically available rotozoom function */
+
+SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth)
+{
SDL_Surface *rz_src;
SDL_Surface *rz_dst;
double zoominv;
@@ -594,6 +616,7 @@
double x, y, cx, cy, sx, sy;
int is32bit;
int i, src_converted;
+ int flipx,flipy;
/*
* Sanity check
@@ -625,10 +648,13 @@
/*
* Sanity check zoom factor
*/
- if (zoom < VALUE_LIMIT) {
- zoom = VALUE_LIMIT;
- }
- zoominv = 65536.0 / (zoom * zoom);
+ flipx = (zoomx<0);
+ if (flipx) zoomx=-zoomx;
+ flipy = (zoomy<0);
+ if (flipy) zoomy=-zoomy;
+ if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT;
+ if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT;
+ zoominv = 65536.0 / (zoomx * zoomx);
/*
* Check if we have a rotozoom or just a zoom
@@ -643,7 +669,7 @@
*/
/* Determine target size */
- rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoom, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
+ rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
/*
* Calculate target factors from sin/cos and zoom
@@ -688,7 +714,9 @@
* Call the 32bit transformation routine to do the rotation (using alpha)
*/
transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
- (int) (sanglezoominv), (int) (canglezoominv), smooth);
+ (int) (sanglezoominv), (int) (canglezoominv),
+ flipx, flipy,
+ smooth);
/*
* Turn on source-alpha support
*/
@@ -725,7 +753,7 @@
/*
* Calculate target size
*/
- zoomSurfaceSize(rz_src->w, rz_src->h, zoom, zoom, &dstwidth, &dstheight);
+ zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
/*
* Alloc space to completely contain the zoomed surface
@@ -757,7 +785,7 @@
/*
* Call the 32bit transformation routine to do the zooming (using alpha)
*/
- zoomSurfaceRGBA(rz_src, rz_dst, smooth);
+ zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
/*
* Turn on source-alpha support
*/
@@ -773,7 +801,7 @@
/*
* Call the 8bit transformation routine to do the zooming
*/
- zoomSurfaceY(rz_src, rz_dst);
+ zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
}
/*
@@ -840,6 +868,7 @@
int dstwidth, dstheight;
int is32bit;
int i, src_converted;
+ int flipx, flipy;
/*
* Sanity check
@@ -868,6 +897,11 @@
is32bit = 1;
}
+ flipx = (zoomx<0);
+ if (flipx) zoomx = -zoomx;
+ flipy = (zoomy<0);
+ if (flipy) zoomy = -zoomy;
+
/* Get size if target */
zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
@@ -901,7 +935,7 @@
/*
* Call the 32bit transformation routine to do the zooming (using alpha)
*/
- zoomSurfaceRGBA(rz_src, rz_dst, smooth);
+ zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
/*
* Turn on source-alpha support
*/
@@ -917,7 +951,7 @@
/*
* Call the 8bit transformation routine to do the zooming
*/
- zoomSurfaceY(rz_src, rz_dst);
+ zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
}
/*
--- End Message ---