#include "joystick.h"
#include "text.h"
#include "misc.h"
+#include "hash.h"
/* file names and filename extensions */
#if !defined(PLATFORM_MSDOS)
#define MAX_COOKIE_LEN 256
-#define ARTWORKINFO_FILENAME(type) ((type) == TREE_TYPE_GRAPHICS_DIR ? \
- GRAPHICSINFO_FILENAME : \
- (type) == TREE_TYPE_SOUNDS_DIR ? \
- SOUNDSINFO_FILENAME : \
- (type) == TREE_TYPE_MUSIC_DIR ? \
+#define ARTWORKINFO_FILENAME(type) ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ GRAPHICSINFO_FILENAME : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ SOUNDSINFO_FILENAME : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
MUSICINFO_FILENAME : "")
-#define ARTWORK_DIRECTORY(type) ((type) == TREE_TYPE_GRAPHICS_DIR ? \
- GRAPHICS_DIRECTORY : \
- (type) == TREE_TYPE_SOUNDS_DIR ? \
- SOUNDS_DIRECTORY : \
- (type) == TREE_TYPE_MUSIC_DIR ? \
+#define ARTWORK_DIRECTORY(type) ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ GRAPHICS_DIRECTORY : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ SOUNDS_DIRECTORY : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
MUSIC_DIRECTORY : "")
-#define OPTIONS_ARTWORK_DIRECTORY(type) ((type) == TREE_TYPE_GRAPHICS_DIR ? \
- options.graphics_directory : \
- (type) == TREE_TYPE_SOUNDS_DIR ? \
- options.sounds_directory : \
- (type) == TREE_TYPE_MUSIC_DIR ? \
+#define OPTIONS_ARTWORK_DIRECTORY(type) ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ options.graphics_directory : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ options.sounds_directory : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
options.music_directory : "")
static char *getScoreDir(char *level_subdir)
{
static char *score_dir = NULL;
- char *data_dir = options.rw_base_directory;
+ char *data_dir = getCommonDataDir();
char *score_subdir = SCORES_DIRECTORY;
if (score_dir)
return music_dir;
}
+static char *getDefaultArtworkSet(int type)
+{
+ return (type == TREE_TYPE_GRAPHICS_DIR ? GFX_CLASSIC_SUBDIR :
+ type == TREE_TYPE_SOUNDS_DIR ? SND_CLASSIC_SUBDIR :
+ type == TREE_TYPE_MUSIC_DIR ? MUS_CLASSIC_SUBDIR : "");
+}
+
+static char *getDefaultArtworkDir(int type)
+{
+ return (type == TREE_TYPE_GRAPHICS_DIR ?
+ getDefaultGraphicsDir(GFX_CLASSIC_SUBDIR) :
+ type == TREE_TYPE_SOUNDS_DIR ?
+ getDefaultSoundsDir(SND_CLASSIC_SUBDIR) :
+ type == TREE_TYPE_MUSIC_DIR ?
+ getDefaultMusicDir(MUS_CLASSIC_SUBDIR) : "");
+}
+
static char *getUserGraphicsDir()
{
static char *usergraphics_dir = NULL;
return artwork_dir;
}
-void setLevelArtworkDir(TreeInfo *ti)
+char *setLevelArtworkDir(TreeInfo *ti)
{
- char **artwork_path_ptr, *artwork_set;
+ char **artwork_path_ptr, **artwork_set_ptr;
TreeInfo *level_artwork;
if (ti == NULL || leveldir_current == NULL)
- return;
-
- artwork_path_ptr =
- (ti->type == TREE_TYPE_GRAPHICS_DIR ? &leveldir_current->graphics_path :
- ti->type == TREE_TYPE_SOUNDS_DIR ? &leveldir_current->sounds_path :
- &leveldir_current->music_path);
-
- artwork_set =
- (ti->type == TREE_TYPE_GRAPHICS_DIR ? leveldir_current->graphics_set :
- ti->type == TREE_TYPE_SOUNDS_DIR ? leveldir_current->sounds_set :
- leveldir_current->music_set);
+ return NULL;
- if ((level_artwork = getTreeInfoFromIdentifier(ti, artwork_set)) == NULL)
- return;
+ artwork_path_ptr = &(LEVELDIR_ARTWORK_PATH(leveldir_current, ti->type));
+ artwork_set_ptr = &(LEVELDIR_ARTWORK_SET( leveldir_current, ti->type));
if (*artwork_path_ptr != NULL)
free(*artwork_path_ptr);
- *artwork_path_ptr = getStringCopy(getSetupArtworkDir(level_artwork));
+ if ((level_artwork = getTreeInfoFromIdentifier(ti, *artwork_set_ptr)))
+ *artwork_path_ptr = getStringCopy(getSetupArtworkDir(level_artwork));
+ else
+ {
+ /* No (or non-existing) artwork configured in "levelinfo.conf". This would
+ normally result in using the artwork configured in the setup menu. But
+ if an artwork subdirectory exists (which might contain custom artwork
+ or an artwork configuration file), this level artwork must be treated
+ as relative to the default "classic" artwork, not to the artwork that
+ is currently configured in the setup menu. */
+
+ char *dir = getPath2(getCurrentLevelDir(), ARTWORK_DIRECTORY(ti->type));
+
+ if (*artwork_set_ptr != NULL)
+ free(*artwork_set_ptr);
+
+ if (fileExists(dir))
+ {
+ *artwork_path_ptr = getStringCopy(getDefaultArtworkDir(ti->type));
+ *artwork_set_ptr = getStringCopy(getDefaultArtworkSet(ti->type));
+ }
+ else
+ {
+ *artwork_path_ptr = getStringCopy(UNDEFINED_FILENAME);
+ *artwork_set_ptr = NULL;
+ }
+
+ free(dir);
+ }
+
+ return *artwork_set_ptr;
}
-static char *getLevelArtworkDir(int type)
+inline static char *getLevelArtworkSet(int type)
{
- char *artwork_path;
+ if (leveldir_current == NULL)
+ return NULL;
+
+ return LEVELDIR_ARTWORK_SET(leveldir_current, type);
+}
+inline static char *getLevelArtworkDir(int type)
+{
if (leveldir_current == NULL)
return UNDEFINED_FILENAME;
- artwork_path =
- (type == TREE_TYPE_GRAPHICS_DIR ? leveldir_current->graphics_path :
- type == TREE_TYPE_SOUNDS_DIR ? leveldir_current->sounds_path :
- type == TREE_TYPE_MUSIC_DIR ? leveldir_current->music_path :
- UNDEFINED_FILENAME);
-
- return artwork_path;
+ return LEVELDIR_ARTWORK_PATH(leveldir_current, type);
}
char *getLevelFilename(int nr)
if (filename != NULL)
free(filename);
- sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION);
+ if (nr < 0)
+ sprintf(basename, "template.%s", LEVELFILE_EXTENSION);
+ else
+ sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION);
+
filename = getPath2(getCurrentLevelDir(), basename);
return filename;
return filename;
}
-static char *getCorrectedImageBasename(char *basename)
+static char *getCorrectedArtworkBasename(char *basename)
{
char *basename_corrected = basename;
/* 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)
+ if (strlen(basename_corrected) > 8 + 1 + 3)
{
static char *msdos_filename = NULL;
- if (filename != NULL)
- free(filename);
+ if (msdos_filename != NULL)
+ free(msdos_filename);
+
+ msdos_filename = getStringCopy(basename_corrected);
+ strncpy(&msdos_filename[8], &basename[strlen(basename) - (1+3)], 1+3 +1);
- filename = getStringCopy(basename_corrected);
- strncpy(&filename[8], &basename[strlen(basename) - 1+3], 1+3 + 1);
+ basename_corrected = msdos_filename;
}
}
#endif
return basename_corrected;
}
-static boolean fileExists(char *filename)
-{
-#if 0
- printf("checking file '%s'\n", filename);
-#endif
-
- return (access(filename, F_OK) == 0);
-}
-
char *getCustomImageFilename(char *basename)
{
static char *filename = NULL;
+ boolean skip_setup_artwork = FALSE;
if (filename != NULL)
free(filename);
- basename = getCorrectedImageBasename(basename);
+ basename = getCorrectedArtworkBasename(basename);
if (!setup.override_level_graphics)
{
- /* 1st try: look for special artwork configured in level series config */
- filename = getPath2(getLevelArtworkDir(TREE_TYPE_GRAPHICS_DIR), basename);
+ /* 1st try: look for special artwork in current level series directory */
+ filename = getPath3(getCurrentLevelDir(), GRAPHICS_DIRECTORY, basename);
if (fileExists(filename))
return filename;
free(filename);
- /* 2nd try: look for special artwork in current level series directory */
- filename = getPath3(getCurrentLevelDir(), GRAPHICS_DIRECTORY, basename);
+ /* check if there is special artwork configured in level series config */
+ if (getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) != NULL)
+ {
+ /* 2nd try: look for special artwork configured in level series config */
+ filename = getPath2(getLevelArtworkDir(ARTWORK_TYPE_GRAPHICS), basename);
+ if (fileExists(filename))
+ return filename;
+
+ free(filename);
+
+ /* take missing artwork configured in level set config from default */
+ skip_setup_artwork = TRUE;
+ }
+ }
+
+ if (!skip_setup_artwork)
+ {
+ /* 3rd try: look for special artwork in configured artwork directory */
+ filename = getPath2(getSetupArtworkDir(artwork.gfx_current), basename);
if (fileExists(filename))
return filename;
free(filename);
}
- /* 3rd try: look for special artwork in configured artwork directory */
- filename = getPath2(getSetupArtworkDir(artwork.gfx_current), basename);
- if (fileExists(filename))
- return filename;
-
- free(filename);
-
/* 4th try: look for default artwork in new default artwork directory */
- filename = getPath2(getDefaultGraphicsDir(GRAPHICS_SUBDIR), basename);
+ filename = getPath2(getDefaultGraphicsDir(GFX_CLASSIC_SUBDIR), basename);
if (fileExists(filename))
return filename;
char *getCustomSoundFilename(char *basename)
{
static char *filename = NULL;
+ boolean skip_setup_artwork = FALSE;
if (filename != NULL)
free(filename);
+ basename = getCorrectedArtworkBasename(basename);
+
if (!setup.override_level_sounds)
{
- /* 1st try: look for special artwork configured in level series config */
- filename = getPath2(getLevelArtworkDir(TREE_TYPE_SOUNDS_DIR), basename);
+ /* 1st try: look for special artwork in current level series directory */
+ filename = getPath3(getCurrentLevelDir(), SOUNDS_DIRECTORY, basename);
if (fileExists(filename))
return filename;
free(filename);
- /* 2nd try: look for special artwork in current level series directory */
- filename = getPath3(getCurrentLevelDir(), SOUNDS_DIRECTORY, basename);
+ /* check if there is special artwork configured in level series config */
+ if (getLevelArtworkSet(ARTWORK_TYPE_SOUNDS) != NULL)
+ {
+ /* 2nd try: look for special artwork configured in level series config */
+ filename = getPath2(getLevelArtworkDir(TREE_TYPE_SOUNDS_DIR), basename);
+ if (fileExists(filename))
+ return filename;
+
+ free(filename);
+
+ /* take missing artwork configured in level set config from default */
+ skip_setup_artwork = TRUE;
+ }
+ }
+
+ if (!skip_setup_artwork)
+ {
+ /* 3rd try: look for special artwork in configured artwork directory */
+ filename = getPath2(getSetupArtworkDir(artwork.snd_current), basename);
if (fileExists(filename))
return filename;
free(filename);
}
- /* 3rd try: look for special artwork in configured artwork directory */
- filename = getPath2(getSetupArtworkDir(artwork.snd_current), basename);
- if (fileExists(filename))
- return filename;
-
- free(filename);
-
/* 4th try: look for default artwork in new default artwork directory */
- filename = getPath2(getDefaultSoundsDir(SOUNDS_SUBDIR), basename);
+ filename = getPath2(getDefaultSoundsDir(SND_CLASSIC_SUBDIR), basename);
if (fileExists(filename))
return filename;
return getCustomArtworkFilename(ARTWORKINFO_FILENAME(type), type);
}
+char *getCustomArtworkLevelConfigFilename(int type)
+{
+ static char *filename = NULL;
+
+ if (filename != NULL)
+ free(filename);
+
+ filename = getPath2(getLevelArtworkDir(type), ARTWORKINFO_FILENAME(type));
+
+ return filename;
+}
+
char *getCustomMusicDirectory(void)
{
static char *directory = NULL;
+ boolean skip_setup_artwork = FALSE;
if (directory != NULL)
free(directory);
if (!setup.override_level_music)
{
- /* 1st try: look for special artwork configured in level series config */
- directory = getStringCopy(getLevelArtworkDir(TREE_TYPE_MUSIC_DIR));
+ /* 1st try: look for special artwork in current level series directory */
+ directory = getPath2(getCurrentLevelDir(), MUSIC_DIRECTORY);
if (fileExists(directory))
return directory;
free(directory);
- /* 2nd try: look for special artwork in current level series directory */
- directory = getPath2(getCurrentLevelDir(), MUSIC_DIRECTORY);
+ /* check if there is special artwork configured in level series config */
+ if (getLevelArtworkSet(ARTWORK_TYPE_MUSIC) != NULL)
+ {
+ /* 2nd try: look for special artwork configured in level series config */
+ directory = getStringCopy(getLevelArtworkDir(TREE_TYPE_MUSIC_DIR));
+ if (fileExists(directory))
+ return directory;
+
+ free(directory);
+
+ /* take missing artwork configured in level set config from default */
+ skip_setup_artwork = TRUE;
+ }
+ }
+
+ if (!skip_setup_artwork)
+ {
+ /* 3rd try: look for special artwork in configured artwork directory */
+ directory = getStringCopy(getSetupArtworkDir(artwork.mus_current));
if (fileExists(directory))
return directory;
free(directory);
}
- /* 3rd try: look for special artwork in configured artwork directory */
- directory = getStringCopy(getSetupArtworkDir(artwork.mus_current));
- if (fileExists(directory))
- return directory;
-
- free(directory);
-
/* 4th try: look for default artwork in new default artwork directory */
- directory = getStringCopy(getDefaultMusicDir(MUSIC_SUBDIR));
+ directory = getStringCopy(getDefaultMusicDir(MUS_CLASSIC_SUBDIR));
if (fileExists(directory))
return directory;
void InitScoreDirectory(char *level_subdir)
{
+ createDirectory(getCommonDataDir(), "common data", PERMS_PUBLIC);
createDirectory(getScoreDir(NULL), "main score", PERMS_PUBLIC);
createDirectory(getScoreDir(level_subdir), "level score", PERMS_PUBLIC);
}
{
static char *userdata_dir = NULL;
- if (!userdata_dir)
+ if (userdata_dir == NULL)
+ userdata_dir = getPath2(getHomeDir(), program.userdata_directory);
+
+ return userdata_dir;
+}
+
+char *getCommonDataDir(void)
+{
+ static char *common_data_dir = NULL;
+
+#if defined(PLATFORM_WIN32)
+ if (common_data_dir == NULL)
{
- char *home_dir = getHomeDir();
- char *data_dir = program.userdata_directory;
+ char *dir = checked_malloc(MAX_PATH + 1);
- userdata_dir = getPath2(home_dir, data_dir);
+ if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, 0, dir))
+ && strcmp(dir, "") != 0) /* empty for Windows 95/98 */
+ common_data_dir = getPath2(dir, program.userdata_directory);
+ else
+ common_data_dir = options.rw_base_directory;
}
+#else
+ if (common_data_dir == NULL)
+ common_data_dir = options.rw_base_directory;
+#endif
- return userdata_dir;
+ return common_data_dir;
}
char *getSetupDir()
}
/* ------------------------------------------------------------------------- */
-/* setup file list handling functions */
+/* setup file list and hash handling functions */
/* ------------------------------------------------------------------------- */
char *getFormattedSetupEntry(char *token, char *value)
return entry;
}
-void freeSetupFileList(struct SetupFileList *setup_file_list)
-{
- if (!setup_file_list)
- return;
-
- if (setup_file_list->token)
- free(setup_file_list->token);
- if (setup_file_list->value)
- free(setup_file_list->value);
- if (setup_file_list->next)
- freeSetupFileList(setup_file_list->next);
- free(setup_file_list);
-}
-
-static struct SetupFileList *newSetupFileList(char *token, char *value)
+SetupFileList *newSetupFileList(char *token, char *value)
{
- struct SetupFileList *new = checked_malloc(sizeof(struct SetupFileList));
+ SetupFileList *new = checked_malloc(sizeof(SetupFileList));
- new->token = checked_malloc(strlen(token) + 1);
- strcpy(new->token, token);
-
- new->value = checked_malloc(strlen(value) + 1);
- strcpy(new->value, value);
+ new->token = getStringCopy(token);
+ new->value = getStringCopy(value);
new->next = NULL;
return new;
}
-char *getTokenValue(struct SetupFileList *setup_file_list, char *token)
+void freeSetupFileList(SetupFileList *list)
+{
+ if (list == NULL)
+ return;
+
+ if (list->token)
+ free(list->token);
+ if (list->value)
+ free(list->value);
+ if (list->next)
+ freeSetupFileList(list->next);
+ free(list);
+}
+
+char *getListEntry(SetupFileList *list, char *token)
{
- if (!setup_file_list)
+ if (list == NULL)
return NULL;
- if (strcmp(setup_file_list->token, token) == 0)
- return setup_file_list->value;
+ if (strcmp(list->token, token) == 0)
+ return list->value;
else
- return getTokenValue(setup_file_list->next, token);
+ return getListEntry(list->next, token);
}
-void setTokenValue(struct SetupFileList *setup_file_list,
- char *token, char *value)
+void setListEntry(SetupFileList *list, char *token, char *value)
{
- if (!setup_file_list)
+ if (list == NULL)
return;
- if (strcmp(setup_file_list->token, token) == 0)
+ if (strcmp(list->token, token) == 0)
{
- free(setup_file_list->value);
- setup_file_list->value = checked_malloc(strlen(value) + 1);
- strcpy(setup_file_list->value, value);
+ if (list->value)
+ free(list->value);
+
+ list->value = getStringCopy(value);
}
- else if (setup_file_list->next == NULL)
- setup_file_list->next = newSetupFileList(token, value);
+ else if (list->next == NULL)
+ list->next = newSetupFileList(token, value);
else
- setTokenValue(setup_file_list->next, token, value);
+ setListEntry(list->next, token, value);
}
#ifdef DEBUG
-static void printSetupFileList(struct SetupFileList *setup_file_list)
+static void printSetupFileList(SetupFileList *list)
{
- if (!setup_file_list)
+ if (!list)
return;
- printf("token: '%s'\n", setup_file_list->token);
- printf("value: '%s'\n", setup_file_list->value);
+ printf("token: '%s'\n", list->token);
+ printf("value: '%s'\n", list->value);
- printSetupFileList(setup_file_list->next);
+ printSetupFileList(list->next);
}
#endif
-struct SetupFileList *loadSetupFileList(char *filename)
+#ifdef DEBUG
+DEFINE_HASHTABLE_INSERT(insert_hash_entry, char, char);
+DEFINE_HASHTABLE_SEARCH(search_hash_entry, char, char);
+DEFINE_HASHTABLE_CHANGE(change_hash_entry, char, char);
+DEFINE_HASHTABLE_REMOVE(remove_hash_entry, char, char);
+#else
+#define insert_hash_entry hashtable_insert
+#define search_hash_entry hashtable_search
+#define change_hash_entry hashtable_change
+#define remove_hash_entry hashtable_remove
+#endif
+
+static unsigned int get_hash_from_key(void *key)
+{
+ /*
+ djb2
+
+ This algorithm (k=33) was first reported by Dan Bernstein many years ago in
+ 'comp.lang.c'. Another version of this algorithm (now favored by Bernstein)
+ uses XOR: hash(i) = hash(i - 1) * 33 ^ str[i]; the magic of number 33 (why
+ it works better than many other constants, prime or not) has never been
+ adequately explained.
+
+ If you just want to have a good hash function, and cannot wait, djb2
+ is one of the best string hash functions i know. It has excellent
+ distribution and speed on many different sets of keys and table sizes.
+ You are not likely to do better with one of the "well known" functions
+ such as PJW, K&R, etc.
+
+ Ozan (oz) Yigit [http://www.cs.yorku.ca/~oz/hash.html]
+ */
+
+ char *str = (char *)key;
+ unsigned int hash = 5381;
+ int c;
+
+ while ((c = *str++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ return hash;
+}
+
+static int keys_are_equal(void *key1, void *key2)
+{
+ return (strcmp((char *)key1, (char *)key2) == 0);
+}
+
+SetupFileHash *newSetupFileHash()
+{
+ SetupFileHash *new_hash =
+ create_hashtable(16, 0.75, get_hash_from_key, keys_are_equal);
+
+ return new_hash;
+}
+
+void freeSetupFileHash(SetupFileHash *hash)
+{
+ if (hash == NULL)
+ return;
+
+ hashtable_destroy(hash, 1); /* 1 == also free values stored in hash */
+}
+
+char *getHashEntry(SetupFileHash *hash, char *token)
+{
+ if (hash == NULL)
+ return NULL;
+
+ return search_hash_entry(hash, token);
+}
+
+void setHashEntry(SetupFileHash *hash, char *token, char *value)
+{
+ char *value_copy;
+
+ if (hash == NULL)
+ return;
+
+ value_copy = getStringCopy(value);
+
+ /* change value; if it does not exist, insert it as new */
+ if (!change_hash_entry(hash, token, value_copy))
+ if (!insert_hash_entry(hash, getStringCopy(token), value_copy))
+ Error(ERR_EXIT, "cannot insert into hash -- aborting");
+}
+
+#if 0
+#ifdef DEBUG
+static void printSetupFileHash(SetupFileHash *hash)
+{
+ BEGIN_HASH_ITERATION(hash, itr)
+ {
+ printf("token: '%s'\n", HASH_ITERATION_TOKEN(itr));
+ printf("value: '%s'\n", HASH_ITERATION_VALUE(itr));
+ }
+ END_HASH_ITERATION(hash, itr)
+}
+#endif
+#endif
+
+static void *loadSetupFileData(char *filename, boolean use_hash)
{
int line_len;
char line[MAX_LINE_LEN];
char *token, *value, *line_ptr;
- struct SetupFileList *setup_file_list = newSetupFileList("", "");
- struct SetupFileList *first_valid_list_entry;
-
+ void *setup_file_data;
FILE *file;
+ if (use_hash)
+ setup_file_data = newSetupFileHash();
+ else
+ setup_file_data = newSetupFileList("", "");
+
if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot open configuration file '%s'", filename);
break;
if (*token && *value)
- setTokenValue(setup_file_list, token, value);
+ {
+ if (use_hash)
+ setHashEntry((SetupFileHash *)setup_file_data, token, value);
+ else
+ setListEntry((SetupFileList *)setup_file_data, token, value);
+ }
}
fclose(file);
- first_valid_list_entry = setup_file_list->next;
+ if (use_hash)
+ {
+ if (hashtable_count((SetupFileHash *)setup_file_data) == 0)
+ Error(ERR_WARN, "configuration file '%s' is empty", filename);
+ }
+ else
+ {
+ SetupFileList *setup_file_list = (SetupFileList *)setup_file_data;
+ SetupFileList *first_valid_list_entry = setup_file_list->next;
- /* free empty list header */
- setup_file_list->next = NULL;
- freeSetupFileList(setup_file_list);
+ /* free empty list header */
+ setup_file_list->next = NULL;
+ freeSetupFileList(setup_file_list);
+ setup_file_data = first_valid_list_entry;
- if (first_valid_list_entry == NULL)
- Error(ERR_WARN, "configuration file '%s' is empty", filename);
+ if (first_valid_list_entry == NULL)
+ Error(ERR_WARN, "configuration file '%s' is empty", filename);
+ }
- return first_valid_list_entry;
+ return setup_file_data;
}
-void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
- char *identifier)
+SetupFileList *loadSetupFileList(char *filename)
{
- if (!setup_file_list)
- return;
+ return (SetupFileList *)loadSetupFileData(filename, FALSE);
+}
- if (strcmp(setup_file_list->token, TOKEN_STR_FILE_IDENTIFIER) == 0)
- {
- if (!checkCookieString(setup_file_list->value, identifier))
- {
- Error(ERR_WARN, "configuration file has wrong file identifier");
- return;
- }
- else
- return;
- }
+SetupFileHash *loadSetupFileHash(char *filename)
+{
+ return (SetupFileHash *)loadSetupFileData(filename, TRUE);
+}
- if (setup_file_list->next)
- checkSetupFileListIdentifier(setup_file_list->next, identifier);
- else
- {
+void checkSetupFileHashIdentifier(SetupFileHash *setup_file_hash,
+ char *identifier)
+{
+ char *value = getHashEntry(setup_file_hash, TOKEN_STR_FILE_IDENTIFIER);
+
+ if (value == NULL)
Error(ERR_WARN, "configuration file has no file identifier");
- return;
- }
+ else if (!checkCookieString(value, identifier))
+ Error(ERR_WARN, "configuration file has wrong file identifier");
}
if (ldi->type == TREE_TYPE_LEVEL_DIR)
{
ldi->imported_from = NULL;
+
ldi->graphics_set = NULL;
ldi->sounds_set = NULL;
ldi->music_set = NULL;
ldi->graphics_path = getStringCopy(UNDEFINED_FILENAME);
ldi->sounds_path = getStringCopy(UNDEFINED_FILENAME);
ldi->music_path = getStringCopy(UNDEFINED_FILENAME);
+
ldi->levels = 0;
ldi->first_level = 0;
ldi->last_level = 0;
{
Error(ERR_WARN, "setTreeInfoToDefaultsFromParent(): parent == NULL");
- setTreeInfoToDefaults(ldi, TREE_TYPE_GENERIC);
+ setTreeInfoToDefaults(ldi, TREE_TYPE_UNDEFINED);
+
return;
}
+#if 1
+ /* copy all values from the parent structure */
+
+ ldi->type = parent->type;
+
+ ldi->node_top = parent->node_top;
+ ldi->node_parent = parent;
+ ldi->node_group = NULL;
+ ldi->next = NULL;
+
+ ldi->cl_first = -1;
+ ldi->cl_cursor = -1;
+
+ ldi->filename = NULL;
+ ldi->fullpath = NULL;
+ ldi->basepath = NULL;
+ ldi->identifier = NULL;
+ ldi->name = getStringCopy(ANONYMOUS_NAME);
+ ldi->name_sorting = NULL;
+ ldi->author = getStringCopy(parent->author);
+
+ ldi->sort_priority = parent->sort_priority;
+ ldi->parent_link = FALSE;
+ ldi->user_defined = parent->user_defined;
+ ldi->color = parent->color;
+ ldi->class_desc = getStringCopy(parent->class_desc);
+
+ if (ldi->type == TREE_TYPE_LEVEL_DIR)
+ {
+ ldi->imported_from = getStringCopy(parent->imported_from);
+
+ ldi->graphics_set = NULL;
+ ldi->sounds_set = NULL;
+ ldi->music_set = NULL;
+ ldi->graphics_path = getStringCopy(UNDEFINED_FILENAME);
+ ldi->sounds_path = getStringCopy(UNDEFINED_FILENAME);
+ ldi->music_path = getStringCopy(UNDEFINED_FILENAME);
+
+ ldi->levels = 0;
+ ldi->first_level = 0;
+ ldi->last_level = 0;
+ ldi->level_group = FALSE;
+ ldi->handicap_level = 0;
+ ldi->readonly = TRUE;
+ }
+
+
+#else
+
/* first copy all values from the parent structure ... */
*ldi = *parent;
ldi->name = getStringCopy(ANONYMOUS_NAME);
ldi->name_sorting = NULL;
ldi->author = getStringCopy(parent->author);
+
ldi->imported_from = getStringCopy(parent->imported_from);
+ ldi->class_desc = getStringCopy(parent->class_desc);
+
+ ldi->graphics_set = NULL;
+ ldi->sounds_set = NULL;
+ ldi->music_set = NULL;
+ ldi->graphics_path = NULL;
+ ldi->sounds_path = NULL;
+ ldi->music_path = NULL;
ldi->level_group = FALSE;
ldi->parent_link = FALSE;
ldi->node_parent = parent;
ldi->node_group = NULL;
ldi->next = NULL;
+
+#endif
}
void setSetupInfo(struct TokenInfo *token_info,
{
char *directory_path = getPath2(level_directory, directory_name);
char *filename = getPath2(directory_path, LEVELINFO_FILENAME);
- struct SetupFileList *setup_file_list = loadSetupFileList(filename);
+ SetupFileHash *setup_file_hash = loadSetupFileHash(filename);
LevelDirTree *leveldir_new = NULL;
int i;
- if (setup_file_list == NULL)
+ if (setup_file_hash == NULL)
{
Error(ERR_WARN, "ignoring level directory '%s'", directory_path);
leveldir_new->filename = getStringCopy(directory_name);
- checkSetupFileListIdentifier(setup_file_list, getCookie("LEVELINFO"));
+ checkSetupFileHashIdentifier(setup_file_hash, getCookie("LEVELINFO"));
/* set all structure fields according to the token/value pairs */
ldi = *leveldir_new;
for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
setSetupInfo(levelinfo_tokens, i,
- getTokenValue(setup_file_list, levelinfo_tokens[i].text));
+ getHashEntry(setup_file_hash, levelinfo_tokens[i].text));
*leveldir_new = ldi;
if (strcmp(leveldir_new->name, ANONYMOUS_NAME) == 0)
pushTreeInfo(node_first, leveldir_new);
- freeSetupFileList(setup_file_list);
+ freeSetupFileHash(setup_file_hash);
if (leveldir_new->level_group)
{
{
char *directory_path = getPath2(base_directory, directory_name);
char *filename = getPath2(directory_path, ARTWORKINFO_FILENAME(type));
- struct SetupFileList *setup_file_list = NULL;
+ SetupFileHash *setup_file_hash = NULL;
TreeInfo *artwork_new = NULL;
int i;
if (access(filename, F_OK) == 0) /* file exists */
- setup_file_list = loadSetupFileList(filename);
+ setup_file_hash = loadSetupFileHash(filename);
- if (setup_file_list == NULL) /* no config file -- look for artwork files */
+ if (setup_file_hash == NULL) /* no config file -- look for artwork files */
{
DIR *dir;
struct dirent *dir_entry;
artwork_new->filename = getStringCopy(directory_name);
- if (setup_file_list) /* (before defining ".color" and ".class_desc") */
+ if (setup_file_hash) /* (before defining ".color" and ".class_desc") */
{
#if 0
- checkSetupFileListIdentifier(setup_file_list, getCookie("..."));
+ checkSetupFileHashIdentifier(setup_file_hash, 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,
- getTokenValue(setup_file_list, levelinfo_tokens[i].text));
+ getHashEntry(setup_file_hash, levelinfo_tokens[i].text));
*artwork_new = ldi;
if (strcmp(artwork_new->name, ANONYMOUS_NAME) == 0)
artwork_new->user_defined =
(artwork_new->basepath == OPTIONS_ARTWORK_DIRECTORY(type) ? FALSE : TRUE);
- /* (may use ".sort_priority" from "setup_file_list" above) */
+ /* (may use ".sort_priority" from "setup_file_hash" above) */
artwork_new->color = ARTWORKCOLOR(artwork_new);
artwork_new->class_desc = getLevelClassDescription(artwork_new);
- if (setup_file_list == NULL) /* (after determining ".user_defined") */
+ if (setup_file_hash == NULL) /* (after determining ".user_defined") */
{
if (artwork_new->name != NULL)
free(artwork_new->name);
pushTreeInfo(node_first, artwork_new);
- freeSetupFileList(setup_file_list);
+ freeSetupFileHash(setup_file_hash);
free(directory_path);
free(filename);
/* before sorting, the first entries will be from the user directory */
artwork.gfx_current =
getTreeInfoFromIdentifier(artwork.gfx_first, setup.graphics_set);
+ if (artwork.gfx_current == NULL)
+ artwork.gfx_current =
+ getTreeInfoFromIdentifier(artwork.gfx_first, GFX_CLASSIC_SUBDIR);
if (artwork.gfx_current == NULL)
artwork.gfx_current = getFirstValidTreeInfoEntry(artwork.gfx_first);
artwork.snd_current =
getTreeInfoFromIdentifier(artwork.snd_first, setup.sounds_set);
+ if (artwork.snd_current == NULL)
+ artwork.snd_current =
+ getTreeInfoFromIdentifier(artwork.snd_first, SND_CLASSIC_SUBDIR);
if (artwork.snd_current == NULL)
artwork.snd_current = getFirstValidTreeInfoEntry(artwork.snd_first);
artwork.mus_current =
getTreeInfoFromIdentifier(artwork.mus_first, setup.music_set);
+ if (artwork.mus_current == NULL)
+ artwork.mus_current =
+ getTreeInfoFromIdentifier(artwork.mus_first, MUS_CLASSIC_SUBDIR);
if (artwork.mus_current == NULL)
artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first);
{
artwork.gfx_current =
getTreeInfoFromIdentifier(artwork.gfx_first, setup.graphics_set);
+ if (artwork.gfx_current == NULL)
+ artwork.gfx_current =
+ getTreeInfoFromIdentifier(artwork.gfx_first, GFX_CLASSIC_SUBDIR);
if (artwork.gfx_current == NULL)
artwork.gfx_current = getFirstValidTreeInfoEntry(artwork.gfx_first);
}
{
artwork.snd_current =
getTreeInfoFromIdentifier(artwork.snd_first, setup.sounds_set);
+ if (artwork.snd_current == NULL)
+ artwork.snd_current =
+ getTreeInfoFromIdentifier(artwork.snd_first, SND_CLASSIC_SUBDIR);
if (artwork.snd_current == NULL)
artwork.snd_current = getFirstValidTreeInfoEntry(artwork.snd_first);
}
{
artwork.mus_current =
getTreeInfoFromIdentifier(artwork.mus_first, setup.music_set);
+ if (artwork.mus_current == NULL)
+ artwork.mus_current =
+ getTreeInfoFromIdentifier(artwork.mus_first, MUS_CLASSIC_SUBDIR);
if (artwork.mus_current == NULL)
artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first);
}
/* always start with reliable default values */
setTreeInfoToDefaults(&ldi, TREE_TYPE_LEVEL_DIR);
+#if 0
+ /* !!! FIX ME !!! */
+ setString(&ldi.name, getLoginName());
+ setString(&ldi.author, getRealName());
+ ldi.levels = 100;
+ ldi.first_level = 1;
+ ldi.sort_priority = LEVELCLASS_USER_START;
+ ldi.readonly = FALSE;
+ setString(&ldi.graphics_set, GFX_CLASSIC_SUBDIR);
+ setString(&ldi.sounds_set, SND_CLASSIC_SUBDIR);
+ setString(&ldi.music_set, MUS_CLASSIC_SUBDIR);
+#else
ldi.name = getStringCopy(getLoginName());
ldi.author = getStringCopy(getRealName());
ldi.levels = 100;
ldi.first_level = 1;
ldi.sort_priority = LEVELCLASS_USER_START;
ldi.readonly = FALSE;
- ldi.graphics_set = getStringCopy(GRAPHICS_SUBDIR);
- ldi.sounds_set = getStringCopy(SOUNDS_SUBDIR);
- ldi.music_set = getStringCopy(MUSIC_SUBDIR);
+ ldi.graphics_set = getStringCopy(GFX_CLASSIC_SUBDIR);
+ ldi.sounds_set = getStringCopy(SND_CLASSIC_SUBDIR);
+ ldi.music_set = getStringCopy(MUS_CLASSIC_SUBDIR);
+#endif
fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
getCookie("LEVELINFO")));
void LoadLevelSetup_LastSeries()
{
char *filename;
- struct SetupFileList *level_setup_list = NULL;
+ SetupFileHash *level_setup_hash = NULL;
/* always start with reliable default values */
leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
- if ((level_setup_list = loadSetupFileList(filename)))
+ if ((level_setup_hash = loadSetupFileHash(filename)))
{
char *last_level_series =
- getTokenValue(level_setup_list, TOKEN_STR_LAST_LEVEL_SERIES);
+ getHashEntry(level_setup_hash, TOKEN_STR_LAST_LEVEL_SERIES);
leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
last_level_series);
if (leveldir_current == NULL)
leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
- checkSetupFileListIdentifier(level_setup_list, getCookie("LEVELSETUP"));
+ checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP"));
- freeSetupFileList(level_setup_list);
+ freeSetupFileHash(level_setup_hash);
}
else
Error(ERR_WARN, "using default setup values");
levelnum_value = atoi(levelnum_str);
+#if 0
if (levelnum_value < leveldir_current->first_level)
{
Error(ERR_WARN, "additional level %d found", levelnum_value);
Error(ERR_WARN, "additional level %d found", levelnum_value);
leveldir_current->last_level = levelnum_value;
}
+#endif
}
}
void LoadLevelSetup_SeriesInfo()
{
char *filename;
- struct SetupFileList *level_setup_list = NULL;
+ SetupFileHash *level_setup_hash = NULL;
char *level_subdir = leveldir_current->filename;
/* always start with reliable default values */
filename = getPath2(getLevelSetupDir(level_subdir), LEVELSETUP_FILENAME);
- if ((level_setup_list = loadSetupFileList(filename)))
+ if ((level_setup_hash = loadSetupFileHash(filename)))
{
char *token_value;
- token_value = getTokenValue(level_setup_list, TOKEN_STR_LAST_PLAYED_LEVEL);
+ token_value = getHashEntry(level_setup_hash, TOKEN_STR_LAST_PLAYED_LEVEL);
if (token_value)
{
level_nr = leveldir_current->last_level;
}
- token_value = getTokenValue(level_setup_list, TOKEN_STR_HANDICAP_LEVEL);
+ token_value = getHashEntry(level_setup_hash, TOKEN_STR_HANDICAP_LEVEL);
if (token_value)
{
leveldir_current->handicap_level = level_nr;
}
- checkSetupFileListIdentifier(level_setup_list, getCookie("LEVELSETUP"));
+ checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP"));
- freeSetupFileList(level_setup_list);
+ freeSetupFileHash(level_setup_hash);
}
else
Error(ERR_WARN, "using default setup values");