static int token_value_position = TOKEN_VALUE_POSITION_DEFAULT;
static int token_comment_position = TOKEN_COMMENT_POSITION_DEFAULT;
+static SetupFileHash *artworkinfo_hash = NULL;
+
/* ------------------------------------------------------------------------- */
/* file functions */
char *getUserGameDataDir(void)
{
- if (program.userdata_path == NULL)
- program.userdata_path = getPath2(getPersonalDataDir(),
- program.userdata_subdir);
+ static char *user_game_data_dir = NULL;
+
+ if (user_game_data_dir == NULL)
+ user_game_data_dir = getPath2(getPersonalDataDir(),
+ program.userdata_subdir);
- return program.userdata_path;
+ return user_game_data_dir;
}
void updateUserGameDataDir()
{
#if defined(PLATFORM_MACOSX)
char *userdata_dir_old = getPath2(getHomeDir(), program.userdata_subdir_unix);
- char *userdata_dir_new = getUserGameDataDir();
+ char *userdata_dir_new = getUserGameDataDir(); /* do not free() this */
/* convert old Unix style game data directory to Mac OS X style, if needed */
if (fileExists(userdata_dir_old) && !fileExists(userdata_dir_new))
}
free(userdata_dir_old);
- free(userdata_dir_new);
#endif
}
return setup_file_data;
}
+void saveSetupFileHash(SetupFileHash *hash, char *filename)
+{
+ FILE *file;
+
+ if (!(file = fopen(filename, MODE_WRITE)))
+ {
+ Error(ERR_WARN, "cannot write configuration file '%s'", filename);
+
+ return;
+ }
+
+ BEGIN_HASH_ITERATION(hash, itr)
+ {
+ fprintf(file, "%s\n", getFormattedSetupEntry(HASH_ITERATION_TOKEN(itr),
+ HASH_ITERATION_VALUE(itr)));
+ }
+ END_HASH_ITERATION(hash, itr)
+
+ fclose(file);
+}
+
SetupFileList *loadSetupFileList(char *filename)
{
return (SetupFileList *)loadSetupFileData(filename, FALSE);
{ TYPE_BOOLEAN, &ldi.skip_levels, "skip_levels" }
};
+static struct TokenInfo artworkinfo_tokens[] =
+{
+ /* artwork directory info */
+ { TYPE_STRING, &ldi.identifier, "identifier" },
+ { TYPE_STRING, &ldi.subdir, "subdir" },
+ { TYPE_STRING, &ldi.name, "name" },
+ { TYPE_STRING, &ldi.name_sorting, "name_sorting" },
+ { TYPE_STRING, &ldi.author, "author" },
+ { TYPE_INTEGER, &ldi.sort_priority, "sort_priority" },
+ { 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 },
+};
+
static void setTreeInfoToDefaults(TreeInfo *ti, int type)
{
ti->type = type;
pushTreeInfo(&node_parent->node_group, ti_new);
}
+
+/* -------------------------------------------------------------------------- */
+/* functions for handling custom artwork info cache */
+/* -------------------------------------------------------------------------- */
+
+#define ARTWORKINFO_CACHE_FILENAME "cache.conf"
+
+static void LoadArtworkInfoCache()
+{
+ if (artworkinfo_hash == NULL)
+ {
+ char *filename = getPath2(getSetupDir(), ARTWORKINFO_CACHE_FILENAME);
+
+ /* try to load artwork info hash from already existing cache file */
+ artworkinfo_hash = loadSetupFileHash(filename);
+
+ /* if no artwork info cache file was found, start with empty hash */
+ if (artworkinfo_hash == NULL)
+ artworkinfo_hash = newSetupFileHash();
+
+ free(filename);
+ }
+}
+
+static void SaveArtworkInfoCache()
+{
+ char *filename = getPath2(getSetupDir(), ARTWORKINFO_CACHE_FILENAME);
+
+ saveSetupFileHash(artworkinfo_hash, filename);
+
+ free(filename);
+}
+
+static TreeInfo *getArtworkInfoFromCache(char *identifier, int type)
+{
+ char *type_string = ARTWORK_DIRECTORY(type);
+ char *token_prefix = getStringCat2WithSeparator(type_string, identifier, ".");
+ char *cache_entry = getHashEntry(artworkinfo_hash, token_prefix);
+ boolean cached = (cache_entry != NULL && strEqual(cache_entry, "true"));
+ TreeInfo *artwork_new = NULL;
+
+ if (cached)
+ {
+ int i;
+
+ printf("::: LOADING existing hash entry for '%s' ...\n", identifier);
+
+ artwork_new = newTreeInfo();
+ setTreeInfoToDefaults(artwork_new, type);
+
+ /* set all structure fields according to the token/value pairs */
+ ldi = *artwork_new;
+ for (i = 0; artworkinfo_tokens[i].type != -1; i++)
+ {
+ char *token = getStringCat2WithSeparator(token_prefix,
+ artworkinfo_tokens[i].text, ".");
+ char *value = getHashEntry(artworkinfo_hash, token);
+
+ printf("::: - setting '%s' => '%s'\n", token, value);
+
+ setSetupInfo(artworkinfo_tokens, i, value);
+
+ /* check if cache entry for this item is invalid or incomplete */
+ if (value == NULL)
+ {
+ printf("::: - WARNING: cache entry '%s' invalid\n", token);
+
+ cached = FALSE;
+ }
+
+ checked_free(token);
+ }
+ *artwork_new = ldi;
+
+ if (!cached)
+ freeTreeInfo(artwork_new);
+ }
+
+ free(token_prefix);
+
+ return artwork_new;
+}
+
+
+/* -------------------------------------------------------------------------- */
+/* functions for loading level info and custom artwork info */
+/* -------------------------------------------------------------------------- */
+
/* forward declaration for recursive call by "LoadLevelInfoFromLevelDir()" */
static void LoadLevelInfoFromLevelDir(TreeInfo **, TreeInfo *, char *);
void LoadArtworkInfo()
{
+ LoadArtworkInfoCache();
+
DrawInitText("Looking for custom artwork:", 120, FC_GREEN);
LoadArtworkInfoFromArtworkDir(&artwork.gfx_first, NULL,
TreeInfo *topnode_last = *artwork_node;
char *path = getPath2(getLevelDirFromTreeInfo(level_node),
ARTWORK_DIRECTORY((*artwork_node)->type));
+ TreeInfo *artwork_new = getArtworkInfoFromCache(level_node->subdir,
+ (*artwork_node)->type);
+ boolean cached = FALSE;
- LoadArtworkInfoFromArtworkDir(artwork_node, NULL, path,
- (*artwork_node)->type);
+ if (artwork_new != NULL)
+ {
+ pushTreeInfo(artwork_node, artwork_new);
+ cached = TRUE;
+ }
+ else
+ {
+ LoadArtworkInfoFromArtworkDir(artwork_node, NULL, path,
+ (*artwork_node)->type);
+ }
+#if 1
+ if (!cached && topnode_last != *artwork_node)
+#else
if (topnode_last != *artwork_node)
+#endif
{
free((*artwork_node)->identifier);
free((*artwork_node)->name);
(*artwork_node)->sort_priority = level_node->sort_priority;
(*artwork_node)->color = LEVELCOLOR((*artwork_node));
+
+#if 1
+ {
+ char *identifier = level_node->subdir;
+ char *type_string = ARTWORK_DIRECTORY((*artwork_node)->type);
+ char *type_identifier =
+ getStringCat2WithSeparator(type_string, identifier, ".");
+ int i;
+
+ printf("::: adding hash entry for set '%s' ...\n", type_identifier);
+
+ setHashEntry(artworkinfo_hash, type_identifier, "true");
+
+ ldi = **artwork_node;
+ for (i = 0; artworkinfo_tokens[i].type != -1; i++)
+ {
+ char *token = getStringCat2WithSeparator(type_identifier,
+ artworkinfo_tokens[i].text,
+ ".");
+ char *value = getSetupValue(artworkinfo_tokens[i].type,
+ artworkinfo_tokens[i].value);
+ if (value != NULL)
+ {
+ setHashEntry(artworkinfo_hash, token, value);
+
+ printf("::: - setting '%s' => '%s'\n\n",
+ token, value);
+ }
+
+ checked_free(token);
+ }
+
+ free(type_identifier);
+ }
+#endif
}
free(path);
LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first_all);
LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first_all);
+ SaveArtworkInfoCache();
+
/* needed for reloading level artwork not known at ealier stage */
if (!strEqual(artwork.gfx_current_identifier, setup.graphics_set))
break;
case TYPE_STRING:
+ if (*(char **)value == NULL)
+ return NULL;
+
strcpy(value_string, *(char **)value);
break;