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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) \
|
||||
{ \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
SDL_FillRect (dst, &sr, sdlColor);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user