+/* forward declaration for recursive call by "LoadLevelInfoFromSetupFile()" */
+static void LoadLevelInfoFromLevelGroupDir(struct LevelDirInfo **,
+ struct LevelDirInfo *,
+ char *);
+
+static boolean LoadLevelInfoFromLevelDir(struct LevelDirInfo **node_first,
+ struct LevelDirInfo *node_parent,
+ char *level_directory,
+ char *directory_name)
+{
+ char *directory_path = getPath2(level_directory, directory_name);
+ char *filename = getPath2(directory_path, LEVELINFO_FILENAME);
+ struct SetupFileList *setup_file_list = loadSetupFileList(filename);
+ struct LevelDirInfo *leveldir_new = NULL;
+ int i;
+
+ if (setup_file_list == NULL)
+ {
+ Error(ERR_WARN, "ignoring level directory '%s'", level_directory);
+
+ free(directory_path);
+ free(filename);
+
+ return FALSE;
+ }
+
+ leveldir_new = newLevelDirInfo();
+
+ checkSetupFileListIdentifier(setup_file_list, getCookie("LEVELINFO"));
+ setLevelDirInfoToDefaultsFromParent(leveldir_new, node_parent);
+
+ /* set all structure fields according to the token/value pairs */
+ ldi = *leveldir_new;
+ for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
+ setSetupInfo(levelinfo_tokens, i,
+ getTokenValue(setup_file_list, levelinfo_tokens[i].text));
+ *leveldir_new = ldi;
+
+ DrawInitText(leveldir_new->name, 150, FC_YELLOW);
+
+ if (leveldir_new->name_short == NULL)
+ leveldir_new->name_short = getStringCopy(leveldir_new->name);
+
+ if (leveldir_new->name_sorting == NULL)
+ leveldir_new->name_sorting = getStringCopy(leveldir_new->name);
+
+ leveldir_new->filename = getStringCopy(directory_name);
+
+ if (node_parent == NULL) /* top level group */
+ {
+ leveldir_new->basepath = level_directory;
+ leveldir_new->fullpath = leveldir_new->filename;
+ }
+ else /* sub level group */
+ {
+ leveldir_new->basepath = node_parent->basepath;
+ leveldir_new->fullpath = getPath2(node_parent->fullpath,
+ directory_name);
+ }
+
+ if (leveldir_new->levels < 1)
+ leveldir_new->levels = 1;
+
+ leveldir_new->last_level =
+ leveldir_new->first_level + leveldir_new->levels - 1;
+
+ leveldir_new->user_defined =
+ (leveldir_new->basepath == options.level_directory ? FALSE : TRUE);
+
+ leveldir_new->color = LEVELCOLOR(leveldir_new);
+ leveldir_new->class_desc = getLevelClassDescription(leveldir_new);
+
+ leveldir_new->handicap_level = /* set handicap to default value */
+ (leveldir_new->user_defined ?
+ leveldir_new->last_level :
+ leveldir_new->first_level);
+
+ pushLevelDirInfo(node_first, leveldir_new);
+
+ freeSetupFileList(setup_file_list);
+
+ if (leveldir_new->level_group)
+ {
+ /* create node to link back to current level directory */
+ createParentLevelDirNode(leveldir_new);
+
+ /* step into sub-directory and look for more level series */
+ LoadLevelInfoFromLevelGroupDir(&leveldir_new->node_group,
+ leveldir_new, directory_path);
+ }
+
+ free(directory_path);
+ free(filename);
+
+ return TRUE;
+}
+
+static void LoadLevelInfoFromLevelGroupDir(struct LevelDirInfo **node_first,
+ struct LevelDirInfo *node_parent,
+ char *level_directory)