rnd-20060313-1-src
authorHolger Schemel <info@artsoft.org>
Mon, 13 Mar 2006 01:07:59 +0000 (02:07 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:51:09 +0000 (10:51 +0200)
* fixed some bugs in player focus switching in EMC and RND game engine

ChangeLog
src/conftime.h
src/engines.h
src/events.c
src/game.c
src/game_em/convert.c
src/game_em/graphics.c
src/main.h
src/tools.c

index 0844cc327a5ae59df90e9d4abc6cea12f1aa7261..51d4a414609274c5be8fa83e4cc9413e47006033 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2006-03-13
+       * fixed some bugs in player focus switching in EMC and RND game engine
+
 2006-03-11
        * added special Supaplex animations for Murphy digging and snapping
        * added special Supaplex animations for Murphy being bored and sleeping
index d3dfeac764e8f1c51f144081787eba12608e62f1..f69b18c9a904e704b4e01175ab8e58ba6cf98568 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2006-03-11 15:37]"
+#define COMPILE_DATE_STRING "[2006-03-13 02:03]"
index 243eb8ba3747534a9b75e22f5d03a331ce849ff2..55352e0fcc2988edf9b4b2639e9a57185b8c28fe 100644 (file)
@@ -27,7 +27,9 @@ extern void DrawAllGameValues(int, int, int, int, int);
 
 extern void setCenteredPlayerNr_EM(int);
 extern int getCenteredPlayerNr_EM();
-extern int getActivePlayers_EM();
+extern void setSetCenteredPlayer_EM(boolean);
+extern boolean getSetCenteredPlayer_EM();
+extern int getNumActivePlayers_EM();
 extern int getGameFrameDelay_EM(int);
 
 extern void PlayLevelSound_EM(int, int, int, int);
index 4d7a7a36d68ee479fb0b8c1644c6935f5a5212cf..e8f205564eb968a174789767ac649db42ebe0b0e 100644 (file)
@@ -700,12 +700,20 @@ void HandleKey(Key key, int key_status)
 
   if (game_status == GAME_MODE_PLAYING)
   {
+    int centered_player_nr_next = -999;
+
     if (key == setup.shortcut.focus_player_all)
-      game.centered_player_nr_next = -1;
+      centered_player_nr_next = -1;
     else
       for (i = 0; i < MAX_PLAYERS; i++)
        if (key == setup.shortcut.focus_player[i])
-         game.centered_player_nr_next = i;
+         centered_player_nr_next = i;
+
+    if (centered_player_nr_next != -999)
+    {
+      game.centered_player_nr_next = centered_player_nr_next;
+      game.set_centered_player = TRUE;
+    }
   }
 
   HandleKeysSpecial(key);
index ed6978926e595e70e109880a7cd51919845e0265..1843274873a34c4b8778dcd982ea540681b63016 100644 (file)
@@ -1958,6 +1958,7 @@ void InitGame()
   game.envelope_active = FALSE;
 
   game.centered_player_nr = game.centered_player_nr_next = -1; /* focus all */
+  game.set_centered_player = FALSE;
 
   for (i = 0; i < NUM_BELTS; i++)
   {
@@ -3145,6 +3146,183 @@ void CheckDynamite(int x, int y)
   Bang(x, y);
 }
 
+#if 1
+
+static void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2)
+{
+  boolean num_checked_players = 0;
+  int i;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (stored_player[i].active)
+    {
+      int sx = stored_player[i].jx;
+      int sy = stored_player[i].jy;
+
+      if (num_checked_players == 0)
+      {
+       *sx1 = *sx2 = sx;
+       *sy1 = *sy2 = sy;
+      }
+      else
+      {
+       *sx1 = MIN(*sx1, sx);
+       *sy1 = MIN(*sy1, sy);
+       *sx2 = MAX(*sx2, sx);
+       *sy2 = MAX(*sy2, sy);
+      }
+
+      num_checked_players++;
+    }
+  }
+}
+
+static boolean checkIfAllPlayersFitToScreen_RND()
+{
+  int sx1 = 0, sy1 = 0, sx2 = 0, sy2 = 0;
+
+  setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
+
+  return (sx2 - sx1 < SCR_FIELDX &&
+         sy2 - sy1 < SCR_FIELDY);
+}
+
+static void setScreenCenteredToAllPlayers(int *sx, int *sy)
+{
+  int sx1 = scroll_x, sy1 = scroll_y, sx2 = scroll_x, sy2 = scroll_y;
+
+  setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
+
+  *sx = (sx1 + sx2) / 2;
+  *sy = (sy1 + sy2) / 2;
+}
+
+#if 0
+static void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy,
+                                             int center_x, int center_y)
+{
+  int sx1 = center_x, sy1 = center_y, sx2 = center_x, sy2 = center_y;
+
+  setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
+
+  *max_dx = MAX(ABS(sx1 - center_x), ABS(sx2 - center_x));
+  *max_dy = MAX(ABS(sy1 - center_y), ABS(sy2 - center_y));
+}
+
+static boolean checkIfAllPlayersAreVisible(int center_x, int center_y)
+{
+  int max_dx, max_dy;
+
+  setMaxCenterDistanceForAllPlayers(&max_dx, &max_dy, center_x, center_y);
+
+  return (max_dx <= SCR_FIELDX / 2 &&
+         max_dy <= SCR_FIELDY / 2);
+}
+#endif
+
+#endif
+
+#if 1
+
+void DrawRelocateScreen(int x, int y, int move_dir, boolean center_screen,
+                       boolean quick_relocation)
+{
+  boolean ffwd_delay = (tape.playing && tape.fast_forward);
+  boolean no_delay = (tape.warp_forward);
+  int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
+  int wait_delay_value = (no_delay ? 0 : frame_delay_value);
+
+  if (quick_relocation)
+  {
+    int offset = (setup.scroll_delay ? 3 : 0);
+
+#if 0
+    if (center_screen)
+      offset = 0;
+#endif
+
+    if (!IN_VIS_FIELD(SCREENX(x), SCREENY(y)) || center_screen)
+    {
+      scroll_x = (x < SBX_Left  + MIDPOSX ? SBX_Left :
+                 x > SBX_Right + MIDPOSX ? SBX_Right :
+                 x - MIDPOSX);
+
+      scroll_y = (y < SBY_Upper + MIDPOSY ? SBY_Upper :
+                 y > SBY_Lower + MIDPOSY ? SBY_Lower :
+                 y - MIDPOSY);
+    }
+    else
+    {
+      if ((move_dir == MV_LEFT  && scroll_x > x - MIDPOSX + offset) ||
+         (move_dir == MV_RIGHT && scroll_x < x - MIDPOSX - offset))
+       scroll_x = x - MIDPOSX + (scroll_x < x - MIDPOSX ? -offset : +offset);
+
+      if ((move_dir == MV_UP   && scroll_y > y - MIDPOSY + offset) ||
+         (move_dir == MV_DOWN && scroll_y < y - MIDPOSY - offset))
+       scroll_y = y - MIDPOSY + (scroll_y < y - MIDPOSY ? -offset : +offset);
+
+      /* don't scroll over playfield boundaries */
+      if (scroll_x < SBX_Left || scroll_x > SBX_Right)
+       scroll_x = (scroll_x < SBX_Left ? SBX_Left : SBX_Right);
+
+      /* don't scroll over playfield boundaries */
+      if (scroll_y < SBY_Upper || scroll_y > SBY_Lower)
+       scroll_y = (scroll_y < SBY_Upper ? SBY_Upper : SBY_Lower);
+    }
+
+    RedrawPlayfield(TRUE, 0,0,0,0);
+  }
+  else
+  {
+    int scroll_xx = (x < SBX_Left  + MIDPOSX ? SBX_Left :
+                    x > SBX_Right + MIDPOSX ? SBX_Right :
+                    x - MIDPOSX);
+
+    int scroll_yy = (y < SBY_Upper + MIDPOSY ? SBY_Upper :
+                    y > SBY_Lower + MIDPOSY ? SBY_Lower :
+                    y - MIDPOSY);
+
+    ScrollScreen(NULL, SCROLL_GO_ON);  /* scroll last frame to full tile */
+
+    while (scroll_x != scroll_xx || scroll_y != scroll_yy)
+    {
+      int dx = 0, dy = 0;
+      int fx = FX, fy = FY;
+
+      dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0);
+      dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0);
+
+      if (dx == 0 && dy == 0)          /* no scrolling needed at all */
+       break;
+
+      scroll_x -= dx;
+      scroll_y -= dy;
+
+      fx += dx * TILEX / 2;
+      fy += dy * TILEY / 2;
+
+      ScrollLevel(dx, dy);
+      DrawAllPlayers();
+
+      /* scroll in two steps of half tile size to make things smoother */
+      BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
+      FlushDisplay();
+      Delay(wait_delay_value);
+
+      /* scroll second step to align at full tile size */
+      BackToFront();
+      Delay(wait_delay_value);
+    }
+
+    DrawAllPlayers();
+    BackToFront();
+    Delay(wait_delay_value);
+  }
+}
+
+#else
+
 void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation)
 {
   boolean ffwd_delay = (tape.playing && tape.fast_forward);
@@ -3237,6 +3415,8 @@ void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation)
   }
 }
 
+#endif
+
 void RelocatePlayer(int jx, int jy, int el_player_raw)
 {
   int el_player = GET_PLAYER_ELEMENT(el_player_raw);
@@ -3314,8 +3494,13 @@ void RelocatePlayer(int jx, int jy, int el_player_raw)
 
 #if 1
   /* only visually relocate centered player */
+#if 1
+  DrawRelocateScreen(player->jx, player->jy, player->MovDir, FALSE,
+                    level.instant_relocation);
+#else
   if (player->index_nr == game.centered_player_nr)
     DrawRelocatePlayer(player, level.instant_relocation);
+#endif
 #else
   if (player == local_player)  /* only visually relocate local player */
     DrawRelocatePlayer(player, level.instant_relocation);
@@ -8659,7 +8844,7 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting)
 #if 1
     if (player->is_sleeping && player->use_murphy)
     {
-      /* special for Murphy: leaning against solid objects when sleeping */
+      /* special case for sleeping Murphy when leaning against non-free tile */
 
       if (!IN_LEV_FIELD(player->jx - 1, player->jy) ||
          Feld[player->jx - 1][player->jy] != EL_EMPTY)
@@ -8902,25 +9087,69 @@ void GameActions()
 
   InitPlayfieldScanModeVars();
 
-  if (ScreenMovPos == 0)       /* screen currently aligned at tile position */
+  if (game.set_centered_player)
+  {
+    boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen_RND();
+
+    /* switching to "all players" only possible if all players fit to screen */
+    if (game.centered_player_nr_next == -1 && !all_players_fit_to_screen)
+    {
+      game.centered_player_nr_next = game.centered_player_nr;
+      game.set_centered_player = FALSE;
+    }
+
+    /* do not switch focus to non-existing (or non-active) player */
+    if (game.centered_player_nr_next >= 0 &&
+       !stored_player[game.centered_player_nr_next].active)
+    {
+      game.centered_player_nr_next = game.centered_player_nr;
+      game.set_centered_player = FALSE;
+    }
+  }
+
+  if (game.set_centered_player &&
+      ScreenMovPos == 0)       /* screen currently aligned at tile position */
   {
+#if 0
     struct PlayerInfo *player;
     int player_nr = game.centered_player_nr_next;
+#endif
+    int sx, sy;
 
     if (game.centered_player_nr_next == -1)
-      player_nr = local_player->index_nr;
+    {
+      setScreenCenteredToAllPlayers(&sx, &sy);
+    }
+    else
+    {
+      sx = stored_player[game.centered_player_nr_next].jx;
+      sy = stored_player[game.centered_player_nr_next].jy;
+    }
 
+#if 0
     player = &stored_player[player_nr];
 
     if (!player->active)
       game.centered_player_nr_next = game.centered_player_nr;
 
+    sx = player->jx;
+    sy = player->jy;
+#endif
+
+#if 0
     if (game.centered_player_nr != game.centered_player_nr_next)
+#endif
     {
+#if 1
+      DrawRelocateScreen(sx, sy, MV_NONE, TRUE, setup.quick_switch);
+#else
       DrawRelocatePlayer(player, setup.quick_switch);
+#endif
 
       game.centered_player_nr = game.centered_player_nr_next;
     }
+
+    game.set_centered_player = FALSE;
   }
 
 #if USE_ONE_MORE_CHANGE_PER_FRAME
index f53bd21d43d28d8e4e68b049760ad67d50c404a9..3aa00be4d19cc842565791444b865d68dab69f4e 100644 (file)
@@ -975,7 +975,7 @@ void prepare_em_level(void)
     }
   }
 
-  num_tape_players = getActivePlayers_EM();
+  num_tape_players = getNumActivePlayers_EM();
 
   if (num_tape_players != -1)
     lev.home_initial = MIN(lev.home_initial, num_tape_players);
index f623ac7a8c9ce148d9a0b5fea58dee75984916eb..331491cfb25c7c0209bbae411d2d54e7a009645a 100644 (file)
@@ -574,7 +574,7 @@ void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation)
 }
 #endif
 
-void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2)
+static void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2)
 {
   boolean num_checked_players = 0;
   int i;
@@ -614,7 +614,7 @@ boolean checkIfAllPlayersFitToScreen()
          sy2 - sy1 <= SCR_FIELDY * TILEY);
 }
 
-void setScreenCenteredToAllPlayers(int *sx, int *sy)
+static void setScreenCenteredToAllPlayers(int *sx, int *sy)
 {
   int sx1 = screen_x, sy1 = screen_y, sx2 = screen_x, sy2 = screen_y;
 
@@ -624,8 +624,8 @@ void setScreenCenteredToAllPlayers(int *sx, int *sy)
   *sy = (sy1 + sy2) / 2;
 }
 
-void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy,
-                                      int center_x, int center_y)
+static void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy,
+                                             int center_x, int center_y)
 {
   int sx1 = center_x, sy1 = center_y, sx2 = center_x, sy2 = center_y;
 
@@ -635,7 +635,7 @@ void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy,
   *max_dy = MAX(ABS(sy1 - center_y), ABS(sy2 - center_y));
 }
 
-boolean checkIfAllPlayersAreVisible(int center_x, int center_y)
+static boolean checkIfAllPlayersAreVisible(int center_x, int center_y)
 {
   int max_dx, max_dy;
 
@@ -650,12 +650,12 @@ void RedrawPlayfield_EM(boolean force_redraw)
 #if 0
   boolean all_players_visible = checkIfAllPlayersAreVisible();
 #endif
-  boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen();
   boolean draw_new_player_location = FALSE;
   boolean quick_relocation = setup.quick_switch;
 #if 0
   boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0);
 #endif
+  boolean set_centered_player = getSetCenteredPlayer_EM();
   int centered_player_nr_next = getCenteredPlayerNr_EM();
   int offset = (setup.scroll_delay ? 3 : 0) * TILEX;
   int offset_x = offset;
@@ -665,12 +665,29 @@ void RedrawPlayfield_EM(boolean force_redraw)
   int x, y, sx, sy;
   int i;
 
-  /* switching to "all players" only possible if all players fit to screen */
-  if (centered_player_nr_next == -1 && !all_players_fit_to_screen)
+  if (set_centered_player)
   {
-    setCenteredPlayerNr_EM(centered_player_nr);
+    boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen();
 
-    centered_player_nr_next = centered_player_nr;
+    /* switching to "all players" only possible if all players fit to screen */
+    if (centered_player_nr_next == -1 && !all_players_fit_to_screen)
+    {
+      centered_player_nr_next = centered_player_nr;
+      setCenteredPlayerNr_EM(centered_player_nr);
+
+      set_centered_player = FALSE;
+      setSetCenteredPlayer_EM(FALSE);
+    }
+
+    /* do not switch focus to non-existing (or non-active) player */
+    if (centered_player_nr_next >= 0 && !ply[centered_player_nr_next].alive)
+    {
+      centered_player_nr_next = centered_player_nr;
+      setCenteredPlayerNr_EM(centered_player_nr);
+
+      set_centered_player = FALSE;
+      setSetCenteredPlayer_EM(FALSE);
+    }
   }
 
 #if 1
@@ -679,12 +696,18 @@ void RedrawPlayfield_EM(boolean force_redraw)
   if (!scrolling)      /* screen currently aligned at tile position */
 #endif
   {
+#if 1
+    if (set_centered_player)
+#else
     if (centered_player_nr != centered_player_nr_next)
+#endif
     {
       centered_player_nr = centered_player_nr_next;
 
       draw_new_player_location = TRUE;
       force_redraw = TRUE;
+
+      setSetCenteredPlayer_EM(FALSE);
     }
   }
 
@@ -706,6 +729,19 @@ void RedrawPlayfield_EM(boolean force_redraw)
     sy = PLAYER_SCREEN_Y(centered_player_nr);
   }
 
+  if (draw_new_player_location && quick_relocation)
+  {
+    screen_x = VALID_SCREEN_X(sx);
+    screen_y = VALID_SCREEN_Y(sy);
+    screen_x_old = screen_x;
+    screen_y_old = screen_y;
+
+#if 0
+    offset_x = 0;
+    offset_y = 0;
+#endif
+  }
+
   if (draw_new_player_location && !quick_relocation)
   {
 #if 1
index 87e68516942e5234f8f596986becc7a92a94f5ee..bb7d8766f9146d446bc7d0b3be113c8293074556 100644 (file)
@@ -2104,6 +2104,7 @@ struct GameInfo
   /* values for special game control */
   int centered_player_nr;
   int centered_player_nr_next;
+  boolean set_centered_player;
 };
 
 struct GlobalInfo
index 04bb48de94604ce972d7997069b508c70d301017..f9b4f6394e41ce11db31acc447be9493a2835f3a 100644 (file)
@@ -5132,9 +5132,11 @@ void setCenteredPlayerNr_EM(int centered_player_nr)
 
 int getCenteredPlayerNr_EM()
 {
+#if 0
   if (game.centered_player_nr_next >= 0 &&
       !native_em_level.ply[game.centered_player_nr_next]->alive)
     game.centered_player_nr_next = game.centered_player_nr;
+#endif
 
   if (game.centered_player_nr != game.centered_player_nr_next)
     game.centered_player_nr = game.centered_player_nr_next;
@@ -5142,7 +5144,17 @@ int getCenteredPlayerNr_EM()
   return game.centered_player_nr;
 }
 
-int getActivePlayers_EM()
+void setSetCenteredPlayer_EM(boolean set_centered_player)
+{
+  game.set_centered_player = set_centered_player;
+}
+
+boolean getSetCenteredPlayer_EM()
+{
+  return game.set_centered_player;
+}
+
+int getNumActivePlayers_EM()
 {
   int num_players = 0;
   int i;