+ sortTreeInfo(&leveldir_first, compareTreeInfoEntries);
+
+#if 0
+ dumpTreeInfo(leveldir_first, 0);
+#endif
+}
+
+static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
+ TreeInfo *node_parent,
+ char *base_directory,
+ char *directory_name, int type)
+{
+ char *directory_path = getPath2(base_directory, directory_name);
+ char *filename =
+ getPath2(directory_path,
+ (type == TREE_TYPE_GRAPHICS_DIR ? GRAPHICSINFO_FILENAME :
+ type == TREE_TYPE_SOUNDS_DIR ? SOUNDSINFO_FILENAME :
+ type == TREE_TYPE_MUSIC_DIR ? MUSICINFO_FILENAME : ""));
+ struct SetupFileList *setup_file_list = NULL;
+ TreeInfo *artwork_new = NULL;
+ char *check_dir = NULL;
+ int i;
+
+ if (access(filename, F_OK) == 0) /* file exists */
+ loadSetupFileList(filename);
+
+ if (setup_file_list == NULL) /* no config file -- look for artwork files */
+ {
+ DIR *dir;
+ struct dirent *dir_entry;
+ boolean valid_file_found = FALSE;
+
+ if ((dir = opendir(directory_path)) != NULL)
+ {
+ while ((dir_entry = readdir(dir)) != NULL)
+ {
+ char *entry_name = dir_entry->d_name;
+
+ if ((type == TREE_TYPE_GRAPHICS_DIR && FileIsGraphic(entry_name)) ||
+ (type == TREE_TYPE_SOUNDS_DIR && FileIsSound(entry_name)) ||
+ (type == TREE_TYPE_MUSIC_DIR && FileIsMusic(entry_name)))
+ {
+ valid_file_found = TRUE;
+ break;
+ }
+ }
+
+ closedir(dir);
+ }
+
+ if (!valid_file_found)
+ {
+ if (options.debug)
+ Error(ERR_WARN, "ignoring artwork directory '%s'", base_directory);
+
+ free(directory_path);
+ free(filename);
+
+ return FALSE;
+ }
+ }
+
+ artwork_new = newTreeInfo();
+
+ if (node_parent)
+ setTreeInfoToDefaultsFromParent(artwork_new, node_parent);
+ else
+ setTreeInfoToDefaults(artwork_new, type);
+
+ artwork_new->filename = getStringCopy(directory_name);
+
+ if (setup_file_list) /* (before defining ".color" and ".class_desc") */
+ {
+#if 0
+ checkSetupFileListIdentifier(setup_file_list, getCookie("..."));
+#endif
+
+ /* set all structure fields according to the token/value pairs */
+ ldi = *artwork_new;
+ for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
+ setSetupInfo(levelinfo_tokens, i,
+ getTokenValue(setup_file_list, levelinfo_tokens[i].text));
+ *artwork_new = ldi;
+
+ DrawInitText(artwork_new->name, 150, FC_YELLOW);
+
+ if (artwork_new->name_short == NULL)
+ artwork_new->name_short = getStringCopy(artwork_new->name);
+
+ if (artwork_new->name_sorting == NULL)
+ artwork_new->name_sorting = getStringCopy(artwork_new->name);
+ }
+
+ if (node_parent == NULL) /* top level group */
+ {
+ artwork_new->basepath = getStringCopy(base_directory);
+ artwork_new->fullpath = getStringCopy(artwork_new->filename);
+ }
+ else /* sub level group */
+ {
+ artwork_new->basepath = getStringCopy(node_parent->basepath);
+ artwork_new->fullpath = getPath2(node_parent->fullpath, directory_name);
+ }
+
+ check_dir = (type == TREE_TYPE_GRAPHICS_DIR ? options.graphics_directory :
+ type == TREE_TYPE_SOUNDS_DIR ? options.sounds_directory :
+ type == TREE_TYPE_MUSIC_DIR ? options.music_directory : "");
+ artwork_new->user_defined =
+ (artwork_new->basepath == check_dir ? FALSE : TRUE);
+
+ /* (may use ".sort_priority" from "setup_file_list" above) */
+ artwork_new->color = LEVELCOLOR(artwork_new);
+ artwork_new->class_desc = getLevelClassDescription(artwork_new);
+
+ if (setup_file_list == NULL) /* (after determining ".user_defined") */
+ {
+ if (artwork_new->name != NULL)
+ free(artwork_new->name);
+
+ if (strcmp(artwork_new->filename, ".") == 0)
+ {
+ if (artwork_new->user_defined)
+ artwork_new->name = getStringCopy("private");
+ else
+ artwork_new->name = getStringCopy("default");
+ }
+ else
+ artwork_new->name = getStringCopy(artwork_new->filename);
+
+ artwork_new->name_short = getStringCopy(artwork_new->name);
+ artwork_new->name_sorting = getStringCopy(artwork_new->name);
+ }
+
+ pushTreeInfo(node_first, artwork_new);
+
+ freeSetupFileList(setup_file_list);
+
+ free(directory_path);
+ free(filename);
+
+ return TRUE;
+}
+
+static void LoadArtworkInfoFromArtworkDir(TreeInfo **node_first,
+ TreeInfo *node_parent,
+ char *base_directory, int type)
+{
+ DIR *dir;
+ struct dirent *dir_entry;
+ boolean valid_entry_found = FALSE;
+
+ if ((dir = opendir(base_directory)) == NULL)
+ {
+ if ((type == TREE_TYPE_GRAPHICS_DIR &&
+ base_directory == options.graphics_directory) ||
+ (type == TREE_TYPE_SOUNDS_DIR &&
+ base_directory == options.sounds_directory) ||
+ (type == TREE_TYPE_MUSIC_DIR &&
+ base_directory == options.music_directory))
+ Error(ERR_WARN, "cannot read directory '%s'", base_directory);
+ return;
+ }
+
+ while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
+ {
+ struct stat file_status;
+ char *directory_name = dir_entry->d_name;
+ char *directory_path = getPath2(base_directory, directory_name);
+
+ /* skip entries for current and parent directory */
+ if (strcmp(directory_name, ".") == 0 ||
+ strcmp(directory_name, "..") == 0)
+ {
+ free(directory_path);
+ continue;
+ }
+
+ /* find out if directory entry is itself a directory */
+ if (stat(directory_path, &file_status) != 0 || /* cannot stat file */
+ (file_status.st_mode & S_IFMT) != S_IFDIR) /* not a directory */
+ {
+ free(directory_path);
+ continue;
+ }
+
+ free(directory_path);
+
+ /* check if this directory contains artwork with or without config file */
+ valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first,node_parent,
+ base_directory,
+ directory_name, type);
+ }
+
+ closedir(dir);
+
+ /* check if this directory directly contains artwork itself */
+ valid_entry_found |= LoadArtworkInfoFromArtworkConf(node_first,node_parent,
+ base_directory, ".",
+ type);
+ if (!valid_entry_found)
+ Error(ERR_WARN, "cannot find any valid artwork in directory '%s'",
+ base_directory);
+}
+
+void LoadArtworkInfo()
+{
+ DrawInitText("Looking for custom artwork:", 120, FC_GREEN);
+
+ LoadArtworkInfoFromArtworkDir(&artwork.gfx_first, NULL,
+ options.graphics_directory,
+ TREE_TYPE_GRAPHICS_DIR);
+ LoadArtworkInfoFromArtworkDir(&artwork.gfx_first, NULL,
+ getUserGraphicsDir(),
+ TREE_TYPE_GRAPHICS_DIR);
+
+ LoadArtworkInfoFromArtworkDir(&artwork.snd_first, NULL,
+ options.sounds_directory,
+ TREE_TYPE_SOUNDS_DIR);
+ LoadArtworkInfoFromArtworkDir(&artwork.snd_first, NULL,
+ getUserSoundsDir(),
+ TREE_TYPE_SOUNDS_DIR);
+
+ LoadArtworkInfoFromArtworkDir(&artwork.mus_first, NULL,
+ options.music_directory,
+ TREE_TYPE_MUSIC_DIR);
+ LoadArtworkInfoFromArtworkDir(&artwork.mus_first, NULL,
+ getUserMusicDir(),
+ TREE_TYPE_MUSIC_DIR);
+
+ /* before sorting, the first entries will be from the user directory */
+ artwork.gfx_current =
+ getTreeInfoFromFilename(artwork.gfx_first, setup.graphics_set);
+ if (artwork.gfx_current == NULL)
+ artwork.gfx_current = getFirstValidTreeInfoEntry(artwork.gfx_first);
+
+ artwork.snd_current =
+ getTreeInfoFromFilename(artwork.snd_first, setup.sounds_set);
+ if (artwork.snd_current == NULL)
+ artwork.snd_current = getFirstValidTreeInfoEntry(artwork.snd_first);
+
+ artwork.mus_current =
+ getTreeInfoFromFilename(artwork.mus_first, setup.music_set);
+ if (artwork.mus_current == NULL)
+ artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first);
+
+ artwork.graphics_set_current = artwork.gfx_current->name;
+ artwork.sounds_set_current = artwork.snd_current->name;
+ artwork.music_set_current = artwork.mus_current->name;
+
+ sortTreeInfo(&artwork.gfx_first, compareTreeInfoEntries);
+ sortTreeInfo(&artwork.snd_first, compareTreeInfoEntries);
+ sortTreeInfo(&artwork.mus_first, compareTreeInfoEntries);