-/***********************************************************
-* Artsoft Retro-Game Library *
-*----------------------------------------------------------*
-* (c) 1994-2006 Artsoft Entertainment *
-* Holger Schemel *
-* Detmolder Strasse 189 *
-* 33604 Bielefeld *
-* Germany *
-* e-mail: info@artsoft.org *
-*----------------------------------------------------------*
-* setup.c *
-***********************************************************/
+// ============================================================================
+// Artsoft Retro-Game Library
+// ----------------------------------------------------------------------------
+// (c) 1995-2014 by Artsoft Entertainment
+// Holger Schemel
+// info@artsoft.org
+// http://www.artsoft.org/
+// ----------------------------------------------------------------------------
+// setup.c
+// ============================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include "hash.h"
+#define ENABLE_UNUSED_CODE FALSE /* for currently unused functions */
+
#define NUM_LEVELCLASS_DESC 8
static char *levelclass_desc[NUM_LEVELCLASS_DESC] =
{
static char *artwork_dir = NULL;
+ if (ti == NULL)
+ return NULL;
+
checked_free(artwork_dir);
artwork_dir = getPath2(ti->basepath, ti->fullpath);
return LEVELDIR_ARTWORK_PATH(leveldir_current, type);
}
+char *getProgramConfigFilename(char *command_filename_ptr)
+{
+ char *command_filename_1 = getStringCopy(command_filename_ptr);
+
+ // 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 *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");
+
+ // 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;
+}
+
char *getTapeFilename(int nr)
{
static char *filename = NULL;
return filename;
}
+char *getDefaultSetupFilename()
+{
+ return program.config_filename;
+}
+
char *getEditorSetupFilename()
{
static char *filename = NULL;
static char *getCorrectedArtworkBasename(char *basename)
{
- char *basename_corrected = basename;
-
-#if defined(PLATFORM_MSDOS)
- if (program.filename_prefix != NULL)
- {
- int prefix_len = strlen(program.filename_prefix);
-
- if (strncmp(basename, program.filename_prefix, prefix_len) == 0)
- basename_corrected = &basename[prefix_len];
-
- /* if corrected filename is still longer than standard MS-DOS filename
- size (8 characters + 1 dot + 3 characters file extension), shorten
- filename by writing file extension after 8th basename character */
- if (strlen(basename_corrected) > 8 + 1 + 3)
- {
- static char *msdos_filename = NULL;
-
- checked_free(msdos_filename);
-
- msdos_filename = getStringCopy(basename_corrected);
- strncpy(&msdos_filename[8], &basename[strlen(basename) - (1+3)], 1+3 +1);
-
- basename_corrected = msdos_filename;
- }
- }
-#endif
-
- return basename_corrected;
+ return basename;
}
char *getCustomImageFilename(char *basename)
if (!gfx.override_level_graphics)
{
/* 1st try: look for special artwork in current level series directory */
- filename = getPath3(getCurrentLevelDir(), GRAPHICS_DIRECTORY, basename);
+ filename = getImg3(getCurrentLevelDir(), GRAPHICS_DIRECTORY, basename);
if (fileExists(filename))
return filename;
if (getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) != NULL)
{
/* 2nd try: look for special artwork configured in level series config */
- filename = getPath2(getLevelArtworkDir(ARTWORK_TYPE_GRAPHICS), basename);
+ filename = getImg2(getLevelArtworkDir(ARTWORK_TYPE_GRAPHICS), basename);
if (fileExists(filename))
return filename;
if (!skip_setup_artwork)
{
/* 3rd try: look for special artwork in configured artwork directory */
- filename = getPath2(getSetupArtworkDir(artwork.gfx_current), basename);
+ filename = getImg2(getSetupArtworkDir(artwork.gfx_current), basename);
if (fileExists(filename))
return filename;
}
/* 4th try: look for default artwork in new default artwork directory */
- filename = getPath2(getDefaultGraphicsDir(GFX_DEFAULT_SUBDIR), basename);
+ filename = getImg2(getDefaultGraphicsDir(GFX_DEFAULT_SUBDIR), basename);
if (fileExists(filename))
return filename;
free(filename);
/* 5th try: look for default artwork in old default artwork directory */
- filename = getPath2(options.graphics_directory, basename);
+ filename = getImg2(options.graphics_directory, basename);
if (fileExists(filename))
return filename;
-#if defined(CREATE_SPECIAL_EDITION)
- free(filename);
+ if (!strEqual(GFX_FALLBACK_FILENAME, UNDEFINED_FILENAME))
+ {
+ free(filename);
- if (options.debug)
- Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)", basename);
+ if (options.debug)
+ Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)",
+ basename);
- /* 6th try: look for fallback artwork in old default artwork directory */
- /* (needed to prevent errors when trying to access unused artwork files) */
- filename = getPath2(options.graphics_directory, GFX_FALLBACK_FILENAME);
- if (fileExists(filename))
- return filename;
-#endif
+ /* 6th try: look for fallback artwork in old default artwork directory */
+ /* (needed to prevent errors when trying to access unused artwork files) */
+ filename = getImg2(options.graphics_directory, GFX_FALLBACK_FILENAME);
+ if (fileExists(filename))
+ return filename;
+ }
return NULL; /* cannot find specified artwork file anywhere */
}
if (fileExists(filename))
return filename;
-#if defined(CREATE_SPECIAL_EDITION)
- free(filename);
+ if (!strEqual(SND_FALLBACK_FILENAME, UNDEFINED_FILENAME))
+ {
+ free(filename);
- if (options.debug)
- Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)", basename);
+ if (options.debug)
+ Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)",
+ basename);
- /* 6th try: look for fallback artwork in old default artwork directory */
- /* (needed to prevent errors when trying to access unused artwork files) */
- filename = getPath2(options.sounds_directory, SND_FALLBACK_FILENAME);
- if (fileExists(filename))
- return filename;
-#endif
+ /* 6th try: look for fallback artwork in old default artwork directory */
+ /* (needed to prevent errors when trying to access unused artwork files) */
+ filename = getPath2(options.sounds_directory, SND_FALLBACK_FILENAME);
+ if (fileExists(filename))
+ return filename;
+ }
return NULL; /* cannot find specified artwork file anywhere */
}
if (fileExists(filename))
return filename;
-#if defined(CREATE_SPECIAL_EDITION)
- free(filename);
+ if (!strEqual(MUS_FALLBACK_FILENAME, UNDEFINED_FILENAME))
+ {
+ free(filename);
- if (options.debug)
- Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)", basename);
+ if (options.debug)
+ Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)",
+ basename);
- /* 6th try: look for fallback artwork in old default artwork directory */
- /* (needed to prevent errors when trying to access unused artwork files) */
- filename = getPath2(options.music_directory, MUS_FALLBACK_FILENAME);
- if (fileExists(filename))
- return filename;
-#endif
+ /* 6th try: look for fallback artwork in old default artwork directory */
+ /* (needed to prevent errors when trying to access unused artwork files) */
+ filename = getPath2(options.music_directory, MUS_FALLBACK_FILENAME);
+ if (fileExists(filename))
+ return filename;
+ }
return NULL; /* cannot find specified artwork file anywhere */
}
return cloneTreeNode(node_top, node_parent, node->next,
skip_sets_without_levels);
-#if 1
node_new = getTreeInfoCopy(node); /* copy complete node */
-#else
- node_new = newTreeInfo();
-
- *node_new = *node; /* copy complete node */
-#endif
node_new->node_top = node_top; /* correct top node link */
node_new->node_parent = node_parent; /* correct parent node link */
return user_game_data_dir;
}
-void updateUserGameDataDir()
-{
-#if defined(PLATFORM_MACOSX)
- char *userdata_dir_old = getPath2(getHomeDir(), program.userdata_subdir_unix);
- char *userdata_dir_new = getUserGameDataDir(); /* do not free() this */
-
- /* convert old Unix style game data directory to Mac OS X style, if needed */
- if (directoryExists(userdata_dir_old) && !directoryExists(userdata_dir_new))
- {
- if (rename(userdata_dir_old, userdata_dir_new) != 0)
- {
- Error(ERR_WARN, "cannot move game data directory '%s' to '%s'",
- userdata_dir_old, userdata_dir_new);
-
- /* continue using Unix style data directory -- this should not happen */
- program.userdata_path = getPath2(getPersonalDataDir(),
- program.userdata_subdir_unix);
- }
- }
-
- free(userdata_dir_old);
-#endif
-}
-
char *getSetupDir()
{
return getUserGameDataDir();
return cookie;
}
+void fprintFileHeader(FILE *file, char *basename)
+{
+ char *prefix = "# ";
+ char *sep1 = "=";
+
+ fprintf_line_with_prefix(file, prefix, sep1, 77);
+ fprintf(file, "%s%s\n", prefix, basename);
+ fprintf_line_with_prefix(file, prefix, sep1, 77);
+ fprintf(file, "\n");
+}
+
int getFileVersionFromCookieString(const char *cookie)
{
const char *ptr_cookie1, *ptr_cookie2;
return TRUE;
}
+
/* ------------------------------------------------------------------------- */
/* setup file list and hash handling functions */
/* ------------------------------------------------------------------------- */
return addListEntry(list->next, token, value);
}
-#if 0
+#if ENABLE_UNUSED_CODE
#ifdef DEBUG
static void printSetupFileList(SetupFileList *list)
{
return remove_hash_entry(hash, token);
}
-#if 0
+#if ENABLE_UNUSED_CODE
+#if DEBUG
static void printSetupFileHash(SetupFileHash *hash)
{
BEGIN_HASH_ITERATION(hash, itr)
END_HASH_ITERATION(hash, itr)
}
#endif
+#endif
#define ALLOW_TOKEN_VALUE_SEPARATOR_BEING_WHITESPACE 1
#define CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING 0
/* find end of token to determine start of value */
for (line_ptr = token; *line_ptr; line_ptr++)
{
-#if 1
/* first look for an explicit token/value separator, like ':' or '=' */
if (*line_ptr == ':' || *line_ptr == '=')
-#else
- if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':')
-#endif
{
*line_ptr = '\0'; /* terminate token string */
value = line_ptr + 1; /* set beginning of value */
if (*value != ' ' && *value != '\t')
break;
-#if 0
- if (*value == '\0')
- value = "true"; /* treat tokens without value as "true" */
-#endif
-
*token_ptr = token;
*value_ptr = value;
return getTokenValueFromSetupLineExt(line, token, value, NULL, NULL, 0, TRUE);
}
-#if 1
-
-#if 1
static boolean loadSetupFileData(void *setup_file_data, char *filename,
boolean top_recursion_level, boolean is_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;
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++;
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);
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);
return TRUE;
}
-#else
-
-static boolean loadSetupFileData(void *setup_file_data, char *filename,
- boolean top_recursion_level, boolean is_hash)
+void saveSetupFileHash(SetupFileHash *hash, char *filename)
{
- 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 (!(file = fopen(filename, MODE_READ)))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
- Error(ERR_WARN, "cannot open configuration file '%s'", filename);
+ Error(ERR_WARN, "cannot write configuration file '%s'", filename);
- return FALSE;
+ return;
}
- /* use "insert pointer" to store list end for constant insertion complexity */
- if (!is_hash)
- insert_ptr = setup_file_data;
+ BEGIN_HASH_ITERATION(hash, itr)
+ {
+ fprintf(file, "%s\n", getFormattedSetupEntry(HASH_ITERATION_TOKEN(itr),
+ HASH_ITERATION_VALUE(itr)));
+ }
+ END_HASH_ITERATION(hash, itr)
- /* on top invocation, create hash to mark included files (to prevent loops) */
- if (top_recursion_level)
- include_filename_hash = newSetupFileHash();
+ fclose(file);
+}
- /* mark this file as already included (to prevent including it again) */
- setHashEntry(include_filename_hash, getBaseNamePtr(filename), "true");
+SetupFileList *loadSetupFileList(char *filename)
+{
+ SetupFileList *setup_file_list = newSetupFileList("", "");
+ SetupFileList *first_valid_list_entry;
- while (!feof(file))
+ if (!loadSetupFileData(setup_file_list, filename, TRUE, FALSE))
{
- /* read next line of input file */
- if (!fgets(line, MAX_LINE_LEN, file))
- break;
-
- /* check if line was completely read and is terminated by line break */
- if (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
- line_nr++;
+ freeSetupFileList(setup_file_list);
- /* 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';
+ return NULL;
+ }
- /* copy raw input line for later use (mainly debugging output) */
- strcpy(line_raw, line);
+ first_valid_list_entry = setup_file_list->next;
- 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
+ /* free empty list header */
+ setup_file_list->next = NULL;
+ freeSetupFileList(setup_file_list);
- /* 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);
+ return first_valid_list_entry;
+}
- strcpy(line, previous_line); /* copy storage buffer to line */
+SetupFileHash *loadSetupFileHash(char *filename)
+{
+ SetupFileHash *setup_file_hash = newSetupFileHash();
- read_continued_line = FALSE;
- }
+ if (!loadSetupFileData(setup_file_hash, filename, TRUE, TRUE))
+ {
+ freeSetupFileHash(setup_file_hash);
- /* 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 */
+ return NULL;
+ }
- read_continued_line = TRUE;
+ return setup_file_hash;
+}
- continue;
- }
- if (!getTokenValueFromSetupLineExt(line, &token, &value, filename,
- line_raw, line_nr, FALSE))
- continue;
+/* ========================================================================= */
+/* setup file stuff */
+/* ========================================================================= */
- 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);
+#define TOKEN_STR_LAST_LEVEL_SERIES "last_level_series"
+#define TOKEN_STR_LAST_PLAYED_LEVEL "last_played_level"
+#define TOKEN_STR_HANDICAP_LEVEL "handicap_level"
-#if 0
- Error(ERR_INFO, "[including file '%s']", filename_include);
-#endif
+/* level directory info */
+#define LEVELINFO_TOKEN_IDENTIFIER 0
+#define LEVELINFO_TOKEN_NAME 1
+#define LEVELINFO_TOKEN_NAME_SORTING 2
+#define LEVELINFO_TOKEN_AUTHOR 3
+#define LEVELINFO_TOKEN_YEAR 4
+#define LEVELINFO_TOKEN_IMPORTED_FROM 5
+#define LEVELINFO_TOKEN_IMPORTED_BY 6
+#define LEVELINFO_TOKEN_TESTED_BY 7
+#define LEVELINFO_TOKEN_LEVELS 8
+#define LEVELINFO_TOKEN_FIRST_LEVEL 9
+#define LEVELINFO_TOKEN_SORT_PRIORITY 10
+#define LEVELINFO_TOKEN_LATEST_ENGINE 11
+#define LEVELINFO_TOKEN_LEVEL_GROUP 12
+#define LEVELINFO_TOKEN_READONLY 13
+#define LEVELINFO_TOKEN_GRAPHICS_SET_ECS 14
+#define LEVELINFO_TOKEN_GRAPHICS_SET_AGA 15
+#define LEVELINFO_TOKEN_GRAPHICS_SET 16
+#define LEVELINFO_TOKEN_SOUNDS_SET 17
+#define LEVELINFO_TOKEN_MUSIC_SET 18
+#define LEVELINFO_TOKEN_FILENAME 19
+#define LEVELINFO_TOKEN_FILETYPE 20
+#define LEVELINFO_TOKEN_SPECIAL_FLAGS 21
+#define LEVELINFO_TOKEN_HANDICAP 22
+#define LEVELINFO_TOKEN_SKIP_LEVELS 23
- loadSetupFileData(setup_file_data, filename_include, FALSE, is_hash);
+#define NUM_LEVELINFO_TOKENS 24
- 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++;
- }
- }
- }
-
- fclose(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;
-}
-
-#endif
-
-#else
-
-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;
- int token_count = 0;
-
-#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING
- token_value_separator_warning = FALSE;
-#endif
-
- if (!(file = fopen(filename, MODE_READ)))
- {
- Error(ERR_WARN, "cannot open configuration file '%s'", filename);
-
- return FALSE;
- }
-
- /* 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 (!feof(file))
- {
- /* read next line of input file */
- if (!fgets(line, MAX_LINE_LEN, file))
- break;
-
- /* 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)
- {
- /* cut leading whitespaces from input line */
- for (line_ptr = line; *line_ptr; line_ptr++)
- if (*line_ptr != ' ' && *line_ptr != '\t')
- break;
-
- /* 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;
- }
-
- /* cut trailing comment from input line */
- for (line_ptr = line; *line_ptr; line_ptr++)
- {
- if (*line_ptr == '#')
- {
- *line_ptr = '\0';
- break;
- }
- }
-
- /* cut trailing whitespaces from input line */
- for (line_ptr = &line[strlen(line)]; line_ptr >= line; line_ptr--)
- if ((*line_ptr == ' ' || *line_ptr == '\t') && *(line_ptr + 1) == '\0')
- *line_ptr = '\0';
-
- /* ignore empty lines */
- if (*line == '\0')
- continue;
-
- /* cut leading whitespaces from token */
- for (token = line; *token; token++)
- if (*token != ' ' && *token != '\t')
- break;
-
- /* start with empty value as reliable default */
- value = "";
-
- token_value_separator_found = FALSE;
-
- /* find end of token to determine start of value */
- for (line_ptr = token; *line_ptr; line_ptr++)
- {
-#if 1
- /* first look for an explicit token/value separator, like ':' or '=' */
- if (*line_ptr == ':' || *line_ptr == '=')
-#else
- if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':')
-#endif
- {
- *line_ptr = '\0'; /* terminate token string */
- value = line_ptr + 1; /* set beginning of value */
-
- token_value_separator_found = TRUE;
-
- break;
- }
- }
-
-#if ALLOW_TOKEN_VALUE_SEPARATOR_BEING_WHITESPACE
- /* fallback: if no token/value separator found, also allow whitespaces */
- if (!token_value_separator_found)
- {
- for (line_ptr = token; *line_ptr; line_ptr++)
- {
- if (*line_ptr == ' ' || *line_ptr == '\t')
- {
- *line_ptr = '\0'; /* terminate token string */
- value = line_ptr + 1; /* set beginning of value */
-
- token_value_separator_found = TRUE;
-
- break;
- }
- }
-
-#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING
- if (token_value_separator_found)
- {
- if (!token_value_separator_warning)
- {
- Error(ERR_INFO_LINE, "-");
- Error(ERR_WARN, "missing token/value separator(s) in config file:");
- Error(ERR_INFO, "- config file: '%s'", filename);
-
- token_value_separator_warning = TRUE;
- }
-
- Error(ERR_INFO, "- line %d: '%s'", line_nr, line_raw);
- }
-#endif
- }
-#endif
-
- /* cut trailing whitespaces from token */
- for (line_ptr = &token[strlen(token)]; line_ptr >= token; line_ptr--)
- if ((*line_ptr == ' ' || *line_ptr == '\t') && *(line_ptr + 1) == '\0')
- *line_ptr = '\0';
-
- /* cut leading whitespaces from value */
- for (; *value; value++)
- if (*value != ' ' && *value != '\t')
- break;
-
-#if 0
- if (*value == '\0')
- value = "true"; /* treat tokens without value as "true" */
-#endif
-
- 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);
- }
- else
- {
- Error(ERR_WARN, "ignoring already processed file '%s'", value);
- }
- }
- else
- {
- if (is_hash)
- setHashEntry((SetupFileHash *)setup_file_data, token, value);
- else
- insert_ptr = addListEntry((SetupFileList *)insert_ptr, token, value);
-
- token_count++;
- }
- }
- }
-
- fclose(file);
-
-#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING
- if (token_value_separator_warning)
- Error(ERR_INFO_LINE, "-");
-#endif
-
- if (token_count == 0)
- Error(ERR_WARN, "configuration file '%s' is empty", filename);
-
- if (top_recursion_level)
- freeSetupFileHash(include_filename_hash);
-
- return TRUE;
-}
-#endif
-
-void saveSetupFileHash(SetupFileHash *hash, char *filename)
-{
- FILE *file;
-
- if (!(file = fopen(filename, MODE_WRITE)))
- {
- Error(ERR_WARN, "cannot write configuration file '%s'", filename);
-
- return;
- }
-
- BEGIN_HASH_ITERATION(hash, itr)
- {
- fprintf(file, "%s\n", getFormattedSetupEntry(HASH_ITERATION_TOKEN(itr),
- HASH_ITERATION_VALUE(itr)));
- }
- END_HASH_ITERATION(hash, itr)
-
- fclose(file);
-}
-
-SetupFileList *loadSetupFileList(char *filename)
-{
- SetupFileList *setup_file_list = newSetupFileList("", "");
- SetupFileList *first_valid_list_entry;
-
- if (!loadSetupFileData(setup_file_list, filename, TRUE, FALSE))
- {
- freeSetupFileList(setup_file_list);
-
- return NULL;
- }
-
- first_valid_list_entry = setup_file_list->next;
-
- /* free empty list header */
- setup_file_list->next = NULL;
- freeSetupFileList(setup_file_list);
-
- return first_valid_list_entry;
-}
-
-SetupFileHash *loadSetupFileHash(char *filename)
-{
- SetupFileHash *setup_file_hash = newSetupFileHash();
-
- if (!loadSetupFileData(setup_file_hash, filename, TRUE, TRUE))
- {
- freeSetupFileHash(setup_file_hash);
-
- return NULL;
- }
-
- return setup_file_hash;
-}
-
-void checkSetupFileHashIdentifier(SetupFileHash *setup_file_hash,
- char *filename, char *identifier)
-{
- char *value = getHashEntry(setup_file_hash, TOKEN_STR_FILE_IDENTIFIER);
-
- if (value == NULL)
- Error(ERR_WARN, "config file '%s' has no file identifier", filename);
- else if (!checkCookieString(value, identifier))
- Error(ERR_WARN, "config file '%s' has wrong file identifier", filename);
-}
-
-
-/* ========================================================================= */
-/* setup file stuff */
-/* ========================================================================= */
-
-#define TOKEN_STR_LAST_LEVEL_SERIES "last_level_series"
-#define TOKEN_STR_LAST_PLAYED_LEVEL "last_played_level"
-#define TOKEN_STR_HANDICAP_LEVEL "handicap_level"
-
-/* level directory info */
-#define LEVELINFO_TOKEN_IDENTIFIER 0
-#define LEVELINFO_TOKEN_NAME 1
-#define LEVELINFO_TOKEN_NAME_SORTING 2
-#define LEVELINFO_TOKEN_AUTHOR 3
-#define LEVELINFO_TOKEN_YEAR 4
-#define LEVELINFO_TOKEN_IMPORTED_FROM 5
-#define LEVELINFO_TOKEN_IMPORTED_BY 6
-#define LEVELINFO_TOKEN_TESTED_BY 7
-#define LEVELINFO_TOKEN_LEVELS 8
-#define LEVELINFO_TOKEN_FIRST_LEVEL 9
-#define LEVELINFO_TOKEN_SORT_PRIORITY 10
-#define LEVELINFO_TOKEN_LATEST_ENGINE 11
-#define LEVELINFO_TOKEN_LEVEL_GROUP 12
-#define LEVELINFO_TOKEN_READONLY 13
-#define LEVELINFO_TOKEN_GRAPHICS_SET_ECS 14
-#define LEVELINFO_TOKEN_GRAPHICS_SET_AGA 15
-#define LEVELINFO_TOKEN_GRAPHICS_SET 16
-#define LEVELINFO_TOKEN_SOUNDS_SET 17
-#define LEVELINFO_TOKEN_MUSIC_SET 18
-#define LEVELINFO_TOKEN_FILENAME 19
-#define LEVELINFO_TOKEN_FILETYPE 20
-#define LEVELINFO_TOKEN_SPECIAL_FLAGS 21
-#define LEVELINFO_TOKEN_HANDICAP 22
-#define LEVELINFO_TOKEN_SKIP_LEVELS 23
-
-#define NUM_LEVELINFO_TOKENS 24
-
-static LevelDirTree ldi;
+static LevelDirTree ldi;
static struct TokenInfo levelinfo_tokens[] =
{
ti->last_level = 0;
ti->level_group = FALSE;
ti->handicap_level = 0;
-#if 1
ti->readonly = parent->readonly;
-#else
- ti->readonly = TRUE;
-#endif
ti->handicap = TRUE;
ti->skip_levels = FALSE;
}
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 compare_result;
}
-static void createParentTreeInfoNode(TreeInfo *node_parent)
+static TreeInfo *createParentTreeInfoNode(TreeInfo *node_parent)
{
TreeInfo *ti_new;
if (node_parent == NULL)
- return;
+ return NULL;
+
+ ti_new = newTreeInfo();
+ setTreeInfoToDefaults(ti_new, node_parent->type);
+
+ ti_new->node_parent = node_parent;
+ ti_new->parent_link = TRUE;
+
+ setString(&ti_new->identifier, node_parent->identifier);
+ setString(&ti_new->name, ".. (parent directory)");
+ setString(&ti_new->name_sorting, ti_new->name);
+
+ setString(&ti_new->subdir, STRING_PARENT_DIRECTORY);
+ setString(&ti_new->fullpath, node_parent->fullpath);
+
+ ti_new->sort_priority = node_parent->sort_priority;
+ ti_new->latest_engine = node_parent->latest_engine;
+
+ setString(&ti_new->class_desc, getLevelClassDescription(ti_new));
+
+ pushTreeInfo(&node_parent->node_group, ti_new);
+
+ return ti_new;
+}
+
+static TreeInfo *createTopTreeInfoNode(TreeInfo *node_first)
+{
+ TreeInfo *ti_new, *ti_new2;
+
+ if (node_first == NULL)
+ return NULL;
ti_new = newTreeInfo();
- setTreeInfoToDefaults(ti_new, node_parent->type);
+ setTreeInfoToDefaults(ti_new, TREE_TYPE_LEVEL_DIR);
- ti_new->node_parent = node_parent;
- ti_new->parent_link = TRUE;
+ ti_new->node_parent = NULL;
+ ti_new->parent_link = FALSE;
- setString(&ti_new->identifier, node_parent->identifier);
- setString(&ti_new->name, ".. (parent directory)");
+ setString(&ti_new->identifier, node_first->identifier);
+ setString(&ti_new->name, "level sets");
setString(&ti_new->name_sorting, ti_new->name);
- setString(&ti_new->subdir, "..");
- setString(&ti_new->fullpath, node_parent->fullpath);
+ setString(&ti_new->subdir, STRING_TOP_DIRECTORY);
+ setString(&ti_new->fullpath, node_first->fullpath);
- ti_new->sort_priority = node_parent->sort_priority;
- ti_new->latest_engine = node_parent->latest_engine;
+ ti_new->sort_priority = node_first->sort_priority;;
+ ti_new->latest_engine = node_first->latest_engine;
- setString(&ti_new->class_desc, getLevelClassDescription(ti_new));
+ setString(&ti_new->class_desc, "level sets");
- pushTreeInfo(&node_parent->node_group, ti_new);
+ ti_new->node_group = node_first;
+ ti_new->level_group = TRUE;
+
+ ti_new2 = createParentTreeInfoNode(ti_new);
+
+ setString(&ti_new2->name, ".. (main menu)");
+ setString(&ti_new2->name_sorting, ti_new2->name);
+
+ return ti_new;
}
static char *getFileTimestampString(char *filename)
{
-#if 1
return getStringCopy(i_to_a(getFileTimestampEpochSeconds(filename)));
-#else
- struct stat file_status;
-
- if (stat(filename, &file_status) != 0) /* cannot stat file */
- return getStringCopy(i_to_a(0));
-
- return getStringCopy(i_to_a(file_status.st_mtime));
-#endif
}
static boolean modifiedFileTimestamp(char *filename, char *timestamp_string)
/* check if cache entry for this item is invalid or incomplete */
if (value == NULL)
{
-#if 1
Error(ERR_WARN, "cache entry '%s' invalid", token);
-#endif
cached = FALSE;
}
if (modifiedFileTimestamp(filename_artworkinfo, cache_entry))
cached = FALSE;
-#if 0
- if (!cached)
- printf("::: '%s': INVALIDATED FROM CACHE BY TIMESTAMP\n", identifier);
-#endif
-
checked_free(filename_levelinfo);
checked_free(filename_artworkinfo);
}
char *level_directory,
char *directory_name)
{
-#if 0
- static unsigned int progress_delay = 0;
- unsigned int progress_delay_value = 100; /* (in milliseconds) */
-#endif
char *directory_path = getPath2(level_directory, directory_name);
char *filename = getPath2(directory_path, LEVELINFO_FILENAME);
SetupFileHash *setup_file_hash;
leveldir_new->subdir = getStringCopy(directory_name);
- checkSetupFileHashIdentifier(setup_file_hash, filename,
- getCookie("LEVELINFO"));
-
/* set all structure fields according to the token/value pairs */
ldi = *leveldir_new;
for (i = 0; i < NUM_LEVELINFO_TOKENS; i++)
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;
leveldir_new->in_user_dir =
(!strEqual(leveldir_new->basepath, options.level_directory));
-#if 0
- printf("::: '%s' -> %d\n",
- leveldir_new->identifier,
- leveldir_new->in_user_dir);
-#endif
-
/* adjust some settings if user's private level directory was detected */
if (leveldir_new->sort_priority == LEVELCLASS_UNDEFINED &&
leveldir_new->in_user_dir &&
(leveldir_new->user_defined || !leveldir_new->handicap ?
leveldir_new->last_level : leveldir_new->first_level);
-#if 1
-#if 1
- DrawInitTextExt(leveldir_new->name, 150, FC_YELLOW,
- leveldir_new->level_group);
-#else
- if (leveldir_new->level_group ||
- DelayReached(&progress_delay, progress_delay_value))
- DrawInitText(leveldir_new->name, 150, FC_YELLOW);
-#endif
-#else
DrawInitText(leveldir_new->name, 150, FC_YELLOW);
-#endif
-
-#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);
return TRUE;
}
-#if 1
static void LoadLevelInfoFromLevelDir(TreeInfo **node_first,
TreeInfo *node_parent,
char *level_directory)
DirectoryEntry *dir_entry;
boolean valid_entry_found = FALSE;
-#if 0
- Error(ERR_INFO, "looking for levels in '%s' ...", level_directory);
-#endif
-
if ((dir = openDirectory(level_directory)) == NULL)
{
Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
return;
}
-#if 0
- Error(ERR_INFO, "opening '%s' succeeded ...", level_directory);
-#endif
-
while ((dir_entry = readDirectory(dir)) != NULL) /* loop all entries */
{
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);
-
- 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);
- }
-
- closeDirectory(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);
-}
-
-#else
-
-static void LoadLevelInfoFromLevelDir(TreeInfo **node_first,
- TreeInfo *node_parent,
- char *level_directory)
-{
- DIR *dir;
- struct dirent *dir_entry;
- boolean valid_entry_found = FALSE;
-
-#if 1
- Error(ERR_INFO, "looking for levels in '%s' ...", level_directory);
-#endif
-
- if ((dir = opendir(level_directory)) == NULL)
- {
- Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
-
- return;
- }
-
-#if 1
- Error(ERR_INFO, "opening '%s' succeeded ...", level_directory);
-#endif
-
- 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);
-
-#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()") */
- leveldir_first_all = leveldir_first;
- cloneTree(&leveldir_first, leveldir_first_all, TRUE);
-
- AdjustGraphicsForEMC();
-
- /* before sorting, the first entries will be from the user directory */
- leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
-
- if (leveldir_first == NULL)
- Error(ERR_EXIT, "cannot find any valid level series in any directory");
-
- sortTreeInfo(&leveldir_first);
-
-#if 0
- dumpTreeInfo(leveldir_first, 0);
-#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
+ /* find out if directory entry is itself a directory */
+ if (!dir_entry->is_directory) /* not a directory */
+ {
+ free(directory_path);
- /* 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;
+ continue;
+ }
- if (strEqual(artwork_new->name, ANONYMOUS_NAME))
- setString(&artwork_new->name, artwork_new->subdir);
+ free(directory_path);
- if (artwork_new->identifier == NULL)
- artwork_new->identifier = getStringCopy(artwork_new->subdir);
+ if (strEqual(directory_name, GRAPHICS_DIRECTORY) ||
+ strEqual(directory_name, SOUNDS_DIRECTORY) ||
+ strEqual(directory_name, MUSIC_DIRECTORY))
+ continue;
- if (artwork_new->name_sorting == NULL)
- artwork_new->name_sorting = getStringCopy(artwork_new->name);
+ valid_entry_found |= LoadLevelInfoFromLevelConf(node_first, node_parent,
+ level_directory,
+ directory_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 */
+ closeDirectory(dir);
+
+ /* special case: top level directory may directly contain "levelinfo.conf" */
+ if (node_parent == NULL && !valid_entry_found)
{
- artwork_new->basepath = getStringCopy(node_parent->basepath);
- artwork_new->fullpath = getPath2(node_parent->fullpath, directory_name);
+ /* check if this directory directly contains a file "levelinfo.conf" */
+ valid_entry_found |= LoadLevelInfoFromLevelConf(node_first, node_parent,
+ level_directory, ".");
}
- artwork_new->in_user_dir =
- (!strEqual(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type)));
+ if (!valid_entry_found)
+ Error(ERR_WARN, "cannot find any valid level series in directory '%s'",
+ level_directory);
+}
- /* (may use ".sort_priority" from "setup_file_hash" above) */
- artwork_new->color = ARTWORKCOLOR(artwork_new);
+boolean AdjustGraphicsForEMC()
+{
+ boolean settings_changed = FALSE;
- setString(&artwork_new->class_desc, getLevelClassDescription(artwork_new));
+ settings_changed |= adjustTreeGraphicsForEMC(leveldir_first_all);
+ settings_changed |= adjustTreeGraphicsForEMC(leveldir_first);
- 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;
- }
+ return settings_changed;
+}
- /* set to new values after changing ".sort_priority" */
- artwork_new->color = ARTWORKCOLOR(artwork_new);
+void LoadLevelInfo()
+{
+ InitUserLevelDirectory(getLoginName());
- setString(&artwork_new->class_desc,
- getLevelClassDescription(artwork_new));
- }
- else
- {
- setString(&artwork_new->identifier, artwork_new->subdir);
- }
+ DrawInitText("Loading level series", 120, FC_GREEN);
- setString(&artwork_new->name, artwork_new->identifier);
- setString(&artwork_new->name_sorting, artwork_new->name);
- }
+ LoadLevelInfoFromLevelDir(&leveldir_first, NULL, options.level_directory);
+ LoadLevelInfoFromLevelDir(&leveldir_first, NULL, getUserLevelDir(NULL));
-#if 0
- DrawInitText(artwork_new->name, 150, FC_YELLOW);
-#endif
+ leveldir_first = createTopTreeInfoNode(leveldir_first);
- pushTreeInfo(node_first, artwork_new);
+ /* 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);
- freeSetupFileHash(setup_file_hash);
+ AdjustGraphicsForEMC();
- free(directory_path);
- free(filename);
+ /* before sorting, the first entries will be from the user directory */
+ leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
- return TRUE;
-}
+ if (leveldir_first == NULL)
+ Error(ERR_EXIT, "cannot find any valid level series in any directory");
-#else
+ sortTreeInfo(&leveldir_first);
+
+#if ENABLE_UNUSED_CODE
+ dumpTreeInfo(leveldir_first, 0);
+#endif
+}
static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
TreeInfo *node_parent,
if (setup_file_hash == NULL) /* no config file -- look for artwork files */
{
- DIR *dir;
- struct dirent *dir_entry;
+ Directory *dir;
+ DirectoryEntry *dir_entry;
boolean valid_file_found = FALSE;
- if ((dir = opendir(directory_path)) != NULL)
+ if ((dir = openDirectory(directory_path)) != NULL)
{
- while ((dir_entry = readdir(dir)) != NULL)
+ while ((dir_entry = readDirectory(dir)) != NULL)
{
- char *entry_name = dir_entry->d_name;
-
- if (FileIsArtworkType(entry_name, type))
+ if (FileIsArtworkType(dir_entry->filename, type))
{
valid_file_found = TRUE;
+
break;
}
}
- closedir(dir);
+ closeDirectory(dir);
}
if (!valid_file_found)
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++)
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);
return TRUE;
}
-#endif
-
-#if 1
-
static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first,
TreeInfo *node_parent,
char *base_directory, int type)
continue;
}
-#if 1
/* skip directory entries which are not a directory */
if (!dir_entry->is_directory) /* not a directory */
{
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);
base_directory);
}
-#else
-
-static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first,
- TreeInfo *node_parent,
- char *base_directory, int type)
-{
- DIR *dir;
- struct dirent *dir_entry;
- boolean valid_entry_found = FALSE;
-
- if ((dir = opendir(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 = readdir(dir)) != NULL) /* loop until last dir entry */
- {
- struct stat file_status;
- char *directory_name = dir_entry->d_name;
- 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;
- }
-
- /* skip directory entries which are not a directory or are not accessible */
- 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);
-
- /* check if this directory contains artwork with or without config file */
- valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first, node_parent,
- base_directory,
- directory_name, type);
- }
-
- closedir(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);
-}
-
-#endif
-
static TreeInfo *getDummyArtworkInfo(int type)
{
/* this is only needed when there is completely no artwork available */
artwork.snd_current_identifier = artwork.snd_current->identifier;
artwork.mus_current_identifier = artwork.mus_current->identifier;
-#if 0
+#if ENABLE_UNUSED_CODE
printf("graphics set == %s\n\n", artwork.gfx_current_identifier);
printf("sounds set == %s\n\n", artwork.snd_current_identifier);
printf("music set == %s\n\n", artwork.mus_current_identifier);
sortTreeInfo(&artwork.snd_first);
sortTreeInfo(&artwork.mus_first);
-#if 0
+#if ENABLE_UNUSED_CODE
dumpTreeInfo(artwork.gfx_first, 0);
dumpTreeInfo(artwork.snd_first, 0);
dumpTreeInfo(artwork.mus_first, 0);
void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node,
LevelDirTree *level_node)
{
-#if 0
- static unsigned int progress_delay = 0;
- unsigned int progress_delay_value = 100; /* (in milliseconds) */
-#endif
int type = (*artwork_node)->type;
/* recursively check all level directories for artwork sub-directories */
setArtworkInfoCacheEntry(artwork_new, level_node, type);
}
-#if 1
- DrawInitTextExt(level_node->name, 150, FC_YELLOW,
- level_node->level_group);
-#else
- if (level_node->level_group ||
- DelayReached(&progress_delay, progress_delay_value))
- DrawInitText(level_node->name, 150, FC_YELLOW);
-#endif
+ DrawInitText(level_node->name, 150, FC_YELLOW);
if (level_node->node_group != NULL)
LoadArtworkInfoFromLevelInfo(artwork_node, level_node->node_group);
print_timestamp_time("sortTreeInfo");
-#if 0
+#if ENABLE_UNUSED_CODE
dumpTreeInfo(artwork.gfx_first, 0);
dumpTreeInfo(artwork.snd_first, 0);
dumpTreeInfo(artwork.mus_first, 0);
token_value_position = TOKEN_VALUE_POSITION_SHORT;
- fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
- getCookie("LEVELINFO")));
+ fprintFileHeader(file, LEVELINFO_FILENAME);
ldi = *level_info;
for (i = 0; i < NUM_LEVELINFO_TOKENS; i++)
/* always start with reliable default values */
leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
-#if defined(CREATE_SPECIAL_EDITION_RND_JUE)
- leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
- "jue_start");
- if (leveldir_current == NULL)
- leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
-#endif
+ if (!strEqual(DEFAULT_LEVELSET, UNDEFINED_LEVELSET))
+ {
+ leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
+ DEFAULT_LEVELSET);
+ if (leveldir_current == NULL)
+ leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
+ }
if ((level_setup_hash = loadSetupFileHash(filename)))
{
if (leveldir_current == NULL)
leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
- checkSetupFileHashIdentifier(level_setup_hash, filename,
- getCookie("LEVELSETUP"));
-
freeSetupFileHash(level_setup_hash);
}
else
return;
}
- fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
- getCookie("LEVELSETUP")));
+ fprintFileHeader(file, LEVELSETUP_FILENAME);
if (deactivate_last_level_series)
fprintf(file, "# %s\n# ", "the following level set may have caused a problem and was deactivated");
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' */
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;
- DIR *dir;
-#if 0
- struct dirent *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 = opendir(level_directory)) == NULL)
- {
- Error(ERR_WARN, "cannot read level directory '%s'", level_directory);
-
- return;
- }
-
-#if 0
- while ((dir_entry = readdir(dir)) != NULL) /* last directory entry */
- {
- if (strlen(dir_entry->d_name) > 4 &&
- dir_entry->d_name[3] == '.' &&
- strEqual(&dir_entry->d_name[4], LEVELFILE_EXTENSION))
- {
- 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_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
-
- closedir(dir);
-}
-
-#endif
-
void LoadLevelSetup_SeriesInfo()
{
char *filename;
LevelStats_setSolved(i, 0);
}
- checkSeriesInfo(leveldir_current);
+ checkSeriesInfo();
/* ----------------------------------------------------------------------- */
/* ~/.<program>/levelsetup/<level series>/levelsetup.conf */
}
END_HASH_ITERATION(hash, itr)
- checkSetupFileHashIdentifier(level_setup_hash, filename,
- getCookie("LEVELSETUP"));
-
freeSetupFileHash(level_setup_hash);
}
else
return;
}
- fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
- getCookie("LEVELSETUP")));
+ fprintFileHeader(file, LEVELSETUP_FILENAME);
+
fprintf(file, "%s\n", getFormattedSetupEntry(TOKEN_STR_LAST_PLAYED_LEVEL,
level_nr_str));
fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_HANDICAP_LEVEL,