New image rotation code

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1488 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2005-01-26 23:55:49 +00:00
parent d2ab767130
commit 5331f3cd3d
8 changed files with 1275 additions and 2 deletions
+1
View File
@@ -245,6 +245,7 @@ extern FRAME SetRelFrameIndex (FRAME Frame, SIZE FrameOffs);
extern FRAME SetEquFrameIndex (FRAME DstFrame, FRAME SrcFrame); extern FRAME SetEquFrameIndex (FRAME DstFrame, FRAME SrcFrame);
extern FRAME IncFrameIndex (FRAME Frame); extern FRAME IncFrameIndex (FRAME Frame);
extern FRAME DecFrameIndex (FRAME Frame); extern FRAME DecFrameIndex (FRAME Frame);
extern DRAWABLE RotateFrame (FRAME Frame, COUNT angle);
extern FRAME CaptureDrawable (DRAWABLE Drawable); extern FRAME CaptureDrawable (DRAWABLE Drawable);
extern DRAWABLE ReleaseDrawable (FRAME Frame); extern DRAWABLE ReleaseDrawable (FRAME Frame);
+44
View File
@@ -18,6 +18,9 @@
#include "gfxintrn.h" #include "gfxintrn.h"
#include "misc.h" #include "misc.h"
#include "tfb_draw.h"
#include "units.h"
#include "libs/mathlib.h"
FRAMEPTR _CurFramePtr; FRAMEPTR _CurFramePtr;
@@ -201,3 +204,44 @@ GetFrameHot (FRAMEPTR FramePtr)
return (MAKE_HOT_SPOT (0, 0)); return (MAKE_HOT_SPOT (0, 0));
} }
DRAWABLE
RotateFrame (FRAMEPTR Frame, COUNT angle)
{
DRAWABLE Drawable;
FRAMEPTR RotFramePtr;
SIZE dx, dy;
SIZE d;
COUNT organg;
Drawable = _request_drawable (1, RAM_DRAWABLE, WANT_PIXMAP, 0, 0);
if (!Drawable)
return 0;
RotFramePtr = CaptureDrawable (Drawable);
if (!RotFramePtr)
{
FreeDrawable (Drawable);
return 0;
}
RotFramePtr->image = TFB_DrawImage_New_Rotated (
Frame->image, -ANGLE_TO_DEGREES (angle));
SetFrameBounds (RotFramePtr, RotFramePtr->image->extent.width,
RotFramePtr->image->extent.height);
/* now we need to rotate the hot-spot, eww */
dx = Frame->HotSpot.x - (GetFrameWidth (Frame) / 2);
dy = Frame->HotSpot.y - (GetFrameHeight (Frame) / 2);
d = square_root ((long)dx*dx + (long)dy*dy);
if (d != 0)
{
organg = ARCTAN (dx, dy);
dx = COSINE (organg + angle, d);
dy = SINE (organg + angle, d);
}
RotFramePtr->HotSpot.x = (GetFrameWidth (RotFramePtr) / 2) + dx;
RotFramePtr->HotSpot.y = (GetFrameHeight (RotFramePtr) / 2) + dy;
ReleaseDrawable (RotFramePtr);
return Drawable;
}
@@ -732,7 +732,7 @@ _request_drawable (COUNT NumFrames, DRAWABLE_TYPE DrawableType,
{ {
TFB_Image *Image; TFB_Image *Image;
if (DrawableType == RAM_DRAWABLE if (DrawableType == RAM_DRAWABLE && imgw > 0 && imgh > 0
&& (Image = TFB_DrawImage_New (TFB_DrawCanvas_New_TrueColor (imgw, imgh, FALSE)))) && (Image = TFB_DrawImage_New (TFB_DrawCanvas_New_TrueColor (imgw, imgh, FALSE))))
{ {
FramePtr->image = Image; FramePtr->image = Image;
@@ -3,6 +3,7 @@
#include "libs/graphics/gfx_common.h" #include "libs/graphics/gfx_common.h"
#include "libs/graphics/sdl/primitives.h" #include "libs/graphics/sdl/primitives.h"
#include "libs/graphics/tfb_draw.h" #include "libs/graphics/tfb_draw.h"
#include "rotozoom.h"
#include "options.h" #include "options.h"
#include "types.h" #include "types.h"
@@ -240,6 +241,12 @@ TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int typ
src->format->Amask); src->format->Amask);
if (src->format->palette) if (src->format->palette)
TFB_DrawCanvas_SetTransparentIndex (newsurf, TFB_DrawCanvas_GetTransparentIndex (src), FALSE); TFB_DrawCanvas_SetTransparentIndex (newsurf, TFB_DrawCanvas_GetTransparentIndex (src), FALSE);
else
{
int r, g, b;
if (TFB_DrawCanvas_GetTransparentColor (src, &r, &g, &b))
TFB_DrawCanvas_SetTransparentColor (newsurf, r, g, b, FALSE);
}
} }
} }
else else
@@ -259,6 +266,40 @@ TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int typ
return newsurf; return newsurf;
} }
TFB_Canvas
TFB_DrawCanvas_New_RotationTarget (TFB_Canvas src_canvas, int angle)
{
SDL_Surface *src = (SDL_Surface *)src_canvas;
SDL_Surface *newsurf;
EXTENT size;
TFB_DrawCanvas_GetRotatedExtent (src_canvas, angle, &size);
newsurf = SDL_CreateRGBSurface (SDL_SWSURFACE,
size.width, size.height,
src->format->BitsPerPixel,
src->format->Rmask,
src->format->Gmask,
src->format->Bmask,
src->format->Amask);
if (!newsurf)
{
fprintf(stderr, "TFB_DrawCanvas_New_RotationTarget() INTERNAL PANIC:"
"Failed to create TFB_Canvas: %s", SDL_GetError());
exit (-1);
}
if (src->format->palette)
TFB_DrawCanvas_SetTransparentIndex (newsurf, TFB_DrawCanvas_GetTransparentIndex (src), FALSE);
else
{
int r, g, b;
if (TFB_DrawCanvas_GetTransparentColor (src, &r, &g, &b))
TFB_DrawCanvas_SetTransparentColor (newsurf, r, g, b, FALSE);
}
return newsurf;
}
void void
TFB_DrawCanvas_Delete (TFB_Canvas canvas) TFB_DrawCanvas_Delete (TFB_Canvas canvas)
{ {
@@ -357,6 +398,23 @@ TFB_DrawCanvas_SetTransparentIndex (TFB_Canvas canvas, int index, BOOLEAN rleacc
} }
} }
BOOLEAN
TFB_DrawCanvas_GetTransparentColor (TFB_Canvas canvas, int *r, int *g, int *b)
{
if (!TFB_DrawCanvas_IsPaletted (canvas)
&& (((SDL_Surface *)canvas)->flags & SDL_SRCCOLORKEY) )
{
Uint8 ur, ug, ub;
int colorkey = ((SDL_Surface *)canvas)->format->colorkey;
SDL_GetRGB (colorkey, ((SDL_Surface *)canvas)->format, &ur, &ug, &ub);
*r = ur;
*g = ug;
*b = ub;
return TRUE;
}
return FALSE;
}
void void
TFB_DrawCanvas_SetTransparentColor (TFB_Canvas canvas, int r, int g, int b, BOOLEAN rleaccel) TFB_DrawCanvas_SetTransparentColor (TFB_Canvas canvas, int r, int g, int b, BOOLEAN rleaccel)
{ {
@@ -404,6 +462,15 @@ TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, in
size->height = 1; size->height = 1;
} }
void
TFB_DrawCanvas_GetExtent (TFB_Canvas canvas, PEXTENT size)
{
SDL_Surface *src = (SDL_Surface *)canvas;
size->width = src->w;
size->height = src->h;
}
void void
TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, EXTENT size) TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, EXTENT size)
{ {
@@ -930,3 +997,35 @@ TFB_DrawCanvas_GetLine (TFB_Canvas canvas, int line)
SDL_Surface* surf = (SDL_Surface *)canvas; SDL_Surface* surf = (SDL_Surface *)canvas;
return (uint8*)surf->pixels + surf->pitch * line; return (uint8*)surf->pixels + surf->pitch * line;
} }
void
TFB_DrawCanvas_Rotate (TFB_Canvas src_canvas, TFB_Canvas dst_canvas, int angle, EXTENT size)
{
SDL_Surface *src = (SDL_Surface *)src_canvas;
SDL_Surface *dst = (SDL_Surface *)dst_canvas;
int ret;
if (size.width > dst->w || size.height > dst->h)
{
fprintf (stderr, "TFB_DrawCanvas_Rotate: Tried to rotate image to size %d %d when dst_canvas has only dimensions of %d %d! Failing.\n",
size.width, size.height, dst->w, dst->h);
return;
}
ret = rotateSurface (src, dst, angle, 0);
if (ret != 0)
{
fprintf (stderr, "TFB_DrawCanvas_Rotate: WARNING: actual rotation func returned failure\n");
}
}
void
TFB_DrawCanvas_GetRotatedExtent (TFB_Canvas src_canvas, int angle, PEXTENT size)
{
int dstw, dsth;
SDL_Surface *src = (SDL_Surface *)src_canvas;
rotozoomSurfaceSize (src->w, src->h, angle, 1, &dstw, &dsth);
size->height = dsth;
size->width = dstw;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,95 @@
/*
rotozoom.h - rotozoomer for 32bit or 8bit surfaces
LGPL (c) A. Schiffler
Note by sc2 developers:
Taken from SDL_gfx library and modified, original code can be downloaded
from http://www.ferzkopp.net/Software/SDL_gfx-2.0/
*/
#ifndef ROTOZOOM_H
#define ROTOZOOM_H
#include <math.h>
#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 */
/*
zoomSurfaceRGBA()
Zoom the src surface into dst. The zoom amount is determined
by the dimensions of src and dst
*/
int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth);
/*
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);
int rotateSurface(SDL_Surface * src, SDL_Surface * dst, double angle,
int smooth);
/* Returns the size of the target surface for a rotozoomSurface() call */
void rotozoomSurfaceSize(int width, int height, double angle, double zoom,
int *dstwidth, int *dstheight);
/*
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);
/* Returns the size of the target surface for a zoomSurface() call */
void zoomSurfaceSize(int width, int height, double zoomx, double zoomy,
int *dstwidth, int *dstheight);
#endif
+28
View File
@@ -291,6 +291,7 @@ TFB_DrawImage_New (TFB_Canvas canvas)
img->MipmapImg = NULL; img->MipmapImg = NULL;
img->colormap_index = -1; img->colormap_index = -1;
img->last_scale_type = -1; img->last_scale_type = -1;
TFB_DrawCanvas_GetExtent (canvas, &img->extent);
img->Palette = TFB_DrawCanvas_ExtractPalette (canvas); img->Palette = TFB_DrawCanvas_ExtractPalette (canvas);
@@ -316,12 +317,39 @@ TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha)
img->colormap_index = -1; img->colormap_index = -1;
img->last_scale_type = -1; img->last_scale_type = -1;
img->Palette = NULL; img->Palette = NULL;
img->extent.width = w;
img->extent.height = h;
img->NormalImg = TFB_DrawCanvas_New_ForScreen (w, h, withalpha); img->NormalImg = TFB_DrawCanvas_New_ForScreen (w, h, withalpha);
return img; return img;
} }
TFB_Image *
TFB_DrawImage_New_Rotated (TFB_Image *img, int angle)
{
TFB_Canvas dst;
EXTENT size;
/* sanity check */
if (!img->NormalImg)
{
fprintf (stderr, "TFB_DrawImage_New_Rotated: source canvas is NULL! Failing.\n");
return NULL;
}
TFB_DrawCanvas_GetRotatedExtent (img->NormalImg, angle, &size);
dst = TFB_DrawCanvas_New_RotationTarget (img->NormalImg, angle);
if (!dst)
{
fprintf (stderr, "TFB_DrawImage_New_Rotated: rotation target canvas not created! Failing.\n");
return NULL;
}
TFB_DrawCanvas_Rotate (img->NormalImg, dst, angle, size);
return TFB_DrawImage_New (dst);
}
void void
TFB_DrawImage_Delete (TFB_Image *image) TFB_DrawImage_Delete (TFB_Image *image)
{ {
+6
View File
@@ -86,6 +86,7 @@ void TFB_FlushPaletteCache (void);
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas); TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
TFB_Image *TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha); TFB_Image *TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha);
TFB_Image *TFB_DrawImage_New_Rotated (TFB_Image *img, int angle);
void TFB_DrawImage_Delete (TFB_Image *image); void TFB_DrawImage_Delete (TFB_Image *image);
void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type); void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type);
@@ -98,11 +99,15 @@ TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN hasalpha);
TFB_Canvas TFB_DrawCanvas_New_ForScreen (int w, int h, BOOLEAN withalpha); TFB_Canvas TFB_DrawCanvas_New_ForScreen (int w, int h, BOOLEAN withalpha);
TFB_Canvas TFB_DrawCanvas_New_Paletted (int w, int h, TFB_Palette *palette, int transparent_index); TFB_Canvas TFB_DrawCanvas_New_Paletted (int w, int h, TFB_Palette *palette, int transparent_index);
TFB_Canvas TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int type, int last_type); TFB_Canvas TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int type, int last_type);
TFB_Canvas TFB_DrawCanvas_New_RotationTarget (TFB_Canvas src, int angle);
TFB_Canvas TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas); TFB_Canvas TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas);
BOOLEAN TFB_DrawCanvas_IsPaletted (TFB_Canvas canvas); BOOLEAN TFB_DrawCanvas_IsPaletted (TFB_Canvas canvas);
void TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src, TFB_Canvas dst, EXTENT size); void TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src, TFB_Canvas dst, EXTENT size);
void TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src, TFB_Canvas dst, TFB_Canvas mipmap, EXTENT size); void TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src, TFB_Canvas dst, TFB_Canvas mipmap, EXTENT size);
void TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, int scale, PEXTENT size); void TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, int scale, PEXTENT size);
void TFB_DrawCanvas_Rotate (TFB_Canvas src, TFB_Canvas dst, int angle, EXTENT size);
void TFB_DrawCanvas_GetRotatedExtent (TFB_Canvas src, int angle, PEXTENT size);
void TFB_DrawCanvas_GetExtent (TFB_Canvas canvas, PEXTENT size);
void TFB_DrawCanvas_Delete (TFB_Canvas canvas); void TFB_DrawCanvas_Delete (TFB_Canvas canvas);
@@ -115,6 +120,7 @@ TFB_Palette *TFB_DrawCanvas_ExtractPalette (TFB_Canvas canvas);
void TFB_DrawCanvas_SetPalette (TFB_Canvas target, TFB_Palette *palette); void TFB_DrawCanvas_SetPalette (TFB_Canvas target, TFB_Palette *palette);
int TFB_DrawCanvas_GetTransparentIndex (TFB_Canvas canvas); int TFB_DrawCanvas_GetTransparentIndex (TFB_Canvas canvas);
void TFB_DrawCanvas_SetTransparentIndex (TFB_Canvas canvas, int i, BOOLEAN rleaccel); void TFB_DrawCanvas_SetTransparentIndex (TFB_Canvas canvas, int i, BOOLEAN rleaccel);
BOOLEAN TFB_DrawCanvas_GetTransparentColor (TFB_Canvas canvas, int *r, int *g, int *b);
void TFB_DrawCanvas_SetTransparentColor (TFB_Canvas canvas, int r, int g, int b, BOOLEAN rleaccel); void TFB_DrawCanvas_SetTransparentColor (TFB_Canvas canvas, int r, int g, int b, BOOLEAN rleaccel);
void TFB_DrawCanvas_Initialize (void); void TFB_DrawCanvas_Initialize (void);
void TFB_DrawCanvas_GetScreenFormat (TFB_PixelFormat *fmt); void TFB_DrawCanvas_GetScreenFormat (TFB_PixelFormat *fmt);