+void dumpList(ListNode *node_first)
+{
+ ListNode *node = node_first;
+
+ while (node)
+ {
+ printf("['%s' (%d)]\n", node->key,
+ ((struct ArtworkListNodeInfo *)node->content)->num_references);
+ node = node->next;
+ }
+
+ printf("[%d nodes]\n", getNumNodes(node_first));
+}
+
+
+/* ========================================================================= */
+/* functions for checking filenames */
+/* ========================================================================= */
+
+boolean FileIsGraphic(char *filename)
+{
+ if (strlen(filename) > 4 &&
+ strcmp(&filename[strlen(filename) - 4], ".pcx") == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+boolean FileIsSound(char *basename)
+{
+ if (strlen(basename) > 4 &&
+ strcmp(&basename[strlen(basename) - 4], ".wav") == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+boolean FileIsMusic(char *basename)
+{
+ /* "music" can be a WAV (loop) file or (if compiled with SDL) a MOD file */
+
+ if (FileIsSound(basename))
+ return TRUE;
+
+#if defined(TARGET_SDL)
+ if (strlen(basename) > 4 &&
+ (strcmp(&basename[strlen(basename) - 4], ".mod") == 0 ||
+ strcmp(&basename[strlen(basename) - 4], ".MOD") == 0 ||
+ strncmp(basename, "mod.", 4) == 0 ||
+ strncmp(basename, "MOD.", 4) == 0))
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+boolean FileIsArtworkType(char *basename, int type)
+{
+ if ((type == TREE_TYPE_GRAPHICS_DIR && FileIsGraphic(basename)) ||
+ (type == TREE_TYPE_SOUNDS_DIR && FileIsSound(basename)) ||
+ (type == TREE_TYPE_MUSIC_DIR && FileIsMusic(basename)))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* ========================================================================= */
+/* functions for loading artwork configuration information */
+/* ========================================================================= */
+
+static void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
+{
+ int num_list_entries = artwork_info->num_list_entries;
+ struct ArtworkConfigInfo *config_list = artwork_info->config_list;
+ char *filename = getCustomArtworkConfigFilename(artwork_info->type);
+ struct SetupFileList *setup_file_list;
+ int i;
+
+#if 0
+ printf("GOT CUSTOM ARTWORK CONFIG FILE '%s'\n", filename);
+#endif
+
+ /* always start with reliable default values */
+ for (i=0; i<num_list_entries; i++)
+ config_list[i].filename = NULL;
+
+ if (filename == NULL)
+ return;
+
+ if ((setup_file_list = loadSetupFileList(filename)))
+ {
+ for (i=0; i<num_list_entries; i++)
+ config_list[i].filename =
+ getStringCopy(getTokenValue(setup_file_list, config_list[i].token));
+
+ freeSetupFileList(setup_file_list);
+
+#if 0
+ for (i=0; i<num_list_entries; i++)
+ {
+ printf("'%s' ", config_list[i].token);
+ if (config_list[i].filename)
+ printf("-> '%s'\n", config_list[i].filename);
+ else
+ printf("-> UNDEFINED [-> '%s']\n", config_list[i].default_filename);
+ }
+#endif
+ }
+}
+
+void deleteArtworkListEntry(struct ArtworkListInfo *artwork_info,
+ struct ArtworkListNodeInfo **listnode)
+{
+ if (*listnode)
+ {
+ char *filename = (*listnode)->source_filename;
+
+#if 0
+ printf("[decrementing reference counter of artwork '%s']\n", filename);
+#endif
+
+ if (--(*listnode)->num_references <= 0)
+ {
+#if 0
+ printf("[deleting artwork '%s']\n", filename);
+#endif
+
+ deleteNodeFromList(&artwork_info->file_list, filename,
+ artwork_info->free_artwork);
+ }
+
+ *listnode = NULL;
+ }
+}
+
+static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info,
+ struct ArtworkListNodeInfo **listnode,
+ char *filename)
+{
+ ListNode *node;
+
+ /* check if the old and the new artwork file are the same */
+ if (*listnode && strcmp((*listnode)->source_filename, filename) == 0)
+ {
+ /* The old and new artwork are the same (have the same filename and path).
+ This usually means that this artwork does not exist in this artwork set
+ and a fallback to the existing artwork is done. */
+
+#if 0
+ printf("[artwork '%s' already exists (same list entry)]\n", filename);
+#endif
+
+ return;
+ }
+
+ /* delete existing artwork file entry */
+ deleteArtworkListEntry(artwork_info, listnode);
+
+ /* check if the new artwork file already exists in the list of artworks */
+ if ((node = getNodeFromKey(artwork_info->file_list, filename)) != NULL)
+ {
+#if 0
+ printf("[artwork '%s' already exists (other list entry)]\n", filename);
+#endif
+
+ *listnode = (struct ArtworkListNodeInfo *)node->content;
+ (*listnode)->num_references++;
+ }
+ else if ((*listnode = artwork_info->load_artwork(filename)) != NULL)
+ {
+ (*listnode)->num_references = 1;
+ addNodeToList(&artwork_info->file_list, (*listnode)->source_filename,
+ *listnode);
+ }
+}
+
+static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info,
+ struct ArtworkListNodeInfo **listnode,
+ char *basename)