added single step support for BD engine
authorHolger Schemel <holger.schemel@virtion.de>
Tue, 11 Jun 2024 21:09:43 +0000 (23:09 +0200)
committerHolger Schemel <holger.schemel@virtion.de>
Tue, 11 Jun 2024 21:09:43 +0000 (23:09 +0200)
src/game_bd/bd_caveengine.c
src/game_bd/bd_gameplay.c
src/game_bd/bd_gameplay.h
src/game_bd/export_bd.h
src/game_bd/import_bd.h
src/game_bd/main_bd.c
src/tools.c

index 6d0e3fcd2c13614bfa7ad887f9d2c05f1fad1cda..5b2bfcdfcd1292268083f70c45a5fa64fd235469 100644 (file)
@@ -1570,6 +1570,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire,
 
   gd_cave_clear_sounds(cave);
 
+  game_bd.player_moving = FALSE;
+  game_bd.player_snapping = FALSE;
+
   // if diagonal movements not allowed,
   // horizontal movements have precedence. [BROADRIBB]
   if (!cave->diagonal_movements)
@@ -1835,15 +1838,25 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire,
              // if snapping anything and we have snapping explosions set.
              // but these is not true for pushing.
              if (remains == O_SPACE && player_fire && !push)
+              {
                remains = cave->snap_element;
 
+               game_bd.player_snapping = TRUE;
+              }
+
              if (remains != O_SPACE || player_fire)
+              {
                // if any other element than space, player cannot move.
                // also if pressing fire, will not move.
                store_dir(cave, x, y, player_move, remains);
+              }
              else
+              {
                // if space remains there, the player moves.
                move(cave, x, y, player_move, O_PLAYER);
+
+               game_bd.player_moving = TRUE;
+              }
            }
          }
          break;
index 12eb53bcca2ba1c7e8699e3af954f96907e75c33..3ca3e43c874f020f015d9619ef23ed730f0fd13a 100644 (file)
@@ -188,6 +188,13 @@ GdGame *gd_game_new(const int cave, const int level)
   return game;
 }
 
+boolean check_iteration_reached(GdGame *game)
+{
+  int millisecs_elapsed = 20;
+
+  return (game->milliseconds_game + millisecs_elapsed >= game->cave->speed);
+}
+
 static void iterate_cave(GdGame *game, GdDirection player_move, boolean fire)
 {
   boolean suicide = FALSE;
index aa9a48de387be6ec127c0e09cc5853798353800f..98659a48364e33e373dd6469d64c36dc4dcfc8e6 100644 (file)
@@ -112,6 +112,8 @@ GdGame *gd_game_new(const int cave, const int level);
 GdGame *gd_game_new_snapshot(GdCave *snapshot);
 GdGame *gd_game_new_test(GdCave *cave, int level);
 
+boolean check_iteration_reached(GdGame *game);
+
 void play_game_func(GdGame *game, int action);
 
 #endif // BD_GAMEPLAY_H
index 35f2e687fc2fa57daa740b7a5bf56c33437dca1e..883d4ace79be743d1cfa4613bbc64a30fe0b199c 100644 (file)
@@ -43,6 +43,9 @@ struct GameInfo_BD
   boolean game_over;
   boolean cover_screen;
 
+  boolean player_moving;
+  boolean player_snapping;
+
   // needed for updating panel
   int time_left;
   int gems_still_needed;
index 53af163998b55322770c390380ba043b8cddf96f..75e801c00d6115a2db6eef52eef2b01406da33fc 100644 (file)
@@ -27,6 +27,7 @@
 // ----------------------------------------------------------------------------
 
 void InitGraphicInfo_BD(void);
+boolean CheckSingleStepMode_BD(boolean, boolean, boolean);
 
 void PlayLevelSound_BD(int, int, int, int);
 void StopSound_BD(int, int);
index dae512b67ffc72ebbe5d58ea7b31435f50014744..7730ba9b3cdc581ed3359dfe28a0eab6cd3cb76d 100644 (file)
@@ -340,6 +340,9 @@ void InitGameEngine_BD(void)
   game_bd.game->itermax = 8;   // default; dynamically changed at runtime
   game_bd.game->itermax_last = game_bd.game->itermax;
 
+  game_bd.player_moving = FALSE;
+  game_bd.player_snapping = FALSE;
+
   // default: start with completely covered playfield
   int next_state = GAME_INT_START_UNCOVER + 1;
 
@@ -437,6 +440,15 @@ void GameActions_BD(byte action[MAX_PLAYERS])
     play_game_func(game_bd.game, action[0]);
   }
 
+  boolean single_step_mode_paused =
+    CheckSingleStepMode_BD(check_iteration_reached(game_bd.game),
+                           game_bd.player_moving,
+                           game_bd.player_snapping);
+
+  // draw final movement animation frame before going to single step pause mode
+  if (single_step_mode_paused)
+    game_bd.game->itercycle = game_bd.game->itermax - 1;
+
   RedrawPlayfield_BD(FALSE);
 
   UpdateGameDoorValues_BD();
index 1881220a079c35dc07baa93eb65611af9040a447..d56532d189d8143d7c4ea734a624d615aad68114 100644 (file)
@@ -11215,6 +11215,26 @@ void InitGraphicInfo_EM(void)
   }
 }
 
+static void CheckSaveEngineSnapshot_BD(boolean frame_max,
+                                      boolean player_moving,
+                                      boolean player_snapping)
+{
+  if (frame_max)
+  {
+    if (!local_player->was_waiting)
+    {
+      if (!CheckSaveEngineSnapshotToList())
+       return;
+
+      local_player->was_waiting = TRUE;
+    }
+  }
+  else if (player_moving || player_snapping)
+  {
+    local_player->was_waiting = FALSE;
+  }
+}
+
 static void CheckSaveEngineSnapshot_EM(int frame,
                                       boolean any_player_moving,
                                       boolean any_player_snapping,
@@ -11272,6 +11292,19 @@ static void CheckSaveEngineSnapshot_MM(boolean element_clicked,
   }
 }
 
+boolean CheckSingleStepMode_BD(boolean frame_max,
+                               boolean player_moving,
+                               boolean player_snapping)
+{
+  if (tape.single_step && tape.recording && !tape.pausing)
+    if (frame_max && FrameCounter > 6)
+      TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+
+  CheckSaveEngineSnapshot_BD(frame_max, player_moving, player_snapping);
+
+  return tape.pausing;
+}
+
 boolean CheckSingleStepMode_EM(int frame,
                               boolean any_player_moving,
                               boolean any_player_snapping,