From 8ae535c1c76e1c33572afbcd4b2d3d9c3d7ba63e Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 17 Feb 2016 08:35:07 +0100 Subject: [PATCH] added drawing global animations below and above masked screen border --- src/cartoons.c | 22 ++++++++++-- src/cartoons.h | 2 +- src/init.c | 4 +++ src/libgame/sdl.c | 34 +++++++++++++++--- src/libgame/system.c | 7 +++- src/libgame/system.h | 10 ++++-- src/main.h | 4 +++ src/tools.c | 84 +++++++++++++++++++++++++++++++++----------- src/tools.h | 1 + 9 files changed, 138 insertions(+), 30 deletions(-) diff --git a/src/cartoons.c b/src/cartoons.c index 55edfe52..b2f2eb2b 100644 --- a/src/cartoons.c +++ b/src/cartoons.c @@ -49,6 +49,8 @@ struct GlobalAnimPartControlInfo int anim_delay_counter; int post_delay_counter; + int drawing_stage; + int state; int last_game_status; }; @@ -335,7 +337,7 @@ void InitGlobalAnimControls() InitToonControls(); } -void DrawGlobalAnim() +void DrawGlobalAnimExt(int drawing_stage) { int mode_nr; @@ -345,7 +347,8 @@ void DrawGlobalAnim() if (!do_animations || !setup.toons) return; - DoAnimationExt(); + if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1) + DoAnimationExt(); for (mode_nr = 0; mode_nr < NUM_SPECIAL_GFX_ARGS; mode_nr++) { @@ -394,6 +397,9 @@ void DrawGlobalAnim() if (!(part->state & ANIM_STATE_RUNNING)) continue; + if (part->drawing_stage != drawing_stage) + continue; + if (part->x < 0) { dst_x = 0; @@ -433,6 +439,14 @@ void DrawGlobalAnim() } } +void DrawGlobalAnim(int drawing_stage) +{ + if (!do_animations || !setup.toons) + return; + + DrawGlobalAnimExt(drawing_stage); +} + boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part) { int viewport_x; @@ -446,6 +460,8 @@ boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part) part->last_game_status = game_status; + part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1; + if (part->control_info.class == get_hash_from_key("window") || part->control_info.class == get_hash_from_key("border")) { @@ -453,6 +469,8 @@ boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part) viewport_y = 0; viewport_width = WIN_XSIZE; viewport_height = WIN_YSIZE; + + part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_2; } else if (part->control_info.class == get_hash_from_key("door_1")) { diff --git a/src/cartoons.h b/src/cartoons.h index 257fad27..a2dd0602 100644 --- a/src/cartoons.h +++ b/src/cartoons.h @@ -22,7 +22,7 @@ void InitToons(void); -void DrawGlobalAnim(void); +void DrawGlobalAnim(int); void InitAnimation(void); void StopAnimation(void); diff --git a/src/init.c b/src/init.c index 0aa2f102..fbfad610 100644 --- a/src/init.c +++ b/src/init.c @@ -232,6 +232,9 @@ void InitImageTextures() FreeAllImageTextures(); + for (i = IMG_GLOBAL_BORDER_FIRST; i <= IMG_GLOBAL_BORDER_LAST; i++) + CreateImageTextures(i); + for (i = 0; i < MAX_NUM_TOONS; i++) CreateImageTextures(IMG_TOON_1 + i); @@ -5318,6 +5321,7 @@ void InitGfx() InitGfxDrawBusyAnimFunction(DrawInitAnim); InitGfxDrawGlobalAnimFunction(DrawGlobalAnim); + InitGfxDrawGlobalBorderFunction(DrawMaskedBorderToScreen); /* use copy of busy animation to prevent change while reloading artwork */ init_last = init; diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index d431aacf..9b4e0cf4 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -89,9 +89,17 @@ static void UpdateScreen(SDL_Rect *rect) BlitBitmap(backbuffer, gfx.final_screen_bitmap, 0, 0, gfx.win_xsize, gfx.win_ysize, 0, 0); - // copy global animations to render target buffer, if defined + // copy global animations to render target buffer, if defined (below border) if (gfx.draw_global_anim_function != NULL) - gfx.draw_global_anim_function(); + gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_1); + + // copy global masked border to render target buffer, if defined + if (gfx.draw_global_border_function != NULL) + gfx.draw_global_border_function(REDRAW_ALL); + + // copy global animations to render target buffer, if defined (above border) + if (gfx.draw_global_anim_function != NULL) + gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_2); screen = gfx.final_screen_bitmap->surface; @@ -126,9 +134,17 @@ static void UpdateScreen(SDL_Rect *rect) SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); #if !USE_FINAL_SCREEN_BITMAP - // copy global animations to render target buffer, if defined + // copy global animations to render target buffer, if defined (below border) if (gfx.draw_global_anim_function != NULL) - gfx.draw_global_anim_function(); + gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_1); + + // copy global masked border to render target buffer, if defined + if (gfx.draw_global_border_function != NULL) + gfx.draw_global_border_function(REDRAW_ALL); + + // copy global animations to render target buffer, if defined (above border) + if (gfx.draw_global_anim_function != NULL) + gfx.draw_global_anim_function(DRAW_GLOBAL_ANIM_STAGE_2); #endif // show render target buffer on screen @@ -1098,6 +1114,13 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, int dst_x = x, dst_y = y; unsigned int time_last, time_current; + // store function for drawing global masked border + void (*draw_global_border_function)(int) = gfx.draw_global_border_function; + + // deactivate drawing of global border while fading, if needed + if (draw_border_function == NULL) + gfx.draw_global_border_function = NULL; + /* check if screen size has changed */ if (surface_source != NULL && (video.width != surface_source->w || video.height != surface_source->h)) @@ -1430,6 +1453,9 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, time_current = SDL_GetTicks(); } } + + // restore function for drawing global masked border + gfx.draw_global_border_function = draw_global_border_function; } void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y, diff --git a/src/libgame/system.c b/src/libgame/system.c index a52b4ec2..38ec0b5b 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -234,11 +234,16 @@ void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)) gfx.draw_busy_anim_function = draw_busy_anim_function; } -void InitGfxDrawGlobalAnimFunction(void (*draw_global_anim_function)(void)) +void InitGfxDrawGlobalAnimFunction(void (*draw_global_anim_function)(int)) { gfx.draw_global_anim_function = draw_global_anim_function; } +void InitGfxDrawGlobalBorderFunction(void (*draw_global_border_function)(int)) +{ + gfx.draw_global_border_function = draw_global_border_function; +} + void InitGfxCustomArtworkInfo() { gfx.override_level_graphics = FALSE; diff --git a/src/libgame/system.h b/src/libgame/system.h index 107d5ae0..1fe8d9f4 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -165,6 +165,10 @@ /* values for special "focus player" bitmasks */ #define BIT_SET_FOCUS 6 +/* values for drawing stages for global animations */ +#define DRAW_GLOBAL_ANIM_STAGE_1 1 +#define DRAW_GLOBAL_ANIM_STAGE_2 2 + /* values for move directions and special "button" key bitmasks */ #define MV_NONE 0 #define MV_LEFT (1 << MV_BIT_LEFT) @@ -826,7 +830,8 @@ struct GfxInfo int anim_random_frame; void (*draw_busy_anim_function)(void); - void (*draw_global_anim_function)(void); + void (*draw_global_anim_function)(int); + void (*draw_global_border_function)(int); int cursor_mode; }; @@ -1323,7 +1328,8 @@ void InitGfxWindowInfo(int, int); void InitGfxScrollbufferInfo(int, int); void InitGfxClipRegion(boolean, int, int, int, int); void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)); -void InitGfxDrawGlobalAnimFunction(void (*draw_global_anim_function)(void)); +void InitGfxDrawGlobalAnimFunction(void (*draw_global_anim_function)(int)); +void InitGfxDrawGlobalBorderFunction(void (*draw_global_border_function)(int)); void InitGfxCustomArtworkInfo(); void InitGfxOtherSettings(); void SetDrawDeactivationMask(int); diff --git a/src/main.h b/src/main.h index 1e97b9c9..638b1023 100644 --- a/src/main.h +++ b/src/main.h @@ -1977,6 +1977,10 @@ #define GLOBAL_ANIM_ID_PART_LAST 7 #define GLOBAL_ANIM_ID_PART_BASE 8 +/* values for global border graphics */ +#define IMG_GLOBAL_BORDER_FIRST IMG_GLOBAL_BORDER +#define IMG_GLOBAL_BORDER_LAST IMG_GLOBAL_BORDER_PLAYING + /* values for game_status (must match special image configuration suffixes) */ #define GAME_MODE_DEFAULT 0 #define GAME_MODE_LOADING 1 diff --git a/src/tools.c b/src/tools.c index dbeba50c..6a1306e4 100644 --- a/src/tools.c +++ b/src/tools.c @@ -287,50 +287,63 @@ void RedrawPlayfield() gfx.sx, gfx.sy); } -void DrawMaskedBorder_Rect(int x, int y, int width, int height) +static void DrawMaskedBorderExt_Rect(int x, int y, int width, int height, + boolean blit_to_screen) { Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus(); - BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y); + if (blit_to_screen) + BlitToScreenMasked(bitmap, x, y, width, height, x, y); + else + BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y); } -void DrawMaskedBorder_FIELD() +static void DrawMaskedBorderExt_FIELD(boolean blit_to_screen) { if (global.border_status >= GAME_MODE_TITLE && global.border_status <= GAME_MODE_PLAYING && border.draw_masked[global.border_status]) - DrawMaskedBorder_Rect(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); + DrawMaskedBorderExt_Rect(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, + blit_to_screen); } -void DrawMaskedBorder_DOOR_1() +static void DrawMaskedBorderExt_DOOR_1(boolean blit_to_screen) { + // only draw border over closed doors when drawing to backbuffer + if (!blit_to_screen && (GetDoorState() & DOOR_OPEN_1)) + return; + if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] && (global.border_status != GAME_MODE_EDITOR || border.draw_masked[GFX_SPECIAL_ARG_EDITOR])) - DrawMaskedBorder_Rect(DX, DY, DXSIZE, DYSIZE); + DrawMaskedBorderExt_Rect(DX, DY, DXSIZE, DYSIZE, blit_to_screen); } -void DrawMaskedBorder_DOOR_2() +static void DrawMaskedBorderExt_DOOR_2(boolean blit_to_screen) { + // only draw border over closed doors when drawing to backbuffer + if (!blit_to_screen && (GetDoorState() & DOOR_OPEN_2)) + return; + if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] && global.border_status != GAME_MODE_EDITOR) - DrawMaskedBorder_Rect(VX, VY, VXSIZE, VYSIZE); + DrawMaskedBorderExt_Rect(VX, VY, VXSIZE, VYSIZE, blit_to_screen); } -void DrawMaskedBorder_DOOR_3() +static void DrawMaskedBorderExt_DOOR_3(boolean blit_to_screen) { /* currently not available */ } -void DrawMaskedBorder_ALL() +static void DrawMaskedBorderExt_ALL(boolean blit_to_screen) { - DrawMaskedBorder_FIELD(); - DrawMaskedBorder_DOOR_1(); - DrawMaskedBorder_DOOR_2(); - DrawMaskedBorder_DOOR_3(); + DrawMaskedBorderExt_FIELD(blit_to_screen); + DrawMaskedBorderExt_DOOR_1(blit_to_screen); + DrawMaskedBorderExt_DOOR_2(blit_to_screen); + DrawMaskedBorderExt_DOOR_3(blit_to_screen); } -void DrawMaskedBorder(int redraw_mask) +static void DrawMaskedBorderExt(int redraw_mask, boolean blit_to_screen) { /* never draw masked screen borders on borderless screens */ if (game_status == GAME_MODE_LOADING || @@ -338,20 +351,35 @@ void DrawMaskedBorder(int redraw_mask) return; if (redraw_mask & REDRAW_ALL) - DrawMaskedBorder_ALL(); + DrawMaskedBorderExt_ALL(blit_to_screen); else { if (redraw_mask & REDRAW_FIELD) - DrawMaskedBorder_FIELD(); + DrawMaskedBorderExt_FIELD(blit_to_screen); if (redraw_mask & REDRAW_DOOR_1) - DrawMaskedBorder_DOOR_1(); + DrawMaskedBorderExt_DOOR_1(blit_to_screen); if (redraw_mask & REDRAW_DOOR_2) - DrawMaskedBorder_DOOR_2(); + DrawMaskedBorderExt_DOOR_2(blit_to_screen); if (redraw_mask & REDRAW_DOOR_3) - DrawMaskedBorder_DOOR_3(); + DrawMaskedBorderExt_DOOR_3(blit_to_screen); } } +void DrawMaskedBorder_FIELD() +{ + DrawMaskedBorderExt_FIELD(FALSE); +} + +void DrawMaskedBorder(int redraw_mask) +{ + DrawMaskedBorderExt(redraw_mask, FALSE); +} + +void DrawMaskedBorderToScreen(int redraw_mask) +{ + DrawMaskedBorderExt(redraw_mask, TRUE); +} + void BlitScreenToBitmap_RND(Bitmap *target_bitmap) { int fx = FX, fy = FY; @@ -439,8 +467,12 @@ void BackToFront() if (redraw_mask == REDRAW_NONE) return; +#if 1 + // masked border now drawn immediately when blitting backbuffer to window +#else // draw masked border to all viewports, if defined DrawMaskedBorder(redraw_mask); +#endif // draw frames per second (only if debug mode is enabled) if (redraw_mask & REDRAW_FPS) @@ -598,6 +630,10 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) void FadeIn(int fade_mask) { +#if 1 + DrawMaskedBorder(REDRAW_ALL); +#endif + if (fading.fade_mode & FADE_TYPE_TRANSFORM) FadeExt(fade_mask, fading.fade_mode, FADE_TYPE_FADE_IN); else @@ -611,6 +647,10 @@ void FadeIn(int fade_mask) void FadeOut(int fade_mask) { +#if 0 + DrawMaskedBorder(REDRAW_ALL); +#endif + if (fading.fade_mode & FADE_TYPE_TRANSFORM) FadeExt(fade_mask, fading.fade_mode, FADE_TYPE_FADE_OUT); else @@ -4438,6 +4478,10 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION_2) door2 = door_state & DOOR_ACTION_2; + // draw masked border over door area + DrawMaskedBorder(REDRAW_DOOR_1); + DrawMaskedBorder(REDRAW_DOOR_2); + return (door1 | door2); } diff --git a/src/tools.h b/src/tools.h index 1fc4b5db..439517c2 100644 --- a/src/tools.h +++ b/src/tools.h @@ -76,6 +76,7 @@ void DrawMaskedBorder_DOOR_2(); void DrawMaskedBorder_DOOR_3(); void DrawMaskedBorder_ALL(); void DrawMaskedBorder(int); +void DrawMaskedBorderToScreen(int); void SetDrawtoField(int); void RedrawPlayfield(); -- 2.34.1