From 08de6866153509510777ebc319712ada6865c99b Mon Sep 17 00:00:00 2001 From: avolkov Date: Wed, 15 Aug 2007 08:48:53 +0000 Subject: [PATCH] Fixed trilinear scaling so that it does not use stamp-filled mipmap image; fixes bug #929 git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2842 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/ChangeLog | 2 + sc2/src/sc2code/libs/graphics/drawcmd.h | 2 +- sc2/src/sc2code/libs/graphics/sdl/canvas.c | 16 +++++-- .../sc2code/libs/graphics/sdl/sdl_common.c | 8 ++-- sc2/src/sc2code/libs/graphics/tfb_draw.c | 48 +++++++++++++++++++ sc2/src/sc2code/libs/graphics/tfb_draw.h | 2 + sc2/src/sc2code/process.c | 26 +++++----- 7 files changed, 78 insertions(+), 26 deletions(-) diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 0562811f8..c07703cd8 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,6 @@ Changes towards version 0.7: +- Fixed a problem with blue ships after Avatar's tractor beam, + along with some other fill-stamp situations; bug #929 - Alex - Added TFB_Canvas_Lock(), TFB_Canvas_Unlock() and TFB_Canvas_GetStride() - SvdB - Scaling images with respect to their hotspots: stabilizes compound diff --git a/sc2/src/sc2code/libs/graphics/drawcmd.h b/sc2/src/sc2code/libs/graphics/drawcmd.h index 5973002fa..25fe06c1b 100644 --- a/sc2/src/sc2code/libs/graphics/drawcmd.h +++ b/sc2/src/sc2code/libs/graphics/drawcmd.h @@ -110,7 +110,7 @@ typedef struct tfb_dc_setpal typedef struct tfb_dc_setmip { TFB_Image *image; - TFB_Canvas mipmap; + TFB_Image *mipmap; int hotx, hoty; } TFB_DrawCommand_SetMipmap; diff --git a/sc2/src/sc2code/libs/graphics/sdl/canvas.c b/sc2/src/sc2code/libs/graphics/sdl/canvas.c index 6059b2265..5f69751a4 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/canvas.c +++ b/sc2/src/sc2code/libs/graphics/sdl/canvas.c @@ -1037,7 +1037,6 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, SDL_PixelFormat *mmfmt = mm->format; SDL_PixelFormat *dstfmt = dst->format; SDL_Color *srcpal = srcfmt->palette? srcfmt->palette->colors : 0; - SDL_Color *mmpal = mmfmt->palette ? mmfmt->palette->colors : 0; const int sbpp = srcfmt->BytesPerPixel; const int mmbpp = mmfmt->BytesPerPixel; const int slen = src->pitch; @@ -1058,6 +1057,13 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, int ssx0 = 0, ssy0 = 0, ssx1 = 0, ssy1 = 0; int x, y, w, h; + if (mmfmt->palette && !srcpal) + { + log_add (log_Warning, "TFB_DrawCanvas_Rescale_Trilinear: " + "Mipmap is paletted, but source is not! Failing."); + return; + } + if (scale > 0) { int fw, fh; @@ -1231,13 +1237,13 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, Uint8 *mm_p = src_a1 + px1 * mmbpp; p1[0].value = scale_read_pixel (mm_p, mmfmt, - mmpal, mk1, ck1); + srcpal, mk1, ck1); p1[1].value = scale_read_pixel (mm_p + mmbpp, mmfmt, - mmpal, mk1, ck1); + srcpal, mk1, ck1); p1[2].value = scale_read_pixel (mm_p + mmlen, mmfmt, - mmpal, mk1, ck1); + srcpal, mk1, ck1); p1[3].value = scale_read_pixel (mm_p + mmbpp + mmlen, mmfmt, - mmpal, mk1, ck1); + srcpal, mk1, ck1); } else { diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index a32088abe..da6ceee8e 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -692,11 +692,9 @@ TFB_FlushGraphics (void) // Only call from main thread!! switch (DC.Type) { case TFB_DRAWCOMMANDTYPE_SETMIPMAP: - LockMutex (DC.data.setmipmap.image->mutex); - DC.data.setmipmap.image->MipmapImg = DC.data.setmipmap.mipmap; - DC.data.setmipmap.image->MipmapHs.x = DC.data.setmipmap.hotx; - DC.data.setmipmap.image->MipmapHs.y = DC.data.setmipmap.hoty; - UnlockMutex (DC.data.setmipmap.image->mutex); + TFB_DrawImage_SetMipmap (DC.data.setmipmap.image, + DC.data.setmipmap.mipmap, + DC.data.setmipmap.hotx, DC.data.setmipmap.hoty); break; case TFB_DRAWCOMMANDTYPE_IMAGE: { diff --git a/sc2/src/sc2code/libs/graphics/tfb_draw.c b/sc2/src/sc2code/libs/graphics/tfb_draw.c index 86f44a95e..3f905936f 100644 --- a/sc2/src/sc2code/libs/graphics/tfb_draw.c +++ b/sc2/src/sc2code/libs/graphics/tfb_draw.c @@ -158,6 +158,20 @@ TFB_DrawScreen_Copy (RECT *r, SCREEN src, SCREEN dest) TFB_EnqueueDrawCommand (&DC); } +void +TFB_DrawScreen_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty) +{ + TFB_DrawCommand DC; + + DC.Type = TFB_DRAWCOMMANDTYPE_SETMIPMAP; + DC.data.setmipmap.image = img; + DC.data.setmipmap.mipmap = mmimg; + DC.data.setmipmap.hotx = hotx; + DC.data.setmipmap.hoty = hoty; + + TFB_EnqueueDrawCommand (&DC); +} + void TFB_DrawScreen_DeleteImage (TFB_Image *img) { @@ -358,6 +372,40 @@ TFB_DrawImage_New_Rotated (TFB_Image *img, int angle) return newimg; } +void +TFB_DrawImage_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty) +{ + bool imgpal; + bool mmpal; + + if (!img || !mmimg) + return; + + LockMutex (img->mutex); + LockMutex (mmimg->mutex); + + // Either both images must be using the same colormap, or mipmap image + // must not be paletted. This restriction is due to the current + // implementation of fill-stamp, which replaces the palette with + // fill color. + imgpal = TFB_DrawCanvas_IsPaletted (img->NormalImg); + mmpal = TFB_DrawCanvas_IsPaletted (mmimg->NormalImg); + if (!mmpal || (mmpal && imgpal && + img->colormap_index == mmimg->colormap_index)) + { + img->MipmapImg = mmimg->NormalImg; + img->MipmapHs.x = hotx; + img->MipmapHs.y = hoty; + } + else + { + img->MipmapImg = NULL; + } + + UnlockMutex (mmimg->mutex); + UnlockMutex (img->mutex); +} + void TFB_DrawImage_Delete (TFB_Image *image) { diff --git a/sc2/src/sc2code/libs/graphics/tfb_draw.h b/sc2/src/sc2code/libs/graphics/tfb_draw.h index 6a0fa2e02..a1c9519d3 100644 --- a/sc2/src/sc2code/libs/graphics/tfb_draw.h +++ b/sc2/src/sc2code/libs/graphics/tfb_draw.h @@ -95,6 +95,7 @@ void TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale, int r, void TFB_DrawScreen_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, SCREEN dest); void TFB_DrawScreen_CopyToImage (TFB_Image *img, RECT *lpRect, SCREEN src); +void TFB_DrawScreen_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty); void TFB_DrawScreen_DeleteImage (TFB_Image *img); void TFB_DrawScreen_DeleteData (void *); void TFB_DrawScreen_WaitForSignal (void); @@ -104,6 +105,7 @@ void TFB_DrawScreen_Callback (void (*callback) (void *arg), void *arg); 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_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty); void TFB_DrawImage_Delete (TFB_Image *image); void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type); diff --git a/sc2/src/sc2code/process.c b/sc2/src/sc2code/process.c index e216622c5..2ca10b166 100644 --- a/sc2/src/sc2code/process.c +++ b/sc2/src/sc2code/process.c @@ -932,23 +932,19 @@ PostProcessQueue (VIEW_STATE view_state, SIZE scroll_x, // (smaller) zoom level image as mipmap, // needed for trilinear scaling - FRAME frame = - SetAbsFrameIndex ( - ElementPtr->next.image.farray[index + 1], - GetFrameIndex (ElementPtr->next.image.frame)); + FRAME frame = ElementPtr->next.image.frame; + FRAME mmframe = SetEquFrameIndex ( + ElementPtr->next.image.farray[ + index + 1], frame); - if (frame && frame->image) + // TODO: This is currently hacky, this code + // really should not dereference FRAME. + // Perhaps make mipmap part of STAMP prim? + if (frame && mmframe) { - TFB_DrawCommand DC; - TFB_Image *mmimg = frame->image; - DC.Type = TFB_DRAWCOMMANDTYPE_SETMIPMAP; - DC.data.setmipmap.image = (ElementPtr->next.image.frame)->image; - DC.data.setmipmap.hotx = frame->HotSpot.x; - DC.data.setmipmap.hoty = frame->HotSpot.y; - LockMutex (mmimg->mutex); - DC.data.setmipmap.mipmap = mmimg->NormalImg; - UnlockMutex (mmimg->mutex); - TFB_EnqueueDrawCommand (&DC); + HOT_SPOT mmhs = GetFrameHot (mmframe); + TFB_DrawScreen_SetMipmap (frame->image, + mmframe->image, mmhs.x, mmhs.y); } } }