X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=d867ebbae239e3245939f2a063261ae83fc97b33;hb=3665f23e5708db69ec26ff908b99926afc87b2ce;hp=bfe8d94b2bf0aa5d3f6eb843f73bc376c434700a;hpb=7a7efc88f5ed7fc06eb85b95d263d6a98b04a02a;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index bfe8d94b..d867ebba 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -43,41 +43,6 @@ static char *levelclass_desc[NUM_LEVELCLASS_DESC] = "DX Boulderdash" }; - -#define LEVELCOLOR(n) (IS_LEVELCLASS_TUTORIAL(n) ? FC_BLUE : \ - IS_LEVELCLASS_CLASSICS(n) ? FC_RED : \ - IS_LEVELCLASS_BD(n) ? FC_YELLOW : \ - IS_LEVELCLASS_EM(n) ? FC_YELLOW : \ - IS_LEVELCLASS_SP(n) ? FC_YELLOW : \ - IS_LEVELCLASS_DX(n) ? FC_YELLOW : \ - IS_LEVELCLASS_SB(n) ? FC_YELLOW : \ - IS_LEVELCLASS_CONTRIB(n) ? FC_GREEN : \ - IS_LEVELCLASS_PRIVATE(n) ? FC_RED : \ - FC_BLUE) - -#define LEVELSORTING(n) (IS_LEVELCLASS_TUTORIAL(n) ? 0 : \ - IS_LEVELCLASS_CLASSICS(n) ? 1 : \ - IS_LEVELCLASS_BD(n) ? 2 : \ - IS_LEVELCLASS_EM(n) ? 3 : \ - IS_LEVELCLASS_SP(n) ? 4 : \ - IS_LEVELCLASS_DX(n) ? 5 : \ - IS_LEVELCLASS_SB(n) ? 6 : \ - IS_LEVELCLASS_CONTRIB(n) ? 7 : \ - IS_LEVELCLASS_PRIVATE(n) ? 8 : \ - 9) - -#define ARTWORKCOLOR(n) (IS_ARTWORKCLASS_CLASSICS(n) ? FC_RED : \ - IS_ARTWORKCLASS_CONTRIB(n) ? FC_GREEN : \ - IS_ARTWORKCLASS_PRIVATE(n) ? FC_RED : \ - IS_ARTWORKCLASS_LEVEL(n) ? FC_YELLOW : \ - FC_BLUE) - -#define ARTWORKSORTING(n) (IS_ARTWORKCLASS_CLASSICS(n) ? 0 : \ - IS_ARTWORKCLASS_LEVEL(n) ? 1 : \ - IS_ARTWORKCLASS_CONTRIB(n) ? 2 : \ - IS_ARTWORKCLASS_PRIVATE(n) ? 3 : \ - 9) - #define TOKEN_VALUE_POSITION_SHORT 32 #define TOKEN_VALUE_POSITION_DEFAULT 40 #define TOKEN_COMMENT_POSITION_DEFAULT 60 @@ -1546,6 +1511,8 @@ char *getHomeDir(void) if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir))) strcpy(dir, "."); } +#elif defined(PLATFORM_EMSCRIPTEN) + dir = "/persistent"; #elif defined(PLATFORM_UNIX) if (dir == NULL) { @@ -2326,25 +2293,53 @@ static boolean loadSetupFileData(void *setup_file_data, char *filename, return TRUE; } +static int compareSetupFileData(const void *object1, const void *object2) +{ + const struct ConfigInfo *entry1 = (struct ConfigInfo *)object1; + const struct ConfigInfo *entry2 = (struct ConfigInfo *)object2; + + return strcmp(entry1->token, entry2->token); +} + static void saveSetupFileHash(SetupFileHash *hash, char *filename) { + int item_count = hashtable_count(hash); + int item_size = sizeof(struct ConfigInfo); + struct ConfigInfo *sort_array = checked_malloc(item_count * item_size); FILE *file; + int i = 0; - if (!(file = fopen(filename, MODE_WRITE))) + // copy string pointers from hash to array + BEGIN_HASH_ITERATION(hash, itr) { - Warn("cannot write configuration file '%s'", filename); + sort_array[i].token = HASH_ITERATION_TOKEN(itr); + sort_array[i].value = HASH_ITERATION_VALUE(itr); - return; + i++; + + if (i > item_count) // should never happen + break; } + END_HASH_ITERATION(hash, itr) - BEGIN_HASH_ITERATION(hash, itr) + // sort string pointers from hash in array + qsort(sort_array, item_count, item_size, compareSetupFileData); + + if (!(file = fopen(filename, MODE_WRITE))) { - fprintf(file, "%s\n", getFormattedSetupEntry(HASH_ITERATION_TOKEN(itr), - HASH_ITERATION_VALUE(itr))); + Warn("cannot write configuration file '%s'", filename); + + return; } - END_HASH_ITERATION(hash, itr) + fprintf(file, "%s\n\n", getFormattedSetupEntry("program.version", + program.version_string)); + for (i = 0; i < item_count; i++) + fprintf(file, "%s\n", getFormattedSetupEntry(sort_array[i].token, + sort_array[i].value)); fclose(file); + + checked_free(sort_array); } SetupFileList *loadSetupFileList(char *filename) @@ -2478,7 +2473,6 @@ static struct TokenInfo artworkinfo_tokens[] = { TYPE_STRING, &ldi.basepath, "basepath" }, { TYPE_STRING, &ldi.fullpath, "fullpath" }, { TYPE_BOOLEAN, &ldi.in_user_dir, "in_user_dir" }, - { TYPE_INTEGER, &ldi.color, "color" }, { TYPE_STRING, &ldi.class_desc, "class_desc" }, { -1, NULL, NULL }, @@ -2833,40 +2827,13 @@ static int compareTreeInfoEntries(const void *object1, const void *object2) { const TreeInfo *entry1 = *((TreeInfo **)object1); const TreeInfo *entry2 = *((TreeInfo **)object2); - int class_sorting1 = 0, class_sorting2 = 0; - int compare_result; - - if (entry1->type == TREE_TYPE_LEVEL_DIR) - { - class_sorting1 = LEVELSORTING(entry1); - class_sorting2 = LEVELSORTING(entry2); - } - else if (entry1->type == TREE_TYPE_GRAPHICS_DIR || - entry1->type == TREE_TYPE_SOUNDS_DIR || - entry1->type == TREE_TYPE_MUSIC_DIR) - { - class_sorting1 = ARTWORKSORTING(entry1); - class_sorting2 = ARTWORKSORTING(entry2); - } + int tree_sorting1 = TREE_SORTING(entry1); + int tree_sorting2 = TREE_SORTING(entry2); - if (entry1->parent_link || entry2->parent_link) - compare_result = (entry1->parent_link ? -1 : +1); - else if (entry1->sort_priority == entry2->sort_priority) - { - char *name1 = getStringToLower(entry1->name_sorting); - char *name2 = getStringToLower(entry2->name_sorting); - - compare_result = strcmp(name1, name2); - - free(name1); - free(name2); - } - else if (class_sorting1 == class_sorting2) - compare_result = entry1->sort_priority - entry2->sort_priority; + if (tree_sorting1 != tree_sorting2) + return (tree_sorting1 - tree_sorting2); else - compare_result = class_sorting1 - class_sorting2; - - return compare_result; + return strcasecmp(entry1->name_sorting, entry2->name_sorting); } static TreeInfo *createParentTreeInfoNode(TreeInfo *node_parent) @@ -2889,7 +2856,7 @@ static TreeInfo *createParentTreeInfoNode(TreeInfo *node_parent) setString(&ti_new->subdir, STRING_PARENT_DIRECTORY); setString(&ti_new->fullpath, node_parent->fullpath); - ti_new->sort_priority = node_parent->sort_priority; + ti_new->sort_priority = LEVELCLASS_PARENT; ti_new->latest_engine = node_parent->latest_engine; setString(&ti_new->class_desc, getLevelClassDescription(ti_new)); @@ -2912,14 +2879,14 @@ static TreeInfo *createTopTreeInfoNode(TreeInfo *node_first) ti_new->node_parent = NULL; ti_new->parent_link = FALSE; - setString(&ti_new->identifier, node_first->identifier); + setString(&ti_new->identifier, "top_tree_node"); setString(&ti_new->name, TREE_INFOTEXT(type)); setString(&ti_new->name_sorting, ti_new->name); setString(&ti_new->subdir, STRING_TOP_DIRECTORY); setString(&ti_new->fullpath, "."); - ti_new->sort_priority = node_first->sort_priority;; + ti_new->sort_priority = LEVELCLASS_TOP; ti_new->latest_engine = node_first->latest_engine; setString(&ti_new->class_desc, TREE_INFOTEXT(type)); @@ -2964,6 +2931,17 @@ static void LoadArtworkInfoCache(void) // try to load artwork info hash from already existing cache file artworkinfo_cache_old = loadSetupFileHash(filename); + // try to get program version that artwork info cache was written with + char *version = getHashEntry(artworkinfo_cache_old, "program.version"); + + // check program version of artwork info cache against current version + if (!strEqual(version, program.version_string)) + { + freeSetupFileHash(artworkinfo_cache_old); + + artworkinfo_cache_old = NULL; + } + // if no artwork info cache file was found, start with empty hash if (artworkinfo_cache_old == NULL) artworkinfo_cache_old = newSetupFileHash(); @@ -3026,6 +3004,9 @@ static boolean modifiedFileTimestamp(char *filename, char *timestamp_string) if (timestamp_string == NULL) return TRUE; + if (!fileExists(filename)) // file does not exist + return (atoi(timestamp_string) != 0); + if (stat(filename, &file_status) != 0) // cannot stat file return TRUE; @@ -3480,8 +3461,6 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, leveldir_new->user_defined = (leveldir_new->in_user_dir && IS_LEVELCLASS_PRIVATE(leveldir_new)); - leveldir_new->color = LEVELCOLOR(leveldir_new); - setString(&leveldir_new->class_desc, getLevelClassDescription(leveldir_new)); leveldir_new->handicap_level = // set handicap to default value @@ -3725,9 +3704,6 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, artwork_new->in_user_dir = (!strEqual(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type))); - // (may use ".sort_priority" from "setup_file_hash" above) - artwork_new->color = ARTWORKCOLOR(artwork_new); - setString(&artwork_new->class_desc, getLevelClassDescription(artwork_new)); if (setup_file_hash == NULL) // (after determining ".user_defined") @@ -3745,9 +3721,6 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, artwork_new->sort_priority = ARTWORKCLASS_CLASSICS; } - // set to new values after changing ".sort_priority" - artwork_new->color = ARTWORKCOLOR(artwork_new); - setString(&artwork_new->class_desc, getLevelClassDescription(artwork_new)); } @@ -3945,7 +3918,7 @@ void LoadArtworkInfo(void) static void MoveArtworkInfoIntoSubTree(ArtworkDirTree **artwork_node) { ArtworkDirTree *artwork_new = newTreeInfo(); - char *top_node_name = "dedicated custom artwork"; + char *top_node_name = "standalone artwork"; setTreeInfoToDefaults(artwork_new, (*artwork_node)->type); @@ -4005,7 +3978,7 @@ static void LoadArtworkInfoFromLevelInfoExt(ArtworkDirTree **artwork_node, setString(&artwork_new->name_sorting, level_node->name_sorting); artwork_new->sort_priority = level_node->sort_priority; - artwork_new->color = LEVELCOLOR(artwork_new); + artwork_new->in_user_dir = level_node->in_user_dir; update_artworkinfo_cache = TRUE; } @@ -4036,8 +4009,8 @@ static void LoadArtworkInfoFromLevelInfoExt(ArtworkDirTree **artwork_node, if (node_parent == NULL) // check for top tree node { char *top_node_name = (empty_level_set_mode ? - "artwork-only level sets" : - "artwork from level sets"); + "artwork for certain level sets" : + "artwork included in level sets"); setString(&artwork_new->name, top_node_name); setString(&artwork_new->name_sorting, top_node_name); @@ -4535,9 +4508,11 @@ static void InitLastPlayedLevels_ParentNode(void) setTreeInfoToDefaultsFromParent(leveldir_new, leveldir_first); leveldir_new->level_group = TRUE; + leveldir_new->sort_priority = LEVELCLASS_LAST_PLAYED_LEVEL; setString(&leveldir_new->identifier, TOKEN_STR_LAST_LEVEL_SERIES); setString(&leveldir_new->name, "<< (last played level sets)"); + setString(&leveldir_new->name_sorting, leveldir_new->name); pushTreeInfo(leveldir_top, leveldir_new); @@ -4572,10 +4547,14 @@ void UpdateLastPlayedLevels_TreeInfo(void) freeTreeInfo(*node_new); + *node_new = NULL; + for (i = 0; last_level_series[i] != NULL; i++) { LevelDirTree *node_last = getTreeInfoFromIdentifier(leveldir_first, last_level_series[i]); + if (node_last == NULL) + continue; *node_new = getTreeInfoCopy(node_last); // copy complete node