X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=b419875a580e8fd1f87eab476ec4b496f232db7c;hp=1c3a5dc73ea3429abc4b7f16e84bf2fefe5a36ac;hb=HEAD;hpb=ab08248a4aca608effd20bce7abd56986ef2b17b diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 1c3a5dc7..b419875a 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -19,6 +19,7 @@ #include "platform.h" #include "setup.h" +#include "sound.h" #include "joystick.h" #include "text.h" #include "misc.h" @@ -47,8 +48,6 @@ static char *levelclass_desc[NUM_LEVELCLASS_DESC] = #define TOKEN_VALUE_POSITION_DEFAULT 40 #define TOKEN_COMMENT_POSITION_DEFAULT 60 -#define MAX_COOKIE_LEN 256 - #define TREE_NODE_TYPE_DEFAULT 0 #define TREE_NODE_TYPE_PARENT 1 #define TREE_NODE_TYPE_GROUP 2 @@ -820,9 +819,34 @@ char *getHelpTextFilename(void) return filename; } -char *getLevelSetInfoFilename(void) +static char *getLevelSetInfoBasename(int nr) +{ + static char basename[32]; + + sprintf(basename, "levelset_%d.txt", nr + 1); + + return basename; +} + +char *getLevelSetInfoFilename(int nr) { + char *basename = getLevelSetInfoBasename(nr); + static char *info_subdir = NULL; static char *filename = NULL; + + if (info_subdir == NULL) + info_subdir = getPath2(DOCS_DIRECTORY, LEVELSET_INFO_DIRECTORY); + + checked_free(filename); + + // look for level set info file the current level set directory + filename = getPath3(getCurrentLevelDir(), info_subdir, basename); + if (fileExists(filename)) + return filename; + + if (nr > 0) + return NULL; + char *basenames[] = { "README", @@ -1230,7 +1254,58 @@ char *getCustomArtworkLevelConfigFilename(int type) return filename; } -char *getCustomMusicDirectory(void) +static boolean directoryExists_CheckMusic(char *directory, boolean check_music) +{ + if (!directoryExists(directory)) + return FALSE; + + if (!check_music) + return TRUE; + + Directory *dir; + DirectoryEntry *dir_entry; + int num_music = getMusicListSize(); + boolean music_found = FALSE; + + if ((dir = openDirectory(directory)) == NULL) + return FALSE; + + while ((dir_entry = readDirectory(dir)) != NULL) // loop all entries + { + char *basename = dir_entry->basename; + boolean music_already_used = FALSE; + int i; + + // skip all music files that are configured in music config file + for (i = 0; i < num_music; i++) + { + struct FileInfo *music = getMusicListEntry(i); + + if (strEqual(basename, music->filename)) + { + music_already_used = TRUE; + + break; + } + } + + if (music_already_used) + continue; + + if (FileIsMusic(dir_entry->filename)) + { + music_found = TRUE; + + break; + } + } + + closeDirectory(dir); + + return music_found; +} + +static char *getCustomMusicDirectoryExt(boolean check_music) { static char *directory = NULL; boolean skip_setup_artwork = FALSE; @@ -1241,7 +1316,7 @@ char *getCustomMusicDirectory(void) { // 1st try: look for special artwork in current level series directory directory = getPath2(getCurrentLevelDir(), MUSIC_DIRECTORY); - if (directoryExists(directory)) + if (directoryExists_CheckMusic(directory, check_music)) return directory; free(directory); @@ -1251,7 +1326,9 @@ char *getCustomMusicDirectory(void) { // 2nd try: look for special artwork configured in level series config directory = getStringCopy(getLevelArtworkDir(TREE_TYPE_MUSIC_DIR)); - if (directoryExists(directory)) + + // directory also valid if no unconfigured music found (no game music) + if (directoryExists_CheckMusic(directory, FALSE)) return directory; free(directory); @@ -1265,7 +1342,9 @@ char *getCustomMusicDirectory(void) { // 3rd try: look for special artwork in configured artwork directory directory = getStringCopy(getSetupArtworkDir(artwork.mus_current)); - if (directoryExists(directory)) + + // directory also valid if no unconfigured music found (no game music) + if (directoryExists_CheckMusic(directory, FALSE)) return directory; free(directory); @@ -1273,19 +1352,29 @@ char *getCustomMusicDirectory(void) // 4th try: look for default artwork in new default artwork directory directory = getStringCopy(getDefaultMusicDir(MUS_DEFAULT_SUBDIR)); - if (directoryExists(directory)) + if (directoryExists_CheckMusic(directory, check_music)) return directory; free(directory); // 5th try: look for default artwork in old default artwork directory directory = getStringCopy(options.music_directory); - if (directoryExists(directory)) + if (directoryExists_CheckMusic(directory, check_music)) return directory; return NULL; // cannot find specified artwork file anywhere } +char *getCustomMusicDirectory(void) +{ + return getCustomMusicDirectoryExt(FALSE); +} + +char *getCustomMusicDirectory_NoConf(void) +{ + return getCustomMusicDirectoryExt(TRUE); +} + void MarkTapeDirectoryUploadsAsComplete(char *level_subdir) { char *filename = getPath2(getTapeDir(level_subdir), UPLOADED_FILENAME); @@ -1371,10 +1460,13 @@ void InitUserLevelDirectory(char *level_subdir) { createDirectory(getMainUserGameDataDir(), "main user data"); createDirectory(getUserLevelDir(NULL), "main user level"); - createDirectory(getUserLevelDir(level_subdir), "user level"); if (setup.internal.create_user_levelset) + { + createDirectory(getUserLevelDir(level_subdir), "user level"); + SaveUserLevelInfo(); + } } } @@ -1617,30 +1709,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); @@ -1656,24 +1774,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); @@ -2000,21 +2104,6 @@ void SetFilePermissions(char *filename, int permission_class) chmod(filename, perms); } -char *getCookie(char *file_type) -{ - static char cookie[MAX_COOKIE_LEN + 1]; - - if (strlen(program.cookie_prefix) + 1 + - strlen(file_type) + strlen("_FILE_VERSION_x.x") > MAX_COOKIE_LEN) - return "[COOKIE ERROR]"; // should never happen - - sprintf(cookie, "%s_%s_FILE_VERSION_%d.%d", - program.cookie_prefix, file_type, - program.version_super, program.version_major); - - return cookie; -} - void fprintFileHeader(FILE *file, char *basename) { char *prefix = "# "; @@ -2692,6 +2781,7 @@ SetupFileHash *loadSetupFileHash(char *filename) // ============================================================================ #define TOKEN_STR_LAST_LEVEL_SERIES "last_level_series" +#define TOKEN_STR_LAST_PLAYED_MENU_USED "last_played_menu_used" #define TOKEN_STR_LAST_PLAYED_LEVEL "last_played_level" #define TOKEN_STR_HANDICAP_LEVEL "handicap_level" #define TOKEN_STR_LAST_USER "last_user" @@ -2727,10 +2817,12 @@ SetupFileHash *loadSetupFileHash(char *filename) #define LEVELINFO_TOKEN_EMPTY_LEVEL_NAME 27 #define LEVELINFO_TOKEN_FORCE_LEVEL_NAME 28 #define LEVELINFO_TOKEN_HANDICAP 29 -#define LEVELINFO_TOKEN_SKIP_LEVELS 30 -#define LEVELINFO_TOKEN_USE_EMC_TILES 31 +#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 NUM_LEVELINFO_TOKENS 32 +#define NUM_LEVELINFO_TOKENS 34 static LevelDirTree ldi; @@ -2767,8 +2859,10 @@ static struct TokenInfo levelinfo_tokens[] = { TYPE_STRING, &ldi.empty_level_name, "empty_level_name" }, { TYPE_BOOLEAN, &ldi.force_level_name, "force_level_name" }, { TYPE_BOOLEAN, &ldi.handicap, "handicap" }, + { TYPE_BOOLEAN, &ldi.time_limit, "time_limit" }, { TYPE_BOOLEAN, &ldi.skip_levels, "skip_levels" }, - { TYPE_BOOLEAN, &ldi.use_emc_tiles, "use_emc_tiles" } + { TYPE_BOOLEAN, &ldi.use_emc_tiles, "use_emc_tiles" }, + { TYPE_BOOLEAN, &ldi.info_screens_from_main, "info_screens_from_main" } }; static struct TokenInfo artworkinfo_tokens[] = @@ -2873,9 +2967,11 @@ static void setTreeInfoToDefaults(TreeInfo *ti, int type) ti->handicap_level = 0; ti->readonly = TRUE; ti->handicap = TRUE; + ti->time_limit = TRUE; ti->skip_levels = FALSE; ti->use_emc_tiles = FALSE; + ti->info_screens_from_main = FALSE; } } @@ -2958,9 +3054,11 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ti, TreeInfo *parent) ti->handicap_level = parent->handicap_level; ti->readonly = parent->readonly; ti->handicap = parent->handicap; + ti->time_limit = parent->time_limit; ti->skip_levels = parent->skip_levels; ti->use_emc_tiles = parent->use_emc_tiles; + ti->info_screens_from_main = parent->info_screens_from_main; } } @@ -3030,9 +3128,11 @@ static TreeInfo *getTreeInfoCopy(TreeInfo *ti) ti_copy->user_defined = ti->user_defined; ti_copy->readonly = ti->readonly; ti_copy->handicap = ti->handicap; + ti_copy->time_limit = ti->time_limit; ti_copy->skip_levels = ti->skip_levels; ti_copy->use_emc_tiles = ti->use_emc_tiles; + ti_copy->info_screens_from_main = ti->info_screens_from_main; ti_copy->color = ti->color; ti_copy->class_desc = getStringCopy(ti->class_desc); @@ -3890,9 +3990,13 @@ static void LoadLevelInfoFromLevelDir(TreeInfo **node_first, level_directory, "."); } - if (!valid_entry_found) + boolean valid_entry_expected = + (strEqual(level_directory, options.level_directory) || + setup.internal.create_user_levelset); + + if (valid_entry_expected && !valid_entry_found) Warn("cannot find any valid level series in directory '%s'", - level_directory); + level_directory); } boolean AdjustGraphicsForEMC(void) @@ -4490,6 +4594,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; @@ -4919,33 +5029,51 @@ static void UpdateLastPlayedLevels_List(void) setString(&last_level_series[0], leveldir_current->identifier); } -static TreeInfo *StoreOrRestoreLastPlayedLevels(TreeInfo *node, boolean store) +#define LAST_PLAYED_MODE_SET 1 +#define LAST_PLAYED_MODE_SET_FORCED 2 +#define LAST_PLAYED_MODE_GET 3 + +static TreeInfo *StoreOrRestoreLastPlayedLevels(TreeInfo *node, int mode) { static char *identifier = NULL; - if (store) + if (mode == LAST_PLAYED_MODE_SET) { setString(&identifier, (node && node->is_copy ? node->identifier : NULL)); - - return NULL; // not used } - else + else if (mode == LAST_PLAYED_MODE_SET_FORCED) + { + setString(&identifier, (node ? node->identifier : NULL)); + } + else if (mode == LAST_PLAYED_MODE_GET) { TreeInfo *node_new = getTreeInfoFromIdentifierExt(leveldir_first, identifier, TREE_NODE_TYPE_COPY); return (node_new != NULL ? node_new : node); } + + return NULL; // not used } void StoreLastPlayedLevels(TreeInfo *node) { - StoreOrRestoreLastPlayedLevels(node, TRUE); + StoreOrRestoreLastPlayedLevels(node, LAST_PLAYED_MODE_SET); +} + +void ForcedStoreLastPlayedLevels(TreeInfo *node) +{ + StoreOrRestoreLastPlayedLevels(node, LAST_PLAYED_MODE_SET_FORCED); } void RestoreLastPlayedLevels(TreeInfo **node) { - *node = StoreOrRestoreLastPlayedLevels(*node, FALSE); + *node = StoreOrRestoreLastPlayedLevels(*node, LAST_PLAYED_MODE_GET); +} + +boolean CheckLastPlayedLevels(void) +{ + return (StoreOrRestoreLastPlayedLevels(NULL, LAST_PLAYED_MODE_GET) != NULL); } void LoadLevelSetup_LastSeries(void) @@ -4983,6 +5111,13 @@ void LoadLevelSetup_LastSeries(void) if (leveldir_current == NULL) leveldir_current = getFirstValidTreeInfoEntry(leveldir_first); + char *last_played_menu_used = + getHashEntry(level_setup_hash, TOKEN_STR_LAST_PLAYED_MENU_USED); + + // store if last level set was selected from "last played" menu + if (strEqual(last_played_menu_used, "true")) + ForcedStoreLastPlayedLevels(leveldir_current); + for (i = 0; i < MAX_LEVELDIR_HISTORY; i++) { char token[strlen(TOKEN_STR_LAST_LEVEL_SERIES) + 10]; @@ -5045,7 +5180,14 @@ static void SaveLevelSetup_LastSeries_Ext(boolean deactivate_last_level_series) fprintf(file, "# %s\n# ", "the following level set may have caused a problem and was deactivated"); fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_LAST_LEVEL_SERIES, - leveldir_current->identifier)); + leveldir_current->identifier)); + + // store if last level set was selected from "last played" menu + boolean last_played_menu_used = CheckLastPlayedLevels(); + char *setup_value = getSetupValue(TYPE_BOOLEAN, &last_played_menu_used); + + fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_LAST_PLAYED_MENU_USED, + setup_value)); for (i = 0; last_level_series[i] != NULL; i++) {