added functions to get current player position for all game engines
[rocksndiamonds.git] / src / game.c
index 7f98027c8fd1eab482f50346680d6d6fc4ddebbc..3d2f055f27c88415dccb499d83d65932ad8a5f1e 100644 (file)
@@ -19,6 +19,7 @@
 #include "files.h"
 #include "tape.h"
 #include "network.h"
+#include "anim.h"
 
 
 /* DEBUG SETTINGS */
@@ -2446,7 +2447,7 @@ void DisplayGameControlValues()
   /* redraw game control buttons */
   RedrawGameButtons();
 
-  game_status = GAME_MODE_PSEUDO_PANEL;
+  SetGameStatus(GAME_MODE_PSEUDO_PANEL);
 
   for (i = 0; i < NUM_GAME_PANEL_CONTROLS; i++)
   {
@@ -2574,7 +2575,7 @@ void DisplayGameControlValues()
     redraw_mask |= REDRAW_DOOR_1;
   }
 
-  game_status = GAME_MODE_PLAYING;
+  SetGameStatus(GAME_MODE_PLAYING);
 }
 
 void UpdateAndDisplayGameControlValues()
@@ -3048,6 +3049,7 @@ static void InitGameEngine()
      SNAPSHOT_MODE_EVERY_MOVE :
      strEqual(setup.engine_snapshot_mode, STR_SNAPSHOT_MODE_EVERY_COLLECT) ?
      SNAPSHOT_MODE_EVERY_COLLECT : SNAPSHOT_MODE_OFF);
+  game.snapshot.save_snapshot = FALSE;
 }
 
 int get_num_special_action(int element, int action_first, int action_last)
@@ -3097,13 +3099,10 @@ void InitGame()
   // required here to update video display before fading (FIX THIS)
   DrawMaskedBorder(REDRAW_DOOR_2);
 
-  game_status = GAME_MODE_PLAYING;
-
   if (!game.restart_level)
     CloseDoor(DOOR_CLOSE_1);
 
-  /* needed if different viewport properties defined for playing */
-  ChangeViewportPropertiesIfNeeded();
+  SetGameStatus(GAME_MODE_PLAYING);
 
   if (level_editor_test_game)
     FadeSkipNextFadeIn();
@@ -3113,12 +3112,19 @@ void InitGame()
   if (CheckIfGlobalBorderHasChanged())
     fade_mask = REDRAW_ALL;
 
+  FadeSoundsAndMusic();
+
+  ExpireSoundLoops(TRUE);
+
   FadeOut(fade_mask);
 
-  OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW);
+  /* needed if different viewport properties defined for playing */
+  ChangeViewportPropertiesIfNeeded();
 
   ClearField();
 
+  OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW);
+
   DrawCompleteVideoDisplay();
 
   InitGameEngine();
@@ -3207,6 +3213,11 @@ void InitGame()
     player->is_bored = FALSE;
     player->is_sleeping = FALSE;
 
+    player->was_waiting = TRUE;
+    player->was_moving = FALSE;
+    player->was_snapping = FALSE;
+    player->was_dropping = FALSE;
+
     player->frame_counter_bored = -1;
     player->frame_counter_sleeping = -1;
 
@@ -4026,13 +4037,24 @@ void InitGame()
   SaveEngineSnapshotToListInitial();
 }
 
-void UpdateEngineValues(int actual_scroll_x, int actual_scroll_y)
+void UpdateEngineValues(int actual_scroll_x, int actual_scroll_y,
+                       int actual_player_x, int actual_player_y)
 {
   /* this is used for non-R'n'D game engines to update certain engine values */
 
+  if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+  {
+    actual_player_x = correctLevelPosX_EM(actual_player_x);
+    actual_player_y = correctLevelPosY_EM(actual_player_y);
+  }
+
   /* needed to determine if sounds are played within the visible screen area */
   scroll_x = actual_scroll_x;
   scroll_y = actual_scroll_y;
+
+  /* needed to get player position for "follow finger" playing input method */
+  local_player->jx = actual_player_x;
+  local_player->jy = actual_player_y;
 }
 
 void InitMovDir(int x, int y)
@@ -4422,7 +4444,7 @@ void GameEnd()
 
   if (level_editor_test_game)
   {
-    game_status = GAME_MODE_MAIN;
+    SetGameStatus(GAME_MODE_MAIN);
 
     DrawMainMenu();
 
@@ -4431,7 +4453,7 @@ void GameEnd()
 
   if (!local_player->LevelSolved_SaveScore)
   {
-    game_status = GAME_MODE_MAIN;
+    SetGameStatus(GAME_MODE_MAIN);
 
     DrawMainMenu();
 
@@ -4450,7 +4472,7 @@ void GameEnd()
 
   if ((hi_pos = NewHiScore()) >= 0) 
   {
-    game_status = GAME_MODE_SCORES;
+    SetGameStatus(GAME_MODE_SCORES);
 
     DrawHallOfFame(hi_pos);
 
@@ -4462,7 +4484,7 @@ void GameEnd()
   }
   else
   {
-    game_status = GAME_MODE_MAIN;
+    SetGameStatus(GAME_MODE_MAIN);
 
     if (raise_level)
     {
@@ -4890,6 +4912,7 @@ static void setScreenCenteredToAllPlayers(int *sx, int *sy)
 void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
                        boolean center_screen, boolean quick_relocation)
 {
+  unsigned int frame_delay_value_old = GetVideoFrameDelay();
   boolean ffwd_delay = (tape.playing && tape.fast_forward);
   boolean no_delay = (tape.warp_forward);
   int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
@@ -4957,6 +4980,8 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
 
   ScrollScreen(NULL, SCROLL_GO_ON);    /* scroll last frame to full tile */
 
+  SetVideoFrameDelay(wait_delay_value);
+
   while (scroll_x != new_scroll_x || scroll_y != new_scroll_y)
   {
     int dx = 0, dy = 0;
@@ -4979,16 +5004,15 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
 
     /* scroll in two steps of half tile size to make things smoother */
     BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
-    Delay(wait_delay_value);
 
     /* scroll second step to align at full tile size */
-    BackToFront();
-    Delay(wait_delay_value);
+    BlitScreenToBitmap(window);
   }
 
   DrawAllPlayers();
   BackToFront();
-  Delay(wait_delay_value);
+
+  SetVideoFrameDelay(frame_delay_value_old);
 }
 
 void RelocatePlayer(int jx, int jy, int el_player_raw)
@@ -5038,8 +5062,7 @@ void RelocatePlayer(int jx, int jy, int el_player_raw)
 
       DrawPlayer(player);
 
-      BackToFront();
-      Delay(wait_delay_value);
+      BackToFront_WithFrameDelay(wait_delay_value);
     }
 
     DrawPlayer(player);                /* needed here only to cleanup last field */
@@ -10682,32 +10705,28 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting)
 
 static void CheckSaveEngineSnapshot(struct PlayerInfo *player)
 {
-  static boolean player_was_moving = FALSE;
-  static boolean player_was_snapping = FALSE;
-  static boolean player_was_dropping = FALSE;
-
-  if ((!player->is_moving  && player_was_moving) ||
-      (player->MovPos == 0 && player_was_moving) ||
-      (player->is_snapping && !player_was_snapping) ||
-      (player->is_dropping && !player_was_dropping))
+  if ((!player->is_moving  && player->was_moving) ||
+      (player->MovPos == 0 && player->was_moving) ||
+      (player->is_snapping && !player->was_snapping) ||
+      (player->is_dropping && !player->was_dropping))
   {
-    if (!SaveEngineSnapshotToList())
+    if (!CheckSaveEngineSnapshotToList())
       return;
 
-    player_was_moving = FALSE;
-    player_was_snapping = TRUE;
-    player_was_dropping = TRUE;
+    player->was_moving = FALSE;
+    player->was_snapping = TRUE;
+    player->was_dropping = TRUE;
   }
   else
   {
     if (player->is_moving)
-      player_was_moving = TRUE;
+      player->was_moving = TRUE;
 
     if (!player->is_snapping)
-      player_was_snapping = FALSE;
+      player->was_snapping = FALSE;
 
     if (!player->is_dropping)
-      player_was_dropping = FALSE;
+      player->was_dropping = FALSE;
   }
 }
 
@@ -10952,9 +10971,11 @@ void StartGameActions(boolean init_network_game, boolean record_tape,
   InitGame();
 }
 
-void GameActions()
+void GameActionsExt()
 {
+#if 0
   static unsigned int game_frame_delay = 0;
+#endif
   unsigned int game_frame_delay_value;
   byte *recorded_player_action;
   byte summarized_player_action = 0;
@@ -11032,6 +11053,9 @@ void GameActions()
   if (tape.playing && tape.warp_forward && !tape.pausing)
     game_frame_delay_value = 0;
 
+  SetVideoFrameDelay(game_frame_delay_value);
+
+#if 0
 #if 0
   /* ---------- main game synchronization point ---------- */
 
@@ -11043,6 +11067,7 @@ void GameActions()
   /* ---------- main game synchronization point ---------- */
 
   WaitUntilDelayReached(&game_frame_delay, game_frame_delay_value);
+#endif
 #endif
 
   if (network_playing && !network_player_action_received)
@@ -11097,8 +11122,11 @@ void GameActions()
     SendToServer_MovePlayer(summarized_player_action);
 #endif
 
+  // summarize all actions at local players mapped input device position
+  // (this allows using different input devices in single player mode)
   if (!options.network && !game.team_mode)
-    local_player->effective_action = summarized_player_action;
+    stored_player[map_player_action[local_player->index_nr]].effective_action =
+      summarized_player_action;
 
   if (tape.recording &&
       setup.team_mode &&
@@ -11134,6 +11162,7 @@ void GameActions()
 #if USE_NEW_PLAYER_ASSIGNMENTS
   // !!! also map player actions in single player mode !!!
   // if (game.team_mode)
+  if (1)
   {
     byte mapped_action[MAX_PLAYERS];
 
@@ -11221,6 +11250,24 @@ void GameActions()
   }
 }
 
+static void GameActions_CheckSaveEngineSnapshot()
+{
+  if (!game.snapshot.save_snapshot)
+    return;
+
+  // clear flag for saving snapshot _before_ saving snapshot
+  game.snapshot.save_snapshot = FALSE;
+
+  SaveEngineSnapshotToList();
+}
+
+void GameActions()
+{
+  GameActionsExt();
+
+  GameActions_CheckSaveEngineSnapshot();
+}
+
 void GameActions_EM_Main()
 {
   byte effective_action[MAX_PLAYERS];
@@ -12051,7 +12098,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy)
       AdvanceFrameAndPlayerCounters(player->index_nr);
 
       DrawAllPlayers();
-      BackToFront();
+      BackToFront_WithFrameDelay(0);
     }
 
     player->move_delay_value = original_move_delay_value;
@@ -14466,7 +14513,7 @@ void RequestQuitGameExt(boolean skip_request, boolean quick_quit, char *message)
       if (quick_quit)
        FadeSkipNextFadeIn();
 
-      game_status = GAME_MODE_MAIN;
+      SetGameStatus(GAME_MODE_MAIN);
 
       DrawMainMenu();
     }
@@ -14753,11 +14800,10 @@ void SaveEngineSnapshotSingle()
   snapshot_level_nr = level_nr;
 }
 
-static boolean SaveEngineSnapshotToListExt(boolean initial_snapshot)
+boolean CheckSaveEngineSnapshotToList()
 {
   boolean save_snapshot =
-    (initial_snapshot ||
-     (game.snapshot.mode == SNAPSHOT_MODE_EVERY_STEP) ||
+    ((game.snapshot.mode == SNAPSHOT_MODE_EVERY_STEP) ||
      (game.snapshot.mode == SNAPSHOT_MODE_EVERY_MOVE &&
       game.snapshot.changed_action) ||
      (game.snapshot.mode == SNAPSHOT_MODE_EVERY_COLLECT &&
@@ -14765,30 +14811,28 @@ static boolean SaveEngineSnapshotToListExt(boolean initial_snapshot)
 
   game.snapshot.changed_action = FALSE;
   game.snapshot.collected_item = FALSE;
+  game.snapshot.save_snapshot = save_snapshot;
+
+  return save_snapshot;
+}
 
+void SaveEngineSnapshotToList()
+{
   if (game.snapshot.mode == SNAPSHOT_MODE_OFF ||
-      tape.quick_resume ||
-      !save_snapshot)
-    return FALSE;
+      tape.quick_resume)
+    return;
 
   ListNode *buffers = SaveEngineSnapshotBuffers();
 
   /* finally save all snapshot buffers to snapshot list */
   SaveSnapshotToList(buffers);
-
-  return TRUE;
-}
-
-boolean SaveEngineSnapshotToList()
-{
-  return SaveEngineSnapshotToListExt(FALSE);
 }
 
 void SaveEngineSnapshotToListInitial()
 {
   FreeEngineSnapshotList();
 
-  SaveEngineSnapshotToListExt(TRUE);
+  SaveEngineSnapshotToList();
 }
 
 void LoadEngineSnapshotValues()
@@ -14847,47 +14891,47 @@ static struct
 } gamebutton_info[NUM_GAME_BUTTONS] =
 {
   {
-    IMG_GAME_BUTTON_GFX_STOP,          &game.button.stop,
+    IMG_GFX_GAME_BUTTON_STOP,          &game.button.stop,
     GAME_CTRL_ID_STOP,                 "stop game"
   },
   {
-    IMG_GAME_BUTTON_GFX_PAUSE,         &game.button.pause,
+    IMG_GFX_GAME_BUTTON_PAUSE,         &game.button.pause,
     GAME_CTRL_ID_PAUSE,                        "pause game"
   },
   {
-    IMG_GAME_BUTTON_GFX_PLAY,          &game.button.play,
+    IMG_GFX_GAME_BUTTON_PLAY,          &game.button.play,
     GAME_CTRL_ID_PLAY,                 "play game"
   },
   {
-    IMG_GAME_BUTTON_GFX_UNDO,          &game.button.undo,
+    IMG_GFX_GAME_BUTTON_UNDO,          &game.button.undo,
     GAME_CTRL_ID_UNDO,                 "undo step"
   },
   {
-    IMG_GAME_BUTTON_GFX_REDO,          &game.button.redo,
+    IMG_GFX_GAME_BUTTON_REDO,          &game.button.redo,
     GAME_CTRL_ID_REDO,                 "redo step"
   },
   {
-    IMG_GAME_BUTTON_GFX_SAVE,          &game.button.save,
+    IMG_GFX_GAME_BUTTON_SAVE,          &game.button.save,
     GAME_CTRL_ID_SAVE,                 "save game"
   },
   {
-    IMG_GAME_BUTTON_GFX_PAUSE2,                &game.button.pause2,
+    IMG_GFX_GAME_BUTTON_PAUSE2,                &game.button.pause2,
     GAME_CTRL_ID_PAUSE2,               "pause game"
   },
   {
-    IMG_GAME_BUTTON_GFX_LOAD,          &game.button.load,
+    IMG_GFX_GAME_BUTTON_LOAD,          &game.button.load,
     GAME_CTRL_ID_LOAD,                 "load game"
   },
   {
-    IMG_GAME_BUTTON_GFX_SOUND_MUSIC,   &game.button.sound_music,
+    IMG_GFX_GAME_BUTTON_SOUND_MUSIC,   &game.button.sound_music,
     SOUND_CTRL_ID_MUSIC,               "background music on/off"
   },
   {
-    IMG_GAME_BUTTON_GFX_SOUND_LOOPS,   &game.button.sound_loops,
+    IMG_GFX_GAME_BUTTON_SOUND_LOOPS,   &game.button.sound_loops,
     SOUND_CTRL_ID_LOOPS,               "sound loops on/off"
   },
   {
-    IMG_GAME_BUTTON_GFX_SOUND_SIMPLE,  &game.button.sound_simple,
+    IMG_GFX_GAME_BUTTON_SOUND_SIMPLE,  &game.button.sound_simple,
     SOUND_CTRL_ID_SIMPLE,              "normal sounds on/off"
   }
 };
@@ -14982,7 +15026,7 @@ void FreeGameButtons()
     FreeGadget(game_gadget[i]);
 }
 
-static void MapGameButtonsAtSamePosition(int id)
+static void UnmapGameButtonsAtSamePosition(int id)
 {
   int i;
 
@@ -14990,10 +15034,26 @@ static void MapGameButtonsAtSamePosition(int id)
     if (i != id &&
        gamebutton_info[i].pos->x == gamebutton_info[id].pos->x &&
        gamebutton_info[i].pos->y == gamebutton_info[id].pos->y)
-      MapGadget(game_gadget[i]);
+      UnmapGadget(game_gadget[i]);
 }
 
-static void UnmapGameButtonsAtSamePosition(int id)
+static void UnmapGameButtonsAtSamePosition_All()
+{
+  if (setup.show_snapshot_buttons)
+  {
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_SAVE);
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PAUSE2);
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_LOAD);
+  }
+  else
+  {
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_STOP);
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PAUSE);
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PLAY);
+  }
+}
+
+static void MapGameButtonsAtSamePosition(int id)
 {
   int i;
 
@@ -15001,7 +15061,9 @@ static void UnmapGameButtonsAtSamePosition(int id)
     if (i != id &&
        gamebutton_info[i].pos->x == gamebutton_info[id].pos->x &&
        gamebutton_info[i].pos->y == gamebutton_info[id].pos->y)
-      UnmapGadget(game_gadget[i]);
+      MapGadget(game_gadget[i]);
+
+  UnmapGameButtonsAtSamePosition_All();
 }
 
 void MapUndoRedoButtons()
@@ -15011,6 +15073,8 @@ void MapUndoRedoButtons()
 
   MapGadget(game_gadget[GAME_CTRL_ID_UNDO]);
   MapGadget(game_gadget[GAME_CTRL_ID_REDO]);
+
+  ModifyGadget(game_gadget[GAME_CTRL_ID_PAUSE2], GDI_CHECKED, TRUE, GDI_END);
 }
 
 void UnmapUndoRedoButtons()
@@ -15020,6 +15084,8 @@ void UnmapUndoRedoButtons()
 
   MapGameButtonsAtSamePosition(GAME_CTRL_ID_UNDO);
   MapGameButtonsAtSamePosition(GAME_CTRL_ID_REDO);
+
+  ModifyGadget(game_gadget[GAME_CTRL_ID_PAUSE2], GDI_CHECKED, FALSE, GDI_END);
 }
 
 void MapGameButtons()
@@ -15031,18 +15097,7 @@ void MapGameButtons()
        i != GAME_CTRL_ID_REDO)
       MapGadget(game_gadget[i]);
 
-  if (setup.show_snapshot_buttons)
-  {
-    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_SAVE);
-    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PAUSE2);
-    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_LOAD);
-  }
-  else
-  {
-    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_STOP);
-    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PAUSE);
-    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PLAY);
-  }
+  UnmapGameButtonsAtSamePosition_All();
 
   RedrawGameButtons();
 }
@@ -15078,8 +15133,7 @@ void GameUndoRedoExt()
   DrawCompleteVideoDisplay();
   DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
   DrawVideoDisplay(VIDEO_STATE_FRAME_ON, FrameCounter);
-  DrawVideoDisplay((tape.single_step ? VIDEO_STATE_1STEP_ON :
-                   VIDEO_STATE_1STEP_OFF), 0);
+  DrawVideoDisplay(VIDEO_STATE_1STEP(tape.single_step), 0);
 
   BackToFront();
 }
@@ -15158,7 +15212,7 @@ static void HandleGameButtonsExt(int id, int button)
          SendToServer_ContinuePlaying();
        else
 #endif
-         TapeTogglePause(TAPE_TOGGLE_MANUAL);
+         TapeTogglePause(TAPE_TOGGLE_MANUAL | TAPE_TOGGLE_PLAY_PAUSE);
       }
       break;