From 522cba3565ad60664933d454f83518961deb41c5 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 25 May 2016 21:13:13 +0200 Subject: [PATCH] added also fading in/out global animations to be started/stopped --- src/anim.c | 72 ++++++++++++++++++++++++++++++++++++++------ src/libgame/sdl.c | 40 ++++++++++++++++-------- src/libgame/sdl.h | 2 ++ src/libgame/system.c | 1 + src/libgame/system.h | 1 + src/tools.c | 12 ++++++++ 6 files changed, 107 insertions(+), 21 deletions(-) diff --git a/src/anim.c b/src/anim.c index 3b69da7c..e6c6922e 100644 --- a/src/anim.c +++ b/src/anim.c @@ -184,6 +184,8 @@ static int anim_class_game_modes[NUM_ANIM_CLASSES]; static int anim_status_last = GAME_MODE_DEFAULT; static int anim_classes_last = ANIM_CLASS_NONE; +static boolean drawing_to_fading_buffer = FALSE; + /* ========================================================================= */ /* generic animation frame calculation */ @@ -519,13 +521,17 @@ void InitGlobalAnimations() void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) { + Bitmap *fade_bitmap = + (drawing_target == DRAW_TO_FADE_SOURCE ? gfx.fade_bitmap_source : + drawing_target == DRAW_TO_FADE_TARGET ? gfx.fade_bitmap_target : NULL); int game_mode_anim_action[NUM_GAME_MODES]; int mode_nr; if (!setup.toons) return; - if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1) + if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1 && + drawing_target == DRAW_TO_SCREEN) DoAnimationExt(); // always start with reliable default values (no animation actions) @@ -539,6 +545,9 @@ void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) int anim_classes_next = game_mode_anim_classes[global.anim_status_next]; int i; + if (drawing_target == DRAW_TO_FADE_TARGET) + after_fading = TRUE; + // ---------- part 1 ------------------------------------------------------ // start or stop global animations by change of game mode // (special handling of animations for "current screen" and "all screens") @@ -573,15 +582,27 @@ void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) game_mode_anim_action[anim_class_game_mode] = ANIM_START; } - if (after_fading) - anim_classes_last = anim_classes_next; + if (drawing_target == DRAW_TO_SCREEN) + { + if (after_fading) + anim_classes_last = anim_classes_next; - anim_status_last = global.anim_status; + anim_status_last = global.anim_status; - // start or stop animations determined to be started or stopped above - for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) - if (game_mode_anim_action[mode_nr] != ANIM_NO_ACTION) - HandleGlobalAnim(game_mode_anim_action[mode_nr], mode_nr); + // start or stop animations determined to be started or stopped above + for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) + if (game_mode_anim_action[mode_nr] != ANIM_NO_ACTION) + HandleGlobalAnim(game_mode_anim_action[mode_nr], mode_nr); + } + else if (drawing_target == DRAW_TO_FADE_TARGET) + { + drawing_to_fading_buffer = TRUE; + + // start animations determined to be (temporary) started above + for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) + if (game_mode_anim_action[mode_nr] == ANIM_START) + HandleGlobalAnim(ANIM_START, mode_nr); + } } if (global.anim_status == GAME_MODE_LOADING) @@ -592,6 +613,16 @@ void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr]; int anim_nr; + // when preparing source fading buffer, only draw animations to be stopped + if (drawing_target == DRAW_TO_FADE_SOURCE && + game_mode_anim_action[mode_nr] != ANIM_STOP) + continue; + + // when preparing target fading buffer, only draw animations to be started + if (drawing_target == DRAW_TO_FADE_TARGET && + game_mode_anim_action[mode_nr] != ANIM_START) + continue; + #if 0 if (mode_nr != GFX_SPECIAL_ARG_DEFAULT && mode_nr != game_status) @@ -674,11 +705,25 @@ void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) src_x += cut_x; src_y += cut_y; - BlitToScreenMasked(src_bitmap, src_x, src_y, width, height, + if (drawing_target == DRAW_TO_SCREEN) + BlitToScreenMasked(src_bitmap, src_x, src_y, width, height, + dst_x, dst_y); + else + BlitBitmapMasked(src_bitmap, fade_bitmap, src_x, src_y, width, height, dst_x, dst_y); } } } + + if (drawing_target == DRAW_TO_FADE_TARGET) + { + // stop animations determined to be (temporary) started above + for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) + if (game_mode_anim_action[mode_nr] == ANIM_START) + HandleGlobalAnim(ANIM_STOP, mode_nr); + + drawing_to_fading_buffer = FALSE; + } } void DrawGlobalAnimations(int drawing_target, int drawing_stage) @@ -822,6 +867,10 @@ static void StopGlobalAnimMusic(struct GlobalAnimPartControlInfo *part) static void PlayGlobalAnimSoundAndMusic(struct GlobalAnimPartControlInfo *part) { + // when drawing animations to fading buffer, do not play sounds or music + if (drawing_to_fading_buffer) + return; + PlayGlobalAnimSound(part); PlayGlobalAnimMusic(part); } @@ -843,6 +892,11 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state) if (state & ANIM_STATE_RESTART) { + // when drawing animations to fading buffer, only start fixed animations + if (drawing_to_fading_buffer && (c->x == ARG_UNDEFINED_VALUE || + c->y == ARG_UNDEFINED_VALUE)) + return ANIM_STATE_INACTIVE; + ResetDelayCounterExt(&part->step_delay, anim_sync_frame); part->init_delay_counter = diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index a88201fd..48a3e374 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -908,15 +908,31 @@ void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, int width, int height, UpdateScreen_WithFrameDelay(&rect); } +void PrepareFadeBitmap(int draw_target) +{ + Bitmap *fade_bitmap = + (draw_target == DRAW_TO_FADE_SOURCE ? gfx.fade_bitmap_source : + draw_target == DRAW_TO_FADE_TARGET ? gfx.fade_bitmap_target : NULL); + + if (fade_bitmap == NULL) + return; + + // copy backbuffer to fading buffer + BlitBitmap(backbuffer, fade_bitmap, 0, 0, gfx.win_xsize, gfx.win_ysize, 0, 0); + + // add border and animations to fading buffer + FinalizeScreen(draw_target); +} + void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, int fade_mode, int fade_delay, int post_delay, void (*draw_border_function)(void)) { + SDL_Surface *surface_backup = gfx.fade_bitmap_backup->surface; SDL_Surface *surface_source = gfx.fade_bitmap_source->surface; SDL_Surface *surface_target = gfx.fade_bitmap_target->surface; SDL_Surface *surface_black = gfx.fade_bitmap_black->surface; SDL_Surface *surface_screen = backbuffer->surface; - SDL_Surface *surface_cross = (bitmap_cross ? bitmap_cross->surface : NULL); SDL_Rect src_rect, dst_rect; SDL_Rect dst_rect2; int src_x = x, src_y = y; @@ -942,28 +958,24 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, dst_rect2 = dst_rect; + // before fading in, store backbuffer (without animation graphics) + if (fade_mode & (FADE_TYPE_FADE_IN | FADE_TYPE_TRANSFORM)) + SDL_BlitSurface(surface_screen, &dst_rect, surface_backup, &src_rect); + /* copy source and target surfaces to temporary surfaces for fading */ if (fade_mode & FADE_TYPE_TRANSFORM) { - SDL_BlitSurface(surface_cross, &src_rect, surface_source, &src_rect); - SDL_BlitSurface(surface_screen, &dst_rect, surface_target, &src_rect); - - draw_global_border_function(DRAW_TO_FADE_SOURCE); - draw_global_border_function(DRAW_TO_FADE_TARGET); + // (source and target fading buffer already prepared) } else if (fade_mode & FADE_TYPE_FADE_IN) { + // (target fading buffer already prepared) SDL_BlitSurface(surface_black, &src_rect, surface_source, &src_rect); - SDL_BlitSurface(surface_screen, &dst_rect, surface_target, &src_rect); - - draw_global_border_function(DRAW_TO_FADE_TARGET); } else /* FADE_TYPE_FADE_OUT */ { - SDL_BlitSurface(surface_screen, &dst_rect, surface_source, &src_rect); + // (source fading buffer already prepared) SDL_BlitSurface(surface_black, &src_rect, surface_target, &src_rect); - - draw_global_border_function(DRAW_TO_FADE_SOURCE); } time_current = SDL_GetTicks(); @@ -1198,6 +1210,10 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, // restore function for drawing global masked border gfx.draw_global_border_function = draw_global_border_function; + + // after fading in, restore backbuffer (without animation graphics) + if (fade_mode & (FADE_TYPE_FADE_IN | FADE_TYPE_TRANSFORM)) + SDL_BlitSurface(surface_backup, &dst_rect, surface_screen, &src_rect); } void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y, diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index 2402ca52..8c4ae076 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -479,4 +479,6 @@ void HandleJoystickEvent(Event *); void SDLInitJoysticks(void); boolean SDLReadJoystick(int, int *, int *, boolean *, boolean *); +void PrepareFadeBitmap(int); + #endif /* SDL_H */ diff --git a/src/libgame/system.c b/src/libgame/system.c index 8b81ede9..02938e35 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -212,6 +212,7 @@ void InitGfxWindowInfo(int win_xsize, int win_ysize) ReCreateBitmap(&gfx.final_screen_bitmap, win_xsize, win_ysize, DEFAULT_DEPTH); #endif + ReCreateBitmap(&gfx.fade_bitmap_backup, win_xsize, win_ysize, DEFAULT_DEPTH); ReCreateBitmap(&gfx.fade_bitmap_source, win_xsize, win_ysize, DEFAULT_DEPTH); ReCreateBitmap(&gfx.fade_bitmap_target, win_xsize, win_ysize, DEFAULT_DEPTH); ReCreateBitmap(&gfx.fade_bitmap_black, win_xsize, win_ysize, DEFAULT_DEPTH); diff --git a/src/libgame/system.h b/src/libgame/system.h index 151f8355..7abe7328 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -837,6 +837,7 @@ struct GfxInfo Bitmap *background_bitmap; int background_bitmap_mask; + Bitmap *fade_bitmap_backup; Bitmap *fade_bitmap_source; Bitmap *fade_bitmap_target; Bitmap *fade_bitmap_black; diff --git a/src/tools.c b/src/tools.c index 9d7e5c74..ac83cfd5 100644 --- a/src/tools.c +++ b/src/tools.c @@ -717,6 +717,14 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) static void SetScreenStates_BeforeFadingIn() { + // temporarily set screen mode for animations to screen after fading in + global.anim_status = global.anim_status_next; + + // store backbuffer with all animations that will be started after fading in + PrepareFadeBitmap(DRAW_TO_FADE_TARGET); + + // set screen mode for animations back to fading + global.anim_status = GAME_MODE_PSEUDO_FADING; } static void SetScreenStates_AfterFadingIn() @@ -736,7 +744,11 @@ static void SetScreenStates_BeforeFadingOut() // store new target screen (to use correct masked border for fading) gfx.fade_border_target_status = game_status; + // set screen mode for animations to fading global.anim_status = GAME_MODE_PSEUDO_FADING; + + // store backbuffer with all animations that will be stopped for fading out + PrepareFadeBitmap(DRAW_TO_FADE_SOURCE); } static void SetScreenStates_AfterFadingOut() -- 2.34.1