Added additive and alpha drawing mode to gfxlib proper (TFB_Draw/TFB_Canvas/Color); this is to replace arith_frame_blit()/TFB_BlitSurface()

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3475 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2009-12-27 04:42:50 +00:00
parent ae5303ed3c
commit ec5a400052
16 changed files with 787 additions and 184 deletions
+1
View File
@@ -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
+52
View File
@@ -277,6 +277,56 @@ typedef enum
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 SetContextClipRect (RECT *pRect);
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);
+37 -14
View File
@@ -33,6 +33,11 @@ PRIMITIVE _locPrim;
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 @@ CreateContextAux (void)
if (NewContext)
{
/* initialize context */
CONTEXT OldContext;
#ifdef DEBUG
NewContext->name = name;
NewContext->next = NULL;
@@ -93,12 +96,9 @@ CreateContextAux (void)
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 @@ SetContextForeGroundColor (Color color)
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 @@ Color
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 @@ SetContextBackGroundColor (Color color)
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 @@ Color
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 @@ FixContextFontEffect (void)
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;
+4 -2
View File
@@ -33,6 +33,7 @@ struct context_desc
// High nibble contains GRAPHICS_STATUS
Color ForeGroundColor, BackGroundColor;
DrawMode Mode;
FRAME ForeGroundFrame;
FONT Font;
@@ -62,10 +63,11 @@ extern PRIMITIVE _locPrim;
#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) \
{ \
+6 -3
View File
@@ -377,6 +377,7 @@ TFB_FlushGraphics (void)
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_FlushGraphics (void)
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 @@ TFB_FlushGraphics (void)
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_FlushGraphics (void)
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 @@ TFB_FlushGraphics (void)
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;
+5
View File
@@ -47,6 +47,7 @@ typedef struct tfb_dc_line
{
int x1, y1, x2, y2;
Color color;
DrawMode drawMode;
SCREEN destBuffer;
} TFB_DrawCommand_Line;
@@ -54,6 +55,7 @@ typedef struct tfb_dc_rect
{
RECT rect;
Color color;
DrawMode drawMode;
SCREEN destBuffer;
} TFB_DrawCommand_Rect;
@@ -63,6 +65,7 @@ typedef struct tfb_dc_img
int x, y;
SCREEN destBuffer;
TFB_ColorMap *colormap;
DrawMode drawMode;
int scale;
int scaleMode;
} TFB_DrawCommand_Image;
@@ -73,6 +76,7 @@ typedef struct tfb_dc_filledimg
int x, y;
Color color;
SCREEN destBuffer;
DrawMode drawMode;
int scale;
int scaleMode;
} TFB_DrawCommand_FilledImage;
@@ -82,6 +86,7 @@ typedef struct tfb_dc_fontchar
TFB_Char *fontchar;
TFB_Image *backing;
int x, y;
DrawMode drawMode;
SCREEN destBuffer;
} TFB_DrawCommand_FontChar;
+3 -1
View File
@@ -243,6 +243,7 @@ _text_blt (RECT *pClipRect, TEXT *TextPtr, POINT ctxOrigin)
const char *pStr;
POINT origin;
TFB_Image *backing;
DrawMode mode = _get_context_draw_mode ();
FontPtr = _CurFontPtr;
if (FontPtr == NULL)
@@ -286,7 +287,8 @@ _text_blt (RECT *pClipRect, TEXT *TextPtr, POINT ctxOrigin)
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;
+25 -13
View File
@@ -92,7 +92,8 @@ ClearBackGround (RECT *pClipRect)
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 @@ DrawBatch (PRIMITIVE *lpBasePrim, PRIM_LINKS PrimLinks,
{
COUNT CurIndex;
PRIMITIVE *lpPrim;
DrawMode mode = _get_context_draw_mode ();
BatchGraphics ();
@@ -135,19 +137,21 @@ DrawBatch (PRIMITIVE *lpBasePrim, PRIM_LINKS PrimLinks,
{
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 @@ DrawBatch (PRIMITIVE *lpBasePrim, PRIM_LINKS PrimLinks,
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 @@ DrawPoint (POINT *lpPoint)
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 @@ DrawRectangle (RECT *lpRect)
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 @@ DrawFilledRectangle (RECT *lpRect)
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 @@ DrawLine (LINE *lpLine)
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 @@ DrawStamp (STAMP *stmp)
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 @@ DrawFilledStamp (STAMP *stmp)
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);
}
}
+209 -58
View File
@@ -57,23 +57,46 @@ TFB_DrawCanvas_GetError (void)
}
void
TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, Color color,
TFB_Canvas target)
checkPrimitiveMode (SDL_Surface *surf, Color *color, DrawMode *mode)
{
Uint32 sdlColor;
PutPixelFn screen_plot;
screen_plot = putpixel_for (target);
sdlColor = SDL_MapRGB (((NativeCanvas) target)->format,
color.r, color.g, color.b);
SDL_LockSurface (target);
line (x1, y1, x2, y2, sdlColor, screen_plot, target);
SDL_UnlockSurface (target);
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_Rect (RECT *rect, Color color, TFB_Canvas target)
TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, Color color,
DrawMode mode, TFB_Canvas target)
{
SDL_Surface *dst = target;
SDL_PixelFormat *fmt = dst->format;
Uint32 sdlColor;
RenderPixelFn plotFn;
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, DrawMode mode, TFB_Canvas target)
{
SDL_Surface *dst = target;
SDL_PixelFormat *fmt = dst->format;
@@ -84,22 +107,95 @@ TFB_DrawCanvas_Rect (RECT *rect, Color color, TFB_Canvas target)
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);
SDL_FillRect (dst, &sr, sdlColor);
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);
}
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_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale,
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 @@ TFB_DrawCanvas_Fill (TFB_Canvas source, int width, int height,
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 @@ TFB_DrawCanvas_Fill (TFB_Canvas source, int width, int height,
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 @@ TFB_DrawCanvas_Fill (TFB_Canvas source, int width, int height,
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 @@ TFB_DrawCanvas_Fill (TFB_Canvas source, int width, int height,
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 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale,
return;
}
checkPrimitiveMode (dst, &color, &mode);
LockMutex (img->mutex);
if (scale != 0 && scale != GSCALE_IDENTITY)
@@ -338,6 +450,7 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale,
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 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale,
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 @@ TFB_DrawCanvas_FontChar (TFB_Char *fontChar, TFB_Image *backing,
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 @@ scale_read_pixel (void* ppix, SDL_PixelFormat *fmt, SDL_Color *pal,
#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;
+331 -16
View File
@@ -18,6 +18,7 @@
#ifdef GFXMODULE_SDL
#include "port.h"
#include "sdl_common.h"
#include "primitives.h"
@@ -104,20 +105,16 @@ GetPixelFn getpixel_for(SDL_Surface *surface)
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 @@ PutPixelFn putpixel_for(SDL_Surface *surface)
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 @@ void line(int x1, int y1, int x2, int y2, Uint32 color, PutPixelFn plot,
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 @@ void line(int x1, int y1, int x2, int y2, Uint32 color, PutPixelFn plot,
} 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 @@ compute_code (float x, float y, float xmin, float ymin, float xmax, float ymax)
}
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 @@ clip_line (int *lx1, int *ly1, int *lx2, int *ly2, SDL_Rect *r)
}
}
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
+35 -6
View File
@@ -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 */
+27 -21
View File
@@ -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 @@ TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, Color color, SCREEN dest)
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 @@ TFB_DrawScreen_Rect (RECT *rect, Color color, SCREEN dest)
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 @@ TFB_DrawScreen_Rect (RECT *rect, Color color, 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 *cmap, DrawMode mode, SCREEN dest)
{
TFB_DrawCommand DC;
@@ -74,6 +77,7 @@ TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale,
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 @@ TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale,
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 @@ TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale,
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 @@ TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale,
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 @@ TFB_DrawScreen_FontChar (TFB_Char *fontChar, TFB_Image *backing,
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 @@ TFB_DrawScreen_Callback (void (*callback) (void *arg), void *arg)
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);
}
+15 -15
View File
@@ -79,15 +79,15 @@ typedef struct tfb_pixelformat
// 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 @@ BOOLEAN TFB_DrawImage_Intersect (TFB_Image *img1, POINT img1org,
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_SetClipRect (TFB_Canvas canvas, const RECT *clipRect);
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);
+25 -23
View File
@@ -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 @@ TFB_Prim_Point (POINT *p, Color color, POINT ctxOrigin)
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 @@ TFB_Prim_Rect (RECT *r, Color color, POINT ctxOrigin)
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 @@ TFB_Prim_FillRect (RECT *r, Color color, POINT ctxOrigin)
}
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 @@ TFB_Prim_Line (LINE *line, Color color, POINT ctxOrigin)
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 @@ TFB_Prim_Stamp (STAMP *stmp, POINT ctxOrigin)
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 @@ TFB_Prim_StampFill (STAMP *stmp, Color color, POINT ctxOrigin)
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 @@ TFB_Prim_FontChar (POINT charOrigin, TFB_Char *fontChar, TFB_Image *backing,
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);
}
}
+7 -7
View File
@@ -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);
+4 -4
View File
@@ -147,8 +147,8 @@ processAudioSyncedFrame (VIDEO_REF vid)
// 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 @@ processMuteFrame (VIDEO_REF vid)
// 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