added new option "create_user_levelset" (setup file only)
[rocksndiamonds.git] / src / libgame / setup.c
index 85f6e1f088c6e5f6bd1e3e7e2296f814557002b7..7f080d9c6c0f92fbdb4f2c2a860c7975f6a3ba54 100644 (file)
@@ -178,7 +178,7 @@ static char *getNetworkDir(void)
   return network_dir;
 }
 
-static char *getLevelDirFromTreeInfo(TreeInfo *node)
+char *getLevelDirFromTreeInfo(TreeInfo *node)
 {
   static char *level_dir = NULL;
 
@@ -457,7 +457,7 @@ char *getProgramMainDataPath(char *command_filename, char *base_path)
 {
   // check if the program's main data base directory is configured
   if (!strEqual(base_path, "."))
-    return base_path;
+    return getStringCopy(base_path);
 
   /* if the program is configured to start from current directory (default),
      determine program package directory from program binary (some versions
@@ -494,22 +494,41 @@ char *getProgramMainDataPath(char *command_filename, char *base_path)
 
 char *getProgramConfigFilename(char *command_filename)
 {
-  char *command_filename_1 = getStringCopy(command_filename);
+  static char *config_filename_1 = NULL;
+  static char *config_filename_2 = NULL;
+  static char *config_filename_3 = NULL;
+  static boolean initialized = FALSE;
 
-  // strip trailing executable suffix from command filename
-  if (strSuffix(command_filename_1, ".exe"))
-    command_filename_1[strlen(command_filename_1) - 4] = '\0';
+  if (!initialized)
+  {
+    char *command_filename_1 = getStringCopy(command_filename);
+
+    // strip trailing executable suffix from command filename
+    if (strSuffix(command_filename_1, ".exe"))
+      command_filename_1[strlen(command_filename_1) - 4] = '\0';
+
+    char *ro_base_path = getProgramMainDataPath(command_filename, RO_BASE_PATH);
+    char *conf_directory = getPath2(ro_base_path, CONF_DIRECTORY);
+
+    char *command_basepath = getBasePath(command_filename);
+    char *command_basename = getBaseNameNoSuffix(command_filename);
+    char *command_filename_2 = getPath2(command_basepath, command_basename);
 
-  char *ro_base_path = getProgramMainDataPath(command_filename, RO_BASE_PATH);
-  char *conf_directory = getPath2(ro_base_path, CONF_DIRECTORY);
+    config_filename_1 = getStringCat2(command_filename_1, ".conf");
+    config_filename_2 = getStringCat2(command_filename_2, ".conf");
+    config_filename_3 = getPath2(conf_directory, SETUP_FILENAME);
 
-  char *command_basepath = getBasePath(command_filename);
-  char *command_basename = getBaseNameNoSuffix(command_filename);
-  char *command_filename_2 = getPath2(command_basepath, command_basename);
+    checked_free(ro_base_path);
+    checked_free(conf_directory);
 
-  char *config_filename_1 = getStringCat2(command_filename_1, ".conf");
-  char *config_filename_2 = getStringCat2(command_filename_2, ".conf");
-  char *config_filename_3 = getPath2(conf_directory, SETUP_FILENAME);
+    checked_free(command_basepath);
+    checked_free(command_basename);
+
+    checked_free(command_filename_1);
+    checked_free(command_filename_2);
+
+    initialized = TRUE;
+  }
 
   // 1st try: look for config file that exactly matches the binary filename
   if (fileExists(config_filename_1))
@@ -1074,7 +1093,8 @@ void InitUserLevelDirectory(char *level_subdir)
     createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE);
     createDirectory(getUserLevelDir(level_subdir), "user level", PERMS_PRIVATE);
 
-    SaveUserLevelInfo();
+    if (setup.internal.create_user_levelset)
+      SaveUserLevelInfo();
   }
 }
 
@@ -3860,32 +3880,29 @@ void LoadLevelArtworkInfo(void)
   print_timestamp_done("LoadLevelArtworkInfo");
 }
 
-static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type)
+static boolean AddTreeSetToTreeInfoExt(TreeInfo *tree_node_old, char *tree_dir,
+                                      char *tree_subdir_new, int type)
 {
-  TreeInfo **tree_node_first, *tree_node_old, *tree_node_new;
-  char *tree_user_dir = TREE_USERDIR(type);
-
-  if (tree_user_dir == NULL)           // should not happen
-    return FALSE;
-
-  // get first node of level or artwork tree
-  tree_node_first = TREE_FIRST_NODE_PTR(type);
-
-  if (tree_node_first == NULL)         // should not happen
-    return FALSE;
-
-  if (type == TREE_TYPE_LEVEL_DIR)
+  if (tree_node_old == NULL)
   {
-    // get level info tree node of personal user level set
-    tree_node_old = getTreeInfoFromIdentifier(*tree_node_first, getLoginName());
-  }
-  else
-  {
-    // get artwork info tree node of first artwork set
-    tree_node_old = *tree_node_first;
+    if (type == TREE_TYPE_LEVEL_DIR)
+    {
+      // get level info tree node of personal user level set
+      tree_node_old = getTreeInfoFromIdentifier(leveldir_first, getLoginName());
+    }
+    else
+    {
+      // get artwork info tree node of first artwork set
+      tree_node_old = ARTWORK_FIRST_NODE(artwork, type);
+    }
   }
 
-  if (tree_node_old == NULL)           // should not happen
+  if (tree_dir == NULL)
+    tree_dir = TREE_USERDIR(type);
+
+  if (tree_node_old   == NULL ||
+      tree_dir        == NULL ||
+      tree_subdir_new == NULL)         // should not happen
     return FALSE;
 
   int draw_deactivation_mask = GetDrawDeactivationMask();
@@ -3896,21 +3913,27 @@ static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type)
   if (type == TREE_TYPE_LEVEL_DIR)
   {
     // load new level set config and add it next to first user level set
-    LoadLevelInfoFromLevelConf(&tree_node_old->next, NULL,
-                              tree_user_dir, tree_subdir_new);
+    LoadLevelInfoFromLevelConf(&tree_node_old->next,
+                              tree_node_old->node_parent,
+                              tree_dir, tree_subdir_new);
   }
   else
   {
     // load new artwork set config and add it next to first artwork set
-    LoadArtworkInfoFromArtworkConf(&tree_node_old->next, NULL,
-                                  tree_user_dir, tree_subdir_new, type);
+    LoadArtworkInfoFromArtworkConf(&tree_node_old->next,
+                                  tree_node_old->node_parent,
+                                  tree_dir, tree_subdir_new, type);
   }
 
   // set draw deactivation mask to previous value
   SetDrawDeactivationMask(draw_deactivation_mask);
 
-  // get tree info tree node of newly added tree set
-  tree_node_new = getTreeInfoFromIdentifier(*tree_node_first, tree_subdir_new);
+  // get first node of level or artwork info tree
+  TreeInfo **tree_node_first = TREE_FIRST_NODE_PTR(type);
+
+  // get tree info node of newly added level or artwork set
+  TreeInfo *tree_node_new = getTreeInfoFromIdentifier(*tree_node_first,
+                                                     tree_subdir_new);
 
   if (tree_node_new == NULL)           // should not happen
     return FALSE;
@@ -3919,21 +3942,22 @@ static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type)
   tree_node_new->node_top    = tree_node_old->node_top;
   tree_node_new->node_parent = tree_node_old->node_parent;
 
-  // sort tree info tree to adjust position of newly added tree set
+  // sort tree info to adjust position of newly added tree set
   sortTreeInfo(tree_node_first);
 
   return TRUE;
 }
 
-void AddUserTreeSetToTreeInfo(char *tree_subdir_new, int type)
+void AddTreeSetToTreeInfo(TreeInfo *tree_node, char *tree_dir,
+                         char *tree_subdir_new, int type)
 {
-  if (!AddUserTreeSetToTreeInfoExt(tree_subdir_new, type))
-    Error(ERR_EXIT, "internal tree set structure corrupted -- aborting");
+  if (!AddTreeSetToTreeInfoExt(tree_node, tree_dir, tree_subdir_new, type))
+    Error(ERR_EXIT, "internal tree info structure corrupted -- aborting");
 }
 
 void AddUserLevelSetToLevelInfo(char *level_subdir_new)
 {
-  AddUserTreeSetToTreeInfo(level_subdir_new, TREE_TYPE_LEVEL_DIR);
+  AddTreeSetToTreeInfo(NULL, NULL, level_subdir_new, TREE_TYPE_LEVEL_DIR);
 }
 
 char *getArtworkIdentifierForUserLevelSet(int type)
@@ -3963,8 +3987,17 @@ TreeInfo *getArtworkTreeInfoForUserLevelSet(int type)
 {
   char *artwork_set = getArtworkIdentifierForUserLevelSet(type);
   TreeInfo *artwork_first_node = ARTWORK_FIRST_NODE(artwork, type);
+  TreeInfo *ti = getTreeInfoFromIdentifier(artwork_first_node, artwork_set);
 
-  return getTreeInfoFromIdentifier(artwork_first_node, artwork_set);
+  if (ti == NULL)
+  {
+    ti = getTreeInfoFromIdentifier(artwork_first_node,
+                                  ARTWORK_DEFAULT_SUBDIR(type));
+    if (ti == NULL)
+      Error(ERR_EXIT, "cannot find default graphics -- should not happen");
+  }
+
+  return ti;
 }
 
 boolean checkIfCustomArtworkExistsForCurrentLevelSet(void)