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:
@@ -245,6 +245,7 @@ extern FRAME SetRelFrameIndex (FRAME Frame, SIZE FrameOffs);
|
||||
extern FRAME SetEquFrameIndex (FRAME DstFrame, FRAME SrcFrame);
|
||||
extern FRAME IncFrameIndex (FRAME Frame);
|
||||
extern FRAME DecFrameIndex (FRAME Frame);
|
||||
extern DRAWABLE RotateFrame (FRAME Frame, COUNT angle);
|
||||
|
||||
extern FRAME CaptureDrawable (DRAWABLE Drawable);
|
||||
extern DRAWABLE ReleaseDrawable (FRAME Frame);
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#include "gfxintrn.h"
|
||||
#include "misc.h"
|
||||
#include "tfb_draw.h"
|
||||
#include "units.h"
|
||||
#include "libs/mathlib.h"
|
||||
|
||||
FRAMEPTR _CurFramePtr;
|
||||
|
||||
@@ -201,3 +204,44 @@ GetFrameHot (FRAMEPTR FramePtr)
|
||||
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;
|
||||
|
||||
if (DrawableType == RAM_DRAWABLE
|
||||
if (DrawableType == RAM_DRAWABLE && imgw > 0 && imgh > 0
|
||||
&& (Image = TFB_DrawImage_New (TFB_DrawCanvas_New_TrueColor (imgw, imgh, FALSE))))
|
||||
{
|
||||
FramePtr->image = Image;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/graphics/sdl/primitives.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "rotozoom.h"
|
||||
#include "options.h"
|
||||
#include "types.h"
|
||||
|
||||
@@ -240,6 +241,12 @@ TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int typ
|
||||
src->format->Amask);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -259,6 +266,40 @@ TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int typ
|
||||
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
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawCanvas_GetExtent (TFB_Canvas canvas, PEXTENT size)
|
||||
{
|
||||
SDL_Surface *src = (SDL_Surface *)canvas;
|
||||
|
||||
size->width = src->w;
|
||||
size->height = src->h;
|
||||
}
|
||||
|
||||
void
|
||||
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;
|
||||
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
|
||||
@@ -291,6 +291,7 @@ TFB_DrawImage_New (TFB_Canvas canvas)
|
||||
img->MipmapImg = NULL;
|
||||
img->colormap_index = -1;
|
||||
img->last_scale_type = -1;
|
||||
TFB_DrawCanvas_GetExtent (canvas, &img->extent);
|
||||
|
||||
img->Palette = TFB_DrawCanvas_ExtractPalette (canvas);
|
||||
|
||||
@@ -316,12 +317,39 @@ TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha)
|
||||
img->colormap_index = -1;
|
||||
img->last_scale_type = -1;
|
||||
img->Palette = NULL;
|
||||
|
||||
img->extent.width = w;
|
||||
img->extent.height = h;
|
||||
|
||||
img->NormalImg = TFB_DrawCanvas_New_ForScreen (w, h, withalpha);
|
||||
|
||||
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
|
||||
TFB_DrawImage_Delete (TFB_Image *image)
|
||||
{
|
||||
|
||||
@@ -86,6 +86,7 @@ void TFB_FlushPaletteCache (void);
|
||||
|
||||
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
|
||||
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_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_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_RotationTarget (TFB_Canvas src, int angle);
|
||||
TFB_Canvas TFB_DrawCanvas_ToScreenFormat (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_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_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);
|
||||
|
||||
@@ -115,6 +120,7 @@ TFB_Palette *TFB_DrawCanvas_ExtractPalette (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_SetPalette (TFB_Canvas target, TFB_Palette *palette);
|
||||
int TFB_DrawCanvas_GetTransparentIndex (TFB_Canvas canvas);
|
||||
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_Initialize (void);
|
||||
void TFB_DrawCanvas_GetScreenFormat (TFB_PixelFormat *fmt);
|
||||
|
||||
Reference in New Issue
Block a user