rnd-20100309-1-src
[rocksndiamonds.git] / src / tape.c
index e8fb1b7e4d86410763c02faa029bb28a912b935d..88f0f5a0300e4e0799ff9abf40cda0e138d3fd51 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Rocks'n'Diamonds -- McDuffin Strikes Back!               *
 *----------------------------------------------------------*
-* (c) 1995-2002 Artsoft Entertainment                      *
+* (c) 1995-2006 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
@@ -453,12 +453,16 @@ void TapeDeactivateDisplayOff(boolean redraw_display)
 /* tape control functions                                                    */
 /* ========================================================================= */
 
-static void TapeSetDate()
+void TapeSetDateFromEpochSeconds(time_t epoch_seconds)
 {
-  time_t epoch_seconds = time(NULL);
-  struct tm *now = localtime(&epoch_seconds);
+  struct tm *lt = localtime(&epoch_seconds);
 
-  tape.date = 10000 * (now->tm_year % 100) + 100 * now->tm_mon + now->tm_mday;
+  tape.date = 10000 * (lt->tm_year % 100) + 100 * lt->tm_mon + lt->tm_mday;
+}
+
+void TapeSetDateFromNow()
+{
+  TapeSetDateFromEpochSeconds(time(NULL));
 }
 
 void TapeErase()
@@ -475,16 +479,19 @@ void TapeErase()
   tape.pos[tape.counter].delay = 0;
   tape.changed = TRUE;
 
-  tape.random_seed = InitRND(NEW_RANDOMIZE);
+  tape.random_seed = InitRND(level.random_seed);
 
   tape.file_version = FILE_VERSION_ACTUAL;
   tape.game_version = GAME_VERSION_ACTUAL;
   tape.engine_version = level.game_version;
 
-  TapeSetDate();
+  TapeSetDateFromNow();
 
   for (i = 0; i < MAX_PLAYERS; i++)
     tape.player_participates[i] = FALSE;
+
+  tape.centered_player_nr_next = -1;
+  tape.set_centered_player = FALSE;
 }
 
 static void TapeRewind()
@@ -502,6 +509,9 @@ static void TapeRewind()
   tape.quick_resume = FALSE;
   tape.single_step = FALSE;
 
+  tape.centered_player_nr_next = -1;
+  tape.set_centered_player = FALSE;
+
   InitRND(tape.random_seed);
 }
 
@@ -532,18 +542,18 @@ void TapeStartRecording(long random_seed)
 
 static void TapeStartGameRecording()
 {
-  TapeStartRecording(NEW_RANDOMIZE);
+  TapeStartRecording(level.random_seed);
 
 #if defined(NETWORK_AVALIABLE)
   if (options.network)
-    SendToServer_StartPlaying();
-  else
-#endif
   {
-    game_status = GAME_MODE_PLAYING;
-    StopAnimation();
-    InitGame();
+    SendToServer_StartPlaying();
+
+    return;
   }
+#endif
+
+  InitGame();
 }
 
 static void TapeAppendRecording()
@@ -556,10 +566,14 @@ static void TapeAppendRecording()
   tape.recording = TRUE;
   tape.changed = TRUE;
 
-  TapeSetDate();
+  TapeSetDateFromNow();
 
   DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
   DrawVideoDisplay(VIDEO_STATE_PLAY_OFF | VIDEO_STATE_REC_ON, 0);
+
+#if 1
+  UpdateAndDisplayGameControlValues();
+#endif
 }
 
 void TapeHaltRecording()
@@ -585,8 +599,9 @@ void TapeStopRecording()
   MapTapeEjectButton();
 }
 
-void TapeRecordAction(byte action[MAX_PLAYERS])
+void TapeRecordAction(byte action_raw[MAX_PLAYERS])
 {
+  byte action[MAX_PLAYERS];
   int i;
 
   if (!tape.recording)         /* (record action even when tape is paused) */
@@ -598,6 +613,19 @@ void TapeRecordAction(byte action[MAX_PLAYERS])
     return;
   }
 
+  for (i = 0; i < MAX_PLAYERS; i++)
+    action[i] = action_raw[i];
+
+  if (tape.set_centered_player)
+  {
+    for (i = 0; i < MAX_PLAYERS; i++)
+      if (tape.centered_player_nr_next == i ||
+         tape.centered_player_nr_next == -1)
+       action[i] |= KEY_SET_FOCUS;
+
+    tape.set_centered_player = FALSE;
+  }
+
   if (tape.pos[tape.counter].delay > 0)                /* already stored action */
   {
     boolean changed_events = FALSE;
@@ -657,6 +685,9 @@ void TapeTogglePause(boolean toggle_manual)
       tape.quick_resume = FALSE;
 
       TapeAppendRecording();
+
+      if (!CheckEngineSnapshot())
+       SaveEngineSnapshot();
     }
   }
 }
@@ -686,8 +717,6 @@ static void TapeStartGamePlaying()
 {
   TapeStartPlaying();
 
-  game_status = GAME_MODE_PLAYING;
-  StopAnimation();
   InitGame();
 }
 
@@ -778,6 +807,21 @@ byte *TapePlayAction()
   for (i = 0; i < MAX_PLAYERS; i++)
     action[i] = tape.pos[tape.counter].action[i];
 
+  tape.set_centered_player = FALSE;
+  tape.centered_player_nr_next = -999;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (action[i] & KEY_SET_FOCUS)
+    {
+      tape.set_centered_player = TRUE;
+      tape.centered_player_nr_next =
+       (tape.centered_player_nr_next == -999 ? i : -1);
+    }
+
+    action[i] &= ~KEY_SET_FOCUS;
+  }
+
   tape.delay_played++;
   if (tape.delay_played >= tape.pos[tape.counter].delay)
   {
@@ -800,11 +844,6 @@ void TapeStop()
     DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
     DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
   }
-
-#if 0
-  if (tape.auto_play)
-    AutoPlayTape();    /* continue automatically playing next tape */
-#endif
 }
 
 unsigned int GetTapeLength()
@@ -874,18 +913,28 @@ static void TapeSingleStep()
 
 void TapeQuickSave()
 {
-  if (game_status == GAME_MODE_PLAYING)
+  if (game_status == GAME_MODE_MAIN)
   {
-    if (tape.recording)
-      TapeHaltRecording();     /* prepare tape for saving on-the-fly */
+    Request("No game that can be saved !", REQ_CONFIRM);
 
-    if (TAPE_IS_EMPTY(tape))
-      Request("No tape that can be saved !", REQ_CONFIRM);
-    else
-      SaveTape(tape.level_nr);
+    return;
   }
-  else if (game_status == GAME_MODE_MAIN)
-    Request("No game that can be saved !", REQ_CONFIRM);
+
+  if (game_status != GAME_MODE_PLAYING)
+    return;
+
+  if (tape.recording)
+    TapeHaltRecording();       /* prepare tape for saving on-the-fly */
+
+  if (TAPE_IS_EMPTY(tape))
+  {
+    Request("No tape that can be saved !", REQ_CONFIRM);
+
+    return;
+  }
+
+  if (SaveTapeChecked(tape.level_nr))
+    SaveEngineSnapshot();
 }
 
 void TapeQuickLoad()
@@ -907,25 +956,44 @@ void TapeQuickLoad()
     return;
   }
 
-  if (game_status == GAME_MODE_PLAYING || game_status == GAME_MODE_MAIN)
+  if (game_status != GAME_MODE_PLAYING && game_status != GAME_MODE_MAIN)
+    return;
+
+  if (CheckEngineSnapshot())
   {
-    TapeStop();
-    TapeErase();
+    TapeStartGamePlaying();
 
-    LoadTape(level_nr);
-    if (!TAPE_IS_EMPTY(tape))
-    {
-      TapeStartGamePlaying();
-      TapeStartWarpForward();
+    LoadEngineSnapshot();
 
-      tape.quick_resume = TRUE;
-    }
-    else       /* this should not happen (basically checked above) */
-    {
-      int reopen_door = (game_status == GAME_MODE_PLAYING ? REQ_REOPEN : 0);
+    DrawCompleteVideoDisplay();
 
-      Request("No tape for this level !", REQ_CONFIRM | reopen_door);
-    }
+    tape.playing = TRUE;
+    tape.pausing = TRUE;
+
+    TapeStopWarpForward();
+    TapeAppendRecording();
+
+    if (FrameCounter > 0)
+      return;
+  }
+
+  TapeStop();
+  TapeErase();
+
+  LoadTape(level_nr);
+
+  if (!TAPE_IS_EMPTY(tape))
+  {
+    TapeStartGamePlaying();
+    TapeStartWarpForward();
+
+    tape.quick_resume = TRUE;
+  }
+  else /* this should not happen (basically checked above) */
+  {
+    int reopen_door = (game_status == GAME_MODE_PLAYING ? REQ_REOPEN : 0);
+
+    Request("No tape for this level !", REQ_CONFIRM | reopen_door);
   }
 }
 
@@ -1179,6 +1247,7 @@ void CreateTapeButtons()
                      GDI_STATE, GD_BUTTON_UNPRESSED,
                      GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
                      GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+                     GDI_DIRECT_DRAW, FALSE,
                      GDI_EVENT_MASK, GD_EVENT_RELEASED,
                      GDI_CALLBACK_ACTION, HandleTapeButtons,
                      GDI_END);
@@ -1241,18 +1310,22 @@ static void HandleTapeButtons(struct GadgetInfo *gi)
   {
     case TAPE_CTRL_ID_EJECT:
       TapeStop();
+
       if (TAPE_IS_EMPTY(tape))
       {
        LoadTape(level_nr);
+
        if (TAPE_IS_EMPTY(tape))
          Request("No tape for this level !", REQ_CONFIRM);
       }
       else
       {
        if (tape.changed)
-         SaveTape(tape.level_nr);
+         SaveTapeChecked(tape.level_nr);
+
        TapeErase();
       }
+
       DrawCompleteVideoDisplay();
       break;
 
@@ -1270,6 +1343,7 @@ static void HandleTapeButtons(struct GadgetInfo *gi)
       }
       else if (tape.recording)
        TapeSingleStep();
+
       break;
 
     case TAPE_CTRL_ID_STOP: