X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=af90c247d4a14c9031a8e3b6f6c56bb2a8c5a20e;hb=ac90a37dbfe706bbfc4b21eb581b21067d81a6eb;hp=23579d277ba5b92503aac35cfabdcd26625613de;hpb=46f4e87332b727a832ac242b04d886480ec8f674;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 23579d27..af90c247 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -96,6 +96,7 @@ static SetupFileHash *artworkinfo_cache_old = NULL; static SetupFileHash *artworkinfo_cache_new = NULL; static SetupFileHash *optional_tokens_hash = NULL; static boolean use_artworkinfo_cache = TRUE; +static boolean update_artworkinfo_cache = FALSE; // ---------------------------------------------------------------------------- @@ -2325,25 +2326,51 @@ 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) + 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) @@ -2851,15 +2878,7 @@ static int compareTreeInfoEntries(const void *object1, const void *object2) 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); - } + compare_result = strcasecmp(entry1->name_sorting, entry2->name_sorting); else if (class_sorting1 == class_sorting2) compare_result = entry1->sort_priority - entry2->sort_priority; else @@ -2882,7 +2901,7 @@ static TreeInfo *createParentTreeInfoNode(TreeInfo *node_parent) ti_new->parent_link = TRUE; setString(&ti_new->identifier, node_parent->identifier); - setString(&ti_new->name, ".. (parent directory)"); + setString(&ti_new->name, BACKLINK_TEXT_PARENT); setString(&ti_new->name_sorting, ti_new->name); setString(&ti_new->subdir, STRING_PARENT_DIRECTORY); @@ -2900,19 +2919,19 @@ static TreeInfo *createParentTreeInfoNode(TreeInfo *node_parent) static TreeInfo *createTopTreeInfoNode(TreeInfo *node_first) { - TreeInfo *ti_new, *ti_new2; - if (node_first == NULL) return NULL; - ti_new = newTreeInfo(); - setTreeInfoToDefaults(ti_new, TREE_TYPE_LEVEL_DIR); + TreeInfo *ti_new = newTreeInfo(); + int type = node_first->type; + + setTreeInfoToDefaults(ti_new, type); ti_new->node_parent = NULL; ti_new->parent_link = FALSE; setString(&ti_new->identifier, node_first->identifier); - setString(&ti_new->name, INFOTEXT_LEVEL_DIR); + setString(&ti_new->name, TREE_INFOTEXT(type)); setString(&ti_new->name_sorting, ti_new->name); setString(&ti_new->subdir, STRING_TOP_DIRECTORY); @@ -2921,19 +2940,32 @@ static TreeInfo *createTopTreeInfoNode(TreeInfo *node_first) ti_new->sort_priority = node_first->sort_priority;; ti_new->latest_engine = node_first->latest_engine; - setString(&ti_new->class_desc, INFOTEXT_LEVEL_DIR); + setString(&ti_new->class_desc, TREE_INFOTEXT(type)); ti_new->node_group = node_first; ti_new->level_group = TRUE; - ti_new2 = createParentTreeInfoNode(ti_new); + TreeInfo *ti_new2 = createParentTreeInfoNode(ti_new); - setString(&ti_new2->name, ".. (main menu)"); + setString(&ti_new2->name, TREE_BACKLINK_TEXT(type)); setString(&ti_new2->name_sorting, ti_new2->name); return ti_new; } +static void setTreeInfoParentNodes(TreeInfo *node, TreeInfo *node_parent) +{ + while (node) + { + if (node->node_group) + setTreeInfoParentNodes(node->node_group, node); + + node->node_parent = node_parent; + + node = node->next; + } +} + // ---------------------------------------------------------------------------- // functions for handling level and custom artwork info cache @@ -2959,10 +2991,15 @@ static void LoadArtworkInfoCache(void) if (artworkinfo_cache_new == NULL) artworkinfo_cache_new = newSetupFileHash(); + + update_artworkinfo_cache = FALSE; } static void SaveArtworkInfoCache(void) { + if (!update_artworkinfo_cache) + return; + char *filename = getPath2(getCacheDir(), ARTWORKINFO_CACHE_FILE); InitCacheDirectory(); @@ -3007,6 +3044,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; @@ -3923,6 +3963,29 @@ void LoadArtworkInfo(void) #endif } +static void MoveArtworkInfoIntoSubTree(ArtworkDirTree **artwork_node) +{ + ArtworkDirTree *artwork_new = newTreeInfo(); + char *top_node_name = "standalone artwork"; + + setTreeInfoToDefaults(artwork_new, (*artwork_node)->type); + + artwork_new->level_group = TRUE; + + setString(&artwork_new->identifier, top_node_name); + setString(&artwork_new->name, top_node_name); + setString(&artwork_new->name_sorting, top_node_name); + + // create node to link back to current custom artwork directory + createParentTreeInfoNode(artwork_new); + + // move existing custom artwork tree into newly created sub-tree + artwork_new->node_group->next = *artwork_node; + + // change custom artwork tree to contain only newly created node + *artwork_node = artwork_new; +} + static void LoadArtworkInfoFromLevelInfoExt(ArtworkDirTree **artwork_node, ArtworkDirTree *node_parent, LevelDirTree *level_node, @@ -3964,6 +4027,8 @@ static void LoadArtworkInfoFromLevelInfoExt(ArtworkDirTree **artwork_node, artwork_new->sort_priority = level_node->sort_priority; artwork_new->color = LEVELCOLOR(artwork_new); + + update_artworkinfo_cache = TRUE; } free(path); @@ -3992,8 +4057,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); @@ -4025,8 +4090,18 @@ static void LoadArtworkInfoFromLevelInfoExt(ArtworkDirTree **artwork_node, static void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node) { + // move peviously loaded artwork tree into separate sub-tree + MoveArtworkInfoIntoSubTree(artwork_node); + + // load artwork from level sets into separate sub-trees LoadArtworkInfoFromLevelInfoExt(artwork_node, NULL, leveldir_first_all, TRUE); LoadArtworkInfoFromLevelInfoExt(artwork_node, NULL, leveldir_first_all, FALSE); + + // add top tree node over all three separate sub-trees + *artwork_node = createTopTreeInfoNode(*artwork_node); + + // set all parent links (back links) in complete artwork tree + setTreeInfoParentNodes(*artwork_node, NULL); } void LoadLevelArtworkInfo(void)