+ include_count++;
+ }
+ else
+ {
+ 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)
+ {
+ Debug("setup", "---");
+ Debug("setup", "duplicate token(s) found in config file:");
+ Debug("setup", "- config file: '%s'", filename);
+
+ token_already_exists_warning = TRUE;
+ }
+
+ Debug("setup", "- token: '%s' (in line %d)", token, line_nr);
+ Debug("setup", " old value: '%s'", old_value);
+ Debug("setup", " 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)
+ Debug("setup", "---");
+#endif
+
+#if CHECK_TOKEN__WARN_IF_ALREADY_EXISTS_IN_HASH
+ if (token_already_exists_warning)
+ Debug("setup", "---");
+#endif
+
+ if (token_count == 0 && include_count == 0)
+ Warn("configuration file '%s' is empty", filename);
+
+ if (top_recursion_level)
+ freeSetupFileHash(include_filename_hash);
+
+ return TRUE;
+}
+
+static void saveSetupFileHash(SetupFileHash *hash, char *filename)
+{
+ FILE *file;
+
+ if (!(file = fopen(filename, MODE_WRITE)))
+ {
+ 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;
+}
+
+
+// ============================================================================
+// 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_PROGRAM_TITLE 5
+#define LEVELINFO_TOKEN_PROGRAM_COPYRIGHT 6
+#define LEVELINFO_TOKEN_PROGRAM_COMPANY 7
+#define LEVELINFO_TOKEN_IMPORTED_FROM 8
+#define LEVELINFO_TOKEN_IMPORTED_BY 9
+#define LEVELINFO_TOKEN_TESTED_BY 10
+#define LEVELINFO_TOKEN_LEVELS 11
+#define LEVELINFO_TOKEN_FIRST_LEVEL 12
+#define LEVELINFO_TOKEN_SORT_PRIORITY 13
+#define LEVELINFO_TOKEN_LATEST_ENGINE 14
+#define LEVELINFO_TOKEN_LEVEL_GROUP 15
+#define LEVELINFO_TOKEN_READONLY 16
+#define LEVELINFO_TOKEN_GRAPHICS_SET_ECS 17
+#define LEVELINFO_TOKEN_GRAPHICS_SET_AGA 18
+#define LEVELINFO_TOKEN_GRAPHICS_SET 19
+#define LEVELINFO_TOKEN_SOUNDS_SET_DEFAULT 20
+#define LEVELINFO_TOKEN_SOUNDS_SET_LOWPASS 21
+#define LEVELINFO_TOKEN_SOUNDS_SET 22
+#define LEVELINFO_TOKEN_MUSIC_SET 23
+#define LEVELINFO_TOKEN_FILENAME 24
+#define LEVELINFO_TOKEN_FILETYPE 25
+#define LEVELINFO_TOKEN_SPECIAL_FLAGS 26
+#define LEVELINFO_TOKEN_HANDICAP 27
+#define LEVELINFO_TOKEN_SKIP_LEVELS 28
+#define LEVELINFO_TOKEN_USE_EMC_TILES 29
+
+#define NUM_LEVELINFO_TOKENS 30
+
+static LevelDirTree ldi;
+
+static struct TokenInfo levelinfo_tokens[] =
+{
+ // level directory info
+ { TYPE_STRING, &ldi.identifier, "identifier" },
+ { TYPE_STRING, &ldi.name, "name" },
+ { TYPE_STRING, &ldi.name_sorting, "name_sorting" },
+ { TYPE_STRING, &ldi.author, "author" },
+ { TYPE_STRING, &ldi.year, "year" },
+ { TYPE_STRING, &ldi.program_title, "program_title" },
+ { TYPE_STRING, &ldi.program_copyright, "program_copyright" },
+ { TYPE_STRING, &ldi.program_company, "program_company" },
+ { TYPE_STRING, &ldi.imported_from, "imported_from" },
+ { TYPE_STRING, &ldi.imported_by, "imported_by" },
+ { TYPE_STRING, &ldi.tested_by, "tested_by" },
+ { TYPE_INTEGER, &ldi.levels, "levels" },
+ { TYPE_INTEGER, &ldi.first_level, "first_level" },
+ { TYPE_INTEGER, &ldi.sort_priority, "sort_priority" },
+ { TYPE_BOOLEAN, &ldi.latest_engine, "latest_engine" },
+ { TYPE_BOOLEAN, &ldi.level_group, "level_group" },
+ { TYPE_BOOLEAN, &ldi.readonly, "readonly" },
+ { TYPE_STRING, &ldi.graphics_set_ecs, "graphics_set.ecs" },
+ { TYPE_STRING, &ldi.graphics_set_aga, "graphics_set.aga" },
+ { TYPE_STRING, &ldi.graphics_set, "graphics_set" },
+ { TYPE_STRING, &ldi.sounds_set_default,"sounds_set.default" },
+ { TYPE_STRING, &ldi.sounds_set_lowpass,"sounds_set.lowpass" },
+ { TYPE_STRING, &ldi.sounds_set, "sounds_set" },
+ { TYPE_STRING, &ldi.music_set, "music_set" },
+ { TYPE_STRING, &ldi.level_filename, "filename" },
+ { TYPE_STRING, &ldi.level_filetype, "filetype" },
+ { TYPE_STRING, &ldi.special_flags, "special_flags" },
+ { TYPE_BOOLEAN, &ldi.handicap, "handicap" },
+ { TYPE_BOOLEAN, &ldi.skip_levels, "skip_levels" },
+ { TYPE_BOOLEAN, &ldi.use_emc_tiles, "use_emc_tiles" }
+};
+
+static struct TokenInfo artworkinfo_tokens[] =
+{
+ // artwork directory info
+ { TYPE_STRING, &ldi.identifier, "identifier" },
+ { TYPE_STRING, &ldi.subdir, "subdir" },
+ { TYPE_STRING, &ldi.name, "name" },
+ { TYPE_STRING, &ldi.name_sorting, "name_sorting" },
+ { TYPE_STRING, &ldi.author, "author" },
+ { TYPE_STRING, &ldi.program_title, "program_title" },
+ { TYPE_STRING, &ldi.program_copyright, "program_copyright" },
+ { TYPE_STRING, &ldi.program_company, "program_company" },
+ { TYPE_INTEGER, &ldi.sort_priority, "sort_priority" },
+ { TYPE_STRING, &ldi.basepath, "basepath" },
+ { TYPE_STRING, &ldi.fullpath, "fullpath" },
+ { TYPE_BOOLEAN, &ldi.in_user_dir, "in_user_dir" },
+ { TYPE_INTEGER, &ldi.color, "color" },
+ { TYPE_STRING, &ldi.class_desc, "class_desc" },
+
+ { -1, NULL, NULL },
+};
+
+static char *optional_tokens[] =
+{
+ "program_title",
+ "program_copyright",
+ "program_company",