From 195772c720acfe4195bb121039a2f4b295fa729a Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 28 Oct 2002 06:19:23 +0000 Subject: [PATCH] Fix VC7 project. Make rotozoom C++, updated, junk removed, single zoom function, remove hack that causes image misalignment. --- stepmania/src/RageBitmapTexture.cpp | 12 +- stepmania/src/SDL_rotozoom.cpp | 260 ++++++++++++++++++++++++++++ stepmania/src/SDL_rotozoom.h | 48 ++++- stepmania/src/StepMania.vcproj | 14 +- 4 files changed, 318 insertions(+), 16 deletions(-) create mode 100644 stepmania/src/SDL_rotozoom.cpp diff --git a/stepmania/src/RageBitmapTexture.cpp b/stepmania/src/RageBitmapTexture.cpp index 70dd9fb74d..0eb52765fd 100644 --- a/stepmania/src/RageBitmapTexture.cpp +++ b/stepmania/src/RageBitmapTexture.cpp @@ -281,13 +281,13 @@ void RageBitmapTexture::Create( /* If zoomSurface is having problems with some pixel formats, this will * sanitize it: */ -/* if(img->format->BitsPerPixel == 8 || img->format->colorkey) { + if(img->format->BitsPerPixel == 8 || img->format->colorkey) { int mask = 0; - SDL_Surface *dst = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, img->w, img->h, PixFmtMasks[target][4], - PixFmtMasks[target][0], PixFmtMasks[target][1], PixFmtMasks[target][2], PixFmtMasks[target][3]); - SDL_FreeSurface(img); - img = dst; - } */ + /* resize currently doesn't do paletted */ + if(img->format->BytesPerPixel == 1) + ConvertSDLSurface(img, img->w, img->h, PixFmtMasks[mask][4], + PixFmtMasks[mask][0], PixFmtMasks[mask][1], PixFmtMasks[mask][2], PixFmtMasks[mask][3]); + } SDL_Surface *dst; dst = zoomSurface(img, float(m_iTextureWidth)/m_iImageWidth, float(m_iTextureHeight) / m_iImageHeight, SMOOTHING_ON); diff --git a/stepmania/src/SDL_rotozoom.cpp b/stepmania/src/SDL_rotozoom.cpp new file mode 100644 index 0000000000..15074fa5d6 --- /dev/null +++ b/stepmania/src/SDL_rotozoom.cpp @@ -0,0 +1,260 @@ +/* + + SDL_rotozoom.c - rotozoomer for 32bit or 8bit surfaces + + LGPL (c) A. Schiffler + +*/ + +#ifdef WIN32 +#include +#endif + +#include +#include + +#include "SDL_rotozoom.h" + +typedef struct tColorRGBA { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} tColorRGBA; + +typedef struct tColorY { + Uint8 y; +} tColorY; + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + +/* + + 32bit Zoomer with optional anti-aliasing by bilinear interpolation. + + Zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. + +*/ + +int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth) +{ + int x, y, sx, sy, *sax, *say; + tColorRGBA *c00, *c01, *c10, *c11; + + /* Variable setup */ + // if (smooth) { + /* For interpolation: assume source dimension is one pixel */ + /* smaller to avoid overflow on right and bottom edge. */ + /* XXX: no, this misaligns stuff; we need to clamp properly -glenn */ + // sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w); + // sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h); + // } else { + sx = (int) (65536.0 * (float) src->w / (float) dst->w); + sy = (int) (65536.0 * (float) src->h / (float) dst->h); + //} + + /* + * Allocate memory for row increments + */ + if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) + return (-1); + + if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { + free(sax); + return (-1); + } + + /* + * Precalculate row increments + */ + int csx = 0; + int *csax = sax; + for (x = 0; x <= dst->w; x++) { + *csax = csx; + csax++; + csx &= 0xffff; + csx += sx; + } + int csy = 0; + int *csay = say; + for (y = 0; y <= dst->h; y++) { + *csay = csy; + csay++; + csy &= 0xffff; + csy += sy; + } + + /* + * Pointer setup + */ + tColorRGBA *sp, *csp, *dp; + sp = csp = (tColorRGBA *) src->pixels; + dp = (tColorRGBA *) dst->pixels; + int sgap = src->pitch - src->w * 4; + int dgap = dst->pitch - dst->w * 4; + + /* Switch between interpolating and non-interpolating code */ + csay = say; + if (smooth) { + /* Interpolating Zoom */ + + /* Scan destination */ + for (y = 0; y < dst->h; y++) { + /* + * Setup color source pointers + */ + c00 = csp; + c01 = csp; + c01++; + c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch); + c11 = c10; + c11++; + csax = sax; + for (x = 0; x < dst->w; x++) { + + /* + * Interpolate colors + */ + int ex = (*csax & 0xffff); + int ey = (*csay & 0xffff); + int t1, t2; + t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; + t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; + dp->r = (Uint8)((((t2 - t1) * ey) >> 16) + t1); + t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; + t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; + dp->g = (Uint8)((((t2 - t1) * ey) >> 16) + t1); + t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; + t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; + dp->b = (Uint8)((((t2 - t1) * ey) >> 16) + t1); + t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; + t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; + dp->a = (Uint8)((((t2 - t1) * ey) >> 16) + t1); + + /* + * Advance source pointers + */ + csax++; + int sstep = (*csax >> 16); + c00 += sstep; + c01 += sstep; + c10 += sstep; + c11 += sstep; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer + */ + csay++; + csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch); + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + + } else { + /* Non-Interpolating Zoom */ + + for (y = 0; y < dst->h; y++) { + sp = csp; + csax = sax; + for (x = 0; x < dst->w; x++) { + /* Draw */ + *dp = *sp; + /* Advance source pointers */ + csax++; + sp += (*csax >> 16); + /* Advance destination pointer */ + dp++; + } + /* Advance source pointer */ + csay++; + csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch); + /* Advance destination pointers */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + + } + + /* + * Remove temp arrays + */ + free(sax); + free(say); + + return (0); +} + +#define VALUE_LIMIT 0.001 + + +/* Local rotozoom-size function with trig result return */ + + +/* + + zoomSurface() + + Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1 + then the destination 32bit surface is anti-aliased. If the surface is not 8bit + or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + +*/ + +void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight) +{ + /* + * Sanity check zoom factors + */ + if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT; + if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT; + + + /* Calculate target size */ + *dstwidth = (int) ((double) width * zoomx); + *dstheight = (int) ((double) height * zoomy); + if (*dstwidth < 1) *dstwidth = 1; + if (*dstheight < 1) *dstheight = 1; +} + +SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth) +{ + SDL_Surface *rz_dst; + int dstwidth, dstheight; + + /* + * Sanity check + */ + if (src == NULL) + return (NULL); + + /* Get size if target */ + zoomSurfaceSize(src->w, src->h, zoomx, zoomy, &dstwidth, &dstheight); + + /* Alloc space to completely contain the zoomed surface */ + /* Target surface is 32bit with source RGBA/ABGR ordering */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + src->format->Rmask, src->format->Gmask, + src->format->Bmask, src->format->Amask); + + /* + * Lock source surface + */ + SDL_LockSurface(src); + + /* Call the 32bit transformation routine to do the zooming (using alpha) */ + zoomSurfaceRGBA(src, rz_dst, smooth); + /* Turn on source-alpha support */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + /* Unlock source surface */ + SDL_UnlockSurface(src); + + /* Return destination surface */ + return (rz_dst); +} diff --git a/stepmania/src/SDL_rotozoom.h b/stepmania/src/SDL_rotozoom.h index 2fd5953981..7b0287b344 100644 --- a/stepmania/src/SDL_rotozoom.h +++ b/stepmania/src/SDL_rotozoom.h @@ -1,14 +1,27 @@ -#ifndef _SDL_rotozoom_h -#define _SDL_rotozoom_h + +/* + + SDL_rotozoom - rotozoomer + + LGPL (c) A. Schiffler + +*/ + +#ifndef SDL_rotozoom_h +#define SDL_rotozoom_h /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif +#include +#ifndef M_PI +#define M_PI 3.141592654 +#endif #include "SDL.h" + /* ---- Defines */ #define SMOOTHING_OFF 0 @@ -16,6 +29,16 @@ extern "C" /* ---- Prototypes */ +/* #ifdef WIN32 +#ifdef BUILD_DLL +#define DLLINTERFACE __declspec(dllexport) +#else +#define DLLINTERFACE __declspec(dllimport) +#endif +#else */ +#define DLLINTERFACE +/* #endif */ + /* rotozoomSurface() @@ -27,10 +50,14 @@ extern "C" */ - SDL_Surface *rotozoomSurface (const SDL_Surface * src, double angle, double zoom, - int smooth); + DLLINTERFACE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, 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); + /* zoomSurface() @@ -42,8 +69,11 @@ extern "C" */ - SDL_Surface *zoomSurface (const SDL_Surface * src, double zoomx, double zoomy, - int smooth); + DLLINTERFACE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth); + +/* Returns the size of the target surface for a zoomSurface() call */ + + DLLINTERFACE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight); /* Ends C function definitions when using C++ */ @@ -51,4 +81,4 @@ extern "C" }; #endif -#endif /* _SDL_rotozoom_h */ +#endif /* _SDL_rotozoom_h */ diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index a86e83b062..b6722429ea 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -271,6 +271,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ + + + + @@ -1001,6 +1007,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ + + + + @@ -1056,7 +1068,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ RelativePath="SDL_dither.h"> + RelativePath="SDL_rotozoom.cpp">