fixed playfield flashing black when game started from level editor
[rocksndiamonds.git] / src / game.c
index c1846d6a147ff6abd76ec6caefe8f0e88b7f0d06..99540b18d9622ef055a0066d41c7e32f8dbb53d6 100644 (file)
@@ -3358,14 +3358,15 @@ void InitGame(void)
   else
     FadeSetEnterScreen();
 
-  if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged())
+  if (CheckFadeAll())
     fade_mask = REDRAW_ALL;
 
   FadeLevelSoundsAndMusic();
 
   ExpireSoundLoops(TRUE);
 
-  FadeOut(fade_mask);
+  if (!level_editor_test_game)
+    FadeOut(fade_mask);
 
   // needed if different viewport properties defined for playing
   ChangeViewportPropertiesIfNeeded();
@@ -3543,8 +3544,6 @@ void InitGame(void)
   if (network_playing)
     SendToServer_MovePlayer(MV_NONE);
 
-  ZX = ZY = -1;
-
   FrameCounter = 0;
   TimeFrames = 0;
   TimePlayed = 0;
@@ -3557,6 +3556,9 @@ void InitGame(void)
 
   ScrollStepSize = 0;  // will be correctly initialized by ScrollScreen()
 
+  game.robot_wheel_x = -1;
+  game.robot_wheel_y = -1;
+
   game.exit_x = -1;
   game.exit_y = -1;
 
@@ -3565,6 +3567,8 @@ void InitGame(void)
   game.LevelSolved = FALSE;
   game.GameOver = FALSE;
 
+  game.GamePlayed = !tape.playing;
+
   game.LevelSolved_GameWon = FALSE;
   game.LevelSolved_GameEnd = FALSE;
   game.LevelSolved_SaveTape = FALSE;
@@ -4500,7 +4504,7 @@ void GameWon(void)
     int i;
 
     // do not start end game actions before the player stops moving (to exit)
-    if (local_player->MovPos)
+    if (local_player->active && local_player->MovPos)
       return;
 
     game.LevelSolved_GameWon = TRUE;
@@ -6846,12 +6850,14 @@ static void TurnRoundExt(int x, int y)
       }
     }
 
-    if (element == EL_ROBOT && ZX >= 0 && ZY >= 0 &&
-       (Feld[ZX][ZY] == EL_ROBOT_WHEEL_ACTIVE ||
+    if (element == EL_ROBOT &&
+       game.robot_wheel_x >= 0 &&
+       game.robot_wheel_y >= 0 &&
+       (Feld[game.robot_wheel_x][game.robot_wheel_y] == EL_ROBOT_WHEEL_ACTIVE ||
         game.engine_version < VERSION_IDENT(3,1,0,0)))
     {
-      attr_x = ZX;
-      attr_y = ZY;
+      attr_x = game.robot_wheel_x;
+      attr_y = game.robot_wheel_y;
     }
 
     if (element == EL_PENGUIN)
@@ -9033,10 +9039,11 @@ static void RunRobotWheel(int x, int y)
 
 static void StopRobotWheel(int x, int y)
 {
-  if (ZX == x && ZY == y)
+  if (game.robot_wheel_x == x &&
+      game.robot_wheel_y == y)
   {
-    ZX = ZY = -1;
-
+    game.robot_wheel_x = -1;
+    game.robot_wheel_y = -1;
     game.robot_wheel_active = FALSE;
   }
 }
@@ -11360,6 +11367,15 @@ static void GameActionsExt(void)
 
   SetVideoFrameDelay(game_frame_delay_value);
 
+  // (de)activate virtual buttons depending on current game status
+  if (strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS))
+  {
+    if (game.all_players_gone) // if no players there to be controlled anymore
+      SetOverlayActive(FALSE);
+    else if (!tape.playing)    // if game continues after tape stopped playing
+      SetOverlayActive(TRUE);
+  }
+
 #if 0
 #if 0
   // ---------- main game synchronization point ----------
@@ -11470,6 +11486,10 @@ static void GameActionsExt(void)
   if (tape.recording)
     TapeRecordAction(tape_action);
 
+  // remember if game was played (especially after tape stopped playing)
+  if (!tape.playing && summarized_player_action)
+    game.GamePlayed = TRUE;
+
 #if USE_NEW_PLAYER_ASSIGNMENTS
   // !!! also map player actions in single player mode !!!
   // if (game.team_mode)
@@ -12145,7 +12165,8 @@ void GameActions_RND(void)
   DrawAllPlayers();
   PlayAllPlayersSound();
 
-  if (local_player->show_envelope != 0 && local_player->MovPos == 0)
+  if (local_player->show_envelope != 0 && (!local_player->active ||
+                                          local_player->MovPos == 0))
   {
     ShowEnvelope(local_player->show_envelope - EL_ENVELOPE_1);
 
@@ -13432,6 +13453,9 @@ void RemovePlayer(struct PlayerInfo *player)
   player->present = FALSE;
   player->active = FALSE;
 
+  // required for some CE actions (even if the player is not active anymore)
+  player->MovPos = 0;
+
   if (!ExplodeField[jx][jy])
     StorePlayer[jx][jy] = 0;
 
@@ -13448,8 +13472,8 @@ void RemovePlayer(struct PlayerInfo *player)
     game.GameOver = TRUE;
   }
 
-  game.exit_x = ZX = jx;
-  game.exit_y = ZY = jy;
+  game.exit_x = game.robot_wheel_x = jx;
+  game.exit_y = game.robot_wheel_y = jy;
 }
 
 void ExitPlayer(struct PlayerInfo *player)
@@ -14072,9 +14096,9 @@ static int DigField(struct PlayerInfo *player,
     if (element == EL_ROBOT_WHEEL)
     {
       Feld[x][y] = EL_ROBOT_WHEEL_ACTIVE;
-      ZX = x;
-      ZY = y;
 
+      game.robot_wheel_x = x;
+      game.robot_wheel_y = y;
       game.robot_wheel_active = TRUE;
 
       TEST_DrawLevelField(x, y);
@@ -14954,7 +14978,12 @@ void RequestQuitGameExt(boolean skip_request, boolean quick_quit, char *message)
   {
     // closing door required in case of envelope style request dialogs
     if (!skip_request)
+    {
+      // prevent short reactivation of overlay buttons while closing door
+      SetOverlayActive(FALSE);
+
       CloseDoor(DOOR_CLOSE_1);
+    }
 
     if (network.enabled)
       SendToServer_StopPlaying(NETWORK_STOP_BY_PLAYER);
@@ -15019,6 +15048,10 @@ void CheckGameOver(void)
   if (game.request_active)
     return;
 
+  // do not ask to play again if game was never actually played
+  if (!game.GamePlayed)
+    return;
+
   if (!game_over)
   {
     last_game_over = FALSE;
@@ -15241,9 +15274,6 @@ static ListNode *SaveEngineSnapshotBuffers(void)
   SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(game));
   SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(tape));
 
-  SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ZX));
-  SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(ZY));
-
   SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(FrameCounter));
   SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(TimeFrames));
   SaveSnapshotBuffer(&buffers, ARGS_ADDRESS_AND_SIZEOF(TimePlayed));