fixed single-step mode for wrap-around levels in EM engine
authorHolger Schemel <info@artsoft.org>
Tue, 29 Sep 2020 19:35:09 +0000 (21:35 +0200)
committerHolger Schemel <info@artsoft.org>
Tue, 29 Sep 2020 19:35:09 +0000 (21:35 +0200)
This fixes a graphical bug when wrapping around in single-step mode by
drawing wrap-around animation before going to single step pause mode.

src/engines.h
src/game_em/game.c
src/game_em/global.h
src/game_em/logic.c
src/tools.c

index 46cdbf4fee79fae60cdf394b8c4fd1485b3f55bc..826ad9644aff491e6194f09387742183fe59f0be 100644 (file)
@@ -33,7 +33,7 @@ boolean isActivePlayer_EM(int);
 
 void PlayLevelSound_EM(int, int, int, int);
 void InitGraphicInfo_EM(void);
 
 void PlayLevelSound_EM(int, int, int, int);
 void InitGraphicInfo_EM(void);
-void CheckSingleStepMode_EM(byte action[], int, boolean, boolean, boolean);
+boolean CheckSingleStepMode_EM(byte action[], int, boolean, boolean, boolean);
 
 void SetGfxAnimation_EM(struct GraphicInfo_EM *, int, int, int, int);
 void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *, int, int, int, int);
 
 void SetGfxAnimation_EM(struct GraphicInfo_EM *, int, int, int, int);
 void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *, int, int, int, int);
index 3115fb5adf25ea10e3653cd7aca82f2e936e8a9a..8443ff0535dede2d67982d5150138b042a72ec00 100644 (file)
@@ -108,8 +108,13 @@ void GameActions_EM(byte action[MAX_PLAYERS], boolean warp_mode)
        ply[i].dynamite_cnt < 5)
       any_player_dropping = TRUE;
 
        ply[i].dynamite_cnt < 5)
       any_player_dropping = TRUE;
 
-  CheckSingleStepMode_EM(action, frame, game_em.any_player_moving,
-                        game_em.any_player_snapping, any_player_dropping);
+  boolean single_step_mode_paused =
+    CheckSingleStepMode_EM(action, frame, game_em.any_player_moving,
+                          game_em.any_player_snapping, any_player_dropping);
+
+  // draw wrapping around before going to single step pause mode
+  if (single_step_mode_paused && logic_check_wrap())
+    logic_move();
 
   RedrawPlayfield_EM(FALSE);
 }
 
   RedrawPlayfield_EM(FALSE);
 }
index 3efba4477d546646395f69aedce635e70fd1c70b..33b96423371a5fca79bbb2ee71cfe637b6be2c14 100644 (file)
@@ -19,6 +19,8 @@ void game_init_cave_buffers(void);
 void play_sound(int, int, int);
 void play_element_sound(int, int, int, int);
 
 void play_sound(int, int, int);
 void play_element_sound(int, int, int, int);
 
+boolean logic_check_wrap(void);
+void logic_move(void);
 void logic_init(void);
 void logic(void);
 
 void logic_init(void);
 void logic(void);
 
index 5055be5a11ca930b75d19ddb7f9d42270177d90b..8b759630e93bc8524f02d7c7663af538b7134030 100644 (file)
@@ -7381,27 +7381,28 @@ static void handle_tile(int x, int y)
   }
 }
 
   }
 }
 
-static void logic_players(void)
+boolean logic_check_wrap(void)
 {
 {
-  int start_check_nr;
   int i;
 
   int i;
 
-  cave = lev.cave;
-  next = lev.next;
-  boom = lev.boom;
-
-  game_em.any_player_moving = FALSE;
-  game_em.any_player_snapping = FALSE;
-
-  /* must test for death and actually kill separately */
   for (i = 0; i < MAX_PLAYERS; i++)
   {
   for (i = 0; i < MAX_PLAYERS; i++)
   {
-    boolean ply_kill = player_killed(&ply[i]);
+    if (!ply[i].alive)
+      continue;
 
 
-    if (ply[i].alive && ply_kill)
-      kill_player(&ply[i]);
+    /* check for wrap-around movement */
+    if (ply[i].x < lev.left ||
+       ply[i].x > lev.right - 1)
+      return TRUE;
   }
 
   }
 
+  return FALSE;
+}
+
+void logic_move(void)
+{
+  int i;
+
   for (i = 0; i < MAX_PLAYERS; i++)
   {
     if (!ply[i].alive)
   for (i = 0; i < MAX_PLAYERS; i++)
   {
     if (!ply[i].alive)
@@ -7425,6 +7426,30 @@ static void logic_players(void)
     ply[i].prev_y = ply[i].y;
     ply[i].anim = PLY_still;
   }
     ply[i].prev_y = ply[i].y;
     ply[i].anim = PLY_still;
   }
+}
+
+static void logic_players(void)
+{
+  int start_check_nr;
+  int i;
+
+  cave = lev.cave;
+  next = lev.next;
+  boom = lev.boom;
+
+  game_em.any_player_moving = FALSE;
+  game_em.any_player_snapping = FALSE;
+
+  /* must test for death and actually kill separately */
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    boolean ply_kill = player_killed(&ply[i]);
+
+    if (ply[i].alive && ply_kill)
+      kill_player(&ply[i]);
+  }
+
+  logic_move();
 
   start_check_nr = ((game_em.random & 128 ? 0 : 1) * 2 +
                    (game_em.random & 256 ? 0 : 1));
 
   start_check_nr = ((game_em.random & 128 ? 0 : 1) * 2 +
                    (game_em.random & 256 ? 0 : 1));
index 2c30df83c7fcdfcadf99faf69565b9e00cd0cb28..a4199a14600fb5083b61ed92e6a45debb1beb0b9 100644 (file)
@@ -9078,10 +9078,10 @@ static void CheckSaveEngineSnapshot_MM(boolean element_clicked,
   }
 }
 
   }
 }
 
-void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
-                           boolean any_player_moving,
-                           boolean any_player_snapping,
-                           boolean any_player_dropping)
+boolean CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
+                              boolean any_player_moving,
+                              boolean any_player_snapping,
+                              boolean any_player_dropping)
 {
   if (tape.single_step && tape.recording && !tape.pausing)
     if (frame == 7 && !any_player_dropping)
 {
   if (tape.single_step && tape.recording && !tape.pausing)
     if (frame == 7 && !any_player_dropping)
@@ -9089,6 +9089,8 @@ void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
 
   CheckSaveEngineSnapshot_EM(action, frame, any_player_moving,
                             any_player_snapping, any_player_dropping);
 
   CheckSaveEngineSnapshot_EM(action, frame, any_player_moving,
                             any_player_snapping, any_player_dropping);
+
+  return tape.pausing;
 }
 
 void CheckSingleStepMode_SP(boolean murphy_is_waiting,
 }
 
 void CheckSingleStepMode_SP(boolean murphy_is_waiting,