X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=b4e10780347c6a0766f221d3df738727ff7ffc47;hb=7ef23a490275f99c802131d747e07f2feb67f43c;hp=85f6e1f088c6e5f6bd1e3e7e2296f814557002b7;hpb=4d5bada656d88feb1eef48b153d5047056e2067c;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 85f6e1f0..b4e10780 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -99,6 +99,7 @@ static int token_comment_position = TOKEN_COMMENT_POSITION_DEFAULT; static SetupFileHash *artworkinfo_cache_old = NULL; static SetupFileHash *artworkinfo_cache_new = NULL; +static SetupFileHash *optional_tokens_hash = NULL; static boolean use_artworkinfo_cache = TRUE; @@ -178,7 +179,7 @@ static char *getNetworkDir(void) return network_dir; } -static char *getLevelDirFromTreeInfo(TreeInfo *node) +char *getLevelDirFromTreeInfo(TreeInfo *node) { static char *level_dir = NULL; @@ -457,7 +458,7 @@ char *getProgramMainDataPath(char *command_filename, char *base_path) { // check if the program's main data base directory is configured if (!strEqual(base_path, ".")) - return base_path; + return getStringCopy(base_path); /* if the program is configured to start from current directory (default), determine program package directory from program binary (some versions @@ -494,22 +495,41 @@ char *getProgramMainDataPath(char *command_filename, char *base_path) char *getProgramConfigFilename(char *command_filename) { - char *command_filename_1 = getStringCopy(command_filename); + static char *config_filename_1 = NULL; + static char *config_filename_2 = NULL; + static char *config_filename_3 = NULL; + static boolean initialized = FALSE; - // strip trailing executable suffix from command filename - if (strSuffix(command_filename_1, ".exe")) - command_filename_1[strlen(command_filename_1) - 4] = '\0'; + if (!initialized) + { + char *command_filename_1 = getStringCopy(command_filename); + + // strip trailing executable suffix from command filename + if (strSuffix(command_filename_1, ".exe")) + command_filename_1[strlen(command_filename_1) - 4] = '\0'; + + char *ro_base_path = getProgramMainDataPath(command_filename, RO_BASE_PATH); + char *conf_directory = getPath2(ro_base_path, CONF_DIRECTORY); + + char *command_basepath = getBasePath(command_filename); + char *command_basename = getBaseNameNoSuffix(command_filename); + char *command_filename_2 = getPath2(command_basepath, command_basename); + + config_filename_1 = getStringCat2(command_filename_1, ".conf"); + config_filename_2 = getStringCat2(command_filename_2, ".conf"); + config_filename_3 = getPath2(conf_directory, SETUP_FILENAME); - char *ro_base_path = getProgramMainDataPath(command_filename, RO_BASE_PATH); - char *conf_directory = getPath2(ro_base_path, CONF_DIRECTORY); + checked_free(ro_base_path); + checked_free(conf_directory); - char *command_basepath = getBasePath(command_filename); - char *command_basename = getBaseNameNoSuffix(command_filename); - char *command_filename_2 = getPath2(command_basepath, command_basename); + checked_free(command_basepath); + checked_free(command_basename); - char *config_filename_1 = getStringCat2(command_filename_1, ".conf"); - char *config_filename_2 = getStringCat2(command_filename_2, ".conf"); - char *config_filename_3 = getPath2(conf_directory, SETUP_FILENAME); + checked_free(command_filename_1); + checked_free(command_filename_2); + + initialized = TRUE; + } // 1st try: look for config file that exactly matches the binary filename if (fileExists(config_filename_1)) @@ -1074,7 +1094,8 @@ void InitUserLevelDirectory(char *level_subdir) createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE); createDirectory(getUserLevelDir(level_subdir), "user level", PERMS_PRIVATE); - SaveUserLevelInfo(); + if (setup.internal.create_user_levelset) + SaveUserLevelInfo(); } } @@ -1282,21 +1303,59 @@ static boolean adjustTreeGraphicsForEMC(TreeInfo *node) while (node) { - if (node->graphics_set_ecs && !setup.prefer_aga_graphics && - !strEqual(node->graphics_set, node->graphics_set_ecs)) + 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; + + if (node->graphics_set_ecs && (want_ecs || has_only_ecs)) + graphics_set = node->graphics_set_ecs; + + if (node->graphics_set_aga && (want_aga || has_only_aga)) + graphics_set = node->graphics_set_aga; + + if (graphics_set && !strEqual(node->graphics_set, graphics_set)) { - setString(&node->graphics_set, node->graphics_set_ecs); + setString(&node->graphics_set, graphics_set); settings_changed = TRUE; } - else if (node->graphics_set_aga && setup.prefer_aga_graphics && - !strEqual(node->graphics_set, node->graphics_set_aga)) + + if (node->node_group != NULL) + settings_changed |= adjustTreeGraphicsForEMC(node->node_group); + + node = node->next; + } + + return settings_changed; +} + +static boolean adjustTreeSoundsForEMC(TreeInfo *node) +{ + boolean settings_changed = FALSE; + + 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->graphics_set, node->graphics_set_aga); + setString(&node->sounds_set, sounds_set); settings_changed = TRUE; } if (node->node_group != NULL) - settings_changed |= adjustTreeGraphicsForEMC(node->node_group); + settings_changed |= adjustTreeSoundsForEMC(node->node_group); node = node->next; } @@ -2294,15 +2353,18 @@ SetupFileHash *loadSetupFileHash(char *filename) #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 20 -#define LEVELINFO_TOKEN_MUSIC_SET 21 -#define LEVELINFO_TOKEN_FILENAME 22 -#define LEVELINFO_TOKEN_FILETYPE 23 -#define LEVELINFO_TOKEN_SPECIAL_FLAGS 24 -#define LEVELINFO_TOKEN_HANDICAP 25 -#define LEVELINFO_TOKEN_SKIP_LEVELS 26 - -#define NUM_LEVELINFO_TOKENS 27 +#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; @@ -2329,13 +2391,16 @@ static struct TokenInfo levelinfo_tokens[] = { 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.skip_levels, "skip_levels" }, + { TYPE_BOOLEAN, &ldi.use_emc_tiles, "use_emc_tiles" } }; static struct TokenInfo artworkinfo_tokens[] = @@ -2359,6 +2424,15 @@ static struct TokenInfo artworkinfo_tokens[] = { -1, NULL, NULL }, }; +static char *optional_tokens[] = +{ + "program_title", + "program_copyright", + "program_company", + + NULL +}; + static void setTreeInfoToDefaults(TreeInfo *ti, int type) { ti->type = type; @@ -2408,6 +2482,8 @@ static void setTreeInfoToDefaults(TreeInfo *ti, int type) ti->graphics_set_ecs = NULL; ti->graphics_set_aga = NULL; ti->graphics_set = NULL; + ti->sounds_set_default = NULL; + ti->sounds_set_lowpass = NULL; ti->sounds_set = NULL; ti->music_set = NULL; ti->graphics_path = getStringCopy(UNDEFINED_FILENAME); @@ -2427,6 +2503,8 @@ static void setTreeInfoToDefaults(TreeInfo *ti, int type) ti->readonly = TRUE; ti->handicap = TRUE; ti->skip_levels = FALSE; + + ti->use_emc_tiles = FALSE; } } @@ -2485,6 +2563,8 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ti, TreeInfo *parent) ti->graphics_set_ecs = getStringCopy(parent->graphics_set_ecs); ti->graphics_set_aga = getStringCopy(parent->graphics_set_aga); ti->graphics_set = getStringCopy(parent->graphics_set); + ti->sounds_set_default = getStringCopy(parent->sounds_set_default); + ti->sounds_set_lowpass = getStringCopy(parent->sounds_set_lowpass); ti->sounds_set = getStringCopy(parent->sounds_set); ti->music_set = getStringCopy(parent->music_set); ti->graphics_path = getStringCopy(UNDEFINED_FILENAME); @@ -2504,6 +2584,8 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ti, TreeInfo *parent) ti->readonly = parent->readonly; ti->handicap = parent->handicap; ti->skip_levels = parent->skip_levels; + + ti->use_emc_tiles = parent->use_emc_tiles; } } @@ -2543,6 +2625,8 @@ static TreeInfo *getTreeInfoCopy(TreeInfo *ti) ti_copy->graphics_set_ecs = getStringCopy(ti->graphics_set_ecs); ti_copy->graphics_set_aga = getStringCopy(ti->graphics_set_aga); ti_copy->graphics_set = getStringCopy(ti->graphics_set); + ti_copy->sounds_set_default = getStringCopy(ti->sounds_set_default); + ti_copy->sounds_set_lowpass = getStringCopy(ti->sounds_set_lowpass); ti_copy->sounds_set = getStringCopy(ti->sounds_set); ti_copy->music_set = getStringCopy(ti->music_set); ti_copy->graphics_path = getStringCopy(ti->graphics_path); @@ -2569,6 +2653,8 @@ static TreeInfo *getTreeInfoCopy(TreeInfo *ti) ti_copy->handicap = ti->handicap; ti_copy->skip_levels = ti->skip_levels; + ti_copy->use_emc_tiles = ti->use_emc_tiles; + ti_copy->color = ti->color; ti_copy->class_desc = getStringCopy(ti->class_desc); ti_copy->handicap_level = ti->handicap_level; @@ -2610,6 +2696,8 @@ void freeTreeInfo(TreeInfo *ti) checked_free(ti->graphics_set_ecs); checked_free(ti->graphics_set_aga); checked_free(ti->graphics_set); + checked_free(ti->sounds_set_default); + checked_free(ti->sounds_set_lowpass); checked_free(ti->sounds_set); checked_free(ti->music_set); @@ -2879,6 +2967,16 @@ static TreeInfo *getArtworkInfoCacheEntry(LevelDirTree *level_node, int type) if (!use_artworkinfo_cache) return NULL; + if (optional_tokens_hash == NULL) + { + int i; + + // create hash from list of optional tokens (for quick access) + optional_tokens_hash = newSetupFileHash(); + for (i = 0; optional_tokens[i] != NULL; i++) + setHashEntry(optional_tokens_hash, optional_tokens[i], ""); + } + if (cached) { int i; @@ -2890,16 +2988,28 @@ static TreeInfo *getArtworkInfoCacheEntry(LevelDirTree *level_node, int type) ldi = *artwork_info; for (i = 0; artworkinfo_tokens[i].type != -1; i++) { - char *token = getCacheToken(token_prefix, artworkinfo_tokens[i].text); + char *token_suffix = artworkinfo_tokens[i].text; + char *token = getCacheToken(token_prefix, token_suffix); char *value = getHashEntry(artworkinfo_cache_old, token); + boolean optional = + (getHashEntry(optional_tokens_hash, token_suffix) != NULL); + + setSetupInfo(artworkinfo_tokens, i, value); + + // check if cache entry for this item is mandatory, but missing + if (value == NULL && !optional) + { + Error(ERR_WARN, "missing cache entry '%s'", token); - // if defined, use value from cache, else keep default value - if (value != NULL) - setSetupInfo(artworkinfo_tokens, i, value); + cached = FALSE; + } } *artwork_info = ldi; + } + if (cached) + { char *filename_levelinfo = getPath2(getLevelDirFromTreeInfo(level_node), LEVELINFO_FILENAME); char *filename_artworkinfo = getPath2(getSetupArtworkDir(artwork_info), @@ -3402,6 +3512,16 @@ boolean AdjustGraphicsForEMC(void) return settings_changed; } +boolean AdjustSoundsForEMC(void) +{ + boolean settings_changed = FALSE; + + settings_changed |= adjustTreeSoundsForEMC(leveldir_first_all); + settings_changed |= adjustTreeSoundsForEMC(leveldir_first); + + return settings_changed; +} + void LoadLevelInfo(void) { InitUserLevelDirectory(getLoginName()); @@ -3421,6 +3541,7 @@ void LoadLevelInfo(void) cloneTree(&leveldir_first, leveldir_first_all, TRUE); AdjustGraphicsForEMC(); + AdjustSoundsForEMC(); // before sorting, the first entries will be from the user directory leveldir_current = getFirstValidTreeInfoEntry(leveldir_first); @@ -3860,32 +3981,34 @@ void LoadLevelArtworkInfo(void) print_timestamp_done("LoadLevelArtworkInfo"); } -static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type) +static boolean AddTreeSetToTreeInfoExt(TreeInfo *tree_node_old, char *tree_dir, + char *tree_subdir_new, int type) { - TreeInfo **tree_node_first, *tree_node_old, *tree_node_new; - char *tree_user_dir = TREE_USERDIR(type); - - if (tree_user_dir == NULL) // should not happen - return FALSE; - - // get first node of level or artwork tree - tree_node_first = TREE_FIRST_NODE_PTR(type); - - if (tree_node_first == NULL) // should not happen - return FALSE; - - if (type == TREE_TYPE_LEVEL_DIR) - { - // get level info tree node of personal user level set - tree_node_old = getTreeInfoFromIdentifier(*tree_node_first, getLoginName()); - } - else + if (tree_node_old == NULL) { - // get artwork info tree node of first artwork set - tree_node_old = *tree_node_first; + if (type == TREE_TYPE_LEVEL_DIR) + { + // get level info tree node of personal user level set + tree_node_old = getTreeInfoFromIdentifier(leveldir_first, getLoginName()); + + // this may happen if "setup.internal.create_user_levelset" is FALSE + // or if file "levelinfo.conf" is missing in personal user level set + if (tree_node_old == NULL) + tree_node_old = leveldir_first->node_group; + } + else + { + // get artwork info tree node of first artwork set + tree_node_old = ARTWORK_FIRST_NODE(artwork, type); + } } - if (tree_node_old == NULL) // should not happen + if (tree_dir == NULL) + tree_dir = TREE_USERDIR(type); + + if (tree_node_old == NULL || + tree_dir == NULL || + tree_subdir_new == NULL) // should not happen return FALSE; int draw_deactivation_mask = GetDrawDeactivationMask(); @@ -3896,21 +4019,27 @@ static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type) if (type == TREE_TYPE_LEVEL_DIR) { // load new level set config and add it next to first user level set - LoadLevelInfoFromLevelConf(&tree_node_old->next, NULL, - tree_user_dir, tree_subdir_new); + LoadLevelInfoFromLevelConf(&tree_node_old->next, + tree_node_old->node_parent, + tree_dir, tree_subdir_new); } else { // load new artwork set config and add it next to first artwork set - LoadArtworkInfoFromArtworkConf(&tree_node_old->next, NULL, - tree_user_dir, tree_subdir_new, type); + LoadArtworkInfoFromArtworkConf(&tree_node_old->next, + tree_node_old->node_parent, + tree_dir, tree_subdir_new, type); } // set draw deactivation mask to previous value SetDrawDeactivationMask(draw_deactivation_mask); - // get tree info tree node of newly added tree set - tree_node_new = getTreeInfoFromIdentifier(*tree_node_first, tree_subdir_new); + // get first node of level or artwork info tree + TreeInfo **tree_node_first = TREE_FIRST_NODE_PTR(type); + + // get tree info node of newly added level or artwork set + TreeInfo *tree_node_new = getTreeInfoFromIdentifier(*tree_node_first, + tree_subdir_new); if (tree_node_new == NULL) // should not happen return FALSE; @@ -3919,21 +4048,22 @@ static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type) tree_node_new->node_top = tree_node_old->node_top; tree_node_new->node_parent = tree_node_old->node_parent; - // sort tree info tree to adjust position of newly added tree set + // sort tree info to adjust position of newly added tree set sortTreeInfo(tree_node_first); return TRUE; } -void AddUserTreeSetToTreeInfo(char *tree_subdir_new, int type) +void AddTreeSetToTreeInfo(TreeInfo *tree_node, char *tree_dir, + char *tree_subdir_new, int type) { - if (!AddUserTreeSetToTreeInfoExt(tree_subdir_new, type)) - Error(ERR_EXIT, "internal tree set structure corrupted -- aborting"); + if (!AddTreeSetToTreeInfoExt(tree_node, tree_dir, tree_subdir_new, type)) + Error(ERR_EXIT, "internal tree info structure corrupted -- aborting"); } void AddUserLevelSetToLevelInfo(char *level_subdir_new) { - AddUserTreeSetToTreeInfo(level_subdir_new, TREE_TYPE_LEVEL_DIR); + AddTreeSetToTreeInfo(NULL, NULL, level_subdir_new, TREE_TYPE_LEVEL_DIR); } char *getArtworkIdentifierForUserLevelSet(int type) @@ -3963,8 +4093,17 @@ TreeInfo *getArtworkTreeInfoForUserLevelSet(int type) { char *artwork_set = getArtworkIdentifierForUserLevelSet(type); TreeInfo *artwork_first_node = ARTWORK_FIRST_NODE(artwork, type); + TreeInfo *ti = getTreeInfoFromIdentifier(artwork_first_node, artwork_set); - return getTreeInfoFromIdentifier(artwork_first_node, artwork_set); + if (ti == NULL) + { + ti = getTreeInfoFromIdentifier(artwork_first_node, + ARTWORK_DEFAULT_SUBDIR(type)); + if (ti == NULL) + Error(ERR_EXIT, "cannot find default graphics -- should not happen"); + } + + return ti; } boolean checkIfCustomArtworkExistsForCurrentLevelSet(void)