added "levelinfo.conf" options to rename levels with title "nameless level"
[rocksndiamonds.git] / src / libgame / setup.c
index 9ea1754932adb1371c9d994aca8e8af497411e3a..3557e949273a30f1c3ffc5f3ddd7b456af62ac2b 100644 (file)
@@ -853,6 +853,65 @@ char *getLevelSetTitleMessageFilename(int nr, boolean initial)
   return NULL;         // cannot find specified artwork file anywhere
 }
 
+static char *getCreditsBasename(int nr)
+{
+  static char basename[32];
+
+  sprintf(basename, "credits_%d.txt", nr + 1);
+
+  return basename;
+}
+
+char *getCreditsFilename(int nr, boolean global)
+{
+  char *basename = getCreditsBasename(nr);
+  char *basepath = NULL;
+  static char *credits_subdir = NULL;
+  static char *filename = NULL;
+
+  if (credits_subdir == NULL)
+    credits_subdir = getPath2(DOCS_DIRECTORY, CREDITS_DIRECTORY);
+
+  checked_free(filename);
+
+  // look for credits file in the game's base or current level set directory
+  basepath = (global ? options.base_directory : getCurrentLevelDir());
+
+  filename = getPath3(basepath, credits_subdir, basename);
+  if (fileExists(filename))
+    return filename;
+
+  return NULL;         // cannot find credits file
+}
+
+static char *getProgramInfoBasename(int nr)
+{
+  static char basename[32];
+
+  sprintf(basename, "program_%d.txt", nr + 1);
+
+  return basename;
+}
+
+char *getProgramInfoFilename(int nr)
+{
+  char *basename = getProgramInfoBasename(nr);
+  static char *info_subdir = NULL;
+  static char *filename = NULL;
+
+  if (info_subdir == NULL)
+    info_subdir = getPath2(DOCS_DIRECTORY, INFO_DIRECTORY);
+
+  checked_free(filename);
+
+  // look for program info file in the game's base directory
+  filename = getPath3(options.base_directory, info_subdir, basename);
+  if (fileExists(filename))
+    return filename;
+
+  return NULL;         // cannot find program info file
+}
+
 static char *getCorrectedArtworkBasename(char *basename)
 {
   return basename;
@@ -1697,7 +1756,7 @@ char *getHomeDir(void)
       strcpy(dir, ".");
   }
 #elif defined(PLATFORM_EMSCRIPTEN)
-  dir = "/persistent";
+  dir = PERSISTENT_DIRECTORY;
 #elif defined(PLATFORM_UNIX)
   if (dir == NULL)
   {
@@ -2075,7 +2134,7 @@ unsigned int get_hash_from_key(void *key)
   return hash;
 }
 
-static int keys_are_equal(void *key1, void *key2)
+int hash_keys_are_equal(void *key1, void *key2)
 {
   return (strEqual((char *)key1, (char *)key2));
 }
@@ -2083,7 +2142,7 @@ static int keys_are_equal(void *key1, void *key2)
 SetupFileHash *newSetupFileHash(void)
 {
   SetupFileHash *new_hash =
-    create_hashtable(16, 0.75, get_hash_from_key, keys_are_equal);
+    create_hashtable(16, 0.75, get_hash_from_key, hash_keys_are_equal);
 
   if (new_hash == NULL)
     Fail("create_hashtable() failed -- out of memory");
@@ -2577,11 +2636,13 @@ SetupFileHash *loadSetupFileHash(char *filename)
 #define LEVELINFO_TOKEN_FILENAME               24
 #define LEVELINFO_TOKEN_FILETYPE               25
 #define LEVELINFO_TOKEN_SPECIAL_FLAGS          26
-#define LEVELINFO_TOKEN_HANDICAP               27
-#define LEVELINFO_TOKEN_SKIP_LEVELS            28
-#define LEVELINFO_TOKEN_USE_EMC_TILES          29
+#define LEVELINFO_TOKEN_EMPTY_LEVEL_NAME       27
+#define LEVELINFO_TOKEN_FORCE_LEVEL_NAME       28
+#define LEVELINFO_TOKEN_HANDICAP               29
+#define LEVELINFO_TOKEN_SKIP_LEVELS            30
+#define LEVELINFO_TOKEN_USE_EMC_TILES          31
 
-#define NUM_LEVELINFO_TOKENS                   30
+#define NUM_LEVELINFO_TOKENS                   32
 
 static LevelDirTree ldi;
 
@@ -2615,6 +2676,8 @@ static struct TokenInfo levelinfo_tokens[] =
   { TYPE_STRING,       &ldi.level_filename,    "filename"              },
   { TYPE_STRING,       &ldi.level_filetype,    "filetype"              },
   { TYPE_STRING,       &ldi.special_flags,     "special_flags"         },
+  { TYPE_STRING,       &ldi.empty_level_name,  "empty_level_name"      },
+  { TYPE_BOOLEAN,      &ldi.force_level_name,  "force_level_name"      },
   { TYPE_BOOLEAN,      &ldi.handicap,          "handicap"              },
   { TYPE_BOOLEAN,      &ldi.skip_levels,       "skip_levels"           },
   { TYPE_BOOLEAN,      &ldi.use_emc_tiles,     "use_emc_tiles"         }
@@ -2712,6 +2775,9 @@ static void setTreeInfoToDefaults(TreeInfo *ti, int type)
 
     ti->special_flags = NULL;
 
+    ti->empty_level_name = NULL;
+    ti->force_level_name = FALSE;
+
     ti->levels = 0;
     ti->first_level = 0;
     ti->last_level = 0;
@@ -2794,6 +2860,9 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ti, TreeInfo *parent)
 
     ti->special_flags = getStringCopy(parent->special_flags);
 
+    ti->empty_level_name = getStringCopy(parent->empty_level_name);
+    ti->force_level_name = parent->force_level_name;
+
     ti->levels = parent->levels;
     ti->first_level = parent->first_level;
     ti->last_level = parent->last_level;
@@ -2856,6 +2925,9 @@ static TreeInfo *getTreeInfoCopy(TreeInfo *ti)
 
   ti_copy->special_flags       = getStringCopy(ti->special_flags);
 
+  ti_copy->empty_level_name    = getStringCopy(ti->empty_level_name);
+  ti_copy->force_level_name    = ti->force_level_name;
+
   ti_copy->levels              = ti->levels;
   ti_copy->first_level         = ti->first_level;
   ti_copy->last_level          = ti->last_level;
@@ -3080,6 +3152,17 @@ static void setTreeInfoParentNodes(TreeInfo *node, TreeInfo *node_parent)
   }
 }
 
+TreeInfo *addTopTreeInfoNode(TreeInfo *node_first)
+{
+  // add top tree node with back link node in previous tree
+  node_first = createTopTreeInfoNode(node_first);
+
+  // set all parent links (back links) in complete tree
+  setTreeInfoParentNodes(node_first, NULL);
+
+  return node_first;
+}
+
 
 // ----------------------------------------------------------------------------
 // functions for handling level and custom artwork info cache
@@ -4214,11 +4297,8 @@ static void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node)
   LoadArtworkInfoFromLevelInfoExt(artwork_node, NULL, leveldir_first_all, TRUE);
   LoadArtworkInfoFromLevelInfoExt(artwork_node, NULL, leveldir_first_all, FALSE);
 
-  // add top tree node over all three separate sub-trees
-  *artwork_node = createTopTreeInfoNode(*artwork_node);
-
-  // set all parent links (back links) in complete artwork tree
-  setTreeInfoParentNodes(*artwork_node, NULL);
+  // add top tree node over all sub-trees and set parent links
+  *artwork_node = addTopTreeInfoNode(*artwork_node);
 }
 
 void LoadLevelArtworkInfo(void)