From: <av...@us...> - 2009-12-27 04:42:58
|
Revision: 3475 http://sc2.svn.sourceforge.net/sc2/?rev=3475&view=rev Author: avolkov Date: 2009-12-27 04:42:50 +0000 (Sun, 27 Dec 2009) Log Message: ----------- Added additive and alpha drawing mode to gfxlib proper (TFB_Draw/TFB_Canvas/Color); this is to replace arith_frame_blit()/TFB_BlitSurface() Modified Paths: -------------- trunk/sc2/ChangeLog trunk/sc2/src/libs/gfxlib.h trunk/sc2/src/libs/graphics/context.c trunk/sc2/src/libs/graphics/context.h trunk/sc2/src/libs/graphics/dcqueue.c trunk/sc2/src/libs/graphics/drawcmd.h trunk/sc2/src/libs/graphics/font.c trunk/sc2/src/libs/graphics/frame.c trunk/sc2/src/libs/graphics/sdl/canvas.c trunk/sc2/src/libs/graphics/sdl/primitives.c trunk/sc2/src/libs/graphics/sdl/primitives.h trunk/sc2/src/libs/graphics/tfb_draw.c trunk/sc2/src/libs/graphics/tfb_draw.h trunk/sc2/src/libs/graphics/tfb_prim.c trunk/sc2/src/libs/graphics/tfb_prim.h trunk/sc2/src/libs/video/vidplayer.c Modified: trunk/sc2/ChangeLog =================================================================== --- trunk/sc2/ChangeLog 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/ChangeLog 2009-12-27 04:42:50 UTC (rev 3475) @@ -1,4 +1,5 @@ Changes towards version 0.7: +- Added additive and alpha drawing modes to graphics lib - Alex - Fixed black pixel gaps between the planet and shield when entering the orbit of a shielded planet (bug #32) - Alex - Split off SDL-specific colormap bits into SDL domain - Alex Modified: trunk/sc2/src/libs/gfxlib.h =================================================================== --- trunk/sc2/src/libs/gfxlib.h 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/gfxlib.h 2009-12-27 04:42:50 UTC (rev 3475) @@ -277,6 +277,56 @@ FadeSomeToColor } ScreenFadeType; +typedef enum +{ + DRAW_REPLACE = 0, + // Pixels in the target FRAME are replaced entirely. + // Non-stamp primitives with Color.a < 255 to RGB targets are + // equivalent to DRAW_ALPHA with (DrawMode.factor = Color.a), + // except the Text primitives. + // DrawMode.factor: ignored + // Text: supported (except DRAW_ALPHA via Color.a) + // RGBA sources (WANT_ALPHA): per-pixel alpha blending performed + // RGBA targets (WANT_ALPHA): replace directly supported + DRAW_ADDITIVE, + // Pixel channels of the source FRAME or Color channels of + // a primitive are modulated by (DrawMode.factor / 255) and added + // to the pixel channels of the target FRAME. + // DrawMode.factor range: -32767..32767 (negative values make + // draw subtractive); 255 = 1:1 ratio + // Text: not yet supported + // RGBA sources (WANT_ALPHA): alpha channel ignored + // RGBA targets (WANT_ALPHA): not yet supported + DRAW_ALPHA, + // Pixel channels of the source FRAME or Color channels of + // a primitive are modulated by (DrawMode.factor / 255) and added + // to the pixel channels of the target FRAME, modulated by + // (1 - DrawMode.factor / 255) + // DrawMode.factor range: 0..255; 255 = fully opaque + // Text: supported + // RGBA sources (WANT_ALPHA): alpha channel ignored + // RGBA targets (WANT_ALPHA): not yet supported + + DRAW_DEFAULT = DRAW_REPLACE, +} DrawKind; + +typedef struct +{ + BYTE kind; + SWORD factor; +} DrawMode; + +#define DRAW_REPLACE_MODE MAKE_DRAW_MODE (DRAW_REPLACE, 0) + +static inline DrawMode +MAKE_DRAW_MODE (DrawKind kind, SWORD factor) +{ + DrawMode mode; + mode.kind = kind; + mode.factor = factor; + return mode; +} + extern CONTEXT SetContext (CONTEXT Context); extern Color SetContextForeGroundColor (Color Color); extern Color GetContextForeGroundColor (void); @@ -292,6 +342,8 @@ extern BOOLEAN GetContextClipRect (RECT *pRect); // The actual origin will be orgOffset + context ClipRect.corner extern POINT SetContextOrigin (POINT orgOffset); +extern DrawMode SetContextDrawMode (DrawMode); +extern DrawMode GetContextDrawMode (void); extern TIME_VALUE DrawablesIntersect (INTERSECT_CONTROL *pControl0, INTERSECT_CONTROL *pControl1, TIME_VALUE max_time_val); Modified: trunk/sc2/src/libs/graphics/context.c =================================================================== --- trunk/sc2/src/libs/graphics/context.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/context.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -33,6 +33,11 @@ FONT _CurFontPtr; +#define DEFAULT_FORE_COLOR BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F) +#define DEFAULT_BACK_COLOR BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00) + +#define DEFAULT_DRAW_MODE MAKE_DRAW_MODE (DRAW_DEFAULT, 255) + CONTEXT SetContext (CONTEXT Context) { @@ -84,8 +89,6 @@ if (NewContext) { /* initialize context */ - CONTEXT OldContext; - #ifdef DEBUG NewContext->name = name; NewContext->next = NULL; @@ -93,12 +96,9 @@ contextEnd = &NewContext->next; #endif /* DEBUG */ - OldContext = SetContext (NewContext); - SetContextForeGroundColor ( - BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); - SetContextBackGroundColor ( - BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00)); - SetContext (OldContext); + NewContext->Mode = DEFAULT_DRAW_MODE; + NewContext->ForeGroundColor = DEFAULT_FORE_COLOR; + NewContext->BackGroundColor = DEFAULT_BACK_COLOR; } return NewContext; @@ -149,7 +149,7 @@ Color oldColor; if (!ContextActive ()) - return (BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); + return DEFAULT_FORE_COLOR; oldColor = _get_context_fg_color (); if (!sameColor(oldColor, color)) @@ -170,7 +170,7 @@ GetContextForeGroundColor (void) { if (!ContextActive ()) - return (BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); + return DEFAULT_FORE_COLOR; return _get_context_fg_color (); } @@ -181,7 +181,7 @@ Color oldColor; if (!ContextActive ()) - return (BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00)); + return DEFAULT_BACK_COLOR; oldColor = _get_context_bg_color (); if (!sameColor(oldColor, color)) @@ -194,11 +194,34 @@ GetContextBackGroundColor (void) { if (!ContextActive ()) - return (BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00)); + return DEFAULT_BACK_COLOR; return _get_context_bg_color (); } +DrawMode +SetContextDrawMode (DrawMode mode) +{ + DrawMode oldMode; + + if (!ContextActive ()) + return DEFAULT_DRAW_MODE; + + oldMode = _get_context_draw_mode (); + SwitchContextDrawMode (mode); + + return oldMode; +} + +DrawMode +GetContextDrawMode (void) +{ + if (!ContextActive ()) + return DEFAULT_DRAW_MODE; + + return _get_context_draw_mode (); +} + // Returns a rect based at 0,0 and the size of context foreground frame static inline RECT _get_context_fg_rect (void) @@ -306,14 +329,14 @@ TFB_DrawImage_Image (EffectFrame->image, -EffectFrame->HotSpot.x, -EffectFrame->HotSpot.y, - 0, 0, NULL, img); + 0, 0, NULL, DRAW_REPLACE_MODE, img); } else { // solid color backing RECT r = { {0, 0}, {w, h} }; Color color = _get_context_fg_color (); - TFB_DrawImage_Rect (&r, color, img); + TFB_DrawImage_Rect (&r, color, DRAW_REPLACE_MODE, img); } _pCurContext->FontBacking = img; Modified: trunk/sc2/src/libs/graphics/context.h =================================================================== --- trunk/sc2/src/libs/graphics/context.h 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/context.h 2009-12-27 04:42:50 UTC (rev 3475) @@ -33,6 +33,7 @@ // High nibble contains GRAPHICS_STATUS Color ForeGroundColor, BackGroundColor; + DrawMode Mode; FRAME ForeGroundFrame; FONT Font; @@ -62,10 +63,11 @@ #define _get_context_fbk_flags() (_pCurContext->BackingFlags) #define _get_context_fonteff() (_pCurContext->FontEffect) #define _get_context_font_backing() (_pCurContext->FontBacking) +#define _get_context_draw_mode() (_pCurContext->Mode) -#define SwitchContextDrawState(s) \ +#define SwitchContextDrawMode(m) \ { \ - _pCurContext->DrawState = (s); \ + _pCurContext->Mode = (m); \ } #define SwitchContextForeGroundColor(c) \ { \ Modified: trunk/sc2/src/libs/graphics/dcqueue.c =================================================================== --- trunk/sc2/src/libs/graphics/dcqueue.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/dcqueue.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -377,6 +377,7 @@ TFB_DrawCanvas_Image (DC_image, x, y, cmd->scale, cmd->scaleMode, cmd->colormap, + cmd->drawMode, TFB_GetScreenCanvas (cmd->destBuffer)); if (cmd->destBuffer == TFB_SCREEN_MAIN) @@ -405,6 +406,7 @@ TFB_DrawCanvas_FilledImage (DC_image, x, y, cmd->scale, cmd->scaleMode, cmd->color, + cmd->drawMode, TFB_GetScreenCanvas (cmd->destBuffer)); if (cmd->destBuffer == TFB_SCREEN_MAIN) @@ -432,7 +434,7 @@ const int y = cmd->y; TFB_DrawCanvas_FontChar (DC_char, cmd->backing, x, y, - TFB_GetScreenCanvas (cmd->destBuffer)); + cmd->drawMode, TFB_GetScreenCanvas (cmd->destBuffer)); if (cmd->destBuffer == TFB_SCREEN_MAIN) { @@ -459,7 +461,8 @@ TFB_BBox_RegisterPoint (cmd->x2, cmd->y2); } TFB_DrawCanvas_Line (cmd->x1, cmd->y1, cmd->x2, cmd->y2, - cmd->color, TFB_GetScreenCanvas (cmd->destBuffer)); + cmd->color, cmd->drawMode, + TFB_GetScreenCanvas (cmd->destBuffer)); break; } @@ -469,7 +472,7 @@ if (cmd->destBuffer == TFB_SCREEN_MAIN) TFB_BBox_RegisterRect (&cmd->rect); - TFB_DrawCanvas_Rect (&cmd->rect, cmd->color, + TFB_DrawCanvas_Rect (&cmd->rect, cmd->color, cmd->drawMode, TFB_GetScreenCanvas (cmd->destBuffer)); break; Modified: trunk/sc2/src/libs/graphics/drawcmd.h =================================================================== --- trunk/sc2/src/libs/graphics/drawcmd.h 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/drawcmd.h 2009-12-27 04:42:50 UTC (rev 3475) @@ -47,6 +47,7 @@ { int x1, y1, x2, y2; Color color; + DrawMode drawMode; SCREEN destBuffer; } TFB_DrawCommand_Line; @@ -54,6 +55,7 @@ { RECT rect; Color color; + DrawMode drawMode; SCREEN destBuffer; } TFB_DrawCommand_Rect; @@ -63,6 +65,7 @@ int x, y; SCREEN destBuffer; TFB_ColorMap *colormap; + DrawMode drawMode; int scale; int scaleMode; } TFB_DrawCommand_Image; @@ -73,6 +76,7 @@ int x, y; Color color; SCREEN destBuffer; + DrawMode drawMode; int scale; int scaleMode; } TFB_DrawCommand_FilledImage; @@ -82,6 +86,7 @@ TFB_Char *fontchar; TFB_Image *backing; int x, y; + DrawMode drawMode; SCREEN destBuffer; } TFB_DrawCommand_FontChar; Modified: trunk/sc2/src/libs/graphics/font.c =================================================================== --- trunk/sc2/src/libs/graphics/font.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/font.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -243,6 +243,7 @@ const char *pStr; POINT origin; TFB_Image *backing; + DrawMode mode = _get_context_draw_mode (); FontPtr = _CurFontPtr; if (FontPtr == NULL) @@ -286,7 +287,8 @@ r.extent.height = fontChar->disp.height; if (BoxIntersect (&r, pClipRect, &r)) { - TFB_Prim_FontChar (origin, fontChar, backing, ctxOrigin); + TFB_Prim_FontChar (origin, fontChar, backing, mode, + ctxOrigin); } origin.x += fontChar->disp.width; Modified: trunk/sc2/src/libs/graphics/frame.c =================================================================== --- trunk/sc2/src/libs/graphics/frame.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/frame.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -92,7 +92,8 @@ clearRect.corner.x = 0; clearRect.corner.y = 0; clearRect.extent = pClipRect->extent; - TFB_Prim_FillRect (&clearRect, color, pClipRect->corner); + TFB_Prim_FillRect (&clearRect, color, DRAW_REPLACE_MODE, + pClipRect->corner); } void @@ -106,6 +107,7 @@ { COUNT CurIndex; PRIMITIVE *lpPrim; + DrawMode mode = _get_context_draw_mode (); BatchGraphics (); @@ -135,19 +137,21 @@ { case POINT_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_Point (&lpWorkPrim->Object.Point, color, origin); + TFB_Prim_Point (&lpWorkPrim->Object.Point, color, + mode, origin); break; case STAMP_PRIM: - TFB_Prim_Stamp (&lpWorkPrim->Object.Stamp, origin); + TFB_Prim_Stamp (&lpWorkPrim->Object.Stamp, mode, origin); break; case STAMPFILL_PRIM: color = GetPrimColor (lpWorkPrim); TFB_Prim_StampFill (&lpWorkPrim->Object.Stamp, color, - origin); + mode, origin); break; case LINE_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_Line (&lpWorkPrim->Object.Line, color, origin); + TFB_Prim_Line (&lpWorkPrim->Object.Line, color, + mode, origin); break; case TEXT_PRIM: if (!TextRect (&lpWorkPrim->Object.Text, &ClipRect, NULL)) @@ -157,11 +161,13 @@ break; case RECT_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_Rect (&lpWorkPrim->Object.Rect, color, origin); + TFB_Prim_Rect (&lpWorkPrim->Object.Rect, color, + mode, origin); break; case RECTFILL_PRIM: color = GetPrimColor (lpWorkPrim); - TFB_Prim_FillRect (&lpWorkPrim->Object.Rect, color, origin); + TFB_Prim_FillRect (&lpWorkPrim->Object.Rect, color, + mode, origin); break; } } @@ -189,7 +195,8 @@ if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_Point (lpPoint, color, origin); + DrawMode mode = _get_context_draw_mode (); + TFB_Prim_Point (lpPoint, color, mode, origin); } } @@ -201,7 +208,8 @@ if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_Rect (lpRect, color, origin); + DrawMode mode = _get_context_draw_mode (); + TFB_Prim_Rect (lpRect, color, mode, origin); } } @@ -213,7 +221,8 @@ if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_FillRect (lpRect, color, origin); + DrawMode mode = _get_context_draw_mode (); + TFB_Prim_FillRect (lpRect, color, mode, origin); } } @@ -225,7 +234,8 @@ if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_Line (lpLine, color, origin); + DrawMode mode = _get_context_draw_mode (); + TFB_Prim_Line (lpLine, color, mode, origin); } } @@ -236,7 +246,8 @@ if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { - TFB_Prim_Stamp (stmp, origin); + DrawMode mode = _get_context_draw_mode (); + TFB_Prim_Stamp (stmp, mode, origin); } } @@ -248,7 +259,8 @@ if (GraphicsSystemActive () && GetContextValidRect (NULL, &origin)) { Color color = GetPrimColor (&_locPrim); - TFB_Prim_StampFill (stmp, color, origin); + DrawMode mode = _get_context_draw_mode (); + TFB_Prim_StampFill (stmp, color, mode, origin); } } Modified: trunk/sc2/src/libs/graphics/sdl/canvas.c =================================================================== --- trunk/sc2/src/libs/graphics/sdl/canvas.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/sdl/canvas.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -57,23 +57,46 @@ } void +checkPrimitiveMode (SDL_Surface *surf, Color *color, DrawMode *mode) +{ + const SDL_PixelFormat *fmt = surf->format; + // Special case: We support DRAW_ALPHA mode to non-alpha surfaces + // for primitives via Color.a + if (mode->kind == DRAW_REPLACE && fmt->Amask == 0 && color->a != 0xff) + { + mode->kind = DRAW_ALPHA; + mode->factor = color->a; + color->a = 0xff; + } +} + +void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, Color color, - TFB_Canvas target) + DrawMode mode, TFB_Canvas target) { + SDL_Surface *dst = target; + SDL_PixelFormat *fmt = dst->format; Uint32 sdlColor; - PutPixelFn screen_plot; - - screen_plot = putpixel_for (target); - sdlColor = SDL_MapRGB (((NativeCanvas) target)->format, - color.r, color.g, color.b); + RenderPixelFn plotFn; - SDL_LockSurface (target); - line (x1, y1, x2, y2, sdlColor, screen_plot, target); - SDL_UnlockSurface (target); + checkPrimitiveMode (dst, &color, &mode); + sdlColor = SDL_MapRGBA (fmt, color.r, color.g, color.b, color.a); + + plotFn = renderpixel_for (target, mode.kind); + if (!plotFn) + { + log_add (log_Warning, "ERROR: TFB_DrawCanvas_Line " + "unsupported draw mode (%d)", (int)mode.kind); + return; + } + + SDL_LockSurface (dst); + line_prim (x1, y1, x2, y2, sdlColor, plotFn, mode.factor, dst); + SDL_UnlockSurface (dst); } void -TFB_DrawCanvas_Rect (RECT *rect, Color color, TFB_Canvas target) +TFB_DrawCanvas_Rect (RECT *rect, Color color, DrawMode mode, TFB_Canvas target) { SDL_Surface *dst = target; SDL_PixelFormat *fmt = dst->format; @@ -84,22 +107,95 @@ sr.w = rect->extent.width; sr.h = rect->extent.height; - sdlColor = SDL_MapRGB (fmt, color.r, color.g, color.b); - if (fmt->Amask && (dst->flags & SDL_SRCCOLORKEY)) - { // special case -- alpha surface with colorkey - // colorkey rects are transparent - if ((sdlColor & ~fmt->Amask) == (fmt->colorkey & ~fmt->Amask)) - sdlColor &= ~fmt->Amask; // make transparent + checkPrimitiveMode (dst, &color, &mode); + sdlColor = SDL_MapRGBA (fmt, color.r, color.g, color.b, color.a); + + if (mode.kind == DRAW_REPLACE) + { // Standard SDL fillrect rendering + if (fmt->Amask && (dst->flags & SDL_SRCCOLORKEY)) + { // special case -- alpha surface with colorkey + // colorkey rects are transparent + if ((sdlColor & ~fmt->Amask) == (fmt->colorkey & ~fmt->Amask)) + sdlColor &= ~fmt->Amask; // make transparent + } + SDL_FillRect (dst, &sr, sdlColor); } - - SDL_FillRect (dst, &sr, sdlColor); + else + { // Custom fillrect rendering + RenderPixelFn plotFn = renderpixel_for (target, mode.kind); + if (!plotFn) + { + log_add (log_Warning, "ERROR: TFB_DrawCanvas_Rect " + "unsupported draw mode (%d)", (int)mode.kind); + return; + } + + SDL_LockSurface (dst); + fillrect_prim (sr, sdlColor, plotFn, mode.factor, dst); + SDL_UnlockSurface (dst); + } } +static void +TFB_DrawCanvas_Blit (SDL_Surface *src, SDL_Rect *src_r, + SDL_Surface *dst, SDL_Rect *dst_r, DrawMode mode) +{ + SDL_PixelFormat *srcfmt = src->format; + + if (mode.kind == DRAW_REPLACE) + { // Standard SDL simple blit + SDL_BlitSurface (src, src_r, dst, dst_r); + } + else if (mode.kind == DRAW_ALPHA && srcfmt->Amask == 0) + { // Standard SDL surface-alpha blit + // Note that surface alpha and per-pixel alpha cannot work + // at the same time, which is why the Amask test + assert (!(src->flags & SDL_SRCALPHA)); + // Set surface alpha temporarily + SDL_SetAlpha (src, SDL_SRCALPHA, mode.factor); + SDL_BlitSurface (src, src_r, dst, dst_r); + SDL_SetAlpha (src, 0, 255); + } + else + { // Custom blit + SDL_Rect loc_src_r, loc_dst_r; + RenderPixelFn plotFn = renderpixel_for (dst, mode.kind); + if (!plotFn) + { + log_add (log_Warning, "ERROR: TFB_DrawCanvas_Blit " + "unsupported draw mode (%d)", (int)mode.kind); + return; + } + + if (!src_r) + { // blit whole image; generate rect + loc_src_r.x = 0; + loc_src_r.y = 0; + loc_src_r.w = src->w; + loc_src_r.h = src->h; + src_r = &loc_src_r; + } + + if (!dst_r) + { // blit to 0,0; generate rect + loc_dst_r.x = 0; + loc_dst_r.y = 0; + loc_dst_r.w = dst->w; + loc_dst_r.h = dst->h; + dst_r = &loc_dst_r; + } + + SDL_LockSurface (dst); + blt_prim (src, *src_r, plotFn, mode.factor, dst, *dst_r); + SDL_UnlockSurface (dst); + } +} + // XXX: If a colormap is passed in, it has to have been acquired via // TFB_GetColorMap(). We release the colormap at the end. void TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, - int scaleMode, TFB_ColorMap *cmap, TFB_Canvas target) + int scaleMode, TFB_ColorMap *cmap, DrawMode mode, TFB_Canvas target) { SDL_Rect srcRect, targetRect, *pSrcRect; SDL_Surface *surf; @@ -170,18 +266,18 @@ TFB_ReturnColorMap (cmap); } - SDL_BlitSurface (surf, pSrcRect, target, &targetRect); + TFB_DrawCanvas_Blit (surf, pSrcRect, target, &targetRect, mode); UnlockMutex (img->mutex); } -void -TFB_DrawCanvas_Fill (TFB_Canvas source, int width, int height, - Uint32 fillcolor, TFB_Canvas target) +// Assumes the source and destination surfaces are in the same format +static void +TFB_DrawCanvas_Fill (SDL_Surface *src, Uint32 fillcolor, SDL_Surface *dst) { - SDL_Surface *src = source; - SDL_Surface *dst = target; const SDL_PixelFormat *srcfmt = src->format; SDL_PixelFormat *dstfmt = dst->format; + const int width = src->w; + const int height = src->h; const int bpp = dstfmt->BytesPerPixel; const int sp = src->pitch, dp = dst->pitch; const int slen = sp / bpp, dlen = dp / bpp; @@ -190,6 +286,8 @@ Uint32 *dst_p; int x, y; Uint32 dstkey = 0; // 0 means alpha=0 too + Uint32 amask = srcfmt->Amask; + int alpha = (fillcolor & amask) >> srcfmt->Ashift; if (srcfmt->BytesPerPixel != 4 || dstfmt->BytesPerPixel != 4) { @@ -199,6 +297,10 @@ return; } + // Strip the alpha channel from fillcolor because we process the + // alpha separately + fillcolor &= ~amask; + SDL_LockSurface(src); SDL_LockSurface(dst); @@ -213,35 +315,42 @@ if (srcfmt->Amask) { // alpha-based fill - Uint32 amask = srcfmt->Amask; - - for (y = 0; y < height; ++y) + for (y = 0; y < height; ++y, dst_p += ddst, src_p += dsrc) { for (x = 0; x < width; ++x, ++src_p, ++dst_p) { Uint32 p = *src_p & amask; - - *dst_p = (p == 0) ? dstkey : (p | fillcolor); + + if (p == 0) + { // fully transparent pixel + *dst_p = dstkey; + } + else if (alpha == 0xff) + { // not for DRAW_ALPHA; use alpha chan directly + *dst_p = p | fillcolor; + } + else + { // for DRAW_ALPHA; modulate the alpha channel + p >>= srcfmt->Ashift; + p = (p * alpha) >> 8; + p <<= srcfmt->Ashift; + *dst_p = p | fillcolor; + } } - dst_p += ddst; - src_p += dsrc; } } else if (src->flags & SDL_SRCCOLORKEY) { // colorkey-based fill Uint32 srckey = srcfmt->colorkey; - Uint32 notmask = ~srcfmt->Amask; - for (y = 0; y < height; ++y) + for (y = 0; y < height; ++y, dst_p += ddst, src_p += dsrc) { for (x = 0; x < width; ++x, ++src_p, ++dst_p) { - Uint32 p = *src_p & notmask; + Uint32 p = *src_p; *dst_p = (p == srckey) ? dstkey : fillcolor; } - dst_p += ddst; - src_p += dsrc; } } else @@ -262,8 +371,9 @@ void TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, - int scaleMode, Color color, TFB_Canvas target) + int scaleMode, Color color, DrawMode mode, TFB_Canvas target) { + SDL_Surface *dst = target; SDL_Rect srcRect, targetRect, *pSrcRect; SDL_Surface *surf; SDL_Palette *palette; @@ -277,6 +387,8 @@ return; } + checkPrimitiveMode (dst, &color, &mode); + LockMutex (img->mutex); if (scale != 0 && scale != GSCALE_IDENTITY) @@ -338,6 +450,7 @@ else { // fill the non-transparent parts of the image with fillcolor SDL_Surface *newfill = img->FilledImg; + SDL_PixelFormat *fillfmt; if (newfill && (newfill->w < surf->w || newfill->h < surf->h)) { @@ -357,35 +470,43 @@ surf->format->Amask); force_fill = true; } + fillfmt = newfill->format; - if (force_fill || - img->last_fill.r != color.r || - img->last_fill.g != color.g || - img->last_fill.b != color.b) + if (force_fill || !sameColor (img->last_fill, color)) { // image or fillcolor changed - regenerate - TFB_DrawCanvas_Fill (surf, surf->w, surf->h, SDL_MapRGBA ( - newfill->format, color.r, color.g, color.b, 0), newfill); - // important to keep alpha=0 in fillcolor - // -- we process alpha ourselves + Uint32 fillColor; + if (mode.kind == DRAW_ALPHA && fillfmt->Amask) + { // Per-pixel alpha and surface alpha will not work together + // We have to handle DRAW_ALPHA differently by modulating + // the surface alpha channel ourselves. + color.a = mode.factor; + mode.kind = DRAW_REPLACE; + } + else + { // Make sure we do not modulate the alpha channel + color.a = 0xff; + } + fillColor = SDL_MapRGBA (newfill->format, color.r, color.g, + color.b, color.a); + TFB_DrawCanvas_Fill (surf, fillColor, newfill); // cache filled image if possible - img->last_fill.r = color.r; - img->last_fill.g = color.g; - img->last_fill.b = color.b; + img->last_fill = color; } img->FilledImg = newfill; surf = newfill; } - SDL_BlitSurface (surf, pSrcRect, target, &targetRect); + TFB_DrawCanvas_Blit (surf, pSrcRect, dst, &targetRect, mode); UnlockMutex (img->mutex); } void TFB_DrawCanvas_FontChar (TFB_Char *fontChar, TFB_Image *backing, - int x, int y, TFB_Canvas target) + int x, int y, DrawMode mode, TFB_Canvas target) { + SDL_Surface *dst = target; SDL_Rect srcRect, targetRect; SDL_Surface *surf; int w, h; @@ -439,17 +560,46 @@ Uint8 *src_p = fontChar->data; Uint32 *dst_p = (Uint32 *)surf->pixels; - for (y = 0; y < h; ++y, src_p += sskip, dst_p += dskip) - { - for (x = 0; x < w; ++x, ++src_p, ++dst_p) + if (mode.kind == DRAW_ALPHA) + { // Per-pixel alpha and surface alpha will not work together + // We have to handle DRAW_ALPHA differently by modulating + // the backing surface alpha channel ourselves. + // The existing backing surface alpha channel is ignored. + int alpha = mode.factor; + mode.kind = DRAW_REPLACE; + + for (y = 0; y < h; ++y, src_p += sskip, dst_p += dskip) { - *dst_p = (*dst_p & dmask) | (((Uint32)*src_p) << ashift); + for (x = 0; x < w; ++x, ++src_p, ++dst_p) + { + Uint32 p = *dst_p & dmask; + Uint32 a = *src_p; + + // we use >> 8 instead of / 255, and it does not handle + // alpha == 255 correctly + if (alpha != 0xff) + { // modulate the alpha channel + a = (a * alpha) >> 8; + } + *dst_p = p | (a << ashift); + } } } + else /* if (mode.kind != DRAW_ALPHA) */ + { // Transfer the alpha channel to the backing surface + // DRAW_REPLACE + Color.a is NOT supported right now + for (y = 0; y < h; ++y, src_p += sskip, dst_p += dskip) + { + for (x = 0; x < w; ++x, ++src_p, ++dst_p) + { + *dst_p = (*dst_p & dmask) | ((Uint32)*src_p << ashift); + } + } + } } SDL_UnlockSurface (surf); - SDL_BlitSurface (surf, &srcRect, target, &targetRect); + TFB_DrawCanvas_Blit (surf, &srcRect, dst, &targetRect, mode); UnlockMutex (backing->mutex); } @@ -1090,6 +1240,7 @@ #if 0 SDL_GetRGBA (c, fmt, &p.c.r, &p.c.g, &p.c.b, &p.c.a); #else + // Assume 8 bits/channel; a safe assumption with 32bpp surfaces p.c.r = (c >> fmt->Rshift) & 0xff; p.c.g = (c >> fmt->Gshift) & 0xff; p.c.b = (c >> fmt->Bshift) & 0xff; Modified: trunk/sc2/src/libs/graphics/sdl/primitives.c =================================================================== --- trunk/sc2/src/libs/graphics/sdl/primitives.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/sdl/primitives.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -18,6 +18,7 @@ #ifdef GFXMODULE_SDL +#include "port.h" #include "sdl_common.h" #include "primitives.h" @@ -104,20 +105,16 @@ switch (bpp) { case 1: return &getpixel_8; - break; case 2: return &getpixel_16; - break; case 3: if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { return &getpixel_24_be; } else { return &getpixel_24_le; } - break; case 4: return &getpixel_32; - break; } return NULL; } @@ -128,36 +125,167 @@ switch (bpp) { case 1: return &putpixel_8; - break; case 2: return &putpixel_16; - break; case 3: if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { return &putpixel_24_be; } else { return &putpixel_24_le; } - break; case 4: return &putpixel_32; - break; } return NULL; } +static void renderpixel_replace(SDL_Surface *surface, int x, int y, + Uint32 pixel, int factor) +{ + (void) factor; // ignored + putpixel_32(surface, x, y, pixel); +} + +static inline Uint8 clip_channel(int c) +{ + if (c < 0) + c = 0; + else if (c > 255) + c = 255; + return c; +} + +static inline Uint8 modulated_sum(Uint8 dc, Uint8 sc, int factor) +{ + // We use >> 8 instead of / 255 because it is faster, but it does + // not work 100% correctly. It should be safe because this should + // not be called for factor==255 + int b = dc + ((sc * factor) >> 8); + return clip_channel(b); +} + +static inline Uint8 alpha_blend(Uint8 dc, Uint8 sc, int alpha) +{ + // We use >> 8 instead of / 255 because it is faster, but it does + // not work 100% correctly. It should be safe because this should + // not be called for alpha==255 + // No need to clip since we should never get values outside of 0..255 + // range, unless alpha is over 255, which is not supported. + return (((sc - dc) * alpha) >> 8) + dc; +} + +// Assumes 8 bits/channel, a safe assumption for 32bpp surfaces +#define UNPACK_PIXEL_32(p, fmt, r, g, b) \ + do { \ + (r) = ((p) >> (fmt)->Rshift) & 0xff; \ + (g) = ((p) >> (fmt)->Gshift) & 0xff; \ + (b) = ((p) >> (fmt)->Bshift) & 0xff; \ + } while (0) + +// Assumes the channels already clipped to 8 bits +static inline Uint32 PACK_PIXEL_32(const SDL_PixelFormat *fmt, + Uint8 r, Uint8 g, Uint8 b) +{ + return ((Uint32)r << fmt->Rshift) | ((Uint32)g << fmt->Gshift) + | ((Uint32)b << fmt->Bshift); +} + +static void renderpixel_additive(SDL_Surface *surface, int x, int y, + Uint32 pixel, int factor) +{ + const SDL_PixelFormat *fmt = surface->format; + Uint32 *p; + Uint32 sp; + Uint8 sr, sg, sb; + int r, g, b; + + p = (Uint32 *) ((Uint8 *)surface->pixels + y * surface->pitch + x * 4); + sp = *p; + UNPACK_PIXEL_32(sp, fmt, sr, sg, sb); + UNPACK_PIXEL_32(pixel, fmt, r, g, b); + + // TODO: We may need a special case for factor == -ADDITIVE_FACTOR_1 too, + // but it is not important enough right now to care ;) + if (factor == ADDITIVE_FACTOR_1) + { // no need to modulate the 'pixel', and modulation does not + // work correctly with factor==255 anyway + sr = clip_channel(sr + r); + sg = clip_channel(sg + g); + sb = clip_channel(sb + b); + } + else + { + sr = modulated_sum(sr, r, factor); + sg = modulated_sum(sg, g, factor); + sb = modulated_sum(sb, b, factor); + } + + *p = PACK_PIXEL_32(fmt, sr, sg, sb); +} + +static void renderpixel_alpha(SDL_Surface *surface, int x, int y, + Uint32 pixel, int factor) +{ + const SDL_PixelFormat *fmt = surface->format; + Uint32 *p; + Uint32 sp; + Uint8 sr, sg, sb; + int r, g, b; + + if (factor == FULLY_OPAQUE_ALPHA) + { // alpha == 255 is equivalent to 'replace' and blending does not + // work correctly anyway because we use >> 8 instead of / 255 + putpixel_32(surface, x, y, pixel); + return; + } + + p = (Uint32 *) ((Uint8 *)surface->pixels + y * surface->pitch + x * 4); + sp = *p; + UNPACK_PIXEL_32(sp, fmt, sr, sg, sb); + UNPACK_PIXEL_32(pixel, fmt, r, g, b); + sr = alpha_blend(sr, r, factor); + sg = alpha_blend(sg, g, factor); + sb = alpha_blend(sb, b, factor); + *p = PACK_PIXEL_32(fmt, sr, sg, sb); +} + +RenderPixelFn renderpixel_for(SDL_Surface *surface, RenderKind kind) +{ + const SDL_PixelFormat *fmt = surface->format; + + // The only supported rendering is to 32bpp surfaces + if (fmt->BytesPerPixel != 4) + return NULL; + + // Rendering other than REPLACE is not supported on RGBA surfaces + if (fmt->Amask != 0 && kind != renderReplace) + return NULL; + + switch (kind) + { + case renderReplace: + return &renderpixel_replace; + case renderAdditive: + return &renderpixel_additive; + case renderAlpha: + return &renderpixel_alpha; + } + // should not ever get here + return NULL; +} + /* Line drawing routine * Adapted from Paul Heckbert's implementation of Bresenham's algorithm, * 3 Sep 85; taken from Graphics Gems I */ -void line(int x1, int y1, int x2, int y2, Uint32 color, PutPixelFn plot, - SDL_Surface *surface) +void line_prim(int x1, int y1, int x2, int y2, Uint32 color, + RenderPixelFn plot, int factor, SDL_Surface *dst) { int d, x, y, ax, ay, sx, sy, dx, dy; - SDL_Rect r; + SDL_Rect clip_r; - SDL_GetClipRect (surface, &r); - if (!clip_line (&x1, &y1, &x2, &y2, &r)) + SDL_GetClipRect (dst, &clip_r); + if (!clip_line (&x1, &y1, &x2, &y2, &clip_r)) return; // line is completely outside clipping rectangle dx = x2-x1; @@ -172,7 +300,7 @@ if (ax > ay) { d = ay - (ax >> 1); for (;;) { - (*plot)(surface, x, y, color); + (*plot)(dst, x, y, color, factor); if (x == x2) return; if (d >= 0) { @@ -185,7 +313,7 @@ } else { d = ax - (ay >> 1); for (;;) { - (*plot)(surface, x, y, color); + (*plot)(dst, x, y, color, factor); if (y == y2) return; if (d >= 0) { @@ -219,7 +347,7 @@ } int -clip_line (int *lx1, int *ly1, int *lx2, int *ly2, SDL_Rect *r) +clip_line (int *lx1, int *ly1, int *lx2, int *ly2, const SDL_Rect *r) { int C0, C1, C; float x, y, x0, y0, x1, y1, xmin, ymin, xmax, ymax; @@ -289,4 +417,191 @@ } } +void fillrect_prim(SDL_Rect r, Uint32 color, + RenderPixelFn plot, int factor, SDL_Surface *dst) +{ + int x, y; + int x1, y1; + SDL_Rect clip_r; + + SDL_GetClipRect (dst, &clip_r); + if (!clip_rect (&r, &clip_r)) + return; // rect is completely outside clipping rectangle + + // TODO: calculate destination pointer directly instead of + // using the plot(x,y) version + x1 = r.x + r.w; + y1 = r.y + r.h; + for (y = r.y; y < y1; ++y) + { + for (x = r.x; x < x1; ++x) + plot(dst, x, y, color, factor); + } +} + +// clip the rectangle against the clip rectangle +int clip_rect(SDL_Rect *r, const SDL_Rect *clip_r) +{ + // NOTE: the following clipping code is copied in part + // from SDL-1.2.4 sources + int dx, dy; + + dx = clip_r->x - r->x; + if (dx > 0) + { + r->w -= dx; + r->x += dx; + } + dx = r->x + r->w - clip_r->x - clip_r->w; + if (dx > 0) + r->w -= dx; + + dy = clip_r->y - r->y; + if (dy > 0) + { + r->h -= dy; + r->y += dy; + } + dy = r->y + r->h - clip_r->y - clip_r->h; + if (dy > 0) + r->h -= dy; + + if (r->w <= 0 || r->h <= 0) + { + r->w = 0; + r->h = 0; + return 0; + } + return 1; +} + +void blt_prim(SDL_Surface *src, SDL_Rect src_r, RenderPixelFn plot, int factor, + SDL_Surface *dst, SDL_Rect dst_r) +{ + SDL_PixelFormat *srcfmt = src->format; + SDL_Palette *srcpal = srcfmt->palette; + SDL_PixelFormat *dstfmt = dst->format; + Uint32 mask = 0; + Uint32 key = ~0; + GetPixelFn getpix = getpixel_for(src); + SDL_Rect clip_r; + int x, y; + + SDL_GetClipRect (dst, &clip_r); + if (!clip_blt_rects (&src_r, &dst_r, &clip_r)) + return; // rect is completely outside clipping rectangle + + if (src_r.x >= src->w || src_r.y >= src->h) + return; // rect is completely outside source bounds + + if (src_r.x + src_r.w > src->w) + src_r.w = src->w - src_r.x; + if (src_r.y + src_r.h > src->h) + src_r.h = src->h - src_r.y; + + // use colorkeys where appropriate + if (srcfmt->Amask) + { // alpha transparency + mask = srcfmt->Amask; + key = 0; + } + else if (src->flags & SDL_SRCCOLORKEY) + { // colorkey transparency + mask = ~srcfmt->Amask; + key = srcfmt->colorkey & mask; + } + + // TODO: calculate the source and destination pointers directly + // instead of using the plot(x,y) version + for (y = 0; y < src_r.h; ++y) + { + for (x = 0; x < src_r.w; ++x) + { + Uint8 r, g, b, a; + Uint32 p; + + p = getpix(src, src_r.x + x, src_r.y + y); + if (srcpal) + { // source is paletted, colorkey does not use mask + if (p == key) + continue; // transparent pixel + } + else + { // source is RGB(A), colorkey uses mask + if ((p & mask) == key) + continue; // transparent pixel + } + + // convert pixel format to destination + SDL_GetRGBA(p, srcfmt, &r, &g, &b, &a); + // TODO: handle source pixel alpha; plot() should probably + // get a source alpha parameter + p = SDL_MapRGBA(dstfmt, r, g, b, a); + + plot(dst, dst_r.x + x, dst_r.y + y, p, factor); + } + } +} + +// clip the source and destination rectangles against the clip rectangle +int clip_blt_rects(SDL_Rect *src_r, SDL_Rect *dst_r, const SDL_Rect *clip_r) +{ + // NOTE: the following clipping code is copied in part + // from SDL-1.2.4 sources + int w, h; + int dx, dy; + + // clip the source rectangle to the source surface + w = src_r->w; + if (src_r->x < 0) + { + w += src_r->x; + dst_r->x -= src_r->x; + src_r->x = 0; + } + + h = src_r->h; + if (src_r->y < 0) + { + h += src_r->y; + dst_r->y -= src_r->y; + src_r->y = 0; + } + + // clip the destination rectangle against the clip rectangle, + // minding the source rectangle in the process + dx = clip_r->x - dst_r->x; + if (dx > 0) + { + w -= dx; + dst_r->x += dx; + src_r->x += dx; + } + dx = dst_r->x + w - clip_r->x - clip_r->w; + if (dx > 0) + w -= dx; + + dy = clip_r->y - dst_r->y; + if (dy > 0) + { + h -= dy; + dst_r->y += dy; + src_r->y += dy; + } + dy = dst_r->y + h - clip_r->y - clip_r->h; + if (dy > 0) + h -= dy; + + if (w <= 0 || h <= 0) + { + src_r->w = 0; + src_r->h = 0; + return 0; + } + + src_r->w = w; + src_r->h = h; + return 1; +} + #endif Modified: trunk/sc2/src/libs/graphics/sdl/primitives.h =================================================================== --- trunk/sc2/src/libs/graphics/sdl/primitives.h 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/sdl/primitives.h 2009-12-27 04:42:50 UTC (rev 3475) @@ -21,13 +21,42 @@ /* Function types for the pixel functions */ -typedef Uint32 (*GetPixelFn)(SDL_Surface *, int, int); -typedef void (*PutPixelFn)(SDL_Surface *, int, int, Uint32); +typedef Uint32 (*GetPixelFn)(SDL_Surface *, int x, int y); +// 'pixel' is in destination surface format +typedef void (*PutPixelFn)(SDL_Surface *, int x, int y, Uint32 pixel); GetPixelFn getpixel_for(SDL_Surface *surface); PutPixelFn putpixel_for(SDL_Surface *surface); -void line(int x1, int y1, int x2, int y2, Uint32 color, PutPixelFn plot, - SDL_Surface *surface); -int clip_line(int *lx1, int *ly1, int *lx2, int *ly2, SDL_Rect *r); -#endif +// This currently matches gfxlib.h:DrawKind for simplicity +typedef enum +{ + renderReplace = 0, + renderAdditive, + renderAlpha, +} RenderKind; + +#define FULLY_OPAQUE_ALPHA 255 +#define ADDITIVE_FACTOR_1 255 + +// 'pixel' is in destination surface format +// See gfxlib.h:DrawKind for 'factor' spec +typedef void (*RenderPixelFn)(SDL_Surface *, int x, int y, Uint32 pixel, + int factor); + +RenderPixelFn renderpixel_for(SDL_Surface *surface, RenderKind); + +void line_prim(int x1, int y1, int x2, int y2, Uint32 color, + RenderPixelFn plot, int factor, SDL_Surface *dst); +void fillrect_prim(SDL_Rect r, Uint32 color, + RenderPixelFn plot, int factor, SDL_Surface *dst); +void blt_prim(SDL_Surface *src, SDL_Rect src_r, + RenderPixelFn plot, int factor, + SDL_Surface *dst, SDL_Rect dst_r); + +int clip_line(int *lx1, int *ly1, int *lx2, int *ly2, const SDL_Rect *clip_r); +int clip_rect(SDL_Rect *r, const SDL_Rect *clip_r); +int clip_blt_rects(SDL_Rect *src_r, SDL_Rect *dst_r, const SDL_Rect *clip_r); + + +#endif /* PRIMITIVES_H */ Modified: trunk/sc2/src/libs/graphics/tfb_draw.c =================================================================== --- trunk/sc2/src/libs/graphics/tfb_draw.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/tfb_draw.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -24,7 +24,8 @@ static const HOT_SPOT NullHs = {0, 0}; void -TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, Color color, SCREEN dest) +TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, Color color, + DrawMode mode, SCREEN dest) { TFB_DrawCommand DC; @@ -34,13 +35,14 @@ DC.data.line.x2 = x2; DC.data.line.y2 = y2; DC.data.line.color = color; + DC.data.line.drawMode = mode; DC.data.line.destBuffer = dest; TFB_EnqueueDrawCommand (&DC); } void -TFB_DrawScreen_Rect (RECT *rect, Color color, SCREEN dest) +TFB_DrawScreen_Rect (RECT *rect, Color color, DrawMode mode, SCREEN dest) { RECT locRect; TFB_DrawCommand DC; @@ -56,6 +58,7 @@ DC.Type = TFB_DRAWCOMMANDTYPE_RECTANGLE; DC.data.rect.rect = *rect; DC.data.rect.color = color; + DC.data.rect.drawMode = mode; DC.data.rect.destBuffer = dest; TFB_EnqueueDrawCommand (&DC); @@ -63,7 +66,7 @@ void TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale, - int scaleMode, TFB_ColorMap *cmap, SCREEN dest) + int scaleMode, TFB_ColorMap *cmap, DrawMode mode, SCREEN dest) { TFB_DrawCommand DC; @@ -74,6 +77,7 @@ DC.data.image.y = y; DC.data.image.scale = (scale == GSCALE_IDENTITY) ? 0 : scale; DC.data.image.scaleMode = scaleMode; + DC.data.image.drawMode = mode; DC.data.image.destBuffer = dest; TFB_EnqueueDrawCommand (&DC); @@ -81,7 +85,7 @@ void TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale, - int scaleMode, Color color, SCREEN dest) + int scaleMode, Color color, DrawMode mode, SCREEN dest) { TFB_DrawCommand DC; @@ -92,6 +96,7 @@ DC.data.filledimage.scale = (scale == GSCALE_IDENTITY) ? 0 : scale; DC.data.filledimage.scaleMode = scaleMode; DC.data.filledimage.color = color; + DC.data.filledimage.drawMode = mode; DC.data.filledimage.destBuffer = dest; TFB_EnqueueDrawCommand (&DC); @@ -99,7 +104,7 @@ void TFB_DrawScreen_FontChar (TFB_Char *fontChar, TFB_Image *backing, - int x, int y, SCREEN dest) + int x, int y, DrawMode mode, SCREEN dest) { TFB_DrawCommand DC; @@ -108,6 +113,7 @@ DC.data.fontchar.backing = backing; DC.data.fontchar.x = x; DC.data.fontchar.y = y; + DC.data.fontchar.drawMode = mode; DC.data.fontchar.destBuffer = dest; TFB_EnqueueDrawCommand (&DC); @@ -230,51 +236,51 @@ void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, Color color, - TFB_Image *dest) + DrawMode mode, TFB_Image *target) { - LockMutex (dest->mutex); - TFB_DrawCanvas_Line (x1, y1, x2, y2, color, dest->NormalImg); - dest->dirty = TRUE; - UnlockMutex (dest->mutex); + LockMutex (target->mutex); + TFB_DrawCanvas_Line (x1, y1, x2, y2, color, mode, target->NormalImg); + target->dirty = TRUE; + UnlockMutex (target->mutex); } void -TFB_DrawImage_Rect (RECT *rect, Color color, TFB_Image *image) +TFB_DrawImage_Rect (RECT *rect, Color color, DrawMode mode, TFB_Image *target) { - LockMutex (image->mutex); - TFB_DrawCanvas_Rect (rect, color, image->NormalImg); - image->dirty = TRUE; - UnlockMutex (image->mutex); + LockMutex (target->mutex); + TFB_DrawCanvas_Rect (rect, color, mode, target->NormalImg); + target->dirty = TRUE; + UnlockMutex (target->mutex); } void TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale, - int scaleMode, TFB_ColorMap *cmap, TFB_Image *target) + int scaleMode, TFB_ColorMap *cmap, DrawMode mode, TFB_Image *target) { LockMutex (target->mutex); TFB_DrawCanvas_Image (img, x, y, scale, scaleMode, cmap, - target->NormalImg); + mode, target->NormalImg); target->dirty = TRUE; UnlockMutex (target->mutex); } void TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, int scale, - int scaleMode, Color color, TFB_Image *target) + int scaleMode, Color color, DrawMode mode, TFB_Image *target) { LockMutex (target->mutex); TFB_DrawCanvas_FilledImage (img, x, y, scale, scaleMode, color, - target->NormalImg); + mode, target->NormalImg); target->dirty = TRUE; UnlockMutex (target->mutex); } void TFB_DrawImage_FontChar (TFB_Char *fontChar, TFB_Image *backing, - int x, int y, TFB_Image *target) + int x, int y, DrawMode mode, TFB_Image *target) { LockMutex (target->mutex); - TFB_DrawCanvas_FontChar (fontChar, backing, x, y, target->NormalImg); + TFB_DrawCanvas_FontChar (fontChar, backing, x, y, mode, target->NormalImg); target->dirty = TRUE; UnlockMutex (target->mutex); } Modified: trunk/sc2/src/libs/graphics/tfb_draw.h =================================================================== --- trunk/sc2/src/libs/graphics/tfb_draw.h 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/tfb_draw.h 2009-12-27 04:42:50 UTC (rev 3475) @@ -79,15 +79,15 @@ // Drawing commands void TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, Color color, - SCREEN dest); -void TFB_DrawScreen_Rect (RECT *rect, Color color, SCREEN dest); + DrawMode, SCREEN dest); +void TFB_DrawScreen_Rect (RECT *rect, Color, DrawMode, SCREEN dest); void TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale, - int scaleMode, TFB_ColorMap *cmap, SCREEN dest); + int scaleMode, TFB_ColorMap *, DrawMode, SCREEN dest); void TFB_DrawScreen_Copy (const RECT *r, SCREEN src, SCREEN dest); void TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale, - int scaleMode, Color color, SCREEN dest); + int scaleMode, Color, DrawMode, SCREEN dest); void TFB_DrawScreen_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, - SCREEN dest); + DrawMode, SCREEN dest); void TFB_DrawScreen_CopyToImage (TFB_Image *img, const RECT *r, SCREEN src); void TFB_DrawScreen_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, @@ -109,14 +109,14 @@ TFB_Image *img2, POINT img2org, const RECT *interRect); void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, Color color, - TFB_Image *dest); -void TFB_DrawImage_Rect (RECT *rect, Color color, TFB_Image *image); + DrawMode, TFB_Image *target); +void TFB_DrawImage_Rect (RECT *rect, Color, DrawMode, TFB_Image *target); void TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale, - int scaleMode, TFB_ColorMap *cmap, TFB_Image *target); + int scaleMode, TFB_ColorMap *, DrawMode, TFB_Image *target); void TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, int scale, - int scaleMode, Color color, TFB_Image *target); + int scaleMode, Color, DrawMode, TFB_Image *target); void TFB_DrawImage_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, - TFB_Image *target); + DrawMode, TFB_Image *target); TFB_Canvas TFB_DrawCanvas_LoadFromFile (void *dir, const char *fileName); TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN hasalpha); @@ -147,14 +147,14 @@ void TFB_DrawCanvas_Delete (TFB_Canvas canvas); void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, Color color, - TFB_Canvas dest); -void TFB_DrawCanvas_Rect (RECT *rect, Color color, TFB_Canvas image); + DrawMode, TFB_Canvas target); +void TFB_DrawCanvas_Rect (RECT *rect, Color, DrawMode, TFB_Canvas target); void TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, - int scaleMode, TFB_ColorMap *cmap, TFB_Canvas target); + int scaleMode, TFB_ColorMap *, DrawMode, TFB_Canvas target); void TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, - int scaleMode, Color color, TFB_Canvas target); + int scaleMode, Color, DrawMode, TFB_Canvas target); void TFB_DrawCanvas_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, - TFB_Canvas target); + DrawMode, TFB_Canvas target); void TFB_DrawCanvas_CopyRect (TFB_Canvas source, const RECT *srcRect, TFB_Canvas target, POINT dstPt); Modified: trunk/sc2/src/libs/graphics/tfb_prim.c =================================================================== --- trunk/sc2/src/libs/graphics/tfb_prim.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/tfb_prim.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -29,7 +29,7 @@ #include "libs/log.h" void -TFB_Prim_Point (POINT *p, Color color, POINT ctxOrigin) +TFB_Prim_Point (POINT *p, Color color, DrawMode mode, POINT ctxOrigin) { RECT r; @@ -39,13 +39,13 @@ r.extent.width = r.extent.height = 1; if (_CurFramePtr->Type == SCREEN_DRAWABLE) - TFB_DrawScreen_Rect (&r, color, TFB_SCREEN_MAIN); + TFB_DrawScreen_Rect (&r, color, mode, TFB_SCREEN_MAIN); else - TFB_DrawImage_Rect (&r, color, _CurFramePtr->image); + TFB_DrawImage_Rect (&r, color, mode, _CurFramePtr->image); } void -TFB_Prim_Rect (RECT *r, Color color, POINT ctxOrigin) +TFB_Prim_Rect (RECT *r, Color color, DrawMode mode, POINT ctxOrigin) { RECT arm; int gscale; @@ -57,24 +57,24 @@ arm = *r; arm.extent.width = r->extent.width; arm.extent.height = 1; - TFB_Prim_FillRect (&arm, color, ctxOrigin); + TFB_Prim_FillRect (&arm, color, mode, ctxOrigin); arm.extent.height = r->extent.height; arm.extent.width = 1; - TFB_Prim_FillRect (&arm, color, ctxOrigin); + TFB_Prim_FillRect (&arm, color, mode, ctxOrigin); // rounding error correction here arm.corner.x += ((r->extent.width * gscale + (GSCALE_IDENTITY >> 1)) / GSCALE_IDENTITY) - 1; - TFB_Prim_FillRect (&arm, color, ctxOrigin); + TFB_Prim_FillRect (&arm, color, mode, ctxOrigin); arm.corner.x = r->corner.x; arm.corner.y += ((r->extent.height * gscale + (GSCALE_IDENTITY >> 1)) / GSCALE_IDENTITY) - 1; arm.extent.width = r->extent.width; arm.extent.height = 1; - TFB_Prim_FillRect (&arm, color, ctxOrigin); + TFB_Prim_FillRect (&arm, color, mode, ctxOrigin); } void -TFB_Prim_FillRect (RECT *r, Color color, POINT ctxOrigin) +TFB_Prim_FillRect (RECT *r, Color color, DrawMode mode, POINT ctxOrigin) { RECT rect; int gscale; @@ -97,13 +97,13 @@ } if (_CurFramePtr->Type == SCREEN_DRAWABLE) - TFB_DrawScreen_Rect (&rect, color, TFB_SCREEN_MAIN); + TFB_DrawScreen_Rect (&rect, color, mode, TFB_SCREEN_MAIN); else - TFB_DrawImage_Rect (&rect, color, _CurFramePtr->image); + TFB_DrawImage_Rect (&rect, color, mode, _CurFramePtr->image); } void -TFB_Prim_Line (LINE *line, Color color, POINT ctxOrigin) +TFB_Prim_Line (LINE *line, Color color, DrawMode mode, POINT ctxOrigin) { int x1, y1, x2, y2; @@ -114,13 +114,13 @@ y2=line->second.y + ctxOrigin.y; if (_CurFramePtr->Type == SCREEN_DRAWABLE) - TFB_DrawScreen_Line (x1, y1, x2, y2, color, TFB_SCREEN_MAIN); + TFB_DrawScreen_Line (x1, y1, x2, y2, color, mode, TFB_SCREEN_MAIN); else - TFB_DrawImage_Line (x1, y1, x2, y2, color, _CurFramePtr->image); + TFB_DrawImage_Line (x1, y1, x2, y2, color, mode, _CurFramePtr->image); } void -TFB_Prim_Stamp (STAMP *stmp, POINT ctxOrigin) +TFB_Prim_Stamp (STAMP *stmp, DrawMode mode, POINT ctxOrigin) { int x, y; FRAME SrcFramePtr; @@ -160,17 +160,17 @@ if (_CurFramePtr->Type == SCREEN_DRAWABLE) { TFB_DrawScreen_Image (img, x, y, GetGraphicScale (), - GetGraphicScaleMode (), cmap, TFB_SCREEN_MAIN); + GetGraphicScaleMode (), cmap, mode, TFB_SCREEN_MAIN); } else { TFB_DrawImage_Image (img, x, y, GetGraphicScale (), - GetGraphicScaleMode (), cmap, _CurFramePtr->image); + GetGraphicScaleMode (), cmap, mode, _CurFramePtr->image); } } void -TFB_Prim_StampFill (STAMP *stmp, Color color, POINT ctxOrigin) +TFB_Prim_StampFill (STAMP *stmp, Color color, DrawMode mode, POINT ctxOrigin) { int x, y; FRAME SrcFramePtr; @@ -203,18 +203,18 @@ if (_CurFramePtr->Type == SCREEN_DRAWABLE) { TFB_DrawScreen_FilledImage (img, x, y, GetGraphicScale (), - GetGraphicScaleMode (), color, TFB_SCREEN_MAIN); + GetGraphicScaleMode (), color, mode, TFB_SCREEN_MAIN); } else { TFB_DrawImage_FilledImage (img, x, y, GetGraphicScale (), - GetGraphicScaleMode (), color, _CurFramePtr->image); + GetGraphicScaleMode (), color, mode, _CurFramePtr->image); } } void TFB_Prim_FontChar (POINT charOrigin, TFB_Char *fontChar, TFB_Image *backing, - POINT ctxOrigin) + DrawMode mode, POINT ctxOrigin) { int x, y; @@ -224,11 +224,13 @@ if (_CurFramePtr->Type == SCREEN_DRAWABLE) { - TFB_DrawScreen_FontChar (fontChar, backing, x, y, TFB_SCREEN_MAIN); + TFB_DrawScreen_FontChar (fontChar, backing, x, y, mode, + TFB_SCREEN_MAIN); } else { - TFB_DrawImage_FontChar (fontChar, backing, x, y, _CurFramePtr->image); + TFB_DrawImage_FontChar (fontChar, backing, x, y, mode, + _CurFramePtr->image); } } Modified: trunk/sc2/src/libs/graphics/tfb_prim.h =================================================================== --- trunk/sc2/src/libs/graphics/tfb_prim.h 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/graphics/tfb_prim.h 2009-12-27 04:42:50 UTC (rev 3475) @@ -20,11 +20,11 @@ #include "tfb_draw.h" -void TFB_Prim_Line (LINE *line, Color color, POINT ctxOrigin); -void TFB_Prim_Point (POINT *p, Color color, POINT ctxOrigin); -void TFB_Prim_Rect (RECT *r, Color color, POINT ctxOrigin); -void TFB_Prim_FillRect (RECT *r, Color color, POINT ctxOrigin); -void TFB_Prim_Stamp (STAMP *stamp, POINT ctxOrigin); -void TFB_Prim_StampFill (STAMP *stamp, Color color, POINT ctxOrigin); +void TFB_Prim_Line (LINE *, Color, DrawMode, POINT ctxOrigin); +void TFB_Prim_Point (POINT *, Color, DrawMode, POINT ctxOrigin); +void TFB_Prim_Rect (RECT *, Color, DrawMode, POINT ctxOrigin); +void TFB_Prim_FillRect (RECT *, Color, DrawMode, POINT ctxOrigin); +void TFB_Prim_Stamp (STAMP *, DrawMode, POINT ctxOrigin); +void TFB_Prim_StampFill (STAMP *, Color, DrawMode, POINT ctxOrigin); void TFB_Prim_FontChar (POINT charOrigin, TFB_Char *fontChar, - TFB_Image *backing, POINT ctxOrigin); + TFB_Image *backing, DrawMode, POINT ctxOrigin); Modified: trunk/sc2/src/libs/video/vidplayer.c =================================================================== --- trunk/sc2/src/libs/video/vidplayer.c 2009-12-26 17:15:12 UTC (rev 3474) +++ trunk/sc2/src/libs/video/vidplayer.c 2009-12-27 04:42:50 UTC (rev 3475) @@ -147,8 +147,8 @@ // We have the cliprect precalculated and don't need the rest oldContext = SetContext (NULL); TFB_DrawScreen_Image (vid->frame, - vid->dst_rect.corner.x, vid->dst_rect.corner.y, - 0, 0, NULL, TFB_SCREEN_MAIN); + vid->dst_rect.corner.x, vid->dst_rect.corner.y, 0, 0, + NULL, DRAW_REPLACE_MODE, TFB_SCREEN_MAIN); SetContext (oldContext); UnlockMutex (GraphicsLock); FlushGraphics (); // needed to prevent half-frame updates @@ -199,8 +199,8 @@ // We have the cliprect precalculated and don't need the rest oldContext = SetContext (NULL); TFB_DrawScreen_Image (vid->frame, - vid->dst_rect.corner.x, vid->dst_rect.corner.y, - 0, 0, NULL, TFB_SCREEN_MAIN); + vid->dst_rect.corner.x, vid->dst_rect.corner.y, 0, 0, + NULL, DRAW_REPLACE_MODE, TFB_SCREEN_MAIN); SetContext (oldContext); UnlockMutex (GraphicsLock); FlushGraphics (); // needed to prevent half-frame updates This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |