rnd-19990928-1-src
[rocksndiamonds.git] / src / files.c
index 67f0168c42fbf64e068c11cb09a53017662a500f..1e44ad714fae1c8c10dc28134d70ec2060707d40 100644 (file)
@@ -1061,12 +1061,13 @@ void SaveScore(int level_nr)
 /* level directory info */
 #define LEVELINFO_TOKEN_NAME           29
 #define LEVELINFO_TOKEN_NAME_SHORT     30
-#define LEVELINFO_TOKEN_AUTHOR         31
-#define LEVELINFO_TOKEN_IMPORTED_FROM  32
-#define LEVELINFO_TOKEN_LEVELS         33
-#define LEVELINFO_TOKEN_FIRST_LEVEL    34
-#define LEVELINFO_TOKEN_SORT_PRIORITY  35
-#define LEVELINFO_TOKEN_READONLY       36
+#define LEVELINFO_TOKEN_NAME_SORTING   31
+#define LEVELINFO_TOKEN_AUTHOR         32
+#define LEVELINFO_TOKEN_IMPORTED_FROM  33
+#define LEVELINFO_TOKEN_LEVELS         34
+#define LEVELINFO_TOKEN_FIRST_LEVEL    35
+#define LEVELINFO_TOKEN_SORT_PRIORITY  36
+#define LEVELINFO_TOKEN_READONLY       37
 
 #define FIRST_GLOBAL_SETUP_TOKEN       SETUP_TOKEN_PLAYER_NAME
 #define LAST_GLOBAL_SETUP_TOKEN                SETUP_TOKEN_TIME_LIMIT
@@ -1135,6 +1136,7 @@ static struct
   /* level directory info */
   { TYPE_STRING,  &ldi.name,           "name"                          },
   { TYPE_STRING,  &ldi.name_short,     "name_short"                    },
+  { TYPE_STRING,  &ldi.name_sorting,   "name_sorting"                  },
   { TYPE_STRING,  &ldi.author,         "author"                        },
   { TYPE_STRING,  &ldi.imported_from,  "imported_from"                 },
   { TYPE_INTEGER, &ldi.levels,         "levels"                        },
@@ -1403,6 +1405,7 @@ static void setLevelDirInfoToDefaults(struct LevelDirInfo *ldi)
   ldi->filename = NULL;
   ldi->name = getStringCopy(ANONYMOUS_NAME);
   ldi->name_short = NULL;
+  ldi->name_sorting = NULL;
   ldi->author = getStringCopy(ANONYMOUS_NAME);
   ldi->imported_from = NULL;
   ldi->levels = 0;
@@ -1548,8 +1551,8 @@ static int compareLevelDirInfoEntries(const void *object1, const void *object2)
 
   if (entry1->sort_priority == entry2->sort_priority)
   {
-    char *name1 = getStringToLower(entry1->name_short);
-    char *name2 = getStringToLower(entry2->name_short);
+    char *name1 = getStringToLower(entry1->name_sorting);
+    char *name2 = getStringToLower(entry2->name_sorting);
 
     compare_result = strcmp(name1, name2);
 
@@ -1604,6 +1607,10 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry)
 
     if (setup_file_list)
     {
+#if 0
+      DrawInitText(dir_entry->d_name, 150, FC_YELLOW);
+#endif
+
       checkSetupFileListIdentifier(setup_file_list, LEVELINFO_COOKIE);
       setLevelDirInfoToDefaults(&leveldir[current_entry]);
 
@@ -1612,10 +1619,18 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry)
        setSetupInfo(i, getTokenValue(setup_file_list, token_info[i].text));
       leveldir[current_entry] = ldi;
 
+#if 1
+      DrawInitText(leveldir[current_entry].name, 150, FC_YELLOW);
+#endif
+
       if (leveldir[current_entry].name_short == NULL)
        leveldir[current_entry].name_short =
          getStringCopy(leveldir[current_entry].name);
 
+      if (leveldir[current_entry].name_sorting == NULL)
+       leveldir[current_entry].name_sorting =
+         getStringCopy(leveldir[current_entry].name_short);
+
       leveldir[current_entry].filename = getStringCopy(dir_entry->d_name);
       leveldir[current_entry].last_level =
        leveldir[current_entry].first_level +
@@ -1625,6 +1640,15 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry)
       leveldir[current_entry].color = LEVELCOLOR(&leveldir[current_entry]);
       leveldir[current_entry].class_desc =
        getLevelClassDescription(&leveldir[current_entry]);
+#if 0
+      leveldir[current_entry].handicap_level =
+       leveldir[current_entry].first_level;    /* default value */
+#else
+      leveldir[current_entry].handicap_level =
+       (leveldir[current_entry].user_defined ?
+        leveldir[current_entry].last_level :
+        leveldir[current_entry].first_level);
+#endif
 
       freeSetupFileList(setup_file_list);
       current_entry++;
@@ -1636,13 +1660,15 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry)
     free(filename);
   }
 
-  if (current_entry == MAX_LEVDIR_ENTRIES)
-    Error(ERR_WARN, "using %d level directories -- ignoring the rest",
-         current_entry);
-
   closedir(dir);
 
-  if (current_entry == start_entry)
+  if (current_entry == MAX_LEVDIR_ENTRIES)
+  {
+    Error(ERR_WARN, "maximum of %d level directories reached", current_entry);
+    Error(ERR_WARN, "remaining level directories ignored in directory '%s'",
+         level_directory);
+  }
+  else if (current_entry == start_entry)
     Error(ERR_WARN, "cannot find any valid level series in directory '%s'",
          level_directory);
 
@@ -1656,6 +1682,8 @@ void LoadLevelInfo()
   num_leveldirs = 0;
   leveldir_nr = 0;
 
+  DrawInitText("Loading level series:", 120, FC_GREEN);
+
   num_leveldirs = LoadLevelInfoFromLevelDir(options.level_directory,
                                            num_leveldirs);
   num_leveldirs = LoadLevelInfoFromLevelDir(getUserLevelDir(""),
@@ -1698,7 +1726,9 @@ static void SaveUserLevelInfo()
          getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER, LEVELINFO_COOKIE));
 
   for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++)
-    if (i != LEVELINFO_TOKEN_NAME_SHORT && i != LEVELINFO_TOKEN_IMPORTED_FROM)
+    if (i != LEVELINFO_TOKEN_NAME_SHORT &&
+       i != LEVELINFO_TOKEN_NAME_SORTING &&
+       i != LEVELINFO_TOKEN_IMPORTED_FROM)
       fprintf(file, "%s\n", getSetupLine("", i));
 
   fclose(file);
@@ -1923,6 +1953,55 @@ void SaveLevelSetup_LastSeries()
   chmod(filename, SETUP_PERMS);
 }
 
+static void checkSeriesInfo(int leveldir_nr)
+{
+  static char *level_directory = NULL;
+  DIR *dir;
+  struct dirent *dir_entry;
+
+  /* check for more levels besides the 'levels' field of 'levelinfo.conf' */
+
+  level_directory = getPath2((leveldir[leveldir_nr].user_defined ?
+                             getUserLevelDir("") :
+                             options.level_directory),
+                            leveldir[leveldir_nr].filename);
+
+  if ((dir = opendir(level_directory)) == NULL)
+  {
+    Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
+    return;
+  }
+
+  while ((dir_entry = readdir(dir)) != NULL)   /* last directory entry */
+  {
+    if (strlen(dir_entry->d_name) > 4 &&
+       dir_entry->d_name[3] == '.' &&
+       strcmp(&dir_entry->d_name[4], LEVELFILE_EXTENSION) == 0)
+    {
+      char levelnum_str[4];
+      int levelnum_value;
+
+      strncpy(levelnum_str, dir_entry->d_name, 3);
+      levelnum_str[3] = '\0';
+
+      levelnum_value = atoi(levelnum_str);
+
+      if (levelnum_value < leveldir[leveldir_nr].first_level)
+      {
+       Error(ERR_WARN, "additional level %d found", levelnum_value);
+       leveldir[leveldir_nr].first_level = levelnum_value;
+      }
+      else if (levelnum_value > leveldir[leveldir_nr].last_level)
+      {
+       Error(ERR_WARN, "additional level %d found", levelnum_value);
+       leveldir[leveldir_nr].last_level = levelnum_value;
+      }
+    }
+  }
+
+  closedir(dir);
+}
+
 void LoadLevelSetup_SeriesInfo(int leveldir_nr)
 {
   char *filename;
@@ -1930,8 +2009,14 @@ void LoadLevelSetup_SeriesInfo(int leveldir_nr)
   char *level_subdir = leveldir[leveldir_nr].filename;
 
   /* always start with reliable default values */
+#if 0
   level_nr = 0;
   leveldir[leveldir_nr].handicap_level = 0;
+#else
+  level_nr = leveldir[leveldir_nr].first_level;
+#endif
+
+  checkSeriesInfo(leveldir_nr);
 
   /* ----------------------------------------------------------------------- */
   /* ~/.rocksndiamonds/levelsetup/<level series>/levelsetup.conf             */
@@ -1968,6 +2053,9 @@ void LoadLevelSetup_SeriesInfo(int leveldir_nr)
       if (level_nr > leveldir[leveldir_nr].last_level + 1)
        level_nr = leveldir[leveldir_nr].last_level;
 
+      if (leveldir[leveldir_nr].user_defined)
+       level_nr = leveldir[leveldir_nr].last_level;
+
       leveldir[leveldir_nr].handicap_level = level_nr;
     }
 
@@ -2018,39 +2106,22 @@ void SaveLevelSetup_SeriesInfo(int leveldir_nr)
 }
 
 #ifdef MSDOS
-static boolean initErrorFile()
+void initErrorFile()
 {
   char *filename;
-  FILE *error_file;
 
   InitUserDataDirectory();
 
   filename = getPath2(getUserDataDir(), ERROR_FILENAME);
-  error_file = fopen(filename, "w");
+  unlink(filename);
   free(filename);
-
-  if (error_file == NULL)
-    return FALSE;
-
-  fclose(error_file);
-
-  return TRUE;
 }
 
 FILE *openErrorFile()
 {
-  static boolean first_access = TRUE;
   char *filename;
   FILE *error_file;
 
-  if (first_access)
-  {
-    if (!initErrorFile())
-      return NULL;
-
-    first_access = FALSE;
-  }
-
   filename = getPath2(getUserDataDir(), ERROR_FILENAME);
   error_file = fopen(filename, "a");
   free(filename);