added using native game panel values for Boulder Dash game engine
[rocksndiamonds.git] / src / files.c
index ae0dbf7dc053f11ad0c966185bc2b0115227c2d7..269a749b4c079accd068fb0186b31f5b51b9c103 100644 (file)
@@ -3657,17 +3657,126 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
 static void CopyNativeLevel_RND_to_BD(struct LevelInfo *level)
 {
   struct LevelInfo_BD *level_bd = level->native_bd_level;
+  GdCave *cave = NULL; // will be changed below
+  int cave_w = MIN(level->fieldx, MAX_PLAYFIELD_WIDTH);
+  int cave_h = MIN(level->fieldy, MAX_PLAYFIELD_HEIGHT);
+  int i, x, y;
+
+  setLevelInfoToDefaults_BD_Ext(cave_w, cave_h);
+
+  // cave and map newly allocated when set to defaults above
+  cave = level_bd->cave;
+
+  for (i = 0; i < 5; i++)
+  {
+    cave->level_time[i]                        = level->time;
+    cave->level_diamonds[i]            = level->gems_needed;
+    cave->level_magic_wall_time[i]     = level->time_magic_wall;
+    cave->level_timevalue[i]           = level->score[SC_TIME_BONUS];
+  }
+
+  cave->diamond_value                  = level->score[SC_DIAMOND];
+  cave->extra_diamond_value            = level->score[SC_DIAMOND];
+
+  cave->level_speed[0]                 = 160;  // set cave speed
 
-  level_bd->width  = MIN(level->fieldx, MAX_PLAYFIELD_WIDTH);
-  level_bd->height = MIN(level->fieldy, MAX_PLAYFIELD_HEIGHT);
+  strncpy(cave->name, level->name, sizeof(GdString));
+  cave->name[sizeof(GdString) - 1] = '\0';
+
+  for (x = 0; x < cave->w; x++)
+    for (y = 0; y < cave->h; y++)
+      cave->map[y][x] = map_element_RND_to_BD(level->field[x][y]);
 }
 
 static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level)
 {
   struct LevelInfo_BD *level_bd = level->native_bd_level;
+  GdCave *cave = level_bd->cave;
+  int bd_level_nr = level_bd->level_nr;
+  int x, y;
+
+  level->fieldx = MIN(cave->w, MAX_LEV_FIELDX);
+  level->fieldy = MIN(cave->h, MAX_LEV_FIELDY);
+
+  level->time                  = cave->level_time[bd_level_nr];
+  level->gems_needed           = cave->level_diamonds[bd_level_nr];
+  level->time_magic_wall       = cave->level_magic_wall_time[bd_level_nr];
+
+  level->score[SC_TIME_BONUS]  = cave->level_timevalue[bd_level_nr];
+  level->score[SC_DIAMOND]     = cave->diamond_value;
+
+  strncpy(level->name, cave->name, MAX_LEVEL_NAME_LEN);
+  level->name[MAX_LEVEL_NAME_LEN] = '\0';
+
+  for (x = 0; x < level->fieldx; x++)
+    for (y = 0; y < level->fieldy; y++)
+      level->field[x][y] = map_element_BD_to_RND(cave->map[y][x]);
+}
+
+static void setTapeInfoToDefaults(void);
+
+static void CopyNativeTape_BD_to_RND(struct LevelInfo *level)
+{
+  struct LevelInfo_BD *level_bd = level->native_bd_level;
+  GdCave *cave = level_bd->cave;
+  GdReplay *replay = level_bd->replay;
+  int i;
+
+  if (replay == NULL)
+    return;
+
+  // always start with reliable default values
+  setTapeInfoToDefaults();
+
+  tape.level_nr = level_nr;            // (currently not used)
+  tape.random_seed = replay->seed;
+
+  TapeSetDateFromIsoDateString(replay->date);
+
+  tape.counter = 0;
+  tape.pos[tape.counter].delay = 0;
+
+  tape.bd_replay = TRUE;
+
+  // all time calculations only used to display approximate tape time
+  int cave_speed = cave->speed;
+  int milliseconds_game = 0;
+  int milliseconds_elapsed = 20;
+
+  for (i = 0; i < replay->movements->len; i++)
+  {
+    int replay_action = replay->movements->data[i];
+    int tape_action = map_action_BD_to_RND(replay_action);
+    byte action[MAX_TAPE_ACTIONS] = { tape_action };
+    boolean success = 0;
+
+    while (1)
+    {
+      success = TapeAddAction(action);
+
+      milliseconds_game += milliseconds_elapsed;
+
+      if (milliseconds_game >= cave_speed)
+      {
+       milliseconds_game -= cave_speed;
+
+       break;
+      }
+    }
+
+    tape.counter++;
+    tape.pos[tape.counter].delay = 0;
+    tape.pos[tape.counter].action[0] = 0;
+
+    if (!success)
+    {
+      Warn("BD replay truncated: size exceeds maximum tape size %d", MAX_TAPE_LEN);
+
+      break;
+    }
+  }
 
-  level->fieldx = MIN(level_bd->width,  MAX_LEV_FIELDX);
-  level->fieldy = MIN(level_bd->height, MAX_LEV_FIELDY);
+  TapeHaltRecording();
 }
 
 
@@ -4129,8 +4238,6 @@ static void CopyNativeTape_RND_to_SP(struct LevelInfo *level)
   demo->is_available = TRUE;
 }
 
-static void setTapeInfoToDefaults(void);
-
 static void CopyNativeTape_SP_to_RND(struct LevelInfo *level)
 {
   struct LevelInfo_SP *level_sp = level->native_sp_level;
@@ -8450,10 +8557,15 @@ void LoadSolutionTape(int nr)
 
   LoadTapeFromFilename(filename);
 
-  if (TAPE_IS_EMPTY(tape) &&
-      level.game_engine_type == GAME_ENGINE_TYPE_SP &&
-      level.native_sp_level->demo.is_available)
-    CopyNativeTape_SP_to_RND(&level);
+  if (TAPE_IS_EMPTY(tape))
+  {
+    if (level.game_engine_type == GAME_ENGINE_TYPE_BD &&
+       level.native_bd_level->replay != NULL)
+      CopyNativeTape_BD_to_RND(&level);
+    else if (level.game_engine_type == GAME_ENGINE_TYPE_SP &&
+       level.native_sp_level->demo.is_available)
+      CopyNativeTape_SP_to_RND(&level);
+  }
 }
 
 void LoadScoreTape(char *score_tape_basename, int nr)