added checking for default setup file in global config directory
[rocksndiamonds.git] / src / libgame / setup.c
index 80d224e5747fe3f6eeedf77808e168c159541c87..affc9365fab104533eea93dc8e70d8535f9526ea 100644 (file)
@@ -425,27 +425,74 @@ inline static char *getLevelArtworkDir(int type)
   return LEVELDIR_ARTWORK_PATH(leveldir_current, type);
 }
 
-char *getProgramConfigFilename(char *command_filename_ptr)
+char *getProgramMainDataPath(char *command_filename, char *base_path)
 {
-  char *command_filename_1 = getStringCopy(command_filename_ptr);
+  /* check if the program's main data base directory is configured */
+  if (!strEqual(base_path, "."))
+    return base_path;
+
+  /* if the program is configured to start from current directory (default),
+     determine program package directory from program binary (some versions
+     of KDE/Konqueror and Mac OS X (especially "Mavericks") apparently do not
+     set the current working directory to the program package directory) */
+  char *main_data_path = getBasePath(command_filename);
+
+#if defined(PLATFORM_MACOSX)
+  if (strSuffix(main_data_path, MAC_APP_BINARY_SUBDIR))
+  {
+    char *main_data_path_old = main_data_path;
+
+    // cut relative path to Mac OS X application binary directory from path
+    main_data_path[strlen(main_data_path) -
+                  strlen(MAC_APP_BINARY_SUBDIR)] = '\0';
+
+    // cut trailing path separator from path (but not if path is root directory)
+    if (strSuffix(main_data_path, "/") && !strEqual(main_data_path, "/"))
+      main_data_path[strlen(main_data_path) - 1] = '\0';
+
+    // replace empty path with current directory
+    if (strEqual(main_data_path, ""))
+      main_data_path = ".";
+
+    // add relative path to Mac OS X application resources directory to path
+    main_data_path = getPath2(main_data_path, MAC_APP_FILES_SUBDIR);
+
+    free(main_data_path_old);
+  }
+#endif
+
+  return main_data_path;
+}
+
+char *getProgramConfigFilename(char *command_filename)
+{
+  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 *command_basepath = getBasePath(command_filename_ptr);
-  char *command_basename = getBaseNameNoSuffix(command_filename_ptr);
+  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 *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);
 
   // 1st try: look for config file that exactly matches the binary filename
   if (fileExists(config_filename_1))
     return config_filename_1;
 
-  // 2nd try: return config filename that matches binary filename without suffix
-  return config_filename_2;
+  // 2nd try: look for config file that matches binary filename without suffix
+  if (fileExists(config_filename_2))
+    return config_filename_2;
+
+  // 3rd try: return setup config filename in global program config directory
+  return config_filename_3;
 }
 
 char *getTapeFilename(int nr)
@@ -3559,9 +3606,8 @@ void AddUserLevelSetToLevelInfo(char *level_subdir_new)
     Error(ERR_EXIT, "internal level set structure corrupted -- aborting");
 }
 
-boolean UpdateUserLevelSet(char *level_subdir,
-                          char *level_name, char *level_author,
-                          int num_levels, int first_level_nr)
+boolean UpdateUserLevelSet(char *level_subdir, char *level_name,
+                          char *level_author, int num_levels)
 {
   char *filename = getPath2(getUserLevelDir(level_subdir), LEVELINFO_FILENAME);
   char *filename_tmp = getStringCat2(filename, ".tmp");
@@ -3582,9 +3628,6 @@ boolean UpdateUserLevelSet(char *level_subdir,
   if (num_levels != -1)
     leveldir->levels = num_levels;
 
-  if (first_level_nr != -1)
-    leveldir->first_level = first_level_nr;
-
   // update values that depend on other values
 
   setString(&leveldir->name_sorting, leveldir->name);
@@ -3605,8 +3648,6 @@ boolean UpdateUserLevelSet(char *level_subdir,
        fprintf(file_tmp, "%-32s%s\n", "author:", level_author);
       else if (strPrefix(line, "levels:") && num_levels != -1)
        fprintf(file_tmp, "%-32s%d\n", "levels:", num_levels);
-      else if (strPrefix(line, "first_level:") && first_level_nr != -1)
-       fprintf(file_tmp, "%-32s%d\n", "first_level:", first_level_nr);
       else
        fputs(line, file_tmp);
     }
@@ -3629,9 +3670,8 @@ boolean UpdateUserLevelSet(char *level_subdir,
   return success;
 }
 
-boolean CreateUserLevelSet(char *level_subdir,
-                          char *level_name, char *level_author,
-                          int num_levels, int first_level_nr)
+boolean CreateUserLevelSet(char *level_subdir, char *level_name,
+                          char *level_author, int num_levels)
 {
   LevelDirTree *level_info;
   char *filename;
@@ -3659,7 +3699,7 @@ boolean CreateUserLevelSet(char *level_subdir,
   setString(&level_info->name, level_name);
   setString(&level_info->author, level_author);
   level_info->levels = num_levels;
-  level_info->first_level = first_level_nr;
+  level_info->first_level = 1;
   level_info->sort_priority = LEVELCLASS_PRIVATE_START;
   level_info->readonly = FALSE;
 
@@ -3698,7 +3738,7 @@ boolean CreateUserLevelSet(char *level_subdir,
 
 static void SaveUserLevelInfo()
 {
-  CreateUserLevelSet(getLoginName(), getLoginName(), getRealName(), 100, 1);
+  CreateUserLevelSet(getLoginName(), getLoginName(), getRealName(), 100);
 }
 
 char *getSetupValue(int type, void *value)