rnd-20140307-1-src
[rocksndiamonds.git] / src / game.c
index 2a88b9a805f5de15d3e2ac015f8c89ad661048ee..11a6fed866271b03c2f5ff544ec29cd68827848c 100644 (file)
@@ -1014,8 +1014,10 @@ static struct GamePanelControlInfo game_panel_controls[] =
 #define SOUND_CTRL_ID_MUSIC            3
 #define SOUND_CTRL_ID_LOOPS            4
 #define SOUND_CTRL_ID_SIMPLE           5
+#define GAME_CTRL_ID_SAVE              6
+#define GAME_CTRL_ID_LOAD              7
 
-#define NUM_GAME_BUTTONS               6
+#define NUM_GAME_BUTTONS               8
 
 
 /* forward declaration for internal use */
@@ -1082,7 +1084,6 @@ static void PlayLevelSoundActionIfLoop(int, int, int);
 static void StopLevelSoundActionIfLoop(int, int, int);
 static void PlayLevelMusic();
 
-static void MapGameButtons();
 static void HandleGameButtons(struct GadgetInfo *);
 
 int AmoebeNachbarNr(int, int);
@@ -1142,8 +1143,6 @@ static boolean recursion_loop_element;
 
 static int map_player_action[MAX_PLAYERS];
 
-static boolean TEST_game_team_mode;
-
 
 /* ------------------------------------------------------------------------- */
 /* definition of elements that automatically change to other elements after  */
@@ -3032,6 +3031,21 @@ static void InitGameEngine()
   game.engine_version = (tape.playing ? tape.engine_version :
                         level.game_version);
 
+  /* set single or multi-player game mode (needed for re-playing tapes) */
+  game.team_mode = setup.team_mode;
+
+  if (tape.playing)
+  {
+    int num_players = 0;
+
+    for (i = 0; i < MAX_PLAYERS; i++)
+      if (tape.player_participates[i])
+       num_players++;
+
+    /* multi-player tapes contain input data for more than one player */
+    game.team_mode = (num_players > 1);
+  }
+
   /* ---------------------------------------------------------------------- */
   /* set flags for bugs and changes according to active game engine version */
   /* ---------------------------------------------------------------------- */
@@ -3902,23 +3916,12 @@ void InitGame()
   local_player->connected = TRUE;
   /* !!! SAME AS init.c:InitPlayerInfo() -- FIX THIS !!! */
 
-  TEST_game_team_mode = setup.team_mode;
+#if 0
+  printf("::: TEAM MODE: %d\n", game.team_mode);
+#endif
 
   if (tape.playing)
   {
-#if 1
-    int num_players = 0;
-
-    for (i = 0; i < MAX_PLAYERS; i++)
-      if (tape.player_participates[i])
-       num_players++;
-
-    TEST_game_team_mode = (num_players > 1);
-
-    printf("::: TAPE TEAM MODE: %s (%d)\n",
-          (TEST_game_team_mode ? "true" : "false"), num_players);
-#endif
-
 #if 1
     for (i = 0; i < MAX_PLAYERS; i++)
       stored_player[i].connected = tape.player_participates[i];
@@ -3931,7 +3934,7 @@ void InitGame()
        stored_player[i].connected = TRUE;
 #endif
   }
-  else if (setup.team_mode && !options.network)
+  else if (game.team_mode && !options.network)
   {
     /* try to guess locally connected team mode players (needed for correct
        assignment of player figures from level to locally playing players) */
@@ -4140,8 +4143,7 @@ void InitGame()
 #if USE_NEW_PLAYER_ASSIGNMENTS
 
 #if 1
-    // if (!setup.team_mode)
-    if (!TEST_game_team_mode)
+    if (!game.team_mode)
 #endif
 
     for (i = 0; i < MAX_PLAYERS; i++)
@@ -4162,7 +4164,9 @@ void InitGame()
        Feld[jx][jy] = EL_EMPTY;
       }
     }
+
 #else
+
     for (i = 0; i < MAX_PLAYERS; i++)
     {
       if (stored_player[i].active &&
@@ -4178,7 +4182,7 @@ void InitGame()
     }
 #endif
   }
-  else if (!options.network && !setup.team_mode)       /* && !tape.playing */
+  else if (!options.network && !game.team_mode)                /* && !tape.playing */
   {
     /* when in single player mode, eliminate all but the first active player */
 
@@ -4513,8 +4517,12 @@ void InitGame()
     MapTapeButtons();
 
     /* copy actual game door content to door double buffer for OpenDoor() */
+#if 1
+    BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0);
+#else
     BlitBitmap(drawto, bitmap_db_door,
               DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+#endif
 
     OpenDoor(DOOR_OPEN_ALL);
 
@@ -12375,7 +12383,7 @@ void GameActions()
     summarized_player_action |= stored_player[i].action;
 
 #if 1
-    if (!network_playing && (setup.team_mode || tape.playing))
+    if (!network_playing && (game.team_mode || tape.playing))
       stored_player[i].effective_action = stored_player[i].action;
 #else
     if (!network_playing)
@@ -12388,10 +12396,13 @@ void GameActions()
     SendToServer_MovePlayer(summarized_player_action);
 #endif
 
-  if (!options.network && !setup.team_mode)
+  if (!options.network && !game.team_mode)
     local_player->effective_action = summarized_player_action;
 
-  if (setup.team_mode && setup.input_on_focus && game.centered_player_nr != -1)
+  if (tape.recording &&
+      setup.team_mode &&
+      setup.input_on_focus &&
+      game.centered_player_nr != -1)
   {
     for (i = 0; i < MAX_PLAYERS; i++)
       stored_player[i].effective_action =
@@ -12407,12 +12418,13 @@ void GameActions()
     tape_action[i] = stored_player[i].effective_action;
 
 #if 1
-    /* (this can only happen in the R'n'D game engine) */
-    if (setup.team_mode &&
-       tape.recording &&
+    /* (this may happen in the RND game engine if a player was not present on
+       the playfield on level start, but appeared later from a custom element */
+    if (tape.recording &&
+       setup.team_mode &&
        tape_action[i] &&
        !tape.player_participates[i])
-      tape.player_participates[i] = TRUE;    /* player just appeared from CE */
+      tape.player_participates[i] = TRUE;
 #else
     /* (this can only happen in the R'n'D game engine) */
     if (tape.recording && tape_action[i] && !tape.player_participates[i])
@@ -12426,8 +12438,7 @@ void GameActions()
 
 #if USE_NEW_PLAYER_ASSIGNMENTS
 #if 1
-  // if (setup.team_mode)
-  if (TEST_game_team_mode)
+  if (game.team_mode)
 #endif
   {
     byte mapped_action[MAX_PLAYERS];
@@ -12462,11 +12473,6 @@ void GameActions()
 #endif
 #endif
 
-#if 0
-  if (!options.network && !setup.team_mode)
-    local_player->effective_action = summarized_player_action;
-#endif
-
 #if 0
   printf("::: summarized_player_action == %d\n",
         local_player->effective_action);
@@ -16802,6 +16808,14 @@ static struct
   {
     IMG_GAME_BUTTON_GFX_SOUND_SIMPLE,  &game.button.sound_simple,
     SOUND_CTRL_ID_SIMPLE,              "normal sounds on/off"
+  },
+  {
+    IMG_GAME_BUTTON_GFX_SAVE,          &game.button.save,
+    GAME_CTRL_ID_SAVE,                 "save game"
+  },
+  {
+    IMG_GAME_BUTTON_GFX_LOAD,          &game.button.load,
+    GAME_CTRL_ID_LOAD,                 "load game"
   }
 };
 
@@ -16827,9 +16841,18 @@ void CreateGameButtons()
     int gd_yap = gfx->src_y + gfx->active_yoffset + gfx->pressed_yoffset;
     int id = i;
 
+    if (gfx->bitmap == NULL)
+    {
+      game_gadget[id] = NULL;
+
+      continue;
+    }
+
     if (id == GAME_CTRL_ID_STOP ||
        id == GAME_CTRL_ID_PAUSE ||
-       id == GAME_CTRL_ID_PLAY)
+       id == GAME_CTRL_ID_PLAY ||
+       id == GAME_CTRL_ID_SAVE ||
+       id == GAME_CTRL_ID_LOAD)
     {
       button_type = GD_TYPE_NORMAL_BUTTON;
       checked = FALSE;
@@ -16847,8 +16870,8 @@ void CreateGameButtons()
 
     gi = CreateGadget(GDI_CUSTOM_ID, id,
                      GDI_INFO_TEXT, gamebutton_info[i].infotext,
-                     GDI_X, DX + pos->x,
-                     GDI_Y, DY + pos->y,
+                     GDI_X, DX + GDI_ACTIVE_POS(pos->x),
+                     GDI_Y, DY + GDI_ACTIVE_POS(pos->y),
                      GDI_WIDTH, gfx->width,
                      GDI_HEIGHT, gfx->height,
                      GDI_TYPE, button_type,
@@ -16878,7 +16901,7 @@ void FreeGameButtons()
     FreeGadget(game_gadget[i]);
 }
 
-static void MapGameButtons()
+void MapGameButtons()
 {
   int i;
 
@@ -16984,6 +17007,14 @@ static void HandleGameButtonsExt(int id)
       }
       break;
 
+    case GAME_CTRL_ID_SAVE:
+      TapeQuickSave();
+      break;
+
+    case GAME_CTRL_ID_LOAD:
+      TapeQuickLoad();
+      break;
+
     default:
       break;
   }