X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=0a406540224696e012e1243fe9944407a62a4863;hb=refs%2Fheads%2Fmaster-next-major-release;hp=f9fb34eaeb50f636a67448cedb2ceed10ee47e2e;hpb=fb260f5e9048cac10367caaaefa6e9d635847241;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index f9fb34ea..fb63321b 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -725,7 +725,7 @@ char *getScoreTapeBasename(char *name) sprintf(timestamp, "%s", getCurrentTimestamp()); sprintf(basename_raw, "%s-%s", timestamp, name); - sprintf(basename, "%s-%08x", timestamp, get_hash_from_key(basename_raw)); + sprintf(basename, "%s-%08x", timestamp, get_hash_from_string(basename_raw)); return basename; } @@ -797,26 +797,68 @@ char *getEditorSetupFilename(void) return filename; } -char *getHelpAnimFilename(void) +char *getFilenameFromCurrentLevelDirUpward(char *basename) { + // global variable "leveldir_current" must be modified in the loop below + LevelDirTree *leveldir_current_last = leveldir_current; static char *filename = NULL; - checked_free(filename); + // check for filename in path from current to topmost tree node + + while (leveldir_current != NULL) + { + checked_free(filename); + + filename = getPath2(getCurrentLevelDir(), basename); + + if (fileExists(filename)) + break; - filename = getPath2(getCurrentLevelDir(), HELPANIM_FILENAME); + leveldir_current = leveldir_current->node_parent; + } + + // restore global variable "leveldir_current" modified in above loop + leveldir_current = leveldir_current_last; return filename; } -char *getHelpTextFilename(void) +static char *getHelpFilename(char *basename) { static char *filename = NULL; checked_free(filename); - filename = getPath2(getCurrentLevelDir(), HELPTEXT_FILENAME); + // 1st try: look for help filename in current level set directory + filename = getPath2(getCurrentLevelDir(), basename); + if (fileExists(filename)) + return filename; + + free(filename); - return filename; + // 2nd try: look for help filename in configured graphics set directory + filename = getPath2(getLevelArtworkDir(ARTWORK_TYPE_GRAPHICS), basename); + if (fileExists(filename)) + return filename; + + free(filename); + + // 3rd try: look for help filename in path from current to topmost level set directory + filename = getStringCopy(getFilenameFromCurrentLevelDirUpward(basename)); + if (fileExists(filename)) + return filename; + + return NULL; +} + +char *getHelpAnimFilename(void) +{ + return getHelpFilename(HELPANIM_FILENAME); +} + +char *getHelpTextFilename(void) +{ + return getHelpFilename(HELPTEXT_FILENAME); } static char *getLevelSetInfoBasename(int nr) @@ -1326,7 +1368,9 @@ static char *getCustomMusicDirectoryExt(boolean check_music) { // 2nd try: look for special artwork configured in level series config directory = getStringCopy(getLevelArtworkDir(TREE_TYPE_MUSIC_DIR)); - if (directoryExists_CheckMusic(directory, check_music)) + + // directory also valid if no unconfigured music found (no game music) + if (directoryExists_CheckMusic(directory, FALSE)) return directory; free(directory); @@ -1340,7 +1384,9 @@ static char *getCustomMusicDirectoryExt(boolean check_music) { // 3rd try: look for special artwork in configured artwork directory directory = getStringCopy(getSetupArtworkDir(artwork.mus_current)); - if (directoryExists_CheckMusic(directory, check_music)) + + // directory also valid if no unconfigured music found (no game music) + if (directoryExists_CheckMusic(directory, FALSE)) return directory; free(directory); @@ -1705,30 +1751,56 @@ static void cloneTree(TreeInfo **ti_new, TreeInfo *ti, boolean skip_empty_sets) *ti_new = ti_cloned; } -static boolean adjustTreeGraphicsForEMC(TreeInfo *node) +static boolean adjustTreeArtworkForEMC(char **artwork_set_1, + char **artwork_set_2, + char **artwork_set, boolean prefer_2) { - boolean settings_changed = FALSE; + // do nothing if neither special artwork set 1 nor 2 are defined + if (!*artwork_set_1 && !*artwork_set_2) + return FALSE; - while (node) + boolean want_1 = (prefer_2 == FALSE); + boolean want_2 = (prefer_2 == TRUE); + boolean has_only_1 = (!*artwork_set && !*artwork_set_2); + boolean has_only_2 = (!*artwork_set && !*artwork_set_1); + char *artwork_set_new = NULL; + + // replace missing special artwork 1 or 2 with (optional) standard artwork + + if (!*artwork_set_1) + setString(artwork_set_1, *artwork_set); + + if (!*artwork_set_2) + setString(artwork_set_2, *artwork_set); + + // set standard artwork to either special artwork 1 or 2, as requested + + if (*artwork_set_1 && (want_1 || has_only_1)) + artwork_set_new = *artwork_set_1; + + if (*artwork_set_2 && (want_2 || has_only_2)) + artwork_set_new = *artwork_set_2; + + if (artwork_set_new && !strEqual(*artwork_set, artwork_set_new)) { - boolean want_ecs = (setup.prefer_aga_graphics == FALSE); - boolean want_aga = (setup.prefer_aga_graphics == TRUE); - boolean has_only_ecs = (!node->graphics_set && !node->graphics_set_aga); - boolean has_only_aga = (!node->graphics_set && !node->graphics_set_ecs); - char *graphics_set = NULL; + setString(artwork_set, artwork_set_new); - if (node->graphics_set_ecs && (want_ecs || has_only_ecs)) - graphics_set = node->graphics_set_ecs; + return TRUE; + } - if (node->graphics_set_aga && (want_aga || has_only_aga)) - graphics_set = node->graphics_set_aga; + return FALSE; +} - if (graphics_set && !strEqual(node->graphics_set, graphics_set)) - { - setString(&node->graphics_set, graphics_set); - settings_changed = TRUE; - } +static boolean adjustTreeGraphicsForEMC(TreeInfo *node) +{ + boolean settings_changed = FALSE; + while (node) + { + settings_changed |= adjustTreeArtworkForEMC(&node->graphics_set_ecs, + &node->graphics_set_aga, + &node->graphics_set, + setup.prefer_aga_graphics); if (node->node_group != NULL) settings_changed |= adjustTreeGraphicsForEMC(node->node_group); @@ -1744,24 +1816,10 @@ static boolean adjustTreeSoundsForEMC(TreeInfo *node) while (node) { - boolean want_default = (setup.prefer_lowpass_sounds == FALSE); - boolean want_lowpass = (setup.prefer_lowpass_sounds == TRUE); - boolean has_only_default = (!node->sounds_set && !node->sounds_set_lowpass); - boolean has_only_lowpass = (!node->sounds_set && !node->sounds_set_default); - char *sounds_set = NULL; - - if (node->sounds_set_default && (want_default || has_only_default)) - sounds_set = node->sounds_set_default; - - if (node->sounds_set_lowpass && (want_lowpass || has_only_lowpass)) - sounds_set = node->sounds_set_lowpass; - - if (sounds_set && !strEqual(node->sounds_set, sounds_set)) - { - setString(&node->sounds_set, sounds_set); - settings_changed = TRUE; - } - + settings_changed |= adjustTreeArtworkForEMC(&node->sounds_set_default, + &node->sounds_set_lowpass, + &node->sounds_set, + setup.prefer_lowpass_sounds); if (node->node_group != NULL) settings_changed |= adjustTreeSoundsForEMC(node->node_group); @@ -2265,7 +2323,7 @@ DEFINE_HASHTABLE_REMOVE(remove_hash_entry, char, char); #define remove_hash_entry hashtable_remove #endif -unsigned int get_hash_from_key(void *key) +unsigned int get_hash_from_string(void *key) { /* djb2 @@ -2295,15 +2353,27 @@ unsigned int get_hash_from_key(void *key) return hash; } -int hash_keys_are_equal(void *key1, void *key2) +unsigned int get_hash_from_integer(void *key) +{ + unsigned int hash = PTR_TO_UINT(key); + + return hash; +} + +int hash_key_strings_are_equal(void *key1, void *key2) { return (strEqual((char *)key1, (char *)key2)); } +int hash_key_integers_are_equal(void *key1, void *key2) +{ + return (key1 == key2); +} + SetupFileHash *newSetupFileHash(void) { SetupFileHash *new_hash = - create_hashtable(16, 0.75, get_hash_from_key, hash_keys_are_equal); + create_hashtable(get_hash_from_string, hash_key_strings_are_equal, free, free); if (new_hash == NULL) Fail("create_hashtable() failed -- out of memory"); @@ -2316,7 +2386,7 @@ void freeSetupFileHash(SetupFileHash *hash) if (hash == NULL) return; - hashtable_destroy(hash, 1); // 1 == also free values stored in hash + hashtable_destroy(hash); } char *getHashEntry(SetupFileHash *hash, char *token) @@ -2342,12 +2412,12 @@ void setHashEntry(SetupFileHash *hash, char *token, char *value) Fail("cannot insert into hash -- aborting"); } -char *removeHashEntry(SetupFileHash *hash, char *token) +void removeHashEntry(SetupFileHash *hash, char *token) { if (hash == NULL) - return NULL; + return; - return remove_hash_entry(hash, token); + remove_hash_entry(hash, token); } #if ENABLE_UNUSED_CODE @@ -2803,10 +2873,11 @@ SetupFileHash *loadSetupFileHash(char *filename) #define LEVELINFO_TOKEN_HANDICAP 29 #define LEVELINFO_TOKEN_TIME_LIMIT 30 #define LEVELINFO_TOKEN_SKIP_LEVELS 31 -#define LEVELINFO_TOKEN_USE_EMC_TILES 32 -#define LEVELINFO_TOKEN_INFO_SCREENS_FROM_MAIN 33 +#define LEVELINFO_TOKEN_ALLOW_SKIPPING_LEVELS 32 +#define LEVELINFO_TOKEN_USE_EMC_TILES 33 +#define LEVELINFO_TOKEN_INFO_SCREENS_FROM_MAIN 34 -#define NUM_LEVELINFO_TOKENS 34 +#define NUM_LEVELINFO_TOKENS 35 static LevelDirTree ldi; @@ -2830,6 +2901,8 @@ static struct TokenInfo levelinfo_tokens[] = { 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.old" }, + { TYPE_STRING, &ldi.graphics_set_aga, "graphics_set.new" }, { 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" }, @@ -3202,8 +3275,8 @@ void setSetupInfo(struct TokenInfo *token_info, *(boolean *)setup_value = get_boolean_from_string(token_value); break; - case TYPE_SWITCH3: - *(int *)setup_value = get_switch3_from_string(token_value); + case TYPE_SWITCH_3_STATES: + *(int *)setup_value = get_switch_3_state_from_string(token_value); break; case TYPE_KEY: @@ -4578,6 +4651,12 @@ static boolean AddTreeSetToTreeInfoExt(TreeInfo *tree_node_old, char *tree_dir, TreeInfo *tree_node_new = getTreeInfoFromIdentifier(*tree_node_first, tree_subdir_new); + // if not found, check if added node is level group or artwork group + if (tree_node_new == NULL) + tree_node_new = getTreeInfoFromIdentifierExt(*tree_node_first, + tree_subdir_new, + TREE_NODE_TYPE_GROUP); + if (tree_node_new == NULL) // should not happen return FALSE; @@ -4825,9 +4904,10 @@ char *getSetupValue(int type, void *value) strcpy(value_string, (*(boolean *)value ? "on" : "off")); break; - case TYPE_SWITCH3: - strcpy(value_string, (*(int *)value == AUTO ? "auto" : - *(int *)value == FALSE ? "off" : "on")); + case TYPE_SWITCH_3_STATES: + strcpy(value_string, (*(int *)value == STATE_AUTO ? "auto" : + *(int *)value == STATE_ASK ? "ask" : + *(int *)value == STATE_FALSE ? "off" : "on")); break; case TYPE_YES_NO: @@ -4835,12 +4915,17 @@ char *getSetupValue(int type, void *value) break; case TYPE_YES_NO_AUTO: - strcpy(value_string, (*(int *)value == AUTO ? "auto" : - *(int *)value == FALSE ? "no" : "yes")); + strcpy(value_string, (*(int *)value == STATE_AUTO ? "auto" : + *(int *)value == STATE_FALSE ? "no" : "yes")); + break; + + case TYPE_YES_NO_ASK: + strcpy(value_string, (*(int *)value == STATE_ASK ? "ask" : + *(int *)value == STATE_FALSE ? "no" : "yes")); break; case TYPE_ECS_AGA: - strcpy(value_string, (*(boolean *)value ? "AGA" : "ECS")); + strcpy(value_string, (*(boolean *)value ? "new" : "old")); break; case TYPE_KEY: