rnd-20060226-3-src
[rocksndiamonds.git] / src / libgame / setup.c
index 656bc519083cbd3458b55114328060b128917328..c96316f6e56fb4d9e117bb0a74a0a4f1b3980d73 100644 (file)
@@ -799,7 +799,7 @@ void InitLevelSetupDirectory(char *level_subdir)
 
 
 /* ------------------------------------------------------------------------- */
-/* some functions to handle lists of level directories                       */
+/* some functions to handle lists of level and artwork directories           */
 /* ------------------------------------------------------------------------- */
 
 TreeInfo *newTreeInfo()
@@ -927,6 +927,43 @@ TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier)
   return NULL;
 }
 
+TreeInfo *cloneTreeNode(TreeInfo **node_top, TreeInfo *node_parent,
+                       TreeInfo *node, boolean skip_sets_without_levels)
+{
+  TreeInfo *node_new;
+
+  if (node == NULL)
+    return NULL;
+
+  if (!node->parent_link && !node->level_group &&
+      skip_sets_without_levels && node->levels == 0)
+    return cloneTreeNode(node_top, node_parent, node->next,
+                        skip_sets_without_levels);
+
+  node_new = newTreeInfo();
+
+  *node_new = *node;                           /* copy complete node */
+
+  node_new->node_top = node_top;               /* correct top node link */
+  node_new->node_parent = node_parent;         /* correct parent node link */
+
+  if (node->level_group)
+    node_new->node_group = cloneTreeNode(node_top, node_new, node->node_group,
+                                        skip_sets_without_levels);
+
+  node_new->next = cloneTreeNode(node_top, node_parent, node->next,
+                                skip_sets_without_levels);
+  
+  return node_new;
+}
+
+void cloneTree(TreeInfo **ti_new, TreeInfo *ti, boolean skip_empty_sets)
+{
+  TreeInfo *ti_cloned = cloneTreeNode(ti_new, NULL, ti, skip_empty_sets);
+
+  *ti_new = ti_cloned;
+}
+
 void dumpTreeInfo(TreeInfo *node, int depth)
 {
   int i;
@@ -1553,14 +1590,14 @@ SetupFileHash *loadSetupFileHash(char *filename)
 }
 
 void checkSetupFileHashIdentifier(SetupFileHash *setup_file_hash,
-                                 char *identifier)
+                                 char *filename, char *identifier)
 {
   char *value = getHashEntry(setup_file_hash, TOKEN_STR_FILE_IDENTIFIER);
 
   if (value == NULL)
-    Error(ERR_WARN, "configuration file has no file identifier");
+    Error(ERR_WARN, "config file '%s' has no file identifier", filename);
   else if (!checkCookieString(value, identifier))
-    Error(ERR_WARN, "configuration file has wrong file identifier");
+    Error(ERR_WARN, "config file '%s' has wrong file identifier", filename);
 }
 
 
@@ -1925,7 +1962,8 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
 
   leveldir_new->subdir = getStringCopy(directory_name);
 
-  checkSetupFileHashIdentifier(setup_file_hash, getCookie("LEVELINFO"));
+  checkSetupFileHashIdentifier(setup_file_hash, filename,
+                              getCookie("LEVELINFO"));
 
   /* set all structure fields according to the token/value pairs */
   ldi = *leveldir_new;
@@ -1956,8 +1994,10 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
     leveldir_new->fullpath = getPath2(node_parent->fullpath, directory_name);
   }
 
+#if 0
   if (leveldir_new->levels < 1)
     leveldir_new->levels = 1;
+#endif
 
   leveldir_new->last_level =
     leveldir_new->first_level + leveldir_new->levels - 1;
@@ -1987,6 +2027,22 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
     (leveldir_new->user_defined || !leveldir_new->handicap ?
      leveldir_new->last_level : leveldir_new->first_level);
 
+#if 0
+  /* !!! don't skip sets without levels (else artwork base sets are missing) */
+#if 1
+  if (leveldir_new->levels < 1 && !leveldir_new->level_group)
+  {
+    /* skip level sets without levels (which are probably artwork base sets) */
+
+    freeSetupFileHash(setup_file_hash);
+    free(directory_path);
+    free(filename);
+
+    return FALSE;
+  }
+#endif
+#endif
+
   pushTreeInfo(node_first, leveldir_new);
 
   freeSetupFileHash(setup_file_hash);
@@ -2078,6 +2134,15 @@ void LoadLevelInfo()
   LoadLevelInfoFromLevelDir(&leveldir_first, NULL, options.level_directory);
   LoadLevelInfoFromLevelDir(&leveldir_first, NULL, getUserLevelDir(NULL));
 
+#if 1
+  /* after loading all level set information, clone the level directory tree
+     and remove all level sets without levels (these may still contain artwork
+     to be offered in the setup menu as "custom artwork", and are therefore
+     checked for existing artwork in the function "LoadLevelArtworkInfo()") */
+  leveldir_first_all = leveldir_first;
+  cloneTree(&leveldir_first, leveldir_first_all, TRUE);
+#endif
+
   /* before sorting, the first entries will be from the user directory */
   leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
 
@@ -2151,7 +2216,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
   if (setup_file_hash) /* (before defining ".color" and ".class_desc") */
   {
 #if 0
-    checkSetupFileHashIdentifier(setup_file_hash, getCookie("..."));
+    checkSetupFileHashIdentifier(setup_file_hash, filename, getCookie("..."));
 #endif
 
     /* set all structure fields according to the token/value pairs */
@@ -2433,9 +2498,9 @@ void LoadLevelArtworkInfo()
 {
   DrawInitText("Looking for custom level artwork:", 120, FC_GREEN);
 
-  LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first);
-  LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first);
-  LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first);
+  LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first_all);
+  LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first_all);
+  LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first_all);
 
   /* needed for reloading level artwork not known at ealier stage */
 
@@ -2643,7 +2708,8 @@ void LoadLevelSetup_LastSeries()
     if (leveldir_current == NULL)
       leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
 
-    checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP"));
+    checkSetupFileHashIdentifier(level_setup_hash, filename,
+                                getCookie("LEVELSETUP"));
 
     freeSetupFileHash(level_setup_hash);
   }
@@ -2787,7 +2853,8 @@ void LoadLevelSetup_SeriesInfo()
       leveldir_current->handicap_level = level_nr;
     }
 
-    checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP"));
+    checkSetupFileHashIdentifier(level_setup_hash, filename,
+                                getCookie("LEVELSETUP"));
 
     freeSetupFileHash(level_setup_hash);
   }