added new level option to only redraw off-screen player relocation
[rocksndiamonds.git] / src / game.c
index 1f9289e8f7c8241df44992ecceb5fafee49f984f..cea1b769be4fd43ad9ece0c2710720b63434caa9 100644 (file)
@@ -1949,7 +1949,7 @@ static void InitField(int x, int y, boolean init_game)
     CheckTriggeredElementChange(x, y, element, CE_CREATION_OF_X);
 }
 
-static inline void InitField_WithBug1(int x, int y, boolean init_game)
+inline static void InitField_WithBug1(int x, int y, boolean init_game)
 {
   InitField(x, y, init_game);
 
@@ -1959,7 +1959,7 @@ static inline void InitField_WithBug1(int x, int y, boolean init_game)
     InitMovDir(x, y);
 }
 
-static inline void InitField_WithBug2(int x, int y, boolean init_game)
+inline static void InitField_WithBug2(int x, int y, boolean init_game)
 {
   int old_element = Feld[x][y];
 
@@ -3083,6 +3083,7 @@ void InitGame()
 {
   int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
   int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
+  int fade_mask = REDRAW_FIELD;
 
   boolean emulate_bd = TRUE;   /* unless non-BOULDERDASH elements found */
   boolean emulate_sb = TRUE;   /* unless non-SOKOBAN     elements found */
@@ -3090,22 +3091,30 @@ void InitGame()
   int initial_move_dir = MV_DOWN;
   int i, j, x, y;
 
-  game_status = GAME_MODE_PLAYING;
+  // required here to update video display before fading (FIX THIS)
+  DrawMaskedBorder(REDRAW_DOOR_2);
 
-  StopAnimation();
+  game_status = GAME_MODE_PLAYING;
 
   if (!game.restart_level)
     CloseDoor(DOOR_CLOSE_1);
 
+  /* needed if different viewport properties defined for playing */
+  ChangeViewportPropertiesIfNeeded();
+
   if (level_editor_test_game)
     FadeSkipNextFadeIn();
   else
     FadeSetEnterScreen();
 
-  FadeOut(REDRAW_FIELD);
+  if (CheckIfGlobalBorderHasChanged())
+    fade_mask = REDRAW_ALL;
 
-  /* needed if different viewport properties defined for playing */
-  ChangeViewportPropertiesIfNeeded();
+  FadeOut(fade_mask);
+
+  OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW);
+
+  ClearField();
 
   DrawCompleteVideoDisplay();
 
@@ -3919,7 +3928,9 @@ void InitGame()
   BlitScreenToBitmap(backbuffer);
   /* !!! FIX THIS (END) !!! */
 
-  FadeIn(REDRAW_FIELD);
+  DrawMaskedBorder(fade_mask);
+
+  FadeIn(fade_mask);
 
 #if 1
   // full screen redraw is required at this point in the following cases:
@@ -3948,9 +3959,14 @@ void InitGame()
   {
     UnmapGameButtons();
     UnmapTapeButtons();
+
+    FreeGameButtons();
+    CreateGameButtons();
+
     game_gadget[SOUND_CTRL_ID_MUSIC]->checked = setup.sound_music;
     game_gadget[SOUND_CTRL_ID_LOOPS]->checked = setup.sound_loops;
     game_gadget[SOUND_CTRL_ID_SIMPLE]->checked = setup.sound_simple;
+
     MapGameButtons();
     MapTapeButtons();
 
@@ -4405,7 +4421,7 @@ void GameEnd()
   {
     game_status = GAME_MODE_MAIN;
 
-    DrawAndFadeInMainMenu(REDRAW_FIELD);
+    DrawMainMenu();
 
     return;
   }
@@ -4416,7 +4432,7 @@ void GameEnd()
 
     game_status = GAME_MODE_MAIN;
 
-    DrawAndFadeInMainMenu(REDRAW_FIELD);
+    DrawMainMenu();
 
     return;
   }
@@ -4435,9 +4451,6 @@ void GameEnd()
   {
     game_status = GAME_MODE_SCORES;
 
-    /* needed if different viewport properties defined for scores */
-    ChangeViewportPropertiesIfNeeded();
-
     DrawHallOfFame(hi_pos);
 
     if (raise_level)
@@ -4458,7 +4471,7 @@ void GameEnd()
       TapeErase();
     }
 
-    DrawAndFadeInMainMenu(REDRAW_FIELD);
+    DrawMainMenu();
   }
 }
 
@@ -4883,7 +4896,11 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
   int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
   int wait_delay_value = (no_delay ? 0 : frame_delay_value);
 
-  if (quick_relocation)
+  if (level.lazy_relocation && IN_VIS_FIELD(SCREENX(x), SCREENY(y)))
+  {
+    RedrawPlayfield();
+  }
+  else if (quick_relocation)
   {
     if (!IN_VIS_FIELD(SCREENX(x), SCREENY(y)) || center_screen)
     {
@@ -4962,7 +4979,7 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
       }
     }
 
-    RedrawPlayfield(TRUE, 0,0,0,0);
+    RedrawPlayfield();
   }
   else
   {
@@ -5004,7 +5021,6 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
                   offset_y - MIDPOSY);
     }
 
-
     ScrollScreen(NULL, SCROLL_GO_ON);  /* scroll last frame to full tile */
 
     while (scroll_x != scroll_xx || scroll_y != scroll_yy)
@@ -10969,23 +10985,6 @@ void GameActions()
   byte tape_action[MAX_PLAYERS];
   int i;
 
-  for (i = 0; i < MAX_PLAYERS; i++)
-  {
-    struct PlayerInfo *player = &stored_player[i];
-
-    // allow engine snapshot if movement attempt was stopped
-    if ((game.snapshot.last_action[i] & KEY_MOTION) != 0 &&
-       (player->action & KEY_MOTION) == 0)
-      game.snapshot.changed_action = TRUE;
-
-    // allow engine snapshot in case of snapping/dropping attempt
-    if ((game.snapshot.last_action[i] & KEY_BUTTON) == 0 &&
-       (player->action & KEY_BUTTON) != 0)
-      game.snapshot.changed_action = TRUE;
-
-    game.snapshot.last_action[i] = player->action;
-  }
-
   /* detect endless loops, caused by custom element programming */
   if (recursion_loop_detected && recursion_loop_depth == 0)
   {
@@ -11192,6 +11191,21 @@ void GameActions()
 #endif
 #endif
 
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    // allow engine snapshot in case of changed movement attempt
+    if ((game.snapshot.last_action[i] & KEY_MOTION) !=
+       (stored_player[i].effective_action & KEY_MOTION))
+      game.snapshot.changed_action = TRUE;
+
+    // allow engine snapshot in case of snapping/dropping attempt
+    if ((game.snapshot.last_action[i] & KEY_BUTTON) == 0 &&
+       (stored_player[i].effective_action & KEY_BUTTON) != 0)
+      game.snapshot.changed_action = TRUE;
+
+    game.snapshot.last_action[i] = stored_player[i].effective_action;
+  }
+
   if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
   {
     GameActions_EM_Main();
@@ -14470,13 +14484,13 @@ void RequestQuitGameExt(boolean skip_request, boolean quick_quit, char *message)
 
        game_status = GAME_MODE_MAIN;
 
-       DrawAndFadeInMainMenu(REDRAW_FIELD);
+       DrawMainMenu();
       }
       else
       {
        game_status = GAME_MODE_MAIN;
 
-       DrawAndFadeInMainMenu(REDRAW_FIELD);
+       DrawMainMenu();
       }
     }
   }