diff --git a/ediv/src/dlls/graphics/SDL_rotozoom.c b/ediv/src/dlls/graphics/SDL_rotozoom.c new file mode 100644 index 0000000..69b57c9 --- /dev/null +++ b/ediv/src/dlls/graphics/SDL_rotozoom.c @@ -0,0 +1,902 @@ +/* + + SDL_rotozoom.c + + Copyright (C) A. Schiffler, July 2001 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifdef WIN32 +#include +#endif + +#include +#include + +#include "SDL_rotozoom.h" + +#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, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep; + tColorRGBA *c00, *c01, *c10, *c11; + tColorRGBA *sp, *csp, *dp; + int sgap, dgap, orderRGBA; + + /* Variable setup */ + if (smooth) + { + /* For interpolation: assume source dimension is one pixel */ + /* smaller to avoid overflow on right and bottom edge. */ + 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 */ + csx = 0; + csax = sax; + for (x = 0; x <= dst->w; x++) + { + *csax = csx; + csax++; + csx &= 0xffff; + csx += sx; + } + csy = 0; + csay = say; + for (y = 0; y <= dst->h; y++) + { + *csay = csy; + csay++; + csy &= 0xffff; + 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; + orderRGBA = (src->format->Rmask == 0x000000ff); + + /* Switch between interpolating and non-interpolating code */ + if (smooth) + { + + /* Interpolating Zoom */ + + /* Scan destination */ + csay = say; + 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++) + { + /* ABGR ordering */ + /* Interpolate colors */ + ex = (*csax & 0xffff); + ey = (*csay & 0xffff); + t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; + t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; + dp->r = (((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 = (((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 = (((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 = (((t2 - t1) * ey) >> 16) + t1; + /* Advance source pointers */ + csax++; + 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 */ + + csay = say; + 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); +} + +/* + + 8bit Zoomer without smoothing. + + Zoomes 8bit palette/Y 'src' surface to 'dst' surface. + +*/ + +int +zoomSurfaceY (SDL_Surface * src, SDL_Surface * dst) +{ + Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy; + Uint8 *sp, *dp, *csp; + int dgap; + + /* Variable setup */ + sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w); + sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h); + + /* Allocate memory for row increments */ + if ((sax = (Uint32 *) malloc (dst->w * sizeof (Uint32))) == NULL) + { + return (-1); + } + if ((say = (Uint32 *) malloc (dst->h * sizeof (Uint32))) == NULL) + { + if (sax != NULL) + { + free (sax); + } + return (-1); + } + + /* Precalculate row increments */ + csx = 0; + csax = sax; + for (x = 0; x < dst->w; x++) + { + csx += sx; + *csax = (csx >> 16); + csx &= 0xffff; + csax++; + } + csy = 0; + csay = say; + for (y = 0; y < dst->h; y++) + { + csy += sy; + *csay = (csy >> 16); + csy &= 0xffff; + csay++; + } + + csx = 0; + csax = sax; + for (x = 0; x < dst->w; x++) + { + csx += (*csax); + csax++; + } + csy = 0; + csay = say; + for (y = 0; y < dst->h; y++) + { + csy += (*csay); + csay++; + } + + /* Pointer setup */ + sp = csp = (Uint8 *) src->pixels; + dp = (Uint8 *) dst->pixels; + dgap = dst->pitch - dst->w; + + /* Draw */ + csay = say; + for (y = 0; y < dst->h; y++) + { + csax = sax; + sp = csp; + for (x = 0; x < dst->w; x++) + { + /* Draw */ + *dp = *sp; + /* Advance source pointers */ + sp += (*csax); + csax++; + /* Advance destination pointer */ + dp++; + } + /* Advance source pointer (for row) */ + csp += ((*csay) * src->pitch); + csay++; + /* Advance destination pointers */ + dp += dgap; + } + + /* Remove temp arrays */ + free (sax); + free (say); + + return (0); +} + +/* + + 32bit Rotozoomer with optional anti-aliasing by bilinear interpolation. + + Rotates and zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. + +*/ + +void +transformSurfaceRGBA (SDL_Surface * src, SDL_Surface * dst, int cx, int cy, + int isin, int icos, int smooth) +{ + int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; + tColorRGBA c00, c01, c10, c11; + tColorRGBA *pc, *sp; + int gap, orderRGBA; + + + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; + pc = dst->pixels; + gap = dst->pitch - dst->w * 4; + orderRGBA = (src->format->Rmask == 0x000000ff); + + + if (smooth) + { + for (y = 0; y < dst->h; y++) + { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) + { + dx = (sdx >> 16); + dy = (sdy >> 16); + if ((dx >= -1) && (dy >= -1) && (dx < src->w) && (dy < src->h)) + { + if ((dx >= 0) && (dy >= 0) && (dx < sw) && (dy < sh)) + { + sp = + (tColorRGBA *) ((Uint8 *) src->pixels + + src->pitch * dy); + sp += dx; + c00 = *sp; + sp += 1; + c01 = *sp; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + sp -= 1; + c10 = *sp; + sp += 1; + c11 = *sp; + } + else if ((dx == sw) && (dy == sh)) + { + sp = + (tColorRGBA *) ((Uint8 *) src->pixels + + src->pitch * dy); + sp += dx; + c00 = *sp; + c01 = *pc; + c10 = *pc; + c11 = *pc; + } + else if ((dx == -1) && (dy == -1)) + { + sp = (tColorRGBA *) (src->pixels); + c00 = *pc; + c01 = *pc; + c10 = *pc; + c11 = *sp; + } + else if ((dx == -1) && (dy == sh)) + { + sp = (tColorRGBA *) (src->pixels); + sp = + (tColorRGBA *) ((Uint8 *) src->pixels + + src->pitch * dy); + c00 = *pc; + c01 = *sp; + c10 = *pc; + c11 = *pc; + } + else if ((dx == sw) && (dy == -1)) + { + sp = (tColorRGBA *) (src->pixels); + sp += dx; + c00 = *pc; + c01 = *pc; + c10 = *sp; + c11 = *pc; + } + else if (dx == -1) + { + sp = + (tColorRGBA *) ((Uint8 *) src->pixels + + src->pitch * dy); + c00 = *pc; + c01 = *sp; + c10 = *pc; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + c11 = *sp; + } + else if (dy == -1) + { + sp = (tColorRGBA *) (src->pixels); + sp += dx; + c00 = *pc; + c01 = *pc; + c10 = *sp; + sp += 1; + c11 = *sp; + } + else if (dx == sw) + { + sp = + (tColorRGBA *) ((Uint8 *) src->pixels + + src->pitch * dy); + sp += dx; + c00 = *sp; + c01 = *pc; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + c10 = *sp; + c11 = *pc; + } + else if (dy == sh) + { + sp = + (tColorRGBA *) ((Uint8 *) src->pixels + + src->pitch * dy); + sp += dx; + c00 = *sp; + sp += 1; + c01 = *sp; + c10 = *pc; + c11 = *pc; + } + ex = (sdx & 0xffff); + ey = (sdy & 0xffff); + t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; + t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; + pc->r = (((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; + pc->g = (((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; + pc->b = (((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; + pc->a = (((t2 - t1) * ey) >> 16) + t1; + + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } + else + { + + + for (y = 0; y < dst->h; y++) + { + + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) + { + + dx = (short) (sdx >> 16); + dy = (short) (sdy >> 16); + if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) + { + sp = + (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + *pc = *sp; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } +} + +/* + + 8bit Rotozoomer without smoothing + + Rotates and zoomes 8bit palette/Y 'src' surface to 'dst' surface. + +*/ + +void +transformSurfaceY (SDL_Surface * src, SDL_Surface * dst, int cx, int cy, + int isin, int icos) +{ + int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; + tColorY *pc, *sp; + int gap; + + /* Variable setup */ + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; + pc = dst->pixels; + gap = dst->pitch - dst->w; + /* Clear surface to colorkey */ + memset (pc, (unsigned char) (src->format->colorkey & 0xff), + dst->pitch * dst->h); + /* Iterate through destination surface */ + for (y = 0; y < dst->h; y++) + { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) + { + dx = (short) (sdx >> 16); + dy = (short) (sdy >> 16); + if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) + { + sp = (tColorY *) (src->pixels); + sp += (src->pitch * dy + dx); + *pc = *sp; + } + sdx += icos; + sdy += isin; + pc++; + } + pc += gap; + } +} + +/* + + rotozoomSurface() + + Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + 'angle' is the rotation in degrees. 'zoom' a scaling factor. 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. + +*/ + +/*XPUT/* Sanity check */ +/* Determine if source surface is 32bit or 8bit */ +/* New source surface is 32bit with a defined RGBA ordering */ +/* Sanity check zoom factor */ +/* Check if we have a rotozoom or just a zoom */ +/* Angle!=0: full rotozoom * +//* ----------------------- */ +/* Calculate target factors from sin/cos and zoom +*/ +/* Determine destination width and height by rotating a centered source box */ +/* Alloc space to completely contain the rotated surface */ +/* Target surface is 32bit with source RGBA/ABGR ordering */ +/* Lock source surface */ +/* Check which kind of surface we have */ +/* Call the 32bit transformation routine to do the rotation (using alpha) */ + +#define VALUE_LIMIT 0.001 + +SDL_Surface * +rotozoomSurface (SDL_Surface * src, double angle, double zoom, int smooth) +{ + SDL_Surface *rz_src; + SDL_Surface *rz_dst; + double zoominv; + double radangle, sanglezoom, canglezoom, sanglezoominv, canglezoominv; + int dstwidthhalf, dstwidth, dstheighthalf, dstheight; + double x, y, cx, cy, sx, sy; + int is32bit; + int i, src_converted; + + + if (src == NULL) + return (NULL); + + + is32bit = (src->format->BitsPerPixel == 32); + if ((is32bit) || (src->format->BitsPerPixel == 8)) + { + + rz_src = src; + src_converted = 0; + } + else + { + + rz_src = + SDL_CreateRGBSurface (SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface (src, NULL, rz_src, NULL); + src_converted = 1; + is32bit = 1; + } + + + if (zoom < VALUE_LIMIT) + { + zoom = VALUE_LIMIT; + } + zoominv = 65536.0 / zoom; + + + if (fabs (angle) > VALUE_LIMIT) + { + + radangle = angle * (M_PI / 180.0); + sanglezoom = sanglezoominv = sin (radangle); + canglezoom = canglezoominv = cos (radangle); + sanglezoom *= zoom; + canglezoom *= zoom; + sanglezoominv *= zoominv; + canglezoominv *= zoominv; + + x = rz_src->w / 2; + y = rz_src->h / 2; + cx = canglezoom * x; + cy = canglezoom * y; + sx = sanglezoom * x; + sy = sanglezoom * y; + dstwidthhalf = src->w; + dstheighthalf = src->h; + /*dstwidthhalf =MAX ((int) + ceil (MAX + (MAX + (MAX (fabs (cx + sy), fabs (cx - sy)), fabs (-cx + sy)), + fabs (-cx - sy))), 1); + dstheighthalf = MAX ((int) ceil (MAX (MAX (MAX (fabs (sx + cy), fabs (sx - cy)), fabs (-sx + cy)),fabs (-sx - cy))), 1); + */ + dstwidth = 2 * dstwidthhalf; + dstheight = 2 * dstheighthalf; + + rz_dst = NULL; + if (is32bit) + { + + rz_dst = + SDL_CreateRGBSurface (SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, + rz_src->format->Gmask, + rz_src->format->Bmask, + rz_src->format->Amask); + } + else + { + + rz_dst = + SDL_CreateRGBSurface (SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, + 0, 0); + } + + + SDL_LockSurface (rz_src); + + if (is32bit) + { + + transformSurfaceRGBA (rz_src, rz_dst, dstwidthhalf, dstheighthalf, + (int) (sanglezoominv), + (int) (canglezoominv), smooth); + + SDL_SetAlpha (rz_dst, SDL_SRCALPHA, 255); + } + else + { + + for (i = 0; i < rz_src->format->palette->ncolors; i++) + { + rz_dst->format->palette->colors[i] = + rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + + transformSurfaceY (rz_src, rz_dst, dstwidthhalf, dstheighthalf, + (int) (sanglezoominv), (int) (canglezoominv)); + SDL_SetColorKey (rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, + rz_src->format->colorkey); + } + + SDL_UnlockSurface (rz_src); + + } + else + { + + dstwidth = (int) ((double) rz_src->w * zoom); + dstheight = (int) ((double) rz_src->h * zoom); + if (dstwidth < 1) + { + dstwidth = 1; + } + if (dstheight < 1) + { + dstheight = 1; + } + + + rz_dst = NULL; + if (is32bit) + { + + rz_dst = + SDL_CreateRGBSurface (SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, + rz_src->format->Gmask, + rz_src->format->Bmask, + rz_src->format->Amask); + } + else + { + + rz_dst = + SDL_CreateRGBSurface (SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, + 0, 0); + } + + + SDL_LockSurface (rz_src); + + if (is32bit) + { + + zoomSurfaceRGBA (rz_src, rz_dst, smooth); + + SDL_SetAlpha (rz_dst, SDL_SRCALPHA, 255); + } + else + { + + for (i = 0; i < rz_src->format->palette->ncolors; i++) + { + rz_dst->format->palette->colors[i] = + rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + + zoomSurfaceY (rz_src, rz_dst); + SDL_SetColorKey (rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, + rz_src->format->colorkey); + } + + SDL_UnlockSurface (rz_src); + } + + + if (src_converted) + { + SDL_FreeSurface (rz_src); + } + + + return (rz_dst); +} + +/* + + 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. + +*/ + +#define VALUE_LIMIT 0.001 + +SDL_Surface * +zoomSurface (SDL_Surface * src, double zoomx, double zoomy, int smooth) +{ + SDL_Surface *rz_src; + SDL_Surface *rz_dst; + int dstwidth, dstheight; + int is32bit; + int i, src_converted; + + + if (src == NULL) + return (NULL); + + + + is32bit = (src->format->BitsPerPixel == 32); + + if ((is32bit) || (src->format->BitsPerPixel == 8)) + { + + rz_src = src; + src_converted = 0; + } + else + { + + rz_src = + SDL_CreateRGBSurface (SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, + 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface (src, NULL, rz_src, NULL); + src_converted = 1; + is32bit = 1; + } + + + if (zoomx < VALUE_LIMIT) + { + zoomx = VALUE_LIMIT; + } + if (zoomy < VALUE_LIMIT) + { + zoomy = VALUE_LIMIT; + } + + + dstwidth = (int) ((double) rz_src->w * zoomx); + dstheight = (int) ((double) rz_src->h * zoomy); + if (dstwidth < 1) + { + dstwidth = 1; + } + if (dstheight < 1) + { + dstheight = 1; + } + + + rz_dst = NULL; + if (is32bit) + { + + rz_dst = + SDL_CreateRGBSurface (SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } + else + { + + rz_dst = + SDL_CreateRGBSurface (SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, + 0); + } + + + SDL_LockSurface (rz_src); + + if (is32bit) + { + + zoomSurfaceRGBA (rz_src, rz_dst, smooth); + SDL_SetAlpha (rz_dst, SDL_SRCALPHA, 255); + } + else + { + + for (i = 0; i < rz_src->format->palette->ncolors; i++) + { + rz_dst->format->palette->colors[i] = + rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + + zoomSurfaceY (rz_src, rz_dst); + SDL_SetColorKey (rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, + rz_src->format->colorkey); + } + + SDL_UnlockSurface (rz_src); + + + if (src_converted) + { + SDL_FreeSurface (rz_src); + } + + return (rz_dst); +} + +#ifdef WIN32 + /* For DLL building under VC6 */ +BOOL APIENTRY +DllMain (HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif diff --git a/ediv/src/dlls/graphics/SDL_rotozoom.h b/ediv/src/dlls/graphics/SDL_rotozoom.h new file mode 100644 index 0000000..eab3b4f --- /dev/null +++ b/ediv/src/dlls/graphics/SDL_rotozoom.h @@ -0,0 +1,77 @@ +#ifndef _SDL_rotozoom_h +#define _SDL_rotozoom_h + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#ifndef M_PI +#define M_PI 3.141592654 +#endif +#include "SDL.h" + + +/* ---- Defines */ + +#define SMOOTHING_OFF 0 +#define SMOOTHING_ON 1 + +/* ---- Structures */ + + typedef struct tColorRGBA + { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; + } + tColorRGBA; + + typedef struct tColorY + { + Uint8 y; + } + tColorY; + + +/* ---- Prototypes */ + +/* + + rotozoomSurface() + + Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + 'angle' is the rotation in degrees. 'zoom' a scaling factor. 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. + +*/ + + SDL_Surface *rotozoomSurface (SDL_Surface * src, double angle, double zoom, + int smooth); + + +/* + + 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. + +*/ + + SDL_Surface *zoomSurface (SDL_Surface * src, double zoomx, double zoomy, + int smooth); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +}; +#endif + +#endif /* _SDL_rotozoom_h */ diff --git a/ediv/src/dlls/graphics/testrotozoom.c b/ediv/src/dlls/graphics/testrotozoom.c new file mode 100644 index 0000000..cfe8f81 --- /dev/null +++ b/ediv/src/dlls/graphics/testrotozoom.c @@ -0,0 +1,444 @@ +/* + + SDL_rotozoom - test program + + Copyright (C) A. Schiffler, July 2001 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifdef WIN32 +#include +#endif + +#include +#include +#include + +#include "SDL.h" +#include "SDL_rotozoom.h" + +void +HandleEvent () +{ + SDL_Event event; + + /* Check for events */ + while (SDL_PollEvent (&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + case SDL_QUIT: + exit (0); + break; + } + } +} + +void +ClearScreen (SDL_Surface * screen) +{ + int i; + /* Set the screen to black */ + if (SDL_LockSurface (screen) == 0) + { + Uint32 black; + Uint8 *pixels; + black = SDL_MapRGB (screen->format, 0, 0, 0); + pixels = (Uint8 *) screen->pixels; + for (i = 0; i < screen->h; ++i) + { + memset (pixels, black, screen->w * screen->format->BytesPerPixel); + pixels += screen->pitch; + } + SDL_UnlockSurface (screen); + } +} + +void +RotatePicture (SDL_Surface * screen, SDL_Surface * picture, int rotate, + int smooth) +{ + SDL_Surface *rotozoom_picture; + SDL_Rect dest; + + int framecount, framemax, frameinc; + float zoomf; + + /* Rotate and display the picture */ + framemax = 4 * 360; + frameinc = 1; + for (framecount = 360; framecount < framemax; framecount += frameinc) + { + if ((framecount % 360) == 0) + frameinc++; + HandleEvent (); + ClearScreen (screen); + zoomf = (float) framecount / (float) framemax; + zoomf = 1.5 * zoomf * zoomf; + if ((rotozoom_picture = + rotozoomSurface (picture, framecount * rotate, zoomf, + smooth)) != NULL) + { + dest.x = (screen->w - rotozoom_picture->w) / 2;; + dest.y = (screen->h - rotozoom_picture->h) / 2; + dest.w = rotozoom_picture->w; + dest.h = rotozoom_picture->h; + if (SDL_BlitSurface (rotozoom_picture, NULL, screen, &dest) < 0) + { + fprintf (stderr, "Blit failed: %s\n", SDL_GetError ()); + break; + } + SDL_FreeSurface (rotozoom_picture); + } + + /* Display by flipping screens */ + SDL_UpdateRect (screen, 0, 0, 0, 0); + } + + if (rotate) + { + /* Final display with angle=0 */ + HandleEvent (); + ClearScreen (screen); + if ((rotozoom_picture = + rotozoomSurface (picture, 0.01, zoomf, smooth)) != NULL) + { + dest.x = (screen->w - rotozoom_picture->w) / 2;; + dest.y = (screen->h - rotozoom_picture->h) / 2; + dest.w = rotozoom_picture->w; + dest.h = rotozoom_picture->h; + if (SDL_BlitSurface (rotozoom_picture, NULL, screen, &dest) < 0) + { + fprintf (stderr, "Blit failed: %s\n", SDL_GetError ()); + return; + } + SDL_FreeSurface (rotozoom_picture); + } + + /* Display by flipping screens */ + SDL_UpdateRect (screen, 0, 0, 0, 0); + } + + /* Pause for a sec */ + SDL_Delay (1000); +} + +void +ZoomPicture (SDL_Surface * screen, SDL_Surface * picture, int smooth) +{ + SDL_Surface *rotozoom_picture; + SDL_Rect dest; + int framecount, framemax, frameinc; + float zoomxf, zoomyf; + + /* Zoom and display the picture */ + framemax = 4 * 360; + frameinc = 1; + for (framecount = 360; framecount < framemax; framecount += frameinc) + { + if ((framecount % 360) == 0) + frameinc++; + HandleEvent (); + ClearScreen (screen); + zoomxf = (float) framecount / (float) framemax; + zoomxf = 1.5 * zoomxf * zoomxf; + zoomyf = 0.5 + fabs (1.0 * sin ((double) framecount / 80.0)); + + if ((rotozoom_picture = + zoomSurface (picture, zoomxf, zoomyf, smooth)) != NULL) + { + dest.x = (screen->w - rotozoom_picture->w) / 2;; + dest.y = (screen->h - rotozoom_picture->h) / 2; + dest.w = rotozoom_picture->w; + dest.h = rotozoom_picture->h; + if (SDL_BlitSurface (rotozoom_picture, NULL, screen, &dest) < 0) + { + fprintf (stderr, "Blit failed: %s\n", SDL_GetError ()); + break; + } + SDL_FreeSurface (rotozoom_picture); + } + + /* Display by flipping screens */ + SDL_UpdateRect (screen, 0, 0, 0, 0); + } + + /* Pause for a sec */ + SDL_Delay (1000); +} + +void +Draw (SDL_Surface * screen) +{ + SDL_Surface *picture, *picture_again; + char *bmpfile; + + /* --------- 8 bit test -------- */ + + /* Message */ + fprintf (stderr, "Loading 8bit image\n"); + + /* Load the image into a surface */ + /* + bmpfile = "sample8.bmp"; + fprintf (stderr, "Loading picture: %s\n", bmpfile); + picture = SDL_LoadBMP (bmpfile); + if (picture == NULL) + { + fprintf (stderr, "Couldn't load %s: %s\n", bmpfile, SDL_GetError ()); + return; + } + + fprintf (stderr, "rotozoom: Rotating and zooming\n"); + RotatePicture (screen, picture, 1, SMOOTHING_OFF); + + fprintf (stderr, "rotozoom: Just zooming (angle=0)\n"); + RotatePicture (screen, picture, 0, SMOOTHING_OFF); + + fprintf (stderr, "zoom: Just zooming\n"); + ZoomPicture (screen, picture, SMOOTHING_OFF); + + + fprintf (stderr, + "rotozoom: Rotating and zooming, interpolation on but unused\n"); + RotatePicture (screen, picture, 1, SMOOTHING_ON); + + fprintf (stderr, + "rotozoom: Just zooming (angle=0), interpolation on but unused\n"); + RotatePicture (screen, picture, 0, SMOOTHING_ON); + + fprintf (stderr, "zoom: Just zooming, interpolation on but unused\n"); + ZoomPicture (screen, picture, SMOOTHING_ON); + + + SDL_FreeSurface (picture); +*/ + /* -------- 24 bit test --------- */ + + /* Message */ + fprintf (stderr, "Loading 24bit image\n"); + /* Load the image into a surface */ + bmpfile = "sample24.bmp"; + fprintf (stderr, "Loading picture: %s\n", bmpfile); + picture = SDL_LoadBMP (bmpfile); + if (picture == NULL) + { + fprintf (stderr, "Couldn't load %s: %s\n", bmpfile, SDL_GetError ()); + return; + } + + RotatePicture (screen, picture, 1, SMOOTHING_OFF); + + + /* + fprintf (stderr, "rotozoom: Rotating and zooming, no interpolation\n"); + RotatePicture (screen, picture, 1, SMOOTHING_OFF); + + fprintf (stderr, "rotozoom: Just zooming (angle=0), no interpolation\n"); + RotatePicture (screen, picture, 0, SMOOTHING_OFF); + + fprintf (stderr, "zoom: Just zooming, no interpolation\n"); + ZoomPicture (screen, picture, SMOOTHING_OFF); + + + fprintf (stderr, "rotozoom: Rotating and zooming, with interpolation\n"); + RotatePicture (screen, picture, 1, SMOOTHING_ON); + + fprintf (stderr, "rotozoom: Just zooming (angle=0), with interpolation\n"); + RotatePicture (screen, picture, 0, SMOOTHING_ON); + + fprintf (stderr, "zoom: Just zooming, with interpolation\n"); + ZoomPicture (screen, picture, SMOOTHING_ON); + + + + fprintf (stderr, "Converting 24bit image into 32bit RGBA surface ...\n"); + picture_again = + SDL_CreateRGBSurface (SDL_SWSURFACE, picture->w, picture->h, 32, + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface (picture, NULL, picture_again, NULL); + + + fprintf (stderr, "Rotating and zooming, with interpolation\n"); + RotatePicture (screen, picture_again, 1, SMOOTHING_ON); + + + fprintf (stderr, "Just zooming (angle=0), with interpolation\n"); + RotatePicture (screen, picture_again, 0, SMOOTHING_ON); + + SDL_FreeSurface (picture_again); + + + + fprintf (stderr, "Converting 24bit image into 32bit ABGR surface ...\n"); + picture_again = + SDL_CreateRGBSurface (SDL_SWSURFACE, picture->w, picture->h, 32, + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface (picture, NULL, picture_again, NULL); + + + fprintf (stderr, "Rotating and zooming, with interpolation\n"); + RotatePicture (screen, picture_again, 1, SMOOTHING_ON); + + + fprintf (stderr, "Just zooming (angle=0), with interpolation\n"); + RotatePicture (screen, picture_again, 0, SMOOTHING_ON); + + SDL_FreeSurface (picture_again); + + /* Free the picture */ + + //SDL_FreeSurface (picture); + + return; +} + +#ifdef WIN32 +extern char **__argv; +extern int __argc; +int APIENTRY +WinMain (HINSTANCE hInstance, + HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +#else // non WIN32 +int +main (int argc, char *argv[]) +#endif +{ + SDL_Surface *screen; + int w, h; + int desired_bpp; + Uint32 video_flags; +#ifdef WIN32 + int argc; + char **argv; + + argv = __argv; + argc = __argc; +#endif + /* Title */ + fprintf (stderr, "SDL_rotozoom test\n"); + + /* Set default options and check command-line */ + w = 640; + h = 480; + desired_bpp = 0; + video_flags = 0; + while (argc > 1) + { + if (strcmp (argv[1], "-width") == 0) + { + if (argv[2] && ((w = atoi (argv[2])) > 0)) + { + argv += 2; + argc -= 2; + } + else + { + fprintf (stderr, "The -width option requires an argument\n"); + exit (1); + } + } + else if (strcmp (argv[1], "-height") == 0) + { + if (argv[2] && ((h = atoi (argv[2])) > 0)) + { + argv += 2; + argc -= 2; + } + else + { + fprintf (stderr, "The -height option requires an argument\n"); + exit (1); + } + } + else if (strcmp (argv[1], "-bpp") == 0) + { + if (argv[2]) + { + desired_bpp = atoi (argv[2]); + argv += 2; + argc -= 2; + } + else + { + fprintf (stderr, "The -bpp option requires an argument\n"); + exit (1); + } + } + else if (strcmp (argv[1], "-warp") == 0) + { + video_flags |= SDL_HWPALETTE; + argv += 1; + argc -= 1; + } + else if (strcmp (argv[1], "-hw") == 0) + { + video_flags |= SDL_HWSURFACE; + argv += 1; + argc -= 1; + } + else if (strcmp (argv[1], "-fullscreen") == 0) + { + video_flags |= SDL_FULLSCREEN; + argv += 1; + argc -= 1; + } + else + break; + } + + /* Force double buffering */ + video_flags |= SDL_DOUBLEBUF; + + /* Initialize SDL */ + if (SDL_Init (SDL_INIT_VIDEO) < 0) + { + fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError ()); + exit (1); + } + atexit (SDL_Quit); /* Clean up on exit */ + + /* Initialize the display */ + screen = SDL_SetVideoMode (w, h, desired_bpp, video_flags); + if (screen == NULL) + { + fprintf (stderr, "Couldn't set %dx%dx%d video mode: %s\n", + w, h, desired_bpp, SDL_GetError ()); + exit (1); + } + + /* Show some info */ + printf ("Set %dx%dx%d mode\n", + screen->w, screen->h, screen->format->BitsPerPixel); + printf ("Video surface located in %s memory.\n", + (screen->flags & SDL_HWSURFACE) ? "video" : "system"); + + /* Check for double buffering */ + if (screen->flags & SDL_DOUBLEBUF) + { + printf ("Double-buffering enabled - good!\n"); + } + + /* Set the window manager title bar */ + SDL_WM_SetCaption ("SDL_rotozoom test", "rotozoom"); + + /* Do all the drawing work */ + Draw (screen); + + return (0); +}