diff --git a/sc2/src/sc2code/libs/graphics/drawcmd.h b/sc2/src/sc2code/libs/graphics/drawcmd.h index 8701a5f85..4a3172e92 100644 --- a/sc2/src/sc2code/libs/graphics/drawcmd.h +++ b/sc2/src/sc2code/libs/graphics/drawcmd.h @@ -41,6 +41,7 @@ enum TFB_DRAWCOMMANDTYPE_DELETEDATA, TFB_DRAWCOMMANDTYPE_SENDSIGNAL, TFB_DRAWCOMMANDTYPE_REINITVIDEO, + TFB_DRAWCOMMANDTYPE_CALLBACK, }; typedef struct tfb_dc_line @@ -135,6 +136,12 @@ typedef struct tfb_dc_reinit_video int driver, flags, width, height; } TFB_DrawCommand_ReinitVideo; +typedef struct tfb_dc_callback +{ + void (*callback)(void *arg); + void *arg; +} TFB_DrawCommand_Callback; + typedef struct tfb_drawcommand { int Type; @@ -153,6 +160,7 @@ typedef struct tfb_drawcommand TFB_DrawCommand_DeleteData deletedata; TFB_DrawCommand_SendSignal sendsignal; TFB_DrawCommand_ReinitVideo reinitvideo; + TFB_DrawCommand_Callback callback; } data; } TFB_DrawCommand; diff --git a/sc2/src/sc2code/libs/graphics/sdl/canvas.c b/sc2/src/sc2code/libs/graphics/sdl/canvas.c index 6059b2265..4a9f29d12 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/canvas.c +++ b/sc2/src/sc2code/libs/graphics/sdl/canvas.c @@ -1541,6 +1541,14 @@ TFB_DrawCanvas_Unlock (TFB_Canvas canvas) SDL_UnlockSurface (surf); } +// This function should only be called from the graphics thread, +// like from a TFB_DrawCommand_Callback command. +TFB_Canvas +TFB_DrawCanvas_GetScreenCanvas (SCREEN screen) +{ + return (TFB_Canvas) SDL_Screens[screen]; +} + void TFB_DrawCanvas_GetScreenFormat (TFB_PixelFormat *fmt) { diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index 1017832ac..25f38ada6 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -607,7 +607,7 @@ TFB_ComputeFPS (void) } void -TFB_FlushGraphics () // Only call from main thread!! +TFB_FlushGraphics (void) // Only call from main thread!! { int commands_handled; BOOLEAN livelock_deterrence; @@ -908,6 +908,11 @@ TFB_FlushGraphics () // Only call from main thread!! } break; } + case TFB_DRAWCOMMANDTYPE_CALLBACK: + { + DC.data.callback.callback (DC.data.callback.arg); + break; + } } } diff --git a/sc2/src/sc2code/libs/graphics/tfb_draw.c b/sc2/src/sc2code/libs/graphics/tfb_draw.c index 09e8842eb..a76bd79e2 100644 --- a/sc2/src/sc2code/libs/graphics/tfb_draw.c +++ b/sc2/src/sc2code/libs/graphics/tfb_draw.c @@ -211,7 +211,7 @@ TFB_DrawScreen_WaitForSignal (void) DrawCommand.data.sendsignal.sem = s; Lock_DCQ (1); TFB_BatchReset (); - TFB_EnqueueDrawCommand(&DrawCommand); + TFB_EnqueueDrawCommand (&DrawCommand); Unlock_DCQ(); SetSemaphore (s); } @@ -225,6 +225,16 @@ TFB_DrawScreen_ReinitVideo (int driver, int flags, int width, int height) DrawCommand.data.reinitvideo.flags = flags; DrawCommand.data.reinitvideo.width = width; DrawCommand.data.reinitvideo.height = height; + TFB_EnqueueDrawCommand (&DrawCommand); +} + +void +TFB_DrawScreen_Callback (void (*callback) (void *arg), void *arg) +{ + TFB_DrawCommand DrawCommand; + DrawCommand.Type = TFB_DRAWCOMMANDTYPE_CALLBACK; + DrawCommand.data.callback.callback = callback; + DrawCommand.data.callback.arg = arg; TFB_EnqueueDrawCommand(&DrawCommand); } @@ -417,3 +427,4 @@ TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type) image->last_scale = target; } } + diff --git a/sc2/src/sc2code/libs/graphics/tfb_draw.h b/sc2/src/sc2code/libs/graphics/tfb_draw.h index d3b113c55..be97f3c53 100644 --- a/sc2/src/sc2code/libs/graphics/tfb_draw.h +++ b/sc2/src/sc2code/libs/graphics/tfb_draw.h @@ -100,6 +100,7 @@ void TFB_DrawScreen_DeleteData (void *); void TFB_DrawScreen_WaitForSignal (void); void TFB_DrawScreen_ReinitVideo (int driver, int flags, int width, int height); void TFB_DrawScreen_SetPalette (int paletteIndex, int r, int g, int b); +void TFB_DrawScreen_Callback (void (*callback) (void *arg), void *arg); TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas); TFB_Image *TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha); @@ -152,9 +153,10 @@ void TFB_DrawCanvas_CopyTransparencyInfo (TFB_Canvas src, TFB_Canvas dst); void TFB_DrawCanvas_Initialize (void); void TFB_DrawCanvas_Lock (TFB_Canvas canvas); void TFB_DrawCanvas_Unlock (TFB_Canvas canvas); +TFB_Canvas TFB_DrawCanvas_GetScreenCanvas (SCREEN screen); void TFB_DrawCanvas_GetScreenFormat (TFB_PixelFormat *fmt); int TFB_DrawCanvas_GetStride (TFB_Canvas canvas); -void* TFB_DrawCanvas_GetLine (TFB_Canvas canvas, int line); +void *TFB_DrawCanvas_GetLine (TFB_Canvas canvas, int line); void TFB_DrawCanvas_GetPixel (TFB_Canvas canvas, int x, int y, int *r, int *g, int *b); #endif