X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=affc9365fab104533eea93dc8e70d8535f9526ea;hb=74cef390ce23b493089f414047426c73a1197e5f;hp=54e5eeeea21f6d9e51ed870c1c4fbd187a16eeb9;hpb=d0c3964b020fd888d52b219b75d9c436ee5c5213;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 54e5eeee..affc9365 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -202,6 +202,28 @@ char *getCurrentLevelDir() return getLevelDirFromTreeInfo(leveldir_current); } +char *getNewUserLevelSubdir() +{ + static char *new_level_subdir = NULL; + char *subdir_prefix = getLoginName(); + char subdir_suffix[10]; + int max_suffix_number = 1000; + int i = 0; + + while (++i < max_suffix_number) + { + sprintf(subdir_suffix, "_%d", i); + + checked_free(new_level_subdir); + new_level_subdir = getStringCat2(subdir_prefix, subdir_suffix); + + if (!directoryExists(getUserLevelDir(new_level_subdir))) + break; + } + + return new_level_subdir; +} + static char *getTapeDir(char *level_subdir) { static char *tape_dir = NULL; @@ -403,27 +425,74 @@ inline static char *getLevelArtworkDir(int type) return LEVELDIR_ARTWORK_PATH(leveldir_current, type); } -char *getProgramConfigFilename(char *command_filename_ptr) +char *getProgramMainDataPath(char *command_filename, char *base_path) { - char *command_filename_1 = getStringCopy(command_filename_ptr); + /* check if the program's main data base directory is configured */ + if (!strEqual(base_path, ".")) + return base_path; + + /* if the program is configured to start from current directory (default), + determine program package directory from program binary (some versions + of KDE/Konqueror and Mac OS X (especially "Mavericks") apparently do not + set the current working directory to the program package directory) */ + char *main_data_path = getBasePath(command_filename); + +#if defined(PLATFORM_MACOSX) + if (strSuffix(main_data_path, MAC_APP_BINARY_SUBDIR)) + { + char *main_data_path_old = main_data_path; + + // cut relative path to Mac OS X application binary directory from path + main_data_path[strlen(main_data_path) - + strlen(MAC_APP_BINARY_SUBDIR)] = '\0'; + + // cut trailing path separator from path (but not if path is root directory) + if (strSuffix(main_data_path, "/") && !strEqual(main_data_path, "/")) + main_data_path[strlen(main_data_path) - 1] = '\0'; + + // replace empty path with current directory + if (strEqual(main_data_path, "")) + main_data_path = "."; + + // add relative path to Mac OS X application resources directory to path + main_data_path = getPath2(main_data_path, MAC_APP_FILES_SUBDIR); + + free(main_data_path_old); + } +#endif + + return main_data_path; +} + +char *getProgramConfigFilename(char *command_filename) +{ + 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 *command_basepath = getBasePath(command_filename_ptr); - char *command_basename = getBaseNameNoSuffix(command_filename_ptr); + 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); 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); // 1st try: look for config file that exactly matches the binary filename if (fileExists(config_filename_1)) return config_filename_1; - // 2nd try: return config filename that matches binary filename without suffix - return config_filename_2; + // 2nd try: look for config file that matches binary filename without suffix + if (fileExists(config_filename_2)) + return config_filename_2; + + // 3rd try: return setup config filename in global program config directory + return config_filename_3; } char *getTapeFilename(int nr) @@ -2627,7 +2696,7 @@ static TreeInfo *createTopTreeInfoNode(TreeInfo *node_first) setString(&ti_new->name_sorting, ti_new->name); setString(&ti_new->subdir, STRING_TOP_DIRECTORY); - setString(&ti_new->fullpath, node_first->fullpath); + setString(&ti_new->fullpath, "."); ti_new->sort_priority = node_first->sort_priority;; ti_new->latest_engine = node_first->latest_engine; @@ -3494,34 +3563,91 @@ void LoadLevelArtworkInfo() print_timestamp_done("LoadLevelArtworkInfo"); } -boolean UpdateUserLevelSet(char *level_subdir, - char *level_name, char *level_author, - int num_levels, int first_level_nr) +static boolean AddUserLevelSetToLevelInfoExt(char *level_subdir_new) +{ + // get level info tree node of first (original) user level set + char *level_subdir_old = getLoginName(); + LevelDirTree *leveldir_old = getTreeInfoFromIdentifier(leveldir_first, + level_subdir_old); + if (leveldir_old == NULL) // should not happen + return FALSE; + + int draw_deactivation_mask = GetDrawDeactivationMask(); + + // override draw deactivation mask (temporarily disable drawing) + SetDrawDeactivationMask(REDRAW_ALL); + + // load new level set config and add it next to first user level set + LoadLevelInfoFromLevelConf(&leveldir_old->next, NULL, + leveldir_old->basepath, level_subdir_new); + + // set draw deactivation mask to previous value + SetDrawDeactivationMask(draw_deactivation_mask); + + // get level info tree node of newly added user level set + LevelDirTree *leveldir_new = getTreeInfoFromIdentifier(leveldir_first, + level_subdir_new); + if (leveldir_new == NULL) // should not happen + return FALSE; + + // correct top link and parent node link of newly created tree node + leveldir_new->node_top = leveldir_old->node_top; + leveldir_new->node_parent = leveldir_old->node_parent; + + // sort level info tree to adjust position of newly added level set + sortTreeInfo(&leveldir_first); + + return TRUE; +} + +void AddUserLevelSetToLevelInfo(char *level_subdir_new) +{ + if (!AddUserLevelSetToLevelInfoExt(level_subdir_new)) + Error(ERR_EXIT, "internal level set structure corrupted -- aborting"); +} + +boolean UpdateUserLevelSet(char *level_subdir, char *level_name, + char *level_author, int num_levels) { char *filename = getPath2(getUserLevelDir(level_subdir), LEVELINFO_FILENAME); char *filename_tmp = getStringCat2(filename, ".tmp"); FILE *file = NULL; FILE *file_tmp = NULL; char line[MAX_LINE_LEN]; - boolean update_num_levels_only = FALSE; boolean success = FALSE; + LevelDirTree *leveldir = getTreeInfoFromIdentifier(leveldir_first, + level_subdir); + // update values in level directory tree + + if (level_name != NULL) + setString(&leveldir->name, level_name); - if (level_name == NULL || level_author == NULL || first_level_nr == -1) - update_num_levels_only = TRUE; + if (level_author != NULL) + setString(&leveldir->author, level_author); + + if (num_levels != -1) + leveldir->levels = num_levels; + + // update values that depend on other values + + setString(&leveldir->name_sorting, leveldir->name); + + leveldir->last_level = leveldir->first_level + leveldir->levels - 1; + + // sort order of level sets may have changed + sortTreeInfo(&leveldir_first); if ((file = fopen(filename, MODE_READ)) && (file_tmp = fopen(filename_tmp, MODE_WRITE))) { while (fgets(line, MAX_LINE_LEN, file)) { - if (strPrefix(line, "name:") && !update_num_levels_only) + if (strPrefix(line, "name:") && level_name != NULL) fprintf(file_tmp, "%-32s%s\n", "name:", level_name); - else if (strPrefix(line, "author:") && !update_num_levels_only) + else if (strPrefix(line, "author:") && level_author != NULL) fprintf(file_tmp, "%-32s%s\n", "author:", level_author); - else if (strPrefix(line, "levels:")) + else if (strPrefix(line, "levels:") && num_levels != -1) fprintf(file_tmp, "%-32s%d\n", "levels:", num_levels); - else if (strPrefix(line, "first_level:") && !update_num_levels_only) - fprintf(file_tmp, "%-32s%d\n", "first_level:", first_level_nr); else fputs(line, file_tmp); } @@ -3544,9 +3670,8 @@ boolean UpdateUserLevelSet(char *level_subdir, return success; } -boolean CreateUserLevelSet(char *level_subdir, - char *level_name, char *level_author, - int num_levels, int first_level_nr) +boolean CreateUserLevelSet(char *level_subdir, char *level_name, + char *level_author, int num_levels) { LevelDirTree *level_info; char *filename; @@ -3574,7 +3699,7 @@ boolean CreateUserLevelSet(char *level_subdir, setString(&level_info->name, level_name); setString(&level_info->author, level_author); level_info->levels = num_levels; - level_info->first_level = first_level_nr; + level_info->first_level = 1; level_info->sort_priority = LEVELCLASS_PRIVATE_START; level_info->readonly = FALSE; @@ -3594,7 +3719,8 @@ boolean CreateUserLevelSet(char *level_subdir, fprintf(file, "%s\n", getSetupLine(levelinfo_tokens, "", i)); /* just to make things nicer :) */ - if (i == LEVELINFO_TOKEN_AUTHOR) + if (i == LEVELINFO_TOKEN_AUTHOR || + i == LEVELINFO_TOKEN_FIRST_LEVEL) fprintf(file, "\n"); } @@ -3612,7 +3738,7 @@ boolean CreateUserLevelSet(char *level_subdir, static void SaveUserLevelInfo() { - CreateUserLevelSet(getLoginName(), getLoginName(), getRealName(), 100, 1); + CreateUserLevelSet(getLoginName(), getLoginName(), getRealName(), 100); } char *getSetupValue(int type, void *value)