rnd-20060304-1-src
authorHolger Schemel <info@artsoft.org>
Sat, 4 Mar 2006 19:57:45 +0000 (20:57 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:51:00 +0000 (10:51 +0200)
* level sets with "levels: 0" are ignored for levels, but not artwork

ChangeLog
src/conftime.h
src/engines.h
src/game.c
src/game_em/convert.c
src/game_em/graphics.c
src/game_em/init.c
src/game_em/main_em.h
src/game_em/synchro_1.c
src/tools.c

index 1fb0d8b93ae9ede2c04e68318927b40862491a79..c6957838b8132e4003f7200e4ae662b692cfc986 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 2006-02-28
+       * level sets with "levels: 0" are ignored for levels, but not artwork
        * fixed bug when scanning empty level group directories (endless loop)
 
 2006-02-26
index afb446e89071af3d29bd6ec00f60cc1efd3df46f..2f5b70e3f86d4ab4821864ce679f75b3bf1b2e2f 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2006-02-28 20:57]"
+#define COMPILE_DATE_STRING "[2006-03-04 20:57]"
index f89767c644f18701548fe9f45ee9ab6cc07a12a3..243eb8ba3747534a9b75e22f5d03a331ce849ff2 100644 (file)
@@ -25,9 +25,10 @@ extern void SetBitmaps_EM(Bitmap **);
 extern void UpdateEngineValues(int, int);
 extern void DrawAllGameValues(int, int, int, int, int);
 
-extern int getGameFrameDelay_EM(int);
+extern void setCenteredPlayerNr_EM(int);
 extern int getCenteredPlayerNr_EM();
 extern int getActivePlayers_EM();
+extern int getGameFrameDelay_EM(int);
 
 extern void PlayLevelSound_EM(int, int, int, int);
 extern void InitGraphicInfo_EM(void);
index daacf61cd23a4721fe491e711f3edf0091b8b9dd..92a181bbc49ddeea03a43289e0991947c09a04dd 100644 (file)
@@ -3146,23 +3146,21 @@ void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation)
   }
   else
   {
-    int scroll_xx = -999, scroll_yy = -999;
+    int scroll_xx = (player->jx < SBX_Left  + MIDPOSX ? SBX_Left :
+                    player->jx > SBX_Right + MIDPOSX ? SBX_Right :
+                    player->jx - MIDPOSX);
+
+    int scroll_yy = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper :
+                    player->jy > SBY_Lower + MIDPOSY ? SBY_Lower :
+                    player->jy - MIDPOSY);
 
     ScrollScreen(NULL, SCROLL_GO_ON);  /* scroll last frame to full tile */
 
-    while (scroll_xx != scroll_x || scroll_yy != scroll_y)
+    while (scroll_x != scroll_xx || scroll_y != scroll_yy)
     {
       int dx = 0, dy = 0;
       int fx = FX, fy = FY;
 
-      scroll_xx = (player->jx < SBX_Left  + MIDPOSX ? SBX_Left :
-                  player->jx > SBX_Right + MIDPOSX ? SBX_Right :
-                  player->jx - MIDPOSX);
-
-      scroll_yy = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper :
-                  player->jy > SBY_Lower + MIDPOSY ? SBY_Lower :
-                  player->jy - MIDPOSY);
-
       dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0);
       dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0);
 
index 2935a10123be7a50c10443820dd03d93960f52ea..9b888ffce11733dff5f6825af16a24491971ee77 100644 (file)
@@ -1021,4 +1021,10 @@ void prepare_em_level(void)
           i, ply[i].x_initial, ply[i].y_initial, ply[i].alive);
 #endif
   }
+
+  game_em.any_player_moving = FALSE;
+  game_em.last_moving_player = 0;      /* default: first player */
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+    game_em.last_player_direction[i] = MV_NONE;
 }
index d64863b4c46fba0bf68ddacdbc2da226c63de9d7..b068b5396d2b1c51f9b370ea2448a7f1148b62de 100644 (file)
 #define VALID_SCREEN_Y(y)      ((y) < MIN_SCREEN_Y ? MIN_SCREEN_Y :    \
                                 (y) > MAX_SCREEN_Y ? MAX_SCREEN_Y : (y))
 
-#define PLAYER_SCREEN_X(p)     (((    frame) * ply[p].oldx +           \
-                                 (8 - frame) * ply[p].x) * TILEX / 8   \
+#define PLAYER_SCREEN_X_F(p,f) (((    f) * ply[p].oldx +               \
+                                 (8 - f) * ply[p].x) * TILEX / 8       \
                                 - ((SCR_FIELDX - 1) * TILEX) / 2)
-#define PLAYER_SCREEN_Y(p)     (((    frame) * ply[p].oldy +           \
-                                 (8 - frame) * ply[p].y) * TILEY / 8   \
+#define PLAYER_SCREEN_Y_F(p,f) (((    f) * ply[p].oldy +               \
+                                 (8 - f) * ply[p].y) * TILEY / 8       \
                                 - ((SCR_FIELDY - 1) * TILEY) / 2)
 
+#define PLAYER_SCREEN_X(p)     PLAYER_SCREEN_X_F(p, frame)
+#define PLAYER_SCREEN_Y(p)     PLAYER_SCREEN_Y_F(p, frame)
+
 
 int frame;                     /* current screen frame */
-#if 0
-int screen_x;                  /* current scroll position */
-int screen_y;
-#else
 int screen_x;                  /* current scroll position */
 int screen_y;
-#endif
 
 /* tiles currently on screen */
 static int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
@@ -615,24 +613,129 @@ void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation)
 }
 #endif
 
+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 (ply[i].alive)
+    {
+#if 0
+      int sx = PLAYER_SCREEN_X_F(i, 0);
+      int sy = PLAYER_SCREEN_Y_F(i, 0);
+#else
+      int sx = PLAYER_SCREEN_X(i);
+      int sy = PLAYER_SCREEN_Y(i);
+#endif
+
+#if 0
+      /* round player position to full tile */
+      sx = (sx / TILEX) * TILEX;
+      sy = (sy / TILEY) * TILEY;
+#endif
+
+      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++;
+    }
+  }
+}
+
+boolean checkIfAllPlayersFitToScreen()
+{
+  int sx1 = 0, sy1 = 0, sx2 = 0, sy2 = 0;
+
+  setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
+
+  return (sx2 - sx1 <= SCR_FIELDX * TILEX &&
+         sy2 - sy1 <= SCR_FIELDY * TILEY);
+}
+
+void setScreenCenteredToAllPlayers(int *sx, int *sy)
+{
+  int sx1 = screen_x, sy1 = screen_y, sx2 = screen_x, sy2 = screen_y;
+
+  setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
+
+  *sx = (sx1 + sx2) / 2;
+  *sy = (sy1 + sy2) / 2;
+}
+
+void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy)
+{
+  int sx1 = screen_x, sy1 = screen_y, sx2 = screen_x, sy2 = screen_y;
+
+  setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2);
+
+  *max_dx = MAX(ABS(sx1 - screen_x), ABS(sx2 - screen_x));
+  *max_dy = MAX(ABS(sy1 - screen_y), ABS(sy2 - screen_y));
+}
+
+boolean checkIfAllPlayersAreVisible()
+{
+  int max_dx, max_dy;
+
+  setMaxCenterDistanceForAllPlayers(&max_dx, &max_dy);
+
+  return (max_dx <= SCR_FIELDX * TILEX / 2 &&
+         max_dy <= SCR_FIELDY * TILEY / 2);
+}
+
 void RedrawPlayfield_EM(boolean force_redraw)
 {
 #if 1
   int centered_player_nr_next = getCenteredPlayerNr_EM();
-  int player_nr = (centered_player_nr_next != -1 ? centered_player_nr_next :0);
+#if 0
+  int player_nr;
+#endif
+  boolean all_players_visible = checkIfAllPlayersAreVisible();
+  boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen();
   boolean draw_new_player_location = FALSE;
   boolean quick_relocation = setup.quick_switch;
 #else
   int player_nr = 0;           /* !!! FIX THIS (CENTERED TO PLAYER 1) !!! */
 #endif
-  int sx = PLAYER_SCREEN_X(player_nr);
-  int sy = PLAYER_SCREEN_Y(player_nr);
-  int i, x, y;
+  int offset = (setup.scroll_delay ? 3 : 0) * TILEX;
+  int offset_x = offset;
+  int offset_y = offset;
+  int screen_x_old = screen_x;
+  int screen_y_old = screen_y;
+  int x, y, sx, sy;
+  int i;
+
+#if 0
+  player_nr = (centered_player_nr_next != -1 ? centered_player_nr_next :0);
+
+  sx = PLAYER_SCREEN_X(player_nr);
+  sy = PLAYER_SCREEN_Y(player_nr);
+#endif
+
+  if (centered_player_nr_next == -1 && !all_players_fit_to_screen)
+  {
+    setCenteredPlayerNr_EM(centered_player_nr);
+
+    centered_player_nr_next = centered_player_nr;
+  }
 
 #if 1
   boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0);
 
+#if 0
   if (!scrolling)      /* screen currently aligned at tile position */
+#endif
   {
     if (centered_player_nr != centered_player_nr_next)
     {
@@ -644,6 +747,66 @@ void RedrawPlayfield_EM(boolean force_redraw)
   }
 #endif
 
+#if 1
+  if (centered_player_nr == -1)
+  {
+    int max_dx, max_dy;
+
+#if 1
+    if (draw_new_player_location)
+      setScreenCenteredToAllPlayers(&sx, &sy);
+    else
+    {
+      sx = PLAYER_SCREEN_X(game_em.last_moving_player);
+      sy = PLAYER_SCREEN_Y(game_em.last_moving_player);
+    }
+
+#else
+
+#if 0
+    setScreenCenteredToAllPlayers(&sx, &sy);
+#endif
+
+#if 1
+    sx = PLAYER_SCREEN_X(game_em.last_moving_player);
+    sy = PLAYER_SCREEN_Y(game_em.last_moving_player);
+#endif
+#endif
+
+#if 0
+    printf("::: %d\n", all_players_visible);
+
+    if (!all_players_visible)
+    {
+      sx = screen_x;
+      sy = screen_y;
+
+      offset_x = 0;
+      offset_y = 0;
+    }
+#endif
+
+#if 0
+#if 1
+    offset_x = 0;
+    offset_y = 0;
+#else
+    setMaxCenterDistanceForAllPlayers(&max_dx, &max_dy);
+
+    if (max_dx > offset_x)
+      offset_x = MAX(0, offset_x - (max_dx - offset_x));
+    if (max_dy > offset_y)
+      offset_y = MAX(0, offset_y - (max_dy - offset_y));
+#endif
+#endif
+  }
+  else
+  {
+    sx = PLAYER_SCREEN_X(centered_player_nr);
+    sy = PLAYER_SCREEN_Y(centered_player_nr);
+  }
+#endif
+
   if (draw_new_player_location && !quick_relocation)
   {
 #if 1
@@ -652,12 +815,16 @@ void RedrawPlayfield_EM(boolean force_redraw)
     unsigned long game_frame_delay_value = getGameFrameDelay_EM(25);
 #endif
     int wait_delay_value = game_frame_delay_value;
-    int screen_xx = -999, screen_yy = -999;
+#if 1
+    int screen_xx = VALID_SCREEN_X(sx);
+    int screen_yy = VALID_SCREEN_Y(sy);
+#else
+    int screen_xx = VALID_SCREEN_X(PLAYER_SCREEN_X(player_nr));
+    int screen_yy = VALID_SCREEN_Y(PLAYER_SCREEN_Y(player_nr));
+#endif
 
-    while (screen_xx != screen_x || screen_yy != screen_y)
+    while (screen_x != screen_xx || screen_y != screen_yy)
     {
-      int screen_xx = VALID_SCREEN_X(PLAYER_SCREEN_X(player_nr));
-      int screen_yy = VALID_SCREEN_Y(PLAYER_SCREEN_Y(player_nr));
       int dx = (screen_xx < screen_x ? +1 : screen_xx > screen_x ? -1 : 0);
       int dy = (screen_yy < screen_y ? +1 : screen_yy > screen_y ? -1 : 0);
       int dxx = 0, dyy = 0;
@@ -665,11 +832,31 @@ void RedrawPlayfield_EM(boolean force_redraw)
       if (dx == 0 && dy == 0)          /* no scrolling needed at all */
        break;
 
+#if 1
+      if (ABS(screen_xx - screen_x) >= TILEX ||
+         ABS(screen_yy - screen_y) >= TILEY)
+      {
+       screen_x -= dx * TILEX;
+       screen_y -= dy * TILEY;
+
+       dxx = dx * TILEX / 2;
+       dyy = dy * TILEY / 2;
+      }
+      else
+      {
+       screen_x = screen_xx;
+       screen_y = screen_yy;
+
+       dxx = 0;
+       dyy = 0;
+      }
+#else
       screen_x -= dx * TILEX;
       screen_y -= dy * TILEY;
 
       dxx += dx * TILEX / 2;
       dyy += dy * TILEY / 2;
+#endif
 
       /* scroll in two steps of half tile size to make things smoother */
       screen_x += dxx;
@@ -699,9 +886,11 @@ void RedrawPlayfield_EM(boolean force_redraw)
       FlushDisplay();
       Delay(wait_delay_value);
     }
+
+    screen_x_old = screen_x;
+    screen_y_old = screen_y;
   }
 
-#if 1
   if (force_redraw)
   {
     for (y = 0; y < MAX_BUF_YSIZE; y++)
@@ -713,33 +902,74 @@ void RedrawPlayfield_EM(boolean force_redraw)
       }
     }
   }
-#endif
 
-#if 1
+  /* calculate new screen scrolling position, with regard to scroll delay */
+  screen_x = VALID_SCREEN_X(sx + offset_x < screen_x ? sx + offset_x :
+                           sx - offset_x > screen_x ? sx - offset_x :
+                           screen_x);
+  screen_y = VALID_SCREEN_Y(sy + offset_y < screen_y ? sy + offset_y :
+                           sy - offset_y > screen_y ? sy - offset_y :
+                           screen_y);
 
-  int offset = (setup.scroll_delay ? 3 : 0) * TILEX;
+#if 1
+  /* 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)
+  {
+    int dx = SIGN(screen_x - screen_x_old);
+    int dy = SIGN(screen_y - screen_y_old);
 
-  /* calculate new screen scrolling position, with regard to scroll delay */
-  screen_x = VALID_SCREEN_X(sx + offset < screen_x ? sx + offset :
-                           sx - offset > screen_x ? sx - offset : screen_x);
-  screen_y = VALID_SCREEN_Y(sy + offset < screen_y ? sy + offset :
-                           sy - offset > screen_y ? sy - offset : screen_y);
+    screen_x = screen_x_old + dx * TILEX / 8;
+    screen_y = screen_y_old + dy * TILEY / 8;
+  }
+#endif
 
-#else
+#if 1
+  if (centered_player_nr == -1)
+  {
+    boolean all_players_visible_old = all_players_visible;
 
-  if (sx > lev.width * TILEX)
-    sx = lev.width * TILEX;
-  if (sy > lev.height * TILEY)
-    sy = lev.height * TILEY;
+    all_players_visible = checkIfAllPlayersAreVisible();
 
-  if (sx < SCR_FIELDX * TILEX)
-    sx = SCR_FIELDX * TILEY;
-  if (sy < SCR_FIELDY * TILEY)
-    sy = SCR_FIELDY * TILEY;
+#if 0
+    printf("::: OLD(%d) -> NEW(%d) / OLD(%d, %d) -> NEW(%d, %d)\n",
+          all_players_visible_old,
+          all_players_visible,
+          screen_x_old, screen_y_old,
+          screen_x, screen_y);
+#endif
 
-  screen_x = sx - (SCR_FIELDX - 1) * TILEX;
-  screen_y = sy - (SCR_FIELDY - 1) * TILEY;
+    if (!all_players_visible)
+    {
+      screen_x = screen_x_old;
+      screen_y = screen_y_old;
+    }
+  }
+#endif
 
+#if 1
+  /* prevent scrolling if no player is moving */
+  if (!game_em.any_player_moving)
+  {
+    screen_x = screen_x_old;
+    screen_y = screen_y_old;
+  }
+  else
+  {
+    /* prevent scrolling against the players move direction */
+    int player_nr = game_em.last_moving_player;
+    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);
+
+    if (dx < 0 && player_move_dir == MV_RIGHT ||
+       dx > 0 && player_move_dir == MV_LEFT)
+      screen_x = screen_x_old;
+
+    if (dy < 0 && player_move_dir == MV_DOWN ||
+       dy > 0 && player_move_dir == MV_UP)
+      screen_y = screen_y_old;
+  }
 #endif
 
   animscreen();
index f2f074a796a8b9133d9d8df9efb4a116be6f4830..f29b589671c2a91da5b26d6d39327e40ef54875a 100644 (file)
@@ -44,6 +44,7 @@ int play_element[SAMPLE_MAX];
 static boolean use_native_em_sound = 0;
 
 struct GlobalInfo_EM global_em_info;
+struct GameInfo_EM game_em;
 
 #if defined(AUDIO_UNIX_NATIVE)
 static int sound_pid = -1;
index 5781a40e7c9d8c6cf97f6438a36d4a8d757c107f..cd931fcf7913dbac25fd77133c2e1e556d8cc519 100644 (file)
@@ -651,6 +651,13 @@ struct GlobalInfo_EM
   Bitmap *screenbuffer;
 };
 
+struct GameInfo_EM
+{
+  boolean any_player_moving;
+  int last_moving_player;
+  int last_player_direction[MAX_PLAYERS];
+};
+
 struct LevelInfo_EM
 {
   int file_version;
@@ -679,4 +686,6 @@ struct GraphicInfo_EM
   int unique_identifier;       /* used to identify needed screen updates */
 };
 
+extern struct GameInfo_EM game_em;
+
 #endif /* MAIN_EM_H */
index 058c79e3caedb4ebd3e7d40768d1bc0025300f9a..147da4aff72b564899e3155701d3ce52b8e03e7a 100644 (file)
@@ -23,6 +23,8 @@ void synchro_1(void)
   int start_check_nr;
   int i;
 
+  game_em.any_player_moving = FALSE;
+
   /* must test for death and actually kill separately */
 
   for (i = 0; i < MAX_PLAYERS; i++)
@@ -584,6 +586,10 @@ static void check_player(struct PLAYER *ply)
        ply->last_move_dir = (dx < 0 ? MV_LEFT : MV_RIGHT);
       else if (oldy != ply->y)
        ply->last_move_dir = (dy < 0 ? MV_UP : MV_DOWN);
+
+      game_em.any_player_moving = TRUE;
+      game_em.last_moving_player = ply->num;
+      game_em.last_player_direction[ply->num] = ply->last_move_dir;
     }
   }
   else                                 /* player wants to snap */
index b5e022f620c79b6521d50adbd9278c8b95d7ccc7..eaea76ea0da5a3041978dac4ea08d4f24dbac870 100644 (file)
@@ -5119,19 +5119,9 @@ int font2baseimg(int font_nr)
   return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT];
 }
 
-int getGameFrameDelay_EM(int native_em_game_frame_delay)
+void setCenteredPlayerNr_EM(int centered_player_nr)
 {
-  int game_frame_delay_value;
-
-  game_frame_delay_value =
-    (tape.playing && tape.fast_forward ? FfwdFrameDelay :
-     GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay :
-     GameFrameDelay);
-
-  if (tape.playing && tape.warp_forward && !tape.pausing)
-    game_frame_delay_value = 0;
-
-  return game_frame_delay_value;
+  game.centered_player_nr = game.centered_player_nr_next = centered_player_nr;
 }
 
 int getCenteredPlayerNr_EM()
@@ -5161,6 +5151,21 @@ int getActivePlayers_EM()
   return num_players;
 }
 
+int getGameFrameDelay_EM(int native_em_game_frame_delay)
+{
+  int game_frame_delay_value;
+
+  game_frame_delay_value =
+    (tape.playing && tape.fast_forward ? FfwdFrameDelay :
+     GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay :
+     GameFrameDelay);
+
+  if (tape.playing && tape.warp_forward && !tape.pausing)
+    game_frame_delay_value = 0;
+
+  return game_frame_delay_value;
+}
+
 unsigned int InitRND(long seed)
 {
   if (level.game_engine_type == GAME_ENGINE_TYPE_EM)