Strengthened the TFB_Draw library with constructors and destructors
Some code has been changed to use this, some redundant routines have been removed or renamed git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@696 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
+76
-6
@@ -47,7 +47,10 @@ drawable.h: defines FRAME_DESC and DRAWABLE_DESC, and the pointer
|
||||
an element "DataOffs", which, horrifyingly, appears to be
|
||||
a deliberate index past the end of the struct. Given a
|
||||
PFRAME_DESC x, (void *)(x[x->DataOffs]) is a void pointer
|
||||
castable to TFB_Image.)
|
||||
castable to TFB_Image. Preliminary investigations into
|
||||
this code make a conversion of DataOffs into a void
|
||||
pointer both feasible and more efficient on modern
|
||||
architectures.)
|
||||
|
||||
font.h: defines FONT_DESC and PFONT_DESC.
|
||||
|
||||
@@ -215,10 +218,6 @@ void TFB_DrawImage_FilledImage (TFB_Image *img,
|
||||
|
||||
----
|
||||
|
||||
There are some obvious operations missing here. Creation and
|
||||
destruction of TFB_Images are the main gaps. The ability to 'wrap' a
|
||||
TFB_Canvas with a fresh TFB_Image would probably be nice too.
|
||||
|
||||
TFB_DrawCanvas
|
||||
--------------
|
||||
|
||||
@@ -250,7 +249,78 @@ void TFB_DrawCanvas_FilledImage (TFB_Image *img,
|
||||
|
||||
----
|
||||
|
||||
Commentary on needed operations also mirrors that of TFB_Image.
|
||||
Creation and Destruction of TFB_Images, TFB_Canvases, and TFB_Palettes
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Various commands exist for creating and destroying the TFB_Draw data
|
||||
types. The concept of "ownership" is critical here. If a data object
|
||||
owns a pointer inside of it, that pointer's referent is deallocated
|
||||
when the data object is deallocated. If a pointer variable owns its
|
||||
referent, it's permissible to delete it.
|
||||
|
||||
TFB_Canvas and TFB_Palette are primitives. TFB_Image owns NormalImg,
|
||||
ScaledImg, and Palette, and will delete them when it is itself
|
||||
deleted.
|
||||
|
||||
That said, here are the routines:
|
||||
|
||||
---
|
||||
|
||||
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas)
|
||||
|
||||
Creates a new TFB_Image, which the caller then owns. The caller must
|
||||
own the canvas, and transfers ownership of that canvas to the image.
|
||||
The Palette value is automatically created (and the image owns it);
|
||||
ScaledImg will be NULL until you scale the image and draw it to the
|
||||
screen.
|
||||
|
||||
---
|
||||
|
||||
void TFB_DrawImage_Delete (TFB_Image *image)
|
||||
|
||||
Deletes the image, and all non-NULL components. You must own the
|
||||
image you delete.
|
||||
|
||||
---
|
||||
|
||||
TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN has_alpha);
|
||||
|
||||
TFB_Canvas TFB_DrawCanvas_New_Paletted (int w, int h,
|
||||
TFB_Palette *palette,
|
||||
int transparent_index);
|
||||
|
||||
These create new TFB_Canvases, which the caller will then own. Width
|
||||
and height are straightforward. The TrueColor variant produces Canvases
|
||||
with the same color depth and pixel format as the screen. The
|
||||
has_alpha flag indicates whether or not the canvas has an alpha
|
||||
channel.
|
||||
|
||||
The Paletted variant produces 8-bit paletted canvases. The palette
|
||||
argument is optional (it can be NULL, in which case you'll need to set
|
||||
it later - TFB_Images tend to do this when drawn), as is the
|
||||
transparent_index (if -1, there is no transparency; otherwise, it's
|
||||
the index of the transparent color).
|
||||
|
||||
---
|
||||
|
||||
TFB_Canvas TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas);
|
||||
|
||||
Returns a canvas that, if possible, matches the graphics configuration
|
||||
of the screen. You must own the source canvas. If the conversion is
|
||||
possible, it makes the conversion, deletes its argument, and returns
|
||||
the converted version; if conversion is not possible, the canvas is
|
||||
returned intact.
|
||||
|
||||
Regardless of success or failure, the caller owns the result.
|
||||
|
||||
---
|
||||
|
||||
TFB_Palette *TFB_DrawCanvas_ExtractPalette (TFB_Canvas canvas);
|
||||
|
||||
Allocates and returns a 256-entry TFB_Palette array that describes the
|
||||
palette of the canvas, or returns NULL if the canvas is true-color.
|
||||
If the result is non-NULL, the caller owns the result. The caller
|
||||
need not own canvas.
|
||||
|
||||
|
||||
DRAWCMD LIBRARY
|
||||
|
||||
@@ -81,6 +81,7 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
||||
SDL_Surface *new_surf;
|
||||
|
||||
img->scale = gscale;
|
||||
img->dirty = FALSE;
|
||||
new_surf = zoomSurface (img->NormalImg, gscale / 256.0f,
|
||||
gscale / 256.0f, SMOOTHING_OFF);
|
||||
|
||||
@@ -88,16 +89,7 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
||||
{
|
||||
if (!new_surf->format->palette)
|
||||
{
|
||||
img->ScaledImg = TFB_DisplayFormatAlpha (new_surf);
|
||||
if (img->ScaledImg)
|
||||
{
|
||||
SDL_FreeSurface(new_surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "blt(): TFB_DisplayFormatAlpha failed\n");
|
||||
img->ScaledImg = new_surf;
|
||||
}
|
||||
img->ScaledImg = TFB_DrawCanvas_ToScreenFormat (new_surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ process_image (FRAMEPTR FramePtr, SDL_Surface *img[], AniData *ani, int cel_ct)
|
||||
hx = ani[cel_ct].hotspot_x;
|
||||
hy = ani[cel_ct].hotspot_y;
|
||||
|
||||
FramePtr->DataOffs = (BYTE *)TFB_LoadImage (img[cel_ct]) - (BYTE *)FramePtr;
|
||||
FramePtr->DataOffs = (BYTE *)TFB_DrawImage_New (img[cel_ct]) - (BYTE *)FramePtr;
|
||||
|
||||
tfbimg = (TFB_Image *)((BYTE *)FramePtr + FramePtr->DataOffs);
|
||||
tfbimg->colormap_index = ani[cel_ct].colormap_index;
|
||||
@@ -123,7 +123,7 @@ process_font (FRAMEPTR FramePtr, SDL_Surface *img[], int cel_ct)
|
||||
|
||||
img[cel_ct] = new_surf;
|
||||
|
||||
FramePtr->DataOffs = (BYTE *)TFB_LoadImage (img[cel_ct]) - (BYTE *)FramePtr;
|
||||
FramePtr->DataOffs = (BYTE *)TFB_DrawImage_New (img[cel_ct]) - (BYTE *)FramePtr;
|
||||
img[cel_ct] = ((TFB_Image *)((BYTE *)FramePtr + FramePtr->DataOffs))->NormalImg;
|
||||
|
||||
SetFrameHotSpot (FramePtr, MAKE_HOT_SPOT (hx, hy));
|
||||
@@ -722,17 +722,10 @@ _request_drawable (COUNT NumFrames, DRAWABLE_TYPE DrawableType,
|
||||
TFB_Image *Image;
|
||||
|
||||
if (DrawableType == RAM_DRAWABLE
|
||||
&& (Image = TFB_LoadImage (SDL_CreateRGBSurface (
|
||||
SDL_SWSURFACE,
|
||||
imgw,
|
||||
imgh,
|
||||
32,
|
||||
0x00FF0000,
|
||||
0x0000FF00,
|
||||
0x000000FF,
|
||||
0x00000000
|
||||
))))
|
||||
&& (Image = TFB_DrawImage_New (TFB_DrawCanvas_New_TrueColor (imgw, imgh, FALSE))))
|
||||
{
|
||||
FramePtr->DataOffs = (BYTE *)Image - (BYTE *)FramePtr;
|
||||
}
|
||||
|
||||
TYPE_SET (FramePtr->TypeIndexAndFlags, DrawableType);
|
||||
INDEX_SET (FramePtr->TypeIndexAndFlags, NumFrames);
|
||||
|
||||
@@ -131,3 +131,90 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, BOOLEAN scaled, int r,
|
||||
SDL_BlitSurface(surf, NULL, (NativeCanvas) target, &targetRect);
|
||||
UnlockMutex (img->mutex);
|
||||
}
|
||||
|
||||
TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN hasalpha)
|
||||
{
|
||||
SDL_Surface *new_surf;
|
||||
new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, hasalpha ? 0xff000000 : 0);
|
||||
if (!new_surf) {
|
||||
fprintf(stderr, "INTERNAL PANIC: Failed to create TFB_Canvas: %s", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
return new_surf;
|
||||
}
|
||||
|
||||
TFB_Canvas
|
||||
TFB_DrawCanvas_New_Paletted (int w, int h, TFB_Palette *palette, int transparent_index)
|
||||
{
|
||||
SDL_Surface *new_surf;
|
||||
new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
|
||||
if (!new_surf) {
|
||||
fprintf(stderr, "INTERNAL PANIC: Failed to create TFB_Canvas: %s\n", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
if (palette != NULL)
|
||||
{
|
||||
SDL_SetColors(new_surf, (SDL_Color *)palette, 0, 256);
|
||||
}
|
||||
if (transparent_index >= 0)
|
||||
{
|
||||
SDL_SetColorKey (new_surf, SDL_SRCCOLORKEY, transparent_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetColorKey (new_surf, 0, 0);
|
||||
}
|
||||
return new_surf;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawCanvas_Delete (TFB_Canvas canvas)
|
||||
{
|
||||
if (!canvas)
|
||||
{
|
||||
fprintf(stderr, "INTERNAL PANIC: Attempted to delete a NULL canvas!\n");
|
||||
/* Should we actually die here? */
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_FreeSurface ((SDL_Surface *) canvas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TFB_Palette *
|
||||
TFB_DrawCanvas_ExtractPalette (TFB_Canvas canvas)
|
||||
{
|
||||
int i;
|
||||
TFB_Palette *result = (TFB_Palette*) HMalloc (sizeof (TFB_Palette) * 256);
|
||||
SDL_Surface *surf = (SDL_Surface *)canvas;
|
||||
|
||||
if (!surf->format->palette)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
result[i].r = surf->format->palette->colors[i].r;
|
||||
result[i].g = surf->format->palette->colors[i].g;
|
||||
result[i].b = surf->format->palette->colors[i].b;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
TFB_Canvas
|
||||
TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas)
|
||||
{
|
||||
SDL_Surface *result = TFB_DisplayFormatAlpha (canvas);
|
||||
if (result == NULL)
|
||||
{
|
||||
fprintf (stderr, "WARNING: Could not convert sprite-canvas to display format. Expect performance penalties.\n");
|
||||
return canvas;
|
||||
}
|
||||
else
|
||||
{
|
||||
TFB_DrawCanvas_Delete(canvas);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,46 +125,6 @@ TFB_ProcessEvents ()
|
||||
}
|
||||
}
|
||||
|
||||
TFB_Image*
|
||||
TFB_LoadImage (SDL_Surface *img)
|
||||
{
|
||||
TFB_Image *myImage;
|
||||
|
||||
myImage = (TFB_Image*) HMalloc (sizeof (TFB_Image));
|
||||
myImage->mutex = CreateMutex ();
|
||||
myImage->ScaledImg = NULL;
|
||||
myImage->colormap_index = -1;
|
||||
|
||||
if (img->format->palette)
|
||||
{
|
||||
int i;
|
||||
myImage->Palette = (TFB_Palette*) HMalloc (sizeof (TFB_Palette) * 256);
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
myImage->Palette[i].r = img->format->palette->colors[i].r;
|
||||
myImage->Palette[i].g = img->format->palette->colors[i].g;
|
||||
myImage->Palette[i].b = img->format->palette->colors[i].b;
|
||||
}
|
||||
myImage->NormalImg = img;
|
||||
}
|
||||
else
|
||||
{
|
||||
myImage->Palette = NULL;
|
||||
myImage->NormalImg = TFB_DisplayFormatAlpha (img);
|
||||
if (myImage->NormalImg)
|
||||
{
|
||||
SDL_FreeSurface (img);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "TFB_LoadImage(): TFB_DisplayFormatAlpha failed\n");
|
||||
myImage->NormalImg = img;
|
||||
}
|
||||
}
|
||||
|
||||
return(myImage);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_SwapBuffers ()
|
||||
{
|
||||
@@ -178,6 +138,7 @@ TFB_SwapBuffers ()
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Probably ought to clean this away at some point. */
|
||||
SDL_Surface*
|
||||
TFB_DisplayFormatAlpha (SDL_Surface *surface)
|
||||
{
|
||||
@@ -682,27 +643,7 @@ TFB_FlushGraphics () // Only call from main thread!!
|
||||
case TFB_DRAWCOMMANDTYPE_DELETEIMAGE:
|
||||
{
|
||||
TFB_Image *DC_image = (TFB_Image *)DC.data.deleteimage.image;
|
||||
|
||||
if (DC_image == 0)
|
||||
{
|
||||
fprintf (stderr, "DCQ ERROR: DELETEIMAGE passed null image ptr\n");
|
||||
break;
|
||||
}
|
||||
LockMutex (DC_image->mutex);
|
||||
|
||||
SDL_FreeSurface (DC_image->NormalImg);
|
||||
|
||||
if (DC_image->ScaledImg) {
|
||||
SDL_FreeSurface (DC_image->ScaledImg);
|
||||
}
|
||||
|
||||
if (DC_image->Palette)
|
||||
HFree (DC_image->Palette);
|
||||
|
||||
UnlockMutex (DC_image->mutex);
|
||||
DestroyMutex (DC_image->mutex);
|
||||
|
||||
HFree (DC_image);
|
||||
TFB_DrawImage_Delete(DC_image);
|
||||
break;
|
||||
}
|
||||
case TFB_DRAWCOMMANDTYPE_SENDSIGNAL:
|
||||
|
||||
@@ -46,9 +46,6 @@ extern int GfxFlags;
|
||||
void ScreenOrigin (FRAME Display, COORD sx, COORD sy);
|
||||
void LoadDisplay (PDISPLAY_INTERFACE *pDisplay);
|
||||
|
||||
TFB_Image *TFB_LoadImage (SDL_Surface *img);
|
||||
void TFB_FreeImage (TFB_Image *img);
|
||||
|
||||
void TFB_SwapBuffers ();
|
||||
SDL_Surface* TFB_DisplayFormatAlpha (SDL_Surface *surface);
|
||||
void TFB_BlitSurface (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst,
|
||||
|
||||
@@ -242,3 +242,51 @@ TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, BOOLEAN scaled, int r,
|
||||
target->dirty = TRUE;
|
||||
UnlockMutex (target->mutex);
|
||||
}
|
||||
|
||||
TFB_Image *
|
||||
TFB_DrawImage_New (TFB_Canvas canvas)
|
||||
{
|
||||
TFB_Image *img = HMalloc (sizeof (TFB_Image));
|
||||
img->mutex = CreateMutex ();
|
||||
img->ScaledImg = NULL;
|
||||
img->colormap_index = -1;
|
||||
|
||||
img->Palette = TFB_DrawCanvas_ExtractPalette (canvas);
|
||||
|
||||
if (img->Palette)
|
||||
{
|
||||
img->NormalImg = canvas;
|
||||
}
|
||||
else
|
||||
{
|
||||
img->NormalImg = TFB_DrawCanvas_ToScreenFormat (canvas);
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_Delete (TFB_Image *image)
|
||||
{
|
||||
if (image == 0)
|
||||
{
|
||||
fprintf (stderr, "INTERNAL ERROR: Tried to delete a null image!\n");
|
||||
/* Should we die here? */
|
||||
return;
|
||||
}
|
||||
LockMutex (image->mutex);
|
||||
|
||||
TFB_DrawCanvas_Delete (image->NormalImg);
|
||||
|
||||
if (image->ScaledImg) {
|
||||
TFB_DrawCanvas_Delete (image->ScaledImg);
|
||||
}
|
||||
|
||||
if (image->Palette)
|
||||
HFree (image->Palette);
|
||||
|
||||
UnlockMutex (image->mutex);
|
||||
DestroyMutex (image->mutex);
|
||||
|
||||
HFree (image);
|
||||
}
|
||||
|
||||
@@ -64,14 +64,23 @@ void TFB_DrawScreen_WaitForSignal (void);
|
||||
void TFB_DrawScreen_SetPalette (int paletteIndex, int r, int g, int b);
|
||||
void TFB_FlushPaletteCache (void);
|
||||
|
||||
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
|
||||
void TFB_DrawImage_Delete (TFB_Image *image);
|
||||
|
||||
void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, int r, int g, int b, TFB_Image *dest);
|
||||
void TFB_DrawImage_Rect (PRECT rect, int r, int g, int b, TFB_Image *image);
|
||||
void TFB_DrawImage_Image (TFB_Image *img, int x, int y, BOOLEAN scaled, TFB_Palette *palette, TFB_Image *target);
|
||||
void TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, BOOLEAN scaled, int r, int g, int b, TFB_Image *target);
|
||||
|
||||
TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN hasalpha);
|
||||
TFB_Canvas TFB_DrawCanvas_New_Paletted (int w, int h, TFB_Palette *palette, int transparent_index);
|
||||
TFB_Canvas TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_Delete (TFB_Canvas canvas);
|
||||
|
||||
void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, int r, int g, int b, TFB_Canvas dest);
|
||||
void TFB_DrawCanvas_Rect (PRECT rect, int r, int g, int b, TFB_Canvas image);
|
||||
void TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, BOOLEAN scaled, TFB_Palette *palette, TFB_Canvas target);
|
||||
void TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, BOOLEAN scaled, int r, int g, int b, TFB_Canvas target);
|
||||
TFB_Palette *TFB_DrawCanvas_ExtractPalette (TFB_Canvas canvas);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user