rnd-20060407-1-src
[rocksndiamonds.git] / src / game_em / graphics.c
index 331491cfb25c7c0209bbae411d2d54e7a009645a..deee45a380a905e09b93cb2f02609659b33edfa2 100644 (file)
@@ -3,9 +3,7 @@
  * graphics manipulation crap
  */
 
-#include "global.h"
-#include "display.h"
-#include "level.h"
+#include "main_em.h"
 
 #define MIN_SCREEN_XPOS                1
 #define MIN_SCREEN_YPOS                1
@@ -40,11 +38,13 @@ static int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
 
 static boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
 
+#if 0
 #if 1
 int centered_player_nr;
 #else
 static int centered_player_nr;
 #endif
+#endif
 
 /* copy the entire screen to the window at the scroll position */
 
@@ -458,9 +458,11 @@ void game_initscreen(void)
 
   frame = 6;
 
-  centered_player_nr = getCenteredPlayerNr_EM();
+#if 0
+  game.centered_player_nr = getCenteredPlayerNr_EM();
+#endif
 
-  player_nr = (centered_player_nr != -1 ? centered_player_nr : 0);
+  player_nr = (game.centered_player_nr != -1 ? game.centered_player_nr : 0);
 
   screen_x = VALID_SCREEN_X(PLAYER_SCREEN_X(player_nr));
   screen_y = VALID_SCREEN_Y(PLAYER_SCREEN_Y(player_nr));
@@ -574,6 +576,34 @@ void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation)
 }
 #endif
 
+static int getMaxCenterDistancePlayerNr(int center_x, int center_y)
+{
+  int max_dx = 0, max_dy = 0;
+  int player_nr = game_em.last_moving_player;
+  int i;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (ply[i].alive)
+    {
+      int sx = PLAYER_SCREEN_X(i);
+      int sy = PLAYER_SCREEN_Y(i);
+
+      if (game_em.last_player_direction[i] != MV_NONE &&
+         (ABS(sx - center_x) > max_dx ||
+          ABS(sy - center_y) > max_dy))
+      {
+       max_dx = MAX(max_dx, ABS(sx - center_x));
+       max_dy = MAX(max_dy, ABS(sy - center_y));
+
+       player_nr = i;
+      }
+    }
+  }
+
+  return player_nr;
+}
+
 static void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2)
 {
   boolean num_checked_players = 0;
@@ -655,8 +685,17 @@ void RedrawPlayfield_EM(boolean force_redraw)
 #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();
+#if 0
+  boolean game.set_centered_player = getSetCenteredPlayer_EM();
+  int game.centered_player_nr_next = getCenteredPlayerNr_EM();
+#endif
+#if 1
+  int max_center_distance_player_nr =
+    getMaxCenterDistancePlayerNr(screen_x, screen_y);
+#else
+  int player_nr = game_em.last_moving_player;
+#endif
+  int stepsize = TILEX / 8;
   int offset = (setup.scroll_delay ? 3 : 0) * TILEX;
   int offset_x = offset;
   int offset_y = offset;
@@ -665,28 +704,23 @@ void RedrawPlayfield_EM(boolean force_redraw)
   int x, y, sx, sy;
   int i;
 
-  if (set_centered_player)
+  if (game.set_centered_player)
   {
     boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen();
 
     /* switching to "all players" only possible if all players fit to screen */
-    if (centered_player_nr_next == -1 && !all_players_fit_to_screen)
+    if (game.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);
+      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 (centered_player_nr_next >= 0 && !ply[centered_player_nr_next].alive)
+    if (game.centered_player_nr_next >= 0 &&
+       !ply[game.centered_player_nr_next].alive)
     {
-      centered_player_nr_next = centered_player_nr;
-      setCenteredPlayerNr_EM(centered_player_nr);
-
-      set_centered_player = FALSE;
-      setSetCenteredPlayer_EM(FALSE);
+      game.centered_player_nr_next = game.centered_player_nr;
+      game.set_centered_player = FALSE;
     }
   }
 
@@ -697,36 +731,45 @@ void RedrawPlayfield_EM(boolean force_redraw)
 #endif
   {
 #if 1
-    if (set_centered_player)
+    if (game.set_centered_player)
 #else
-    if (centered_player_nr != centered_player_nr_next)
+    if (game.centered_player_nr != game.centered_player_nr_next)
 #endif
     {
-      centered_player_nr = centered_player_nr_next;
+      game.centered_player_nr = game.centered_player_nr_next;
 
       draw_new_player_location = TRUE;
       force_redraw = TRUE;
 
-      setSetCenteredPlayer_EM(FALSE);
+      game.set_centered_player = FALSE;
     }
   }
 
-  if (centered_player_nr == -1)
+  if (game.centered_player_nr == -1)
   {
+#if 1
+    if (draw_new_player_location || offset == 0)
+#else
     if (draw_new_player_location)
+#endif
     {
       setScreenCenteredToAllPlayers(&sx, &sy);
     }
     else
     {
+#if 1
+      sx = PLAYER_SCREEN_X(max_center_distance_player_nr);
+      sy = PLAYER_SCREEN_Y(max_center_distance_player_nr);
+#else
       sx = PLAYER_SCREEN_X(game_em.last_moving_player);
       sy = PLAYER_SCREEN_Y(game_em.last_moving_player);
+#endif
     }
   }
   else
   {
-    sx = PLAYER_SCREEN_X(centered_player_nr);
-    sy = PLAYER_SCREEN_Y(centered_player_nr);
+    sx = PLAYER_SCREEN_X(game.centered_player_nr);
+    sy = PLAYER_SCREEN_Y(game.centered_player_nr);
   }
 
   if (draw_new_player_location && quick_relocation)
@@ -869,23 +912,37 @@ void RedrawPlayfield_EM(boolean force_redraw)
                            sy - offset_y > screen_y ? sy - offset_y :
                            screen_y);
 
-  /* prevent scrolling further than player step size screen when scrolling */
-  if (ABS(screen_x - screen_x_old) > TILEX / 8 ||
-      ABS(screen_y - screen_y_old) > TILEY / 8)
+#if 1
+  /* prevent scrolling further than double player step size when scrolling */
+  if (ABS(screen_x - screen_x_old) > 2 * stepsize ||
+      ABS(screen_y - screen_y_old) > 2 * stepsize)
   {
     int dx = SIGN(screen_x - screen_x_old);
     int dy = SIGN(screen_y - screen_y_old);
 
-    screen_x = screen_x_old + dx * TILEX / 8;
-    screen_y = screen_y_old + dy * TILEY / 8;
+    screen_x = screen_x_old + dx * 2 * stepsize;
+    screen_y = screen_y_old + dy * 2 * stepsize;
   }
+#else
+  /* prevent scrolling further than player step size when scrolling */
+  if (ABS(screen_x - screen_x_old) > stepsize ||
+      ABS(screen_y - screen_y_old) > stepsize)
+  {
+    int dx = SIGN(screen_x - screen_x_old);
+    int dy = SIGN(screen_y - screen_y_old);
+
+    screen_x = screen_x_old + dx * stepsize;
+    screen_y = screen_y_old + dy * stepsize;
+  }
+#endif
 
   /* prevent scrolling away from the other players when focus on all players */
-  if (centered_player_nr == -1)
+  if (game.centered_player_nr == -1)
   {
 #if 1
     /* check if all players are still visible with new scrolling position */
-    if (!checkIfAllPlayersAreVisible(screen_x, screen_y))
+    if (checkIfAllPlayersAreVisible(screen_x_old, screen_y_old) &&
+       !checkIfAllPlayersAreVisible(screen_x, screen_y))
     {
       /* reset horizontal scroll position to last value, if needed */
       if (!checkIfAllPlayersAreVisible(screen_x, screen_y_old))
@@ -917,7 +974,11 @@ void RedrawPlayfield_EM(boolean force_redraw)
   else
   {
     /* prevent scrolling against the players move direction */
+#if 0
     int player_nr = game_em.last_moving_player;
+#endif
+    int player_nr = (game.centered_player_nr == -1 ?
+                    max_center_distance_player_nr : game.centered_player_nr);
     int player_move_dir = game_em.last_player_direction[player_nr];
     int dx = SIGN(screen_x - screen_x_old);
     int dy = SIGN(screen_y - screen_y_old);
@@ -950,12 +1011,47 @@ void game_animscreen(void)
 
 void DrawGameDoorValues_EM()
 {
+#if 1
+  int dynamite_state;
+  int key_state;
+#else
   int dynamite_state = ply[0].dynamite;                /* !!! ONLY PLAYER 1 !!! */
-  int all_keys_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys;
+  int key_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys;
+#endif
+
+#if 1
+  if (game.centered_player_nr == -1)
+  {
+#if 1
+    int i;
+
+    dynamite_state = 0;
+    key_state = 0;
+
+    for (i = 0; i < MAX_PLAYERS; i++)
+    {
+      dynamite_state += ply[i].dynamite;
+      key_state |= ply[i].keys;
+    }
+
+#else
+
+    dynamite_state = ply[0].dynamite;          /* !!! ONLY PLAYER 1 !!! */
+    key_state = ply[0].keys | ply[1].keys | ply[2].keys | ply[3].keys;
+#endif
+  }
+  else
+  {
+    int player_nr = game.centered_player_nr;
+
+    dynamite_state = ply[player_nr].dynamite;
+    key_state = ply[player_nr].keys;
+  }
+#endif
 
 #if 1
   DrawAllGameValues(lev.required, dynamite_state, lev.score,
-                   lev.time, all_keys_state);
+                   lev.time, key_state);
 #else
   DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
                    DISPLAY_TIME(lev.time), ply1.keys | ply2.keys);