X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=2bc46d413a2ebbcbacbfdb9132e4b0212efaa327;hb=2f8793d6536d93616683069786ce444583d68e20;hp=206db77e4de949a765822011b9ddd738a68917ca;hpb=a99a1803e5097bc598b4c6f73259715da148ab27;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 206db77e..2bc46d41 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -18,11 +18,6 @@ #include "platform.h" -#if !defined(PLATFORM_WIN32) -#include -#include -#endif - #include "setup.h" #include "joystick.h" #include "text.h" @@ -126,9 +121,9 @@ static char *getScoreDir(char *level_subdir) if (score_dir == NULL) { if (program.global_scores) - score_dir = getPath2(getCommonDataDir(), score_subdir); + score_dir = getPath2(getCommonDataDir(), score_subdir); else - score_dir = getPath2(getUserGameDataDir(), score_subdir); + score_dir = getPath2(getMainUserGameDataDir(), score_subdir); } if (level_subdir != NULL) @@ -143,6 +138,32 @@ static char *getScoreDir(char *level_subdir) return score_dir; } +static char *getUserSubdir(int nr) +{ + static char user_subdir[16] = { 0 }; + + sprintf(user_subdir, "%03d", nr); + + return user_subdir; +} + +static char *getUserDir(int nr) +{ + static char *user_dir = NULL; + char *main_data_dir = getMainUserGameDataDir(); + char *users_subdir = USERS_DIRECTORY; + char *user_subdir = getUserSubdir(nr); + + checked_free(user_dir); + + if (nr != -1) + user_dir = getPath3(main_data_dir, users_subdir, user_subdir); + else + user_dir = getPath2(main_data_dir, users_subdir); + + return user_dir; +} + static char *getLevelSetupDir(char *level_subdir) { static char *levelsetup_dir = NULL; @@ -164,7 +185,7 @@ static char *getCacheDir(void) static char *cache_dir = NULL; if (cache_dir == NULL) - cache_dir = getPath2(getUserGameDataDir(), CACHE_DIRECTORY); + cache_dir = getPath2(getMainUserGameDataDir(), CACHE_DIRECTORY); return cache_dir; } @@ -174,7 +195,7 @@ static char *getNetworkDir(void) static char *network_dir = NULL; if (network_dir == NULL) - network_dir = getPath2(getUserGameDataDir(), NETWORK_DIRECTORY); + network_dir = getPath2(getMainUserGameDataDir(), NETWORK_DIRECTORY); return network_dir; } @@ -197,7 +218,7 @@ char *getLevelDirFromTreeInfo(TreeInfo *node) char *getUserLevelDir(char *level_subdir) { static char *userlevel_dir = NULL; - char *data_dir = getUserGameDataDir(); + char *data_dir = getMainUserGameDataDir(); char *userlevel_subdir = LEVELS_DIRECTORY; checked_free(userlevel_dir); @@ -346,7 +367,7 @@ char *getUserGraphicsDir(void) static char *usergraphics_dir = NULL; if (usergraphics_dir == NULL) - usergraphics_dir = getPath2(getUserGameDataDir(), GRAPHICS_DIRECTORY); + usergraphics_dir = getPath2(getMainUserGameDataDir(), GRAPHICS_DIRECTORY); return usergraphics_dir; } @@ -356,7 +377,7 @@ char *getUserSoundsDir(void) static char *usersounds_dir = NULL; if (usersounds_dir == NULL) - usersounds_dir = getPath2(getUserGameDataDir(), SOUNDS_DIRECTORY); + usersounds_dir = getPath2(getMainUserGameDataDir(), SOUNDS_DIRECTORY); return usersounds_dir; } @@ -366,7 +387,7 @@ char *getUserMusicDir(void) static char *usermusic_dir = NULL; if (usermusic_dir == NULL) - usermusic_dir = getPath2(getUserGameDataDir(), MUSIC_DIRECTORY); + usermusic_dir = getPath2(getMainUserGameDataDir(), MUSIC_DIRECTORY); return usermusic_dir; } @@ -1072,7 +1093,7 @@ void InitScoreDirectory(char *level_subdir) if (program.global_scores) createDirectory(getCommonDataDir(), "common data", permissions); else - createDirectory(getUserGameDataDir(), "user data", permissions); + createDirectory(getMainUserGameDataDir(), "main user data", permissions); createDirectory(getScoreDir(NULL), "main score", permissions); createDirectory(getScoreDir(level_subdir), "level score", permissions); @@ -1084,7 +1105,7 @@ void InitUserLevelDirectory(char *level_subdir) { if (!directoryExists(getUserLevelDir(level_subdir))) { - createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE); createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE); createDirectory(getUserLevelDir(level_subdir), "user level", PERMS_PRIVATE); @@ -1097,7 +1118,7 @@ void InitNetworkLevelDirectory(char *level_subdir) { if (!directoryExists(getNetworkLevelDir(level_subdir))) { - createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE); createDirectory(getNetworkDir(), "network data", PERMS_PRIVATE); createDirectory(getNetworkLevelDir(NULL), "main network level", PERMS_PRIVATE); createDirectory(getNetworkLevelDir(level_subdir), "network level", PERMS_PRIVATE); @@ -1113,7 +1134,7 @@ void InitLevelSetupDirectory(char *level_subdir) static void InitCacheDirectory(void) { - createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE); createDirectory(getCacheDir(), "cache data", PERMS_PRIVATE); } @@ -1194,7 +1215,7 @@ int numTreeInfoInGroup(TreeInfo *node) return numTreeInfo(getTreeInfoFirstGroupEntry(node)); } -int posTreeInfo(TreeInfo *node) +int getPosFromTreeInfo(TreeInfo *node) { TreeInfo *node_cmp = getTreeInfoFirstGroupEntry(node); int pos = 0; @@ -1228,7 +1249,8 @@ TreeInfo *getTreeInfoFromPos(TreeInfo *node, int pos) return node_default; } -TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier) +static TreeInfo *getTreeInfoFromIdentifierExt(TreeInfo *node, char *identifier, + boolean include_node_groups) { if (identifier == NULL) return NULL; @@ -1237,10 +1259,12 @@ TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier) { if (node->node_group) { - TreeInfo *node_group; - - node_group = getTreeInfoFromIdentifier(node->node_group, identifier); + if (include_node_groups && strEqual(identifier, node->identifier)) + return node; + TreeInfo *node_group = getTreeInfoFromIdentifierExt(node->node_group, + identifier, + include_node_groups); if (node_group) return node_group; } @@ -1256,6 +1280,11 @@ TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier) return NULL; } +TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier) +{ + return getTreeInfoFromIdentifierExt(node, identifier, FALSE); +} + static TreeInfo *cloneTreeNode(TreeInfo **node_top, TreeInfo *node_parent, TreeInfo *node, boolean skip_sets_without_levels) { @@ -1361,18 +1390,18 @@ void dumpTreeInfo(TreeInfo *node, int depth) { int i; - Print("Dumping TreeInfo:\n"); + Debug("tree", "Dumping TreeInfo:"); while (node) { for (i = 0; i < (depth + 1) * 3; i++) - Print(" "); + DebugContinued("", " "); - Print("'%s' / '%s'\n", node->identifier, node->name); + DebugContinued("tree", "'%s' / '%s'\n", node->identifier, node->name); /* // use for dumping artwork info tree - Print("subdir == '%s' ['%s', '%s'] [%d])\n", + Debug("tree", "subdir == '%s' ['%s', '%s'] [%d])", node->subdir, node->fullpath, node->basepath, node->in_user_dir); */ @@ -1504,10 +1533,10 @@ char *getHomeDir(void) { if ((dir = getenv("HOME")) == NULL) { - struct passwd *pwd; + dir = getUnixHomeDir(); - if ((pwd = getpwuid(getuid())) != NULL) - dir = getStringCopy(pwd->pw_dir); + if (dir != NULL) + dir = getStringCopy(dir); else dir = "."; } @@ -1557,23 +1586,31 @@ char *getPersonalDataDir(void) return personal_data_dir; } -char *getUserGameDataDir(void) +char *getMainUserGameDataDir(void) { - static char *user_game_data_dir = NULL; + static char *main_user_data_dir = NULL; #if defined(PLATFORM_ANDROID) - if (user_game_data_dir == NULL) - user_game_data_dir = (char *)(SDL_AndroidGetExternalStorageState() & + if (main_user_data_dir == NULL) + main_user_data_dir = (char *)(SDL_AndroidGetExternalStorageState() & SDL_ANDROID_EXTERNAL_STORAGE_WRITE ? SDL_AndroidGetExternalStoragePath() : SDL_AndroidGetInternalStoragePath()); #else - if (user_game_data_dir == NULL) - user_game_data_dir = getPath2(getPersonalDataDir(), + if (main_user_data_dir == NULL) + main_user_data_dir = getPath2(getPersonalDataDir(), program.userdata_subdir); #endif - return user_game_data_dir; + return main_user_data_dir; +} + +char *getUserGameDataDir(void) +{ + if (user.nr == 0) + return getMainUserGameDataDir(); + else + return getUserDir(user.nr); } char *getSetupDir(void) @@ -1641,9 +1678,20 @@ void createDirectory(char *dir, char *text, int permission_class) posix_umask(last_umask); // restore previous umask } +void InitMainUserDataDirectory(void) +{ + createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE); +} + void InitUserDataDirectory(void) { - createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE); + + if (user.nr != 0) + { + createDirectory(getUserDir(-1), "users", PERMS_PRIVATE); + createDirectory(getUserDir(user.nr), "user data", PERMS_PRIVATE); + } } void SetFilePermissions(char *filename, int permission_class) @@ -1891,7 +1939,7 @@ SetupFileHash *newSetupFileHash(void) create_hashtable(16, 0.75, get_hash_from_key, keys_are_equal); if (new_hash == NULL) - Error(ERR_EXIT, "create_hashtable() failed -- out of memory"); + Fail("create_hashtable() failed -- out of memory"); return new_hash; } @@ -1924,7 +1972,7 @@ void setHashEntry(SetupFileHash *hash, char *token, char *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"); + Fail("cannot insert into hash -- aborting"); } char *removeHashEntry(SetupFileHash *hash, char *token) @@ -2324,6 +2372,7 @@ SetupFileHash *loadSetupFileHash(char *filename) #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_USER "last_user" // level directory info #define LEVELINFO_TOKEN_IDENTIFIER 0 @@ -3540,7 +3589,7 @@ void LoadLevelInfo(void) leveldir_current = getFirstValidTreeInfoEntry(leveldir_first); if (leveldir_first == NULL) - Error(ERR_EXIT, "cannot find any valid level series in any directory"); + Fail("cannot find any valid level series in any directory"); sortTreeInfo(&leveldir_first); @@ -3766,6 +3815,34 @@ static TreeInfo *getDummyArtworkInfo(int type) return artwork_new; } +void SetCurrentArtwork(int type) +{ + ArtworkDirTree **current_ptr = ARTWORK_CURRENT_PTR(artwork, type); + ArtworkDirTree *first_node = ARTWORK_FIRST_NODE(artwork, type); + char *setup_set = SETUP_ARTWORK_SET(setup, type); + char *default_subdir = ARTWORK_DEFAULT_SUBDIR(type); + + // set current artwork to artwork configured in setup menu + *current_ptr = getTreeInfoFromIdentifier(first_node, setup_set); + + // if not found, set current artwork to default artwork + if (*current_ptr == NULL) + *current_ptr = getTreeInfoFromIdentifier(first_node, default_subdir); + + // if not found, set current artwork to first artwork in tree + if (*current_ptr == NULL) + *current_ptr = getFirstValidTreeInfoEntry(first_node); +} + +void ChangeCurrentArtworkIfNeeded(int type) +{ + char *current_identifier = ARTWORK_CURRENT_IDENTIFIER(artwork, type); + char *setup_set = SETUP_ARTWORK_SET(setup, type); + + if (!strEqual(current_identifier, setup_set)) + SetCurrentArtwork(type); +} + void LoadArtworkInfo(void) { LoadArtworkInfoCache(); @@ -3801,29 +3878,9 @@ void LoadArtworkInfo(void) artwork.mus_first = getDummyArtworkInfo(TREE_TYPE_MUSIC_DIR); // 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_DEFAULT_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_DEFAULT_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_DEFAULT_SUBDIR); - if (artwork.mus_current == NULL) - artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first); + SetCurrentArtwork(ARTWORK_TYPE_GRAPHICS); + SetCurrentArtwork(ARTWORK_TYPE_SOUNDS); + SetCurrentArtwork(ARTWORK_TYPE_MUSIC); artwork.gfx_current_identifier = artwork.gfx_current->identifier; artwork.snd_current_identifier = artwork.snd_current->identifier; @@ -3925,39 +3982,9 @@ void LoadLevelArtworkInfo(void) print_timestamp_time("SaveArtworkInfoCache"); // needed for reloading level artwork not known at ealier stage - - if (!strEqual(artwork.gfx_current_identifier, setup.graphics_set)) - { - artwork.gfx_current = - getTreeInfoFromIdentifier(artwork.gfx_first, setup.graphics_set); - if (artwork.gfx_current == NULL) - artwork.gfx_current = - getTreeInfoFromIdentifier(artwork.gfx_first, GFX_DEFAULT_SUBDIR); - if (artwork.gfx_current == NULL) - artwork.gfx_current = getFirstValidTreeInfoEntry(artwork.gfx_first); - } - - if (!strEqual(artwork.snd_current_identifier, setup.sounds_set)) - { - artwork.snd_current = - getTreeInfoFromIdentifier(artwork.snd_first, setup.sounds_set); - if (artwork.snd_current == NULL) - artwork.snd_current = - getTreeInfoFromIdentifier(artwork.snd_first, SND_DEFAULT_SUBDIR); - if (artwork.snd_current == NULL) - artwork.snd_current = getFirstValidTreeInfoEntry(artwork.snd_first); - } - - if (!strEqual(artwork.mus_current_identifier, setup.music_set)) - { - artwork.mus_current = - getTreeInfoFromIdentifier(artwork.mus_first, setup.music_set); - if (artwork.mus_current == NULL) - artwork.mus_current = - getTreeInfoFromIdentifier(artwork.mus_first, MUS_DEFAULT_SUBDIR); - if (artwork.mus_current == NULL) - artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first); - } + ChangeCurrentArtworkIfNeeded(ARTWORK_TYPE_GRAPHICS); + ChangeCurrentArtworkIfNeeded(ARTWORK_TYPE_SOUNDS); + ChangeCurrentArtworkIfNeeded(ARTWORK_TYPE_MUSIC); print_timestamp_time("getTreeInfoFromIdentifier"); @@ -4053,7 +4080,7 @@ void AddTreeSetToTreeInfo(TreeInfo *tree_node, char *tree_dir, char *tree_subdir_new, int type) { if (!AddTreeSetToTreeInfoExt(tree_node, tree_dir, tree_subdir_new, type)) - Error(ERR_EXIT, "internal tree info structure corrupted -- aborting"); + Fail("internal tree info structure corrupted -- aborting"); } void AddUserLevelSetToLevelInfo(char *level_subdir_new) @@ -4095,7 +4122,7 @@ TreeInfo *getArtworkTreeInfoForUserLevelSet(int type) ti = getTreeInfoFromIdentifier(artwork_first_node, ARTWORK_DEFAULT_SUBDIR(type)); if (ti == NULL) - Error(ERR_EXIT, "cannot find default graphics -- should not happen"); + Fail("cannot find default graphics -- should not happen"); } return ti; @@ -4373,6 +4400,99 @@ char *getSetupLine(struct TokenInfo *token_info, char *prefix, int token_nr) return line; } +static void InitLastPlayedLevels_ParentNode(void) +{ + LevelDirTree **leveldir_top = &leveldir_first->node_group->next; + LevelDirTree *leveldir_new = NULL; + + // check if parent node for last played levels already exists + if (strEqual((*leveldir_top)->identifier, TOKEN_STR_LAST_LEVEL_SERIES)) + return; + + leveldir_new = newTreeInfo(); + + setTreeInfoToDefaultsFromParent(leveldir_new, leveldir_first); + + leveldir_new->level_group = TRUE; + + setString(&leveldir_new->identifier, TOKEN_STR_LAST_LEVEL_SERIES); + setString(&leveldir_new->name, "<< (last played level sets)"); + + pushTreeInfo(leveldir_top, leveldir_new); + + /* create node to link back to current level directory */ + createParentTreeInfoNode(leveldir_new); +} + +void UpdateLastPlayedLevels_TreeInfo(void) +{ + char **last_level_series = setup.level_setup.last_level_series; + boolean reset_leveldir_current = FALSE; + LevelDirTree *leveldir_last; + TreeInfo **node_new = NULL; + int i; + + if (last_level_series[0] == NULL) + return; + + InitLastPlayedLevels_ParentNode(); + + // check if current level set is from "last played" sub-tree to be rebuilt + reset_leveldir_current = strEqual(leveldir_current->node_parent->identifier, + TOKEN_STR_LAST_LEVEL_SERIES); + + leveldir_last = getTreeInfoFromIdentifierExt(leveldir_first, + TOKEN_STR_LAST_LEVEL_SERIES, + TRUE); + if (leveldir_last == NULL) + return; + + node_new = &leveldir_last->node_group->next; + + freeTreeInfo(*node_new); + + for (i = 0; last_level_series[i] != NULL; i++) + { + LevelDirTree *node_last = getTreeInfoFromIdentifier(leveldir_first, + last_level_series[i]); + + *node_new = getTreeInfoCopy(node_last); // copy complete node + + (*node_new)->node_top = &leveldir_first; // correct top node link + (*node_new)->node_parent = leveldir_last; // correct parent node link + + (*node_new)->node_group = NULL; + (*node_new)->next = NULL; + + (*node_new)->cl_first = -1; // force setting tree cursor + + node_new = &((*node_new)->next); + } + + if (reset_leveldir_current) + leveldir_current = getTreeInfoFromIdentifier(leveldir_first, + last_level_series[0]); +} + +static void UpdateLastPlayedLevels_List(void) +{ + char **last_level_series = setup.level_setup.last_level_series; + int pos = MAX_LEVELDIR_HISTORY - 1; + int i; + + // search for potentially already existing entry in list of level sets + for (i = 0; last_level_series[i] != NULL; i++) + if (strEqual(last_level_series[i], leveldir_current->identifier)) + pos = i; + + // move list of level sets one entry down (using potentially free entry) + for (i = pos; i > 0; i--) + setString(&last_level_series[i], last_level_series[i - 1]); + + // put last played level set at top position + setString(&last_level_series[0], leveldir_current->identifier); +} + void LoadLevelSetup_LastSeries(void) { // -------------------------------------------------------------------------- @@ -4381,10 +4501,15 @@ void LoadLevelSetup_LastSeries(void) char *filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME); SetupFileHash *level_setup_hash = NULL; + int pos = 0; + int i; // always start with reliable default values leveldir_current = getFirstValidTreeInfoEntry(leveldir_first); + // start with empty history of last played level sets + setup.level_setup.last_level_series[0] = NULL; + if (!strEqual(DEFAULT_LEVELSET, UNDEFINED_LEVELSET)) { leveldir_current = getTreeInfoFromIdentifier(leveldir_first, @@ -4403,6 +4528,24 @@ void LoadLevelSetup_LastSeries(void) if (leveldir_current == NULL) leveldir_current = getFirstValidTreeInfoEntry(leveldir_first); + for (i = 0; i < MAX_LEVELDIR_HISTORY; i++) + { + char token[strlen(TOKEN_STR_LAST_LEVEL_SERIES) + 10]; + LevelDirTree *leveldir_last; + + sprintf(token, "%s.%03d", TOKEN_STR_LAST_LEVEL_SERIES, i); + + last_level_series = getHashEntry(level_setup_hash, token); + + leveldir_last = getTreeInfoFromIdentifier(leveldir_first, + last_level_series); + if (leveldir_last != NULL) + setup.level_setup.last_level_series[pos++] = + getStringCopy(last_level_series); + } + + setup.level_setup.last_level_series[pos] = NULL; + freeSetupFileHash(level_setup_hash); } else @@ -4423,12 +4566,15 @@ static void SaveLevelSetup_LastSeries_Ext(boolean deactivate_last_level_series) if (leveldir_current == NULL) return; + char **last_level_series = setup.level_setup.last_level_series; char *filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME); - char *level_subdir = leveldir_current->subdir; FILE *file; + int i; InitUserDataDirectory(); + UpdateLastPlayedLevels_List(); + if (!(file = fopen(filename, MODE_WRITE))) { Warn("cannot write setup file '%s'", filename); @@ -4443,8 +4589,17 @@ static void SaveLevelSetup_LastSeries_Ext(boolean deactivate_last_level_series) if (deactivate_last_level_series) fprintf(file, "# %s\n# ", "the following level set may have caused a problem and was deactivated"); - fprintf(file, "%s\n", getFormattedSetupEntry(TOKEN_STR_LAST_LEVEL_SERIES, - level_subdir)); + fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_LAST_LEVEL_SERIES, + leveldir_current->identifier)); + + for (i = 0; last_level_series[i] != NULL; i++) + { + char token[strlen(TOKEN_STR_LAST_LEVEL_SERIES) + 10]; + + sprintf(token, "%s.%03d", TOKEN_STR_LAST_LEVEL_SERIES, i); + + fprintf(file, "%s\n", getFormattedSetupEntry(token, last_level_series[i])); + } fclose(file); @@ -4708,3 +4863,66 @@ void LevelStats_incSolved(int nr) if (nr >= 0 && nr < MAX_LEVELS) level_stats[nr].solved++; } + +void LoadUserSetup(void) +{ + // -------------------------------------------------------------------------- + // ~/./usersetup.conf + // -------------------------------------------------------------------------- + + char *filename = getPath2(getMainUserGameDataDir(), USERSETUP_FILENAME); + SetupFileHash *user_setup_hash = NULL; + + // always start with reliable default values + user.nr = 0; + + if ((user_setup_hash = loadSetupFileHash(filename))) + { + char *token_value; + + // get last selected user number + token_value = getHashEntry(user_setup_hash, TOKEN_STR_LAST_USER); + + if (token_value) + user.nr = MIN(MAX(0, atoi(token_value)), MAX_PLAYER_NAMES - 1); + + freeSetupFileHash(user_setup_hash); + } + else + { + Debug("setup", "using default setup values"); + } + + free(filename); +} + +void SaveUserSetup(void) +{ + // -------------------------------------------------------------------------- + // ~/./usersetup.conf + // -------------------------------------------------------------------------- + + char *filename = getPath2(getMainUserGameDataDir(), USERSETUP_FILENAME); + FILE *file; + + InitMainUserDataDirectory(); + + if (!(file = fopen(filename, MODE_WRITE))) + { + Warn("cannot write setup file '%s'", filename); + + free(filename); + + return; + } + + fprintFileHeader(file, USERSETUP_FILENAME); + + fprintf(file, "%s\n", getFormattedSetupEntry(TOKEN_STR_LAST_USER, + i_to_a(user.nr))); + fclose(file); + + SetFilePermissions(filename, PERMS_PRIVATE); + + free(filename); +}