X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=c7cc92f00c2dfc55d4a1d259392d4655c0e04843;hb=8e17da8cdff134bfa0e766a50f408a3c06428f54;hp=d78e3c70f6b2addf7174478c7a8dda4859bb779f;hpb=ee749a764df3dfa944c1f9de740ccbeb1cfdef40;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index d78e3c70..c7cc92f0 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -17,6 +17,13 @@ #include #include +#include "platform.h" + +#if !defined(PLATFORM_WIN32) +#include +#include +#endif + #include "setup.h" #include "joystick.h" #include "text.h" @@ -100,7 +107,7 @@ static char *getLevelClassDescription(TreeInfo *ldi) static char *getUserLevelDir(char *level_subdir) { static char *userlevel_dir = NULL; - char *data_dir = getUserDataDir(); + char *data_dir = getUserGameDataDir(); char *userlevel_subdir = LEVELS_DIRECTORY; checked_free(userlevel_dir); @@ -132,7 +139,7 @@ static char *getScoreDir(char *level_subdir) static char *getLevelSetupDir(char *level_subdir) { static char *levelsetup_dir = NULL; - char *data_dir = getUserDataDir(); + char *data_dir = getUserGameDataDir(); char *levelsetup_subdir = LEVELSETUP_DIRECTORY; checked_free(levelsetup_dir); @@ -168,7 +175,7 @@ char *getCurrentLevelDir() static char *getTapeDir(char *level_subdir) { static char *tape_dir = NULL; - char *data_dir = getUserDataDir(); + char *data_dir = getUserGameDataDir(); char *tape_subdir = TAPES_DIRECTORY; checked_free(tape_dir); @@ -258,7 +265,7 @@ static char *getUserGraphicsDir() static char *usergraphics_dir = NULL; if (usergraphics_dir == NULL) - usergraphics_dir = getPath2(getUserDataDir(), GRAPHICS_DIRECTORY); + usergraphics_dir = getPath2(getUserGameDataDir(), GRAPHICS_DIRECTORY); return usergraphics_dir; } @@ -268,7 +275,7 @@ static char *getUserSoundsDir() static char *usersounds_dir = NULL; if (usersounds_dir == NULL) - usersounds_dir = getPath2(getUserDataDir(), SOUNDS_DIRECTORY); + usersounds_dir = getPath2(getUserGameDataDir(), SOUNDS_DIRECTORY); return usersounds_dir; } @@ -278,7 +285,7 @@ static char *getUserMusicDir() static char *usermusic_dir = NULL; if (usermusic_dir == NULL) - usermusic_dir = getPath2(getUserDataDir(), MUSIC_DIRECTORY); + usermusic_dir = getPath2(getUserGameDataDir(), MUSIC_DIRECTORY); return usermusic_dir; } @@ -764,7 +771,7 @@ char *getCustomMusicDirectory(void) void InitTapeDirectory(char *level_subdir) { - createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); createDirectory(getTapeDir(NULL), "main tape", PERMS_PRIVATE); createDirectory(getTapeDir(level_subdir), "level tape", PERMS_PRIVATE); } @@ -782,7 +789,7 @@ void InitUserLevelDirectory(char *level_subdir) { if (!fileExists(getUserLevelDir(level_subdir))) { - createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE); createDirectory(getUserLevelDir(level_subdir), "user level",PERMS_PRIVATE); @@ -792,14 +799,14 @@ void InitUserLevelDirectory(char *level_subdir) void InitLevelSetupDirectory(char *level_subdir) { - createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); createDirectory(getLevelSetupDir(NULL), "main level setup", PERMS_PRIVATE); createDirectory(getLevelSetupDir(level_subdir), "level setup",PERMS_PRIVATE); } /* ------------------------------------------------------------------------- */ -/* some functions to handle lists of level directories */ +/* some functions to handle lists of level and artwork directories */ /* ------------------------------------------------------------------------- */ TreeInfo *newTreeInfo() @@ -917,7 +924,7 @@ TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier) } else if (!node->parent_link) { - if (strcmp(identifier, node->identifier) == 0) + if (strEqual(identifier, node->identifier)) return node; } @@ -927,6 +934,71 @@ TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier) return NULL; } +TreeInfo *cloneTreeNode(TreeInfo **node_top, TreeInfo *node_parent, + TreeInfo *node, boolean skip_sets_without_levels) +{ + TreeInfo *node_new; + + if (node == NULL) + return NULL; + + if (!node->parent_link && !node->level_group && + skip_sets_without_levels && node->levels == 0) + return cloneTreeNode(node_top, node_parent, node->next, + skip_sets_without_levels); + + node_new = newTreeInfo(); + + *node_new = *node; /* copy complete node */ + + node_new->node_top = node_top; /* correct top node link */ + node_new->node_parent = node_parent; /* correct parent node link */ + + if (node->level_group) + node_new->node_group = cloneTreeNode(node_top, node_new, node->node_group, + skip_sets_without_levels); + + node_new->next = cloneTreeNode(node_top, node_parent, node->next, + skip_sets_without_levels); + + return node_new; +} + +void cloneTree(TreeInfo **ti_new, TreeInfo *ti, boolean skip_empty_sets) +{ + TreeInfo *ti_cloned = cloneTreeNode(ti_new, NULL, ti, skip_empty_sets); + + *ti_new = ti_cloned; +} + +static boolean adjustTreeGraphicsForEMC(TreeInfo *node) +{ + boolean settings_changed = FALSE; + + while (node) + { + if (node->graphics_set_ecs && !setup.prefer_aga_graphics && + !strEqual(node->graphics_set, node->graphics_set_ecs)) + { + setString(&node->graphics_set, node->graphics_set_ecs); + settings_changed = TRUE; + } + else if (node->graphics_set_aga && setup.prefer_aga_graphics && + !strEqual(node->graphics_set, node->graphics_set_aga)) + { + setString(&node->graphics_set, node->graphics_set_aga); + settings_changed = TRUE; + } + + if (node->node_group != NULL) + settings_changed |= adjustTreeGraphicsForEMC(node->node_group); + + node = node->next; + } + + return settings_changed; +} + void dumpTreeInfo(TreeInfo *node, int depth) { int i; @@ -1043,14 +1115,36 @@ void sortTreeInfo(TreeInfo **node_first, #define FILE_PERMS_PRIVATE (MODE_R_ALL | MODE_W_PRIVATE) #define FILE_PERMS_PUBLIC (MODE_R_ALL | MODE_W_PUBLIC) -char *getUserDataDir(void) +char *getHomeDir() { - static char *userdata_dir = NULL; + static char *dir = NULL; - if (userdata_dir == NULL) - userdata_dir = getPath2(getHomeDir(), program.userdata_directory); +#if defined(PLATFORM_WIN32) + if (dir == NULL) + { + dir = checked_malloc(MAX_PATH + 1); - return userdata_dir; + if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir))) + strcpy(dir, "."); + } +#elif defined(PLATFORM_UNIX) + if (dir == NULL) + { + if ((dir = getenv("HOME")) == NULL) + { + struct passwd *pwd; + + if ((pwd = getpwuid(getuid())) != NULL) + dir = getStringCopy(pwd->pw_dir); + else + dir = "."; + } + } +#else + dir = "."; +#endif + + return dir; } char *getCommonDataDir(void) @@ -1063,7 +1157,7 @@ char *getCommonDataDir(void) char *dir = checked_malloc(MAX_PATH + 1); if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, 0, dir)) - && strcmp(dir, "") != 0) /* empty for Windows 95/98 */ + && !strEqual(dir, "")) /* empty for Windows 95/98 */ common_data_dir = getPath2(dir, program.userdata_directory); else common_data_dir = options.rw_base_directory; @@ -1076,9 +1170,58 @@ char *getCommonDataDir(void) return common_data_dir; } +char *getPersonalDataDir(void) +{ + static char *personal_data_dir = NULL; + +#if defined(PLATFORM_MACOSX) + if (personal_data_dir == NULL) + personal_data_dir = getPath2(getHomeDir(), "Documents"); +#else + if (personal_data_dir == NULL) + personal_data_dir = getHomeDir(); +#endif + + return personal_data_dir; +} + +char *getUserGameDataDir(void) +{ + if (program.userdata_path == NULL) + program.userdata_path = getPath2(getPersonalDataDir(), + program.userdata_subdir); + + return program.userdata_path; +} + +void fixUserGameDataDir() +{ +#if defined(PLATFORM_MACOSX) + char *userdata_dir_old = getPath2(getHomeDir(), program.userdata_subdir_unix); + char *userdata_dir_new = getUserGameDataDir(); + + /* convert old Unix style game data directory to Mac OS X style, if needed */ + if (fileExists(userdata_dir_old) && !fileExists(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); + free(userdata_dir_new); +#endif +} + char *getSetupDir() { - return getUserDataDir(); + return getUserGameDataDir(); } static mode_t posix_umask(mode_t mask) @@ -1118,7 +1261,7 @@ void createDirectory(char *dir, char *text, int permission_class) void InitUserDataDirectory() { - createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); } void SetFilePermissions(char *filename, int permission_class) @@ -1244,7 +1387,7 @@ char *getListEntry(SetupFileList *list, char *token) if (list == NULL) return NULL; - if (strcmp(list->token, token) == 0) + if (strEqual(list->token, token)) return list->value; else return getListEntry(list->next, token); @@ -1255,7 +1398,7 @@ SetupFileList *setListEntry(SetupFileList *list, char *token, char *value) if (list == NULL) return NULL; - if (strcmp(list->token, token) == 0) + if (strEqual(list->token, token)) { checked_free(list->value); @@ -1337,7 +1480,7 @@ static unsigned int get_hash_from_key(void *key) static int keys_are_equal(void *key1, void *key2) { - return (strcmp((char *)key1, (char *)key2) == 0); + return (strEqual((char *)key1, (char *)key2)); } SetupFileHash *newSetupFileHash() @@ -1553,14 +1696,14 @@ SetupFileHash *loadSetupFileHash(char *filename) } void checkSetupFileHashIdentifier(SetupFileHash *setup_file_hash, - char *identifier) + char *filename, char *identifier) { char *value = getHashEntry(setup_file_hash, TOKEN_STR_FILE_IDENTIFIER); if (value == NULL) - Error(ERR_WARN, "configuration file has no file identifier"); + Error(ERR_WARN, "config file '%s' has no file identifier", filename); else if (!checkCookieString(value, identifier)) - Error(ERR_WARN, "configuration file has wrong file identifier"); + Error(ERR_WARN, "config file '%s' has wrong file identifier", filename); } @@ -1568,57 +1711,61 @@ void checkSetupFileHashIdentifier(SetupFileHash *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" +#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_IMPORTED_FROM 4 -#define LEVELINFO_TOKEN_IMPORTED_BY 5 -#define LEVELINFO_TOKEN_LEVELS 6 -#define LEVELINFO_TOKEN_FIRST_LEVEL 7 -#define LEVELINFO_TOKEN_SORT_PRIORITY 8 -#define LEVELINFO_TOKEN_LATEST_ENGINE 9 -#define LEVELINFO_TOKEN_LEVEL_GROUP 10 -#define LEVELINFO_TOKEN_READONLY 11 -#define LEVELINFO_TOKEN_GRAPHICS_SET 12 -#define LEVELINFO_TOKEN_SOUNDS_SET 13 -#define LEVELINFO_TOKEN_MUSIC_SET 14 -#define LEVELINFO_TOKEN_FILENAME 15 -#define LEVELINFO_TOKEN_FILETYPE 16 -#define LEVELINFO_TOKEN_HANDICAP 17 -#define LEVELINFO_TOKEN_SKIP_LEVELS 18 - -#define NUM_LEVELINFO_TOKENS 19 +#define LEVELINFO_TOKEN_IDENTIFIER 0 +#define LEVELINFO_TOKEN_NAME 1 +#define LEVELINFO_TOKEN_NAME_SORTING 2 +#define LEVELINFO_TOKEN_AUTHOR 3 +#define LEVELINFO_TOKEN_IMPORTED_FROM 4 +#define LEVELINFO_TOKEN_IMPORTED_BY 5 +#define LEVELINFO_TOKEN_LEVELS 6 +#define LEVELINFO_TOKEN_FIRST_LEVEL 7 +#define LEVELINFO_TOKEN_SORT_PRIORITY 8 +#define LEVELINFO_TOKEN_LATEST_ENGINE 9 +#define LEVELINFO_TOKEN_LEVEL_GROUP 10 +#define LEVELINFO_TOKEN_READONLY 11 +#define LEVELINFO_TOKEN_GRAPHICS_SET_ECS 12 +#define LEVELINFO_TOKEN_GRAPHICS_SET_AGA 13 +#define LEVELINFO_TOKEN_GRAPHICS_SET 14 +#define LEVELINFO_TOKEN_SOUNDS_SET 15 +#define LEVELINFO_TOKEN_MUSIC_SET 16 +#define LEVELINFO_TOKEN_FILENAME 17 +#define LEVELINFO_TOKEN_FILETYPE 18 +#define LEVELINFO_TOKEN_HANDICAP 19 +#define LEVELINFO_TOKEN_SKIP_LEVELS 20 + +#define NUM_LEVELINFO_TOKENS 21 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.imported_from, "imported_from" }, - { TYPE_STRING, &ldi.imported_by, "imported_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, "graphics_set" }, - { 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_BOOLEAN, &ldi.handicap, "handicap" }, - { TYPE_BOOLEAN, &ldi.skip_levels, "skip_levels" } + { 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.imported_from, "imported_from" }, + { TYPE_STRING, &ldi.imported_by, "imported_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, "sounds_set" }, + { TYPE_STRING, &ldi.music_set, "music_set" }, + { TYPE_STRING, &ldi.level_filename, "filename" }, + { TYPE_STRING, &ldi.level_filetype, "filetype" }, + { TYPE_BOOLEAN, &ldi.handicap, "handicap" }, + { TYPE_BOOLEAN, &ldi.skip_levels, "skip_levels" } }; static void setTreeInfoToDefaults(TreeInfo *ldi, int type) @@ -1659,6 +1806,8 @@ static void setTreeInfoToDefaults(TreeInfo *ldi, int type) ldi->imported_from = NULL; ldi->imported_by = NULL; + ldi->graphics_set_ecs = NULL; + ldi->graphics_set_aga = NULL; ldi->graphics_set = NULL; ldi->sounds_set = NULL; ldi->music_set = NULL; @@ -1724,6 +1873,8 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent) ldi->imported_from = getStringCopy(parent->imported_from); ldi->imported_by = getStringCopy(parent->imported_by); + ldi->graphics_set_ecs = NULL; + ldi->graphics_set_aga = NULL; ldi->graphics_set = NULL; ldi->sounds_set = NULL; ldi->music_set = NULL; @@ -1763,6 +1914,8 @@ static void freeTreeInfo(TreeInfo *ldi) checked_free(ldi->imported_from); checked_free(ldi->imported_by); + checked_free(ldi->graphics_set_ecs); + checked_free(ldi->graphics_set_aga); checked_free(ldi->graphics_set); checked_free(ldi->sounds_set); checked_free(ldi->music_set); @@ -1925,7 +2078,8 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, leveldir_new->subdir = getStringCopy(directory_name); - checkSetupFileHashIdentifier(setup_file_hash, getCookie("LEVELINFO")); + checkSetupFileHashIdentifier(setup_file_hash, filename, + getCookie("LEVELINFO")); /* set all structure fields according to the token/value pairs */ ldi = *leveldir_new; @@ -1934,7 +2088,7 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, getHashEntry(setup_file_hash, levelinfo_tokens[i].text)); *leveldir_new = ldi; - if (strcmp(leveldir_new->name, ANONYMOUS_NAME) == 0) + if (strEqual(leveldir_new->name, ANONYMOUS_NAME)) setString(&leveldir_new->name, leveldir_new->subdir); DrawInitText(leveldir_new->name, 150, FC_YELLOW); @@ -1956,20 +2110,27 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, 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 = - (strcmp(leveldir_new->basepath, options.level_directory) != 0); + (!strEqual(leveldir_new->basepath, options.level_directory)); - /* adjust sort priority if user's private level directory was detected */ + /* adjust some settings if user's private level directory was detected */ if (leveldir_new->sort_priority == LEVELCLASS_UNDEFINED && leveldir_new->in_user_dir && - strcmp(leveldir_new->subdir, getLoginName()) == 0) + (strEqual(leveldir_new->subdir, getLoginName()) || + strEqual(leveldir_new->name, getLoginName()) || + strEqual(leveldir_new->author, getRealName()))) + { leveldir_new->sort_priority = LEVELCLASS_PRIVATE_START; + leveldir_new->readonly = FALSE; + } leveldir_new->user_defined = (leveldir_new->in_user_dir && IS_LEVELCLASS_PRIVATE(leveldir_new)); @@ -1982,6 +2143,22 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, (leveldir_new->user_defined || !leveldir_new->handicap ? leveldir_new->last_level : leveldir_new->first_level); +#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); freeSetupFileHash(setup_file_hash); @@ -2023,8 +2200,8 @@ static void LoadLevelInfoFromLevelDir(TreeInfo **node_first, char *directory_path = getPath2(level_directory, directory_name); /* skip entries for current and parent directory */ - if (strcmp(directory_name, ".") == 0 || - strcmp(directory_name, "..") == 0) + if (strEqual(directory_name, ".") || + strEqual(directory_name, "..")) { free(directory_path); continue; @@ -2040,9 +2217,9 @@ static void LoadLevelInfoFromLevelDir(TreeInfo **node_first, free(directory_path); - if (strcmp(directory_name, GRAPHICS_DIRECTORY) == 0 || - strcmp(directory_name, SOUNDS_DIRECTORY) == 0 || - strcmp(directory_name, MUSIC_DIRECTORY) == 0) + 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, @@ -2052,7 +2229,8 @@ static void LoadLevelInfoFromLevelDir(TreeInfo **node_first, closedir(dir); - if (!valid_entry_found) + /* 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, @@ -2064,6 +2242,16 @@ static void LoadLevelInfoFromLevelDir(TreeInfo **node_first, level_directory); } +boolean AdjustGraphicsForEMC() +{ + boolean settings_changed = FALSE; + + settings_changed |= adjustTreeGraphicsForEMC(leveldir_first_all); + settings_changed |= adjustTreeGraphicsForEMC(leveldir_first); + + return settings_changed; +} + void LoadLevelInfo() { InitUserLevelDirectory(getLoginName()); @@ -2073,6 +2261,17 @@ void LoadLevelInfo() LoadLevelInfoFromLevelDir(&leveldir_first, NULL, options.level_directory); LoadLevelInfoFromLevelDir(&leveldir_first, NULL, getUserLevelDir(NULL)); +#if 1 + /* 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); +#endif + + AdjustGraphicsForEMC(); + /* before sorting, the first entries will be from the user directory */ leveldir_current = getFirstValidTreeInfoEntry(leveldir_first); @@ -2124,7 +2323,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, if (!valid_file_found) { - if (strcmp(directory_name, ".") != 0) + if (!strEqual(directory_name, ".")) Error(ERR_WARN, "ignoring artwork directory '%s'", directory_path); free(directory_path); @@ -2146,7 +2345,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, if (setup_file_hash) /* (before defining ".color" and ".class_desc") */ { #if 0 - checkSetupFileHashIdentifier(setup_file_hash, getCookie("...")); + checkSetupFileHashIdentifier(setup_file_hash, filename, getCookie("...")); #endif /* set all structure fields according to the token/value pairs */ @@ -2156,7 +2355,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, getHashEntry(setup_file_hash, levelinfo_tokens[i].text)); *artwork_new = ldi; - if (strcmp(artwork_new->name, ANONYMOUS_NAME) == 0) + if (strEqual(artwork_new->name, ANONYMOUS_NAME)) setString(&artwork_new->name, artwork_new->subdir); #if 0 @@ -2182,7 +2381,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, } artwork_new->in_user_dir = - (strcmp(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type)) != 0); + (!strEqual(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type))); /* (may use ".sort_priority" from "setup_file_hash" above) */ artwork_new->color = ARTWORKCOLOR(artwork_new); @@ -2191,7 +2390,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, if (setup_file_hash == NULL) /* (after determining ".user_defined") */ { - if (strcmp(artwork_new->subdir, ".") == 0) + if (strEqual(artwork_new->subdir, ".")) { if (artwork_new->user_defined) { @@ -2241,8 +2440,10 @@ static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first, 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; } @@ -2252,15 +2453,15 @@ static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first, char *directory_name = dir_entry->d_name; char *directory_path = getPath2(base_directory, directory_name); - /* skip entries for current and parent directory */ - if (strcmp(directory_name, ".") == 0 || - strcmp(directory_name, "..") == 0) + /* skip directory 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 */ + /* 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 */ { @@ -2271,7 +2472,7 @@ static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first, free(directory_path); /* check if this directory contains artwork with or without config file */ - valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first,node_parent, + valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first, node_parent, base_directory, directory_name, type); } @@ -2279,7 +2480,7 @@ static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first, closedir(dir); /* check if this directory directly contains artwork itself */ - valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first,node_parent, + valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first, node_parent, base_directory, ".", type); if (!valid_entry_found) @@ -2390,12 +2591,12 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, while (level_node) { - char *path = getPath2(getLevelDirFromTreeInfo(level_node), - ARTWORK_DIRECTORY((*artwork_node)->type)); - + /* check all tree entries for artwork, but skip parent link entries */ if (!level_node->parent_link) { TreeInfo *topnode_last = *artwork_node; + char *path = getPath2(getLevelDirFromTreeInfo(level_node), + ARTWORK_DIRECTORY((*artwork_node)->type)); LoadArtworkInfoFromArtworkDir(artwork_node, NULL, path, (*artwork_node)->type); @@ -2413,9 +2614,9 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, (*artwork_node)->sort_priority = level_node->sort_priority; (*artwork_node)->color = LEVELCOLOR((*artwork_node)); } - } - free(path); + free(path); + } if (level_node->node_group != NULL) LoadArtworkInfoFromLevelInfo(artwork_node, level_node->node_group); @@ -2428,13 +2629,13 @@ void LoadLevelArtworkInfo() { DrawInitText("Looking for custom level artwork:", 120, FC_GREEN); - LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first); - LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first); - LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first); + LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first_all); + LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first_all); + LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first_all); /* needed for reloading level artwork not known at ealier stage */ - if (strcmp(artwork.gfx_current_identifier, setup.graphics_set) != 0) + if (!strEqual(artwork.gfx_current_identifier, setup.graphics_set)) { artwork.gfx_current = getTreeInfoFromIdentifier(artwork.gfx_first, setup.graphics_set); @@ -2445,7 +2646,7 @@ void LoadLevelArtworkInfo() artwork.gfx_current = getFirstValidTreeInfoEntry(artwork.gfx_first); } - if (strcmp(artwork.snd_current_identifier, setup.sounds_set) != 0) + if (!strEqual(artwork.snd_current_identifier, setup.sounds_set)) { artwork.snd_current = getTreeInfoFromIdentifier(artwork.snd_first, setup.sounds_set); @@ -2456,7 +2657,7 @@ void LoadLevelArtworkInfo() artwork.snd_current = getFirstValidTreeInfoEntry(artwork.snd_first); } - if (strcmp(artwork.mus_current_identifier, setup.music_set) != 0) + if (!strEqual(artwork.mus_current_identifier, setup.music_set)) { artwork.mus_current = getTreeInfoFromIdentifier(artwork.mus_first, setup.music_set); @@ -2554,6 +2755,10 @@ char *getSetupValue(int type, void *value) strcpy(value_string, (*(boolean *)value ? "yes" : "no")); break; + case TYPE_ECS_AGA: + strcpy(value_string, (*(boolean *)value ? "AGA" : "ECS")); + break; + case TYPE_KEY: strcpy(value_string, getKeyNameFromKey(*(Key *)value)); break; @@ -2575,6 +2780,9 @@ char *getSetupValue(int type, void *value) break; } + if (type & TYPE_GHOSTED) + strcpy(value_string, "n/a"); + return value_string; } @@ -2600,8 +2808,8 @@ char *getSetupLine(struct TokenInfo *token_info, char *prefix, int token_nr) char *keyname = getKeyNameFromKey(key); /* add comment, if useful */ - if (strcmp(keyname, "(undefined)") != 0 && - strcmp(keyname, "(unknown)") != 0) + if (!strEqual(keyname, "(undefined)") && + !strEqual(keyname, "(unknown)")) { /* add at least one whitespace */ strcat(line, " "); @@ -2638,7 +2846,8 @@ void LoadLevelSetup_LastSeries() if (leveldir_current == NULL) leveldir_current = getFirstValidTreeInfoEntry(leveldir_first); - checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP")); + checkSetupFileHashIdentifier(level_setup_hash, filename, + getCookie("LEVELSETUP")); freeSetupFileHash(level_setup_hash); } @@ -2702,7 +2911,7 @@ static void checkSeriesInfo() { if (strlen(dir_entry->d_name) > 4 && dir_entry->d_name[3] == '.' && - strcmp(&dir_entry->d_name[4], LEVELFILE_EXTENSION) == 0) + strEqual(&dir_entry->d_name[4], LEVELFILE_EXTENSION)) { char levelnum_str[4]; int levelnum_value; @@ -2782,7 +2991,8 @@ void LoadLevelSetup_SeriesInfo() leveldir_current->handicap_level = level_nr; } - checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP")); + checkSetupFileHashIdentifier(level_setup_hash, filename, + getCookie("LEVELSETUP")); freeSetupFileHash(level_setup_hash); }