added also fading in/out global animations to be started/stopped
authorHolger Schemel <info@artsoft.org>
Wed, 25 May 2016 19:13:13 +0000 (21:13 +0200)
committerHolger Schemel <info@artsoft.org>
Wed, 25 May 2016 19:13:13 +0000 (21:13 +0200)
src/anim.c
src/libgame/sdl.c
src/libgame/sdl.h
src/libgame/system.c
src/libgame/system.h
src/tools.c

index 3b69da7cd88ff69e3ee3dcf3d7c2f091b38caa93..e6c6922e802e2a46346797f811012efcce1d8410 100644 (file)
@@ -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 =
index a88201fde27fb1ea3ea29dcbe34a8e633cd8cc42..48a3e374ec39f5a64796bee38fb02b072137ca9a 100644 (file)
@@ -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,
index 2402ca522a159ab2c72ce404cf38a2e8fb9cb4b7..8c4ae0762d02939b0ad89c59c40e6ec8079e0765 100644 (file)
@@ -479,4 +479,6 @@ void HandleJoystickEvent(Event *);
 void SDLInitJoysticks(void);
 boolean SDLReadJoystick(int, int *, int *, boolean *, boolean *);
 
+void PrepareFadeBitmap(int);
+
 #endif /* SDL_H */
index 8b81ede9deef4db5b27ba81e47f74847b31d51d2..02938e3544e07825eabf196ea4b01faafd5a81fb 100644 (file)
@@ -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);
index 151f83555d4dbfcf11e954b0956729ac2b712d8f..7abe732835c21cf761014e35d200554c0118d2f5 100644 (file)
@@ -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;
index 9d7e5c7482906558affecfadbd1dce7d5e838f39..ac83cfd51c1e54d470f2745512ed5209ede7b620 100644 (file)
@@ -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()