checked_free(*artwork_set_ptr);
- if (fileExists(dir))
+ if (directoryExists(dir))
{
*artwork_path_ptr = getStringCopy(getClassicArtworkDir(ti->type));
*artwork_set_ptr = getStringCopy(getClassicArtworkSet(ti->type));
{
/* 1st try: look for special artwork in current level series directory */
directory = getPath2(getCurrentLevelDir(), MUSIC_DIRECTORY);
- if (fileExists(directory))
+ if (directoryExists(directory))
return directory;
free(directory);
{
/* 2nd try: look for special artwork configured in level series config */
directory = getStringCopy(getLevelArtworkDir(TREE_TYPE_MUSIC_DIR));
- if (fileExists(directory))
+ if (directoryExists(directory))
return directory;
free(directory);
{
/* 3rd try: look for special artwork in configured artwork directory */
directory = getStringCopy(getSetupArtworkDir(artwork.mus_current));
- if (fileExists(directory))
+ if (directoryExists(directory))
return directory;
free(directory);
/* 4th try: look for default artwork in new default artwork directory */
directory = getStringCopy(getDefaultMusicDir(MUS_DEFAULT_SUBDIR));
- if (fileExists(directory))
+ if (directoryExists(directory))
return directory;
free(directory);
/* 5th try: look for default artwork in old default artwork directory */
directory = getStringCopy(options.music_directory);
- if (fileExists(directory))
+ if (directoryExists(directory))
return directory;
return NULL; /* cannot find specified artwork file anywhere */
void InitUserLevelDirectory(char *level_subdir)
{
- if (!fileExists(getUserLevelDir(level_subdir)))
+ if (!directoryExists(getUserLevelDir(level_subdir)))
{
createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE);
createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE);
{
static char *user_game_data_dir = NULL;
+#if defined(PLATFORM_ANDROID)
+ if (user_game_data_dir == NULL)
+ user_game_data_dir = (char *)SDL_AndroidGetInternalStoragePath();
+#else
if (user_game_data_dir == NULL)
user_game_data_dir = getPath2(getPersonalDataDir(),
program.userdata_subdir);
+#endif
return user_game_data_dir;
}
char *userdata_dir_new = getUserGameDataDir(); /* do not free() this */
/* convert old Unix style game data directory to Mac OS X style, if needed */
- if (fileExists(userdata_dir_old) && !fileExists(userdata_dir_new))
+ if (directoryExists(userdata_dir_old) && !directoryExists(userdata_dir_new))
{
if (rename(userdata_dir_old, userdata_dir_new) != 0)
{
else
dir_mode |= MODE_W_ALL;
- if (!fileExists(dir))
+ if (!directoryExists(dir))
if (posix_mkdir(dir, dir_mode) != 0)
Error(ERR_WARN, "cannot create %s directory '%s': %s",
text, dir, strerror(errno));
}
#if 1
+
+#if 1
+static boolean loadSetupFileData(void *setup_file_data, char *filename,
+ boolean top_recursion_level, boolean is_hash)
+{
+ static SetupFileHash *include_filename_hash = NULL;
+ char line[MAX_LINE_LEN], line_raw[MAX_LINE_LEN], previous_line[MAX_LINE_LEN];
+ char *token, *value, *line_ptr;
+ void *insert_ptr = NULL;
+ boolean read_continued_line = FALSE;
+ File *file;
+ int line_nr = 0, token_count = 0, include_count = 0;
+
+#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING
+ token_value_separator_warning = FALSE;
+#endif
+
+#if CHECK_TOKEN__WARN_IF_ALREADY_EXISTS_IN_HASH
+ token_already_exists_warning = FALSE;
+#endif
+
+#if 0
+ Error(ERR_INFO, "===== opening file: '%s'", filename);
+#endif
+
+ if (!(file = openFile(filename, MODE_READ)))
+ {
+ Error(ERR_WARN, "cannot open configuration file '%s'", filename);
+
+ return FALSE;
+ }
+
+#if 0
+ Error(ERR_INFO, "===== reading file: '%s'", filename);
+#endif
+
+ /* use "insert pointer" to store list end for constant insertion complexity */
+ if (!is_hash)
+ insert_ptr = setup_file_data;
+
+ /* on top invocation, create hash to mark included files (to prevent loops) */
+ if (top_recursion_level)
+ include_filename_hash = newSetupFileHash();
+
+ /* mark this file as already included (to prevent including it again) */
+ setHashEntry(include_filename_hash, getBaseNamePtr(filename), "true");
+
+ while (!checkEndOfFile(file))
+ {
+ /* read next line of input file */
+ if (!getStringFromFile(file, line, MAX_LINE_LEN))
+ break;
+
+#if 0
+ Error(ERR_INFO, "got line: '%s'", line);
+#endif
+
+ /* check if line was completely read and is terminated by line break */
+ if (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
+ line_nr++;
+
+ /* cut trailing line break (this can be newline and/or carriage return) */
+ for (line_ptr = &line[strlen(line)]; line_ptr >= line; line_ptr--)
+ if ((*line_ptr == '\n' || *line_ptr == '\r') && *(line_ptr + 1) == '\0')
+ *line_ptr = '\0';
+
+ /* copy raw input line for later use (mainly debugging output) */
+ strcpy(line_raw, line);
+
+ if (read_continued_line)
+ {
+#if 0
+ /* !!! ??? WHY ??? !!! */
+ /* cut leading whitespaces from input line */
+ for (line_ptr = line; *line_ptr; line_ptr++)
+ if (*line_ptr != ' ' && *line_ptr != '\t')
+ break;
+#endif
+
+ /* append new line to existing line, if there is enough space */
+ if (strlen(previous_line) + strlen(line_ptr) < MAX_LINE_LEN)
+ strcat(previous_line, line_ptr);
+
+ strcpy(line, previous_line); /* copy storage buffer to line */
+
+ read_continued_line = FALSE;
+ }
+
+ /* if the last character is '\', continue at next line */
+ if (strlen(line) > 0 && line[strlen(line) - 1] == '\\')
+ {
+ line[strlen(line) - 1] = '\0'; /* cut off trailing backslash */
+ strcpy(previous_line, line); /* copy line to storage buffer */
+
+ read_continued_line = TRUE;
+
+ continue;
+ }
+
+ if (!getTokenValueFromSetupLineExt(line, &token, &value, filename,
+ line_raw, line_nr, FALSE))
+ continue;
+
+ if (*token)
+ {
+ if (strEqual(token, "include"))
+ {
+ if (getHashEntry(include_filename_hash, value) == NULL)
+ {
+ char *basepath = getBasePath(filename);
+ char *basename = getBaseName(value);
+ char *filename_include = getPath2(basepath, basename);
+
+#if 0
+ Error(ERR_INFO, "[including file '%s']", filename_include);
+#endif
+
+ loadSetupFileData(setup_file_data, filename_include, FALSE, is_hash);
+
+ free(basepath);
+ free(basename);
+ free(filename_include);
+
+ include_count++;
+ }
+ else
+ {
+ Error(ERR_WARN, "ignoring already processed file '%s'", value);
+ }
+ }
+ else
+ {
+ if (is_hash)
+ {
+#if CHECK_TOKEN__WARN_IF_ALREADY_EXISTS_IN_HASH
+ char *old_value =
+ getHashEntry((SetupFileHash *)setup_file_data, token);
+
+ if (old_value != NULL)
+ {
+ if (!token_already_exists_warning)
+ {
+ Error(ERR_INFO_LINE, "-");
+ Error(ERR_WARN, "duplicate token(s) found in config file:");
+ Error(ERR_INFO, "- config file: '%s'", filename);
+
+ token_already_exists_warning = TRUE;
+ }
+
+ Error(ERR_INFO, "- token: '%s' (in line %d)", token, line_nr);
+ Error(ERR_INFO, " old value: '%s'", old_value);
+ Error(ERR_INFO, " new value: '%s'", value);
+ }
+#endif
+
+ setHashEntry((SetupFileHash *)setup_file_data, token, value);
+ }
+ else
+ {
+ insert_ptr = addListEntry((SetupFileList *)insert_ptr, token, value);
+ }
+
+ token_count++;
+ }
+ }
+ }
+
+ closeFile(file);
+
+#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING
+ if (token_value_separator_warning)
+ Error(ERR_INFO_LINE, "-");
+#endif
+
+#if CHECK_TOKEN__WARN_IF_ALREADY_EXISTS_IN_HASH
+ if (token_already_exists_warning)
+ Error(ERR_INFO_LINE, "-");
+#endif
+
+ if (token_count == 0 && include_count == 0)
+ Error(ERR_WARN, "configuration file '%s' is empty", filename);
+
+ if (top_recursion_level)
+ freeSetupFileHash(include_filename_hash);
+
+ return TRUE;
+}
+
+#else
+
static boolean loadSetupFileData(void *setup_file_data, char *filename,
boolean top_recursion_level, boolean is_hash)
{
return TRUE;
}
+#endif
+
#else
static boolean loadSetupFileData(void *setup_file_data, char *filename,
checked_free(ti->special_flags);
}
+ // recursively free child node
+ if (ti->node_group)
+ freeTreeInfo(ti->node_group);
+
+ // recursively free next node
+ if (ti->next)
+ freeTreeInfo(ti->next);
+
checked_free(ti);
}
return TRUE;
}
+#if 1
static void LoadLevelInfoFromLevelDir(TreeInfo **node_first,
TreeInfo *node_parent,
char *level_directory)
{
- DIR *dir;
- struct dirent *dir_entry;
+ Directory *dir;
+ DirectoryEntry *dir_entry;
boolean valid_entry_found = FALSE;
-#if 1
+#if 0
Error(ERR_INFO, "looking for levels in '%s' ...", level_directory);
#endif
- if ((dir = opendir(level_directory)) == NULL)
+ if ((dir = openDirectory(level_directory)) == NULL)
{
Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
return;
}
- while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
+#if 0
+ Error(ERR_INFO, "opening '%s' succeeded ...", level_directory);
+#endif
+
+ while ((dir_entry = readDirectory(dir)) != NULL) /* loop all entries */
{
- struct stat file_status;
- char *directory_name = dir_entry->d_name;
+ char *directory_name = dir_entry->basename;
char *directory_path = getPath2(level_directory, directory_name);
+#if 0
+ Error(ERR_INFO, "checking entry '%s' ...", directory_name);
+#endif
+
/* skip entries for current and parent directory */
if (strEqual(directory_name, ".") ||
strEqual(directory_name, ".."))
{
free(directory_path);
+
continue;
}
+#if 1
+ /* find out if directory entry is itself a directory */
+ if (!dir_entry->is_directory) /* not a directory */
+ {
+ free(directory_path);
+
+#if 0
+ Error(ERR_INFO, "* entry '%s' is not a directory ...", directory_name);
+#endif
+
+ continue;
+ }
+#else
/* find out if directory entry is itself a directory */
+ struct stat file_status;
if (stat(directory_path, &file_status) != 0 || /* cannot stat file */
(file_status.st_mode & S_IFMT) != S_IFDIR) /* not a directory */
{
free(directory_path);
+
continue;
}
+#endif
free(directory_path);
directory_name);
}
- closedir(dir);
+ closeDirectory(dir);
/* special case: top level directory may directly contain "levelinfo.conf" */
if (node_parent == NULL && !valid_entry_found)
level_directory);
}
-boolean AdjustGraphicsForEMC()
+#else
+
+static void LoadLevelInfoFromLevelDir(TreeInfo **node_first,
+ TreeInfo *node_parent,
+ char *level_directory)
{
- boolean settings_changed = FALSE;
+ DIR *dir;
+ struct dirent *dir_entry;
+ boolean valid_entry_found = FALSE;
- settings_changed |= adjustTreeGraphicsForEMC(leveldir_first_all);
- settings_changed |= adjustTreeGraphicsForEMC(leveldir_first);
+#if 1
+ Error(ERR_INFO, "looking for levels in '%s' ...", level_directory);
+#endif
- return settings_changed;
-}
+ if ((dir = opendir(level_directory)) == NULL)
+ {
+ Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
-void LoadLevelInfo()
-{
- InitUserLevelDirectory(getLoginName());
+ return;
+ }
- DrawInitText("Loading level series", 120, FC_GREEN);
+#if 1
+ Error(ERR_INFO, "opening '%s' succeeded ...", level_directory);
+#endif
- LoadLevelInfoFromLevelDir(&leveldir_first, NULL, options.level_directory);
- LoadLevelInfoFromLevelDir(&leveldir_first, NULL, getUserLevelDir(NULL));
+ while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
+ {
+ struct stat file_status;
+ char *directory_name = dir_entry->d_name;
+ char *directory_path = getPath2(level_directory, directory_name);
- /* after loading all level set information, clone the level directory tree
+#if 1
+ Error(ERR_INFO, "checking entry '%s' ...", directory_name);
+#endif
+
+ /* skip entries for current and parent directory */
+ if (strEqual(directory_name, ".") ||
+ strEqual(directory_name, ".."))
+ {
+ free(directory_path);
+ continue;
+ }
+
+ /* find out if directory entry is itself a directory */
+ if (stat(directory_path, &file_status) != 0 || /* cannot stat file */
+ (file_status.st_mode & S_IFMT) != S_IFDIR) /* not a directory */
+ {
+ free(directory_path);
+ continue;
+ }
+
+ free(directory_path);
+
+ if (strEqual(directory_name, GRAPHICS_DIRECTORY) ||
+ strEqual(directory_name, SOUNDS_DIRECTORY) ||
+ strEqual(directory_name, MUSIC_DIRECTORY))
+ continue;
+
+ valid_entry_found |= LoadLevelInfoFromLevelConf(node_first, node_parent,
+ level_directory,
+ directory_name);
+ }
+
+ closedir(dir);
+
+ /* special case: top level directory may directly contain "levelinfo.conf" */
+ if (node_parent == NULL && !valid_entry_found)
+ {
+ /* check if this directory directly contains a file "levelinfo.conf" */
+ valid_entry_found |= LoadLevelInfoFromLevelConf(node_first, node_parent,
+ level_directory, ".");
+ }
+
+ if (!valid_entry_found)
+ Error(ERR_WARN, "cannot find any valid level series in directory '%s'",
+ level_directory);
+}
+#endif
+
+boolean AdjustGraphicsForEMC()
+{
+ boolean settings_changed = FALSE;
+
+ settings_changed |= adjustTreeGraphicsForEMC(leveldir_first_all);
+ settings_changed |= adjustTreeGraphicsForEMC(leveldir_first);
+
+ return settings_changed;
+}
+
+void LoadLevelInfo()
+{
+ InitUserLevelDirectory(getLoginName());
+
+ DrawInitText("Loading level series", 120, FC_GREEN);
+
+ LoadLevelInfoFromLevelDir(&leveldir_first, NULL, options.level_directory);
+ LoadLevelInfoFromLevelDir(&leveldir_first, NULL, getUserLevelDir(NULL));
+
+ /* 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()") */
#endif
}
+#if 1
+
+static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
+ TreeInfo *node_parent,
+ char *base_directory,
+ char *directory_name, int type)
+{
+ char *directory_path = getPath2(base_directory, directory_name);
+ char *filename = getPath2(directory_path, ARTWORKINFO_FILENAME(type));
+ SetupFileHash *setup_file_hash = NULL;
+ TreeInfo *artwork_new = NULL;
+ int i;
+
+ if (fileExists(filename))
+ setup_file_hash = loadSetupFileHash(filename);
+
+ if (setup_file_hash == NULL) /* no config file -- look for artwork files */
+ {
+ Directory *dir;
+ DirectoryEntry *dir_entry;
+ boolean valid_file_found = FALSE;
+
+ if ((dir = openDirectory(directory_path)) != NULL)
+ {
+ while ((dir_entry = readDirectory(dir)) != NULL)
+ {
+ char *entry_name = dir_entry->basename;
+
+ if (FileIsArtworkType(entry_name, type))
+ {
+ valid_file_found = TRUE;
+
+ break;
+ }
+ }
+
+ closeDirectory(dir);
+ }
+
+ if (!valid_file_found)
+ {
+ if (!strEqual(directory_name, "."))
+ Error(ERR_WARN, "ignoring artwork directory '%s'", directory_path);
+
+ free(directory_path);
+ free(filename);
+
+ return FALSE;
+ }
+ }
+
+ artwork_new = newTreeInfo();
+
+ if (node_parent)
+ setTreeInfoToDefaultsFromParent(artwork_new, node_parent);
+ else
+ setTreeInfoToDefaults(artwork_new, type);
+
+ artwork_new->subdir = getStringCopy(directory_name);
+
+ if (setup_file_hash) /* (before defining ".color" and ".class_desc") */
+ {
+#if 0
+ checkSetupFileHashIdentifier(setup_file_hash, filename, getCookie("..."));
+#endif
+
+ /* set all structure fields according to the token/value pairs */
+ ldi = *artwork_new;
+ for (i = 0; i < NUM_LEVELINFO_TOKENS; i++)
+ setSetupInfo(levelinfo_tokens, i,
+ getHashEntry(setup_file_hash, levelinfo_tokens[i].text));
+ *artwork_new = ldi;
+
+ if (strEqual(artwork_new->name, ANONYMOUS_NAME))
+ setString(&artwork_new->name, artwork_new->subdir);
+
+ if (artwork_new->identifier == NULL)
+ artwork_new->identifier = getStringCopy(artwork_new->subdir);
+
+ if (artwork_new->name_sorting == NULL)
+ artwork_new->name_sorting = getStringCopy(artwork_new->name);
+ }
+
+ if (node_parent == NULL) /* top level group */
+ {
+ artwork_new->basepath = getStringCopy(base_directory);
+ artwork_new->fullpath = getStringCopy(artwork_new->subdir);
+ }
+ else /* sub level group */
+ {
+ artwork_new->basepath = getStringCopy(node_parent->basepath);
+ artwork_new->fullpath = getPath2(node_parent->fullpath, directory_name);
+ }
+
+ artwork_new->in_user_dir =
+ (!strEqual(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type)));
+
+ /* (may use ".sort_priority" from "setup_file_hash" above) */
+ artwork_new->color = ARTWORKCOLOR(artwork_new);
+
+ setString(&artwork_new->class_desc, getLevelClassDescription(artwork_new));
+
+ if (setup_file_hash == NULL) /* (after determining ".user_defined") */
+ {
+ if (strEqual(artwork_new->subdir, "."))
+ {
+ if (artwork_new->user_defined)
+ {
+ setString(&artwork_new->identifier, "private");
+ artwork_new->sort_priority = ARTWORKCLASS_PRIVATE;
+ }
+ else
+ {
+ setString(&artwork_new->identifier, "classic");
+ artwork_new->sort_priority = ARTWORKCLASS_CLASSICS;
+ }
+
+ /* set to new values after changing ".sort_priority" */
+ artwork_new->color = ARTWORKCOLOR(artwork_new);
+
+ setString(&artwork_new->class_desc,
+ getLevelClassDescription(artwork_new));
+ }
+ else
+ {
+ setString(&artwork_new->identifier, artwork_new->subdir);
+ }
+
+ setString(&artwork_new->name, artwork_new->identifier);
+ setString(&artwork_new->name_sorting, artwork_new->name);
+ }
+
+#if 0
+ DrawInitText(artwork_new->name, 150, FC_YELLOW);
+#endif
+
+ pushTreeInfo(node_first, artwork_new);
+
+ freeSetupFileHash(setup_file_hash);
+
+ free(directory_path);
+ free(filename);
+
+ return TRUE;
+}
+
+#else
+
static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
TreeInfo *node_parent,
char *base_directory,
return TRUE;
}
+#endif
+
+#if 1
+
+static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first,
+ TreeInfo *node_parent,
+ char *base_directory, int type)
+{
+ Directory *dir;
+ DirectoryEntry *dir_entry;
+ boolean valid_entry_found = FALSE;
+
+ if ((dir = openDirectory(base_directory)) == NULL)
+ {
+ /* display error if directory is main "options.graphics_directory" etc. */
+ if (base_directory == OPTIONS_ARTWORK_DIRECTORY(type))
+ Error(ERR_WARN, "cannot read directory '%s'", base_directory);
+
+ return;
+ }
+
+ while ((dir_entry = readDirectory(dir)) != NULL) /* loop all entries */
+ {
+ char *directory_name = dir_entry->basename;
+ char *directory_path = getPath2(base_directory, directory_name);
+
+ /* skip directory entries for current and parent directory */
+ if (strEqual(directory_name, ".") ||
+ strEqual(directory_name, ".."))
+ {
+ free(directory_path);
+
+ continue;
+ }
+
+#if 1
+ /* skip directory entries which are not a directory */
+ if (!dir_entry->is_directory) /* not a directory */
+ {
+ free(directory_path);
+
+ continue;
+ }
+#else
+ /* skip directory entries which are not a directory or are not accessible */
+ struct stat file_status;
+ if (stat(directory_path, &file_status) != 0 || /* cannot stat file */
+ (file_status.st_mode & S_IFMT) != S_IFDIR) /* not a directory */
+ {
+ free(directory_path);
+
+ continue;
+ }
+#endif
+
+ free(directory_path);
+
+ /* check if this directory contains artwork with or without config file */
+ valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first, node_parent,
+ base_directory,
+ directory_name, type);
+ }
+
+ closeDirectory(dir);
+
+ /* check if this directory directly contains artwork itself */
+ valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first, node_parent,
+ base_directory, ".",
+ type);
+ if (!valid_entry_found)
+ Error(ERR_WARN, "cannot find any valid artwork in directory '%s'",
+ base_directory);
+}
+
+#else
+
static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first,
TreeInfo *node_parent,
char *base_directory, int type)
base_directory);
}
+#endif
+
static TreeInfo *getDummyArtworkInfo(int type)
{
/* this is only needed when there is completely no artwork available */
void LoadLevelArtworkInfo()
{
+ print_timestamp_init("LoadLevelArtworkInfo");
+
DrawInitText("Looking for custom level artwork", 120, FC_GREEN);
+ print_timestamp_time("DrawTimeText");
+
LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first_all);
+ print_timestamp_time("LoadArtworkInfoFromLevelInfo (gfx)");
LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first_all);
+ print_timestamp_time("LoadArtworkInfoFromLevelInfo (snd)");
LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first_all);
+ print_timestamp_time("LoadArtworkInfoFromLevelInfo (mus)");
SaveArtworkInfoCache();
+ print_timestamp_time("SaveArtworkInfoCache");
+
/* needed for reloading level artwork not known at ealier stage */
if (!strEqual(artwork.gfx_current_identifier, setup.graphics_set))
artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first);
}
+ print_timestamp_time("getTreeInfoFromIdentifier");
+
sortTreeInfo(&artwork.gfx_first);
sortTreeInfo(&artwork.snd_first);
sortTreeInfo(&artwork.mus_first);
+ print_timestamp_time("sortTreeInfo");
+
#if 0
dumpTreeInfo(artwork.gfx_first, 0);
dumpTreeInfo(artwork.snd_first, 0);
dumpTreeInfo(artwork.mus_first, 0);
#endif
+
+ print_timestamp_done("LoadLevelArtworkInfo");
}
static void SaveUserLevelInfo()
SaveLevelSetup_LastSeries_Ext(TRUE);
}
+#if 1
+
+static void checkSeriesInfo()
+{
+ static char *level_directory = NULL;
+ Directory *dir;
+#if 0
+ DirectoryEntry *dir_entry;
+#endif
+
+ /* check for more levels besides the 'levels' field of 'levelinfo.conf' */
+
+ level_directory = getPath2((leveldir_current->in_user_dir ?
+ getUserLevelDir(NULL) :
+ options.level_directory),
+ leveldir_current->fullpath);
+
+ if ((dir = openDirectory(level_directory)) == NULL)
+ {
+ Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
+
+ return;
+ }
+
+#if 0
+ while ((dir_entry = readDirectory(dir)) != NULL) /* last directory entry */
+ {
+ if (strlen(dir_entry->basename) > 4 &&
+ dir_entry->basename[3] == '.' &&
+ strEqual(&dir_entry->basename[4], LEVELFILE_EXTENSION))
+ {
+ char levelnum_str[4];
+ int levelnum_value;
+
+ strncpy(levelnum_str, dir_entry->basename, 3);
+ levelnum_str[3] = '\0';
+
+ levelnum_value = atoi(levelnum_str);
+
+ if (levelnum_value < leveldir_current->first_level)
+ {
+ Error(ERR_WARN, "additional level %d found", levelnum_value);
+ leveldir_current->first_level = levelnum_value;
+ }
+ else if (levelnum_value > leveldir_current->last_level)
+ {
+ Error(ERR_WARN, "additional level %d found", levelnum_value);
+ leveldir_current->last_level = levelnum_value;
+ }
+ }
+ }
+#endif
+
+ closeDirectory(dir);
+}
+
+#else
+
static void checkSeriesInfo()
{
static char *level_directory = NULL;
closedir(dir);
}
+#endif
+
void LoadLevelSetup_SeriesInfo()
{
char *filename;