added code to load native Boulder Dash levels
authorHolger Schemel <info@artsoft.org>
Sun, 11 Feb 2024 12:28:21 +0000 (13:28 +0100)
committerHolger Schemel <info@artsoft.org>
Sun, 18 Feb 2024 14:57:42 +0000 (15:57 +0100)
src/editor.c
src/files.c
src/game_bd/export_bd.h
src/game_bd/main_bd.c

index 3bed979da4aaff0c642f24bc6e27b1e6883048cf..8fa52676a277cb5aec9b7700206a81081e1fb78d 100644 (file)
@@ -1794,6 +1794,7 @@ static struct ValueTextInfo options_time_score_base[] =
 static struct ValueTextInfo options_game_engine_type[] =
 {
   { GAME_ENGINE_TYPE_RND,      "Rocks'n'Diamonds"              },
+  { GAME_ENGINE_TYPE_BD,       "Boulder Dash"                  },
   { GAME_ENGINE_TYPE_EM,       "Emerald Mine"                  },
   { GAME_ENGINE_TYPE_SP,       "Supaplex"                      },
   { GAME_ENGINE_TYPE_MM,       "Mirror Magic"                  },
index 269a749b4c079accd068fb0186b31f5b51b9c103..b3ef9a7e8fa58dd37a302b626de6da299ec29c7b 100644 (file)
@@ -2101,6 +2101,13 @@ static int getFileTypeFromBasename(char *basename)
       strchr(basename, '%') == NULL)
     return LEVEL_FILE_TYPE_SB;
 
+  // check for typical filename of a Boulder Dash (GDash) level package file
+  if (strSuffixLower(basename, ".bd") ||
+      strSuffixLower(basename, ".bdr") ||
+      strSuffixLower(basename, ".brc") ||
+      strSuffixLower(basename, ".gds"))
+    return LEVEL_FILE_TYPE_BD;
+
   // ---------- try to determine file type from filesize ----------
 
   checked_free(filename);
@@ -6419,6 +6426,20 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
 // functions for handling native levels
 // -------------------------------------------------------------------------
 
+static void LoadLevelFromFileInfo_BD(struct LevelInfo *level,
+                                    struct LevelFileInfo *level_file_info,
+                                    boolean level_info_only)
+{
+  int pos = 0;
+
+  // determine position of requested level inside level package
+  if (level_file_info->packed)
+    pos = level_file_info->nr - leveldir_current->first_level;
+
+  if (!LoadNativeLevel_BD(level_file_info->filename, pos, level_info_only))
+    level->no_valid_file = TRUE;
+}
+
 static void LoadLevelFromFileInfo_EM(struct LevelInfo *level,
                                     struct LevelFileInfo *level_file_info,
                                     boolean level_info_only)
@@ -6505,6 +6526,11 @@ static void LoadLevelFromFileInfo(struct LevelInfo *level,
       LoadLevelFromFileInfo_RND(level, level_file_info, level_info_only);
       break;
 
+    case LEVEL_FILE_TYPE_BD:
+      LoadLevelFromFileInfo_BD(level, level_file_info, level_info_only);
+      level->game_engine_type = GAME_ENGINE_TYPE_BD;
+      break;
+
     case LEVEL_FILE_TYPE_EM:
       LoadLevelFromFileInfo_EM(level, level_file_info, level_info_only);
       level->game_engine_type = GAME_ENGINE_TYPE_EM;
index 5545490baf1a3c692a41396d3e96154dbd9fd165..c0e4d0a3798b2ce6d5994ca418e6e5c372958515 100644 (file)
@@ -88,5 +88,6 @@ boolean checkGameRunning_BD(void);
 
 void setLevelInfoToDefaults_BD_Ext(int, int);
 void setLevelInfoToDefaults_BD(void);
+boolean LoadNativeLevel_BD(char *, int, boolean);
 
 #endif // EXPORT_BD_H
index 646927faecb141b7416a419238469ff267b213be..efaa78f40a127a40b5ceb76d7f24c0a1441af0ec 100644 (file)
@@ -57,10 +57,95 @@ boolean checkGameRunning_BD(void)
 
 void setLevelInfoToDefaults_BD_Ext(int width, int height)
 {
-  // ...
+  GdCave *cave = native_bd_level.cave;
+
+  if (cave != NULL)
+    gd_cave_free(cave);
+
+  // get empty cave, using default values
+  cave = gd_cave_new();
+
+  // set cave size, if defined
+  if (width > 0 && height > 0)
+  {
+    cave->w = width;
+    cave->h = height;
+  }
+
+  gd_flatten_cave(cave, 0);
+
+  cave->selectable = TRUE;
+  cave->intermission = FALSE;
+
+  native_bd_level.cave = cave;
+  native_bd_level.replay = NULL;
+
+  native_bd_level.cave_nr = 0;
+  native_bd_level.level_nr = 0;
+
+  native_bd_level.loaded_from_caveset = FALSE;
 }
 
 void setLevelInfoToDefaults_BD(void)
 {
   setLevelInfoToDefaults_BD_Ext(0, 0);
 }
+
+boolean LoadNativeLevel_BD(char *filename, int level_pos, boolean level_info_only)
+{
+  static char *filename_loaded = NULL;
+
+  if (filename_loaded == NULL || !strEqual(filename, filename_loaded))
+  {
+    if (!gd_caveset_load_from_file(filename))
+    {
+      if (!level_info_only)
+       Warn("cannot load BD cave set from file '%s'", filename);
+
+      return FALSE;
+    }
+
+    setString(&filename_loaded, filename);
+  }
+
+  if (level_pos < 0 || level_pos >= 5 * gd_caveset_count())
+  {
+    Warn("invalid level position %d in BD cave set", level_pos);
+
+    return FALSE;
+  }
+
+  native_bd_level.cave_nr  = level_pos % gd_caveset_count();
+  native_bd_level.level_nr = level_pos / gd_caveset_count();
+
+  if (native_bd_level.cave != NULL)
+    gd_cave_free(native_bd_level.cave);
+
+  // get selected cave, prepared for playing
+  native_bd_level.cave = gd_get_prepared_cave_from_caveset(native_bd_level.cave_nr,
+                                                          native_bd_level.level_nr);
+
+  // set better initial cave speed (to set better native replay tape length)
+  set_initial_cave_speed(native_bd_level.cave);
+
+  native_bd_level.loaded_from_caveset = TRUE;
+
+  // check if this cave has any replays
+  if (native_bd_level.cave->replays != NULL)
+  {
+    GList *item = native_bd_level.cave->replays;
+
+    // try to find replay that was recorded for this difficulty level
+    while (item != NULL &&
+          (item->data == NULL ||
+           ((GdReplay *)item->data)->success == FALSE ||
+           ((GdReplay *)item->data)->level != native_bd_level.level_nr))
+      item = item->next;
+
+    // matching replay found
+    if (item != NULL)
+      native_bd_level.replay = (GdReplay *)item->data;
+  }
+
+  return TRUE;
+}