rnd-20021227-2-src
[rocksndiamonds.git] / src / tape.c
index 3c39d5abc17c3c9e99ea3726d22c666ac004cc00..e9f3cbbcde34908bfcc3661ba0be3ae6eb32c22e 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Rocks'n'Diamonds -- McDuffin Strikes Back!               *
 *----------------------------------------------------------*
-* (c) 1995-2001 Artsoft Entertainment                      *
+* (c) 1995-2002 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
@@ -14,6 +14,7 @@
 #include "libgame/libgame.h"
 
 #include "tape.h"
+#include "init.h"
 #include "game.h"
 #include "tools.h"
 #include "files.h"
@@ -167,7 +168,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value)
   {
     int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2;
 
-    BlitBitmap(pix[PIX_DOOR], drawto,
+    BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
               cx + VIDEO_REC_LABEL_XPOS,
               cy + VIDEO_REC_LABEL_YPOS,
               VIDEO_PBEND_LABEL_XSIZE,
@@ -188,7 +189,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value)
        cx = DOOR_GFX_PAGEX3;   /* i gerade => STATE_OFF / PRESS_ON */
 
       if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY)
-       BlitBitmap(pix[PIX_DOOR], drawto,
+       BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
                   cx + video_pos[pos][part_label][xpos],
                   cy + video_pos[pos][part_label][ypos],
                   video_pos[pos][part_label][xsize],
@@ -196,7 +197,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value)
                   VX + video_pos[pos][part_label][xpos],
                   VY + video_pos[pos][part_label][ypos]);
       if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY)
-       BlitBitmap(pix[PIX_DOOR], drawto,
+       BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
                   cx + video_pos[pos][part_symbol][xpos],
                   cy + video_pos[pos][part_symbol][ypos],
                   video_pos[pos][part_symbol][xsize],
@@ -210,7 +211,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value)
   {
     int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2;
 
-    BlitBitmap(pix[PIX_DOOR], drawto,
+    BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
               cx + VIDEO_PLAY_SYMBOL_XPOS,
               cy + VIDEO_PLAY_SYMBOL_YPOS,
               VIDEO_PLAY_SYMBOL_XSIZE - 2,
@@ -223,7 +224,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value)
   {
     int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
 
-    BlitBitmap(pix[PIX_DOOR], drawto,
+    BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
               cx + VIDEO_PBEND_LABEL_XPOS,
               cy + VIDEO_PBEND_LABEL_YPOS,
               VIDEO_PBEND_LABEL_XSIZE,
@@ -267,9 +268,10 @@ void DrawVideoDisplay(unsigned long state, unsigned long value)
 
 void DrawCompleteVideoDisplay()
 {
-  BlitBitmap(pix[PIX_DOOR], drawto, DOOR_GFX_PAGEX3, DOOR_GFX_PAGEY2,
+  BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
+            DOOR_GFX_PAGEX3, DOOR_GFX_PAGEY2,
             gfx.vxsize, gfx.vysize, gfx.vx, gfx.vy);
-  BlitBitmap(pix[PIX_DOOR], drawto,
+  BlitBitmap(new_graphic_info[IMG_MENU_DOOR].bitmap, drawto,
             DOOR_GFX_PAGEX4 + VIDEO_CONTROL_XPOS,
             DOOR_GFX_PAGEY2 + VIDEO_CONTROL_YPOS,
             VIDEO_CONTROL_XSIZE, VIDEO_CONTROL_YSIZE,
@@ -282,7 +284,7 @@ void DrawCompleteVideoDisplay()
     DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
   }
 
-  BlitBitmap(drawto, pix[PIX_DB_DOOR], gfx.vx, gfx.vy, gfx.vxsize, gfx.vysize,
+  BlitBitmap(drawto, bitmap_db_door, gfx.vx, gfx.vy, gfx.vxsize, gfx.vysize,
             DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
 }
 
@@ -303,10 +305,14 @@ void TapeErase()
   tape.level_nr = level_nr;
   tape.pos[tape.counter].delay = 0;
   tape.changed = TRUE;
+
   tape.date = 10000*(time->tm_year % 100) + 100*time->tm_mon + time->tm_mday;
-  tape.game_version = GAME_VERSION_ACTUAL;
   tape.random_seed = InitRND(NEW_RANDOMIZE);
 
+  tape.file_version = FILE_VERSION_ACTUAL;
+  tape.game_version = GAME_VERSION_ACTUAL;
+  tape.engine_version = level.game_version;
+
   for(i=0; i<MAX_PLAYERS; i++)
     tape.player_participates[i] = FALSE;
 }
@@ -320,6 +326,8 @@ static void TapeRewind()
   tape.playing = FALSE;
   tape.fast_forward = FALSE;
   tape.index_search = FALSE;
+  tape.auto_play = (global.autoplay_leveldir != NULL);
+  tape.auto_play_level_solved = FALSE;
   tape.quick_resume = FALSE;
   tape.single_step = FALSE;
 
@@ -366,16 +374,10 @@ static void TapeAppendRecording()
   if (!tape.playing || !tape.pausing)
     return;
 
-  if (tape.game_version != GAME_VERSION_ACTUAL &&
-      !Request("This may break old version tape ! Append anyway ?",
-              REQ_ASK))
-    return;
-
   tape.pos[tape.counter].delay = tape.delay_played;
   tape.playing = FALSE;
   tape.recording = TRUE;
   tape.changed = TRUE;
-  tape.game_version = GAME_VERSION_ACTUAL;
 
   DrawVideoDisplay(VIDEO_STATE_PLAY_OFF | VIDEO_STATE_REC_ON,0);
 }
@@ -553,7 +555,7 @@ byte *TapePlayAction()
 
   if (tape.counter >= tape.length)     /* end of tape reached */
   {
-    if (tape.index_search)
+    if (tape.index_search && !tape.auto_play)
       TapeTogglePause(TAPE_TOGGLE_MANUAL);
     else
       TapeStop();
@@ -585,6 +587,9 @@ void TapeStop()
     DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
     DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
   }
+
+  if (tape.auto_play)
+    AutoPlayTape();    /* continue automatically playing next tape */
 }
 
 unsigned int GetTapeLength()
@@ -609,7 +614,7 @@ static void TapeStartIndexSearch()
   {
     tape.pausing = FALSE;
 
-    SetDrawDeactivationMask(REDRAW_FIELD | REDRAW_DOOR_1);
+    SetDrawDeactivationMask(REDRAW_FIELD);
     audio.sound_deactivated = TRUE;
   }
 }
@@ -673,6 +678,105 @@ void TapeQuickLoad()
 }
 
 
+/* ------------------------------------------------------------------------- *
+ * tape autoplay functions
+ * ------------------------------------------------------------------------- */
+
+void AutoPlayTape()
+{
+  static LevelDirTree *autoplay_leveldir = NULL;
+  static boolean autoplay_initialized = FALSE;
+  static int autoplay_level_nr = -1;
+  static int levels_played = 0;
+  static int levels_solved = 0;
+
+  if (autoplay_initialized)
+  {
+    /* just finished auto-playing tape */
+    printf("%s.\n", tape.auto_play_level_solved ? "solved" : "NOT SOLVED");
+
+    levels_played++;
+    if (tape.auto_play_level_solved)
+      levels_solved++;
+  }
+  else
+  {
+    DrawCompleteVideoDisplay();
+    audio.sound_enabled = FALSE;
+
+    autoplay_leveldir = getTreeInfoFromIdentifier(leveldir_first,
+                                                 global.autoplay_leveldir);
+
+    if (autoplay_leveldir == NULL)
+      Error(ERR_EXIT, "no such level identifier: '%s'",
+           global.autoplay_leveldir);
+
+    leveldir_current = autoplay_leveldir;
+
+    if (global.autoplay_level_nr != -1)
+    {
+      autoplay_leveldir->first_level = global.autoplay_level_nr;
+      autoplay_leveldir->last_level  = global.autoplay_level_nr;
+    }
+
+    autoplay_level_nr = autoplay_leveldir->first_level;
+
+    printf_line('=', 79);
+    printf("Automatically playing level tapes\n");
+    printf_line('-', 79);
+    printf("Level series identifier: '%s'\n", autoplay_leveldir->identifier);
+    printf("Level series name:       '%s'\n", autoplay_leveldir->name);
+    printf("Level series author:     '%s'\n", autoplay_leveldir->author);
+    printf("Number of levels:        %d\n",   autoplay_leveldir->levels);
+    printf_line('=', 79);
+    printf("\n");
+
+    autoplay_initialized = TRUE;
+  }
+
+  while (autoplay_level_nr <= autoplay_leveldir->last_level)
+  {
+    level_nr = autoplay_level_nr++;
+
+    TapeErase();
+
+    printf("Level %03d: ", level_nr);
+
+    LoadLevel(level_nr);
+    if (level.no_level_file)
+    {
+      printf("(no level)\n");
+      continue;
+    }
+
+    LoadTape(level_nr);
+    if (TAPE_IS_EMPTY(tape))
+    {
+      printf("(no tape)\n");
+      continue;
+    }
+
+    printf("playing tape ... ");
+
+    TapeStartGamePlaying();
+    TapeStartIndexSearch();
+
+    return;
+  }
+
+  printf("\n");
+  printf_line('=', 79);
+  printf("Summary\n");
+  printf_line('-', 79);
+  printf("Number of levels played: %d\n", levels_played);
+  printf("Number of levels solved: %d (%d%%)\n", levels_solved,
+        levels_solved * 100 / levels_played);
+  printf_line('=', 79);
+
+  CloseAllAndExit(0);
+}
+
+
 /* ---------- new tape button stuff ---------------------------------------- */
 
 /* graphic position values for tape buttons */
@@ -733,7 +837,7 @@ void CreateTapeButtons()
 
   for (i=0; i<NUM_TAPE_BUTTONS; i++)
   {
-    Bitmap *gd_bitmap = pix[PIX_DOOR];
+    Bitmap *gd_bitmap = new_graphic_info[IMG_MENU_DOOR].bitmap;
     struct GadgetInfo *gi;
     int gd_xoffset, gd_yoffset;
     int gd_x1, gd_x2, gd_y;
@@ -772,6 +876,14 @@ void CreateTapeButtons()
   }
 }
 
+void FreeTapeButtons()
+{
+  int i;
+
+  for (i=0; i<NUM_TAPE_BUTTONS; i++)
+    FreeGadget(tape_gadget[i]);
+}
+
 void MapTapeEjectButton()
 {
   UnmapGadget(tape_gadget[TAPE_CTRL_ID_INDEX]);