re-enabled storing selection from "last played level set" menu
[rocksndiamonds.git] / src / libgame / setup.c
index 7b3168abeea510bc13a094490bef0404a2c381e8..32ae11215a1a87626d9acdac70e99d6ea62cafaf 100644 (file)
@@ -49,6 +49,16 @@ static char *levelclass_desc[NUM_LEVELCLASS_DESC] =
 
 #define MAX_COOKIE_LEN                         256
 
+#define TREE_NODE_TYPE_DEFAULT                 0
+#define TREE_NODE_TYPE_PARENT                  1
+#define TREE_NODE_TYPE_GROUP                   2
+#define TREE_NODE_TYPE_COPY                    3
+
+#define TREE_NODE_TYPE(ti)     (ti->node_group  ? TREE_NODE_TYPE_GROUP  : \
+                                ti->parent_link ? TREE_NODE_TYPE_PARENT : \
+                                ti->is_copy     ? TREE_NODE_TYPE_COPY   : \
+                                TREE_NODE_TYPE_DEFAULT)
+
 
 static void setTreeInfoToDefaults(TreeInfo *, int);
 static TreeInfo *getTreeInfoCopy(TreeInfo *ti);
@@ -1154,7 +1164,21 @@ int numTreeInfo(TreeInfo *node)
 
 boolean validLevelSeries(TreeInfo *node)
 {
-  return (node != NULL && !node->node_group && !node->parent_link);
+  // in a number of cases, tree node is no valid level set
+  if (node == NULL || node->node_group || node->parent_link || node->is_copy)
+    return FALSE;
+
+  return TRUE;
+}
+
+TreeInfo *getValidLevelSeries(TreeInfo *node, TreeInfo *default_node)
+{
+  if (validLevelSeries(node))
+    return node;
+  else if (node->is_copy)
+    return getTreeInfoFromIdentifier(leveldir_first, node->identifier);
+  else
+    return getFirstValidTreeInfoEntry(default_node);
 }
 
 TreeInfo *getFirstValidTreeInfoEntry(TreeInfo *node)
@@ -1226,29 +1250,25 @@ TreeInfo *getTreeInfoFromPos(TreeInfo *node, int pos)
 }
 
 static TreeInfo *getTreeInfoFromIdentifierExt(TreeInfo *node, char *identifier,
-                                             boolean include_node_groups)
+                                             int node_type_wanted)
 {
   if (identifier == NULL)
     return NULL;
 
   while (node)
   {
+    if (TREE_NODE_TYPE(node) == node_type_wanted &&
+       strEqual(identifier, node->identifier))
+      return node;
+
     if (node->node_group)
     {
-      if (include_node_groups && strEqual(identifier, node->identifier))
-       return node;
-
       TreeInfo *node_group = getTreeInfoFromIdentifierExt(node->node_group,
                                                          identifier,
-                                                         include_node_groups);
+                                                         node_type_wanted);
       if (node_group)
        return node_group;
     }
-    else if (!node->parent_link)
-    {
-      if (strEqual(identifier, node->identifier))
-       return node;
-    }
 
     node = node->next;
   }
@@ -1258,7 +1278,7 @@ static TreeInfo *getTreeInfoFromIdentifierExt(TreeInfo *node, char *identifier,
 
 TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier)
 {
-  return getTreeInfoFromIdentifierExt(node, identifier, FALSE);
+  return getTreeInfoFromIdentifierExt(node, identifier, TREE_NODE_TYPE_DEFAULT);
 }
 
 static TreeInfo *cloneTreeNode(TreeInfo **node_top, TreeInfo *node_parent,
@@ -2520,6 +2540,7 @@ static void setTreeInfoToDefaults(TreeInfo *ti, int type)
   ti->sort_priority = LEVELCLASS_UNDEFINED;    // default: least priority
   ti->latest_engine = FALSE;                   // default: get from level
   ti->parent_link = FALSE;
+  ti->is_copy = FALSE;
   ti->in_user_dir = FALSE;
   ti->user_defined = FALSE;
   ti->color = 0;
@@ -2601,6 +2622,7 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ti, TreeInfo *parent)
   ti->sort_priority = parent->sort_priority;
   ti->latest_engine = parent->latest_engine;
   ti->parent_link = FALSE;
+  ti->is_copy = FALSE;
   ti->in_user_dir = parent->in_user_dir;
   ti->user_defined = parent->user_defined;
   ti->color = parent->color;
@@ -2701,6 +2723,7 @@ static TreeInfo *getTreeInfoCopy(TreeInfo *ti)
 
   ti_copy->level_group         = ti->level_group;
   ti_copy->parent_link         = ti->parent_link;
+  ti_copy->is_copy             = ti->is_copy;
   ti_copy->in_user_dir         = ti->in_user_dir;
   ti_copy->user_defined                = ti->user_defined;
   ti_copy->readonly            = ti->readonly;
@@ -2856,7 +2879,7 @@ static TreeInfo *createParentTreeInfoNode(TreeInfo *node_parent)
   setString(&ti_new->subdir, STRING_PARENT_DIRECTORY);
   setString(&ti_new->fullpath, node_parent->fullpath);
 
-  ti_new->sort_priority = node_parent->sort_priority;
+  ti_new->sort_priority = LEVELCLASS_PARENT;
   ti_new->latest_engine = node_parent->latest_engine;
 
   setString(&ti_new->class_desc, getLevelClassDescription(ti_new));
@@ -2879,14 +2902,14 @@ static TreeInfo *createTopTreeInfoNode(TreeInfo *node_first)
   ti_new->node_parent = NULL;
   ti_new->parent_link = FALSE;
 
-  setString(&ti_new->identifier, node_first->identifier);
+  setString(&ti_new->identifier, "top_tree_node");
   setString(&ti_new->name, TREE_INFOTEXT(type));
   setString(&ti_new->name_sorting, ti_new->name);
 
   setString(&ti_new->subdir, STRING_TOP_DIRECTORY);
   setString(&ti_new->fullpath, ".");
 
-  ti_new->sort_priority = node_first->sort_priority;;
+  ti_new->sort_priority = LEVELCLASS_TOP;
   ti_new->latest_engine = node_first->latest_engine;
 
   setString(&ti_new->class_desc, TREE_INFOTEXT(type));
@@ -4508,6 +4531,7 @@ static void InitLastPlayedLevels_ParentNode(void)
   setTreeInfoToDefaultsFromParent(leveldir_new, leveldir_first);
 
   leveldir_new->level_group = TRUE;
+  leveldir_new->sort_priority = LEVELCLASS_LAST_PLAYED_LEVEL;
 
   setString(&leveldir_new->identifier, TOKEN_STR_LAST_LEVEL_SERIES);
   setString(&leveldir_new->name, "<< (last played level sets)");
@@ -4522,7 +4546,6 @@ static void InitLastPlayedLevels_ParentNode(void)
 void UpdateLastPlayedLevels_TreeInfo(void)
 {
   char **last_level_series = setup.level_setup.last_level_series;
-  boolean reset_leveldir_current = FALSE;
   LevelDirTree *leveldir_last;
   TreeInfo **node_new = NULL;
   int i;
@@ -4532,13 +4555,9 @@ void UpdateLastPlayedLevels_TreeInfo(void)
 
   InitLastPlayedLevels_ParentNode();
 
-  // check if current level set is from "last played" sub-tree to be rebuilt
-  reset_leveldir_current = strEqual(leveldir_current->node_parent->identifier,
-                                   TOKEN_STR_LAST_LEVEL_SERIES);
-
   leveldir_last = getTreeInfoFromIdentifierExt(leveldir_first,
                                               TOKEN_STR_LAST_LEVEL_SERIES,
-                                              TRUE);
+                                              TREE_NODE_TYPE_GROUP);
   if (leveldir_last == NULL)
     return;
 
@@ -4546,16 +4565,22 @@ void UpdateLastPlayedLevels_TreeInfo(void)
 
   freeTreeInfo(*node_new);
 
+  *node_new = NULL;
+
   for (i = 0; last_level_series[i] != NULL; i++)
   {
     LevelDirTree *node_last = getTreeInfoFromIdentifier(leveldir_first,
                                                        last_level_series[i]);
+    if (node_last == NULL)
+      continue;
 
     *node_new = getTreeInfoCopy(node_last);    // copy complete node
 
     (*node_new)->node_top = &leveldir_first;   // correct top node link
     (*node_new)->node_parent = leveldir_last;  // correct parent node link
 
+    (*node_new)->is_copy = TRUE;               // mark entry as node copy
+
     (*node_new)->node_group = NULL;
     (*node_new)->next = NULL;
 
@@ -4563,10 +4588,6 @@ void UpdateLastPlayedLevels_TreeInfo(void)
 
     node_new = &((*node_new)->next);
   }
-
-  if (reset_leveldir_current)
-    leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
-                                                 last_level_series[0]);
 }
 
 static void UpdateLastPlayedLevels_List(void)
@@ -4588,6 +4609,35 @@ static void UpdateLastPlayedLevels_List(void)
   setString(&last_level_series[0], leveldir_current->identifier);
 }
 
+static TreeInfo *StoreOrRestoreLastPlayedLevels(TreeInfo *node, boolean store)
+{
+  static char *identifier = NULL;
+
+  if (store)
+  {
+    setString(&identifier, (node && node->is_copy ? node->identifier : NULL));
+
+    return NULL;       // not used
+  }
+  else
+  {
+    TreeInfo *node_new = getTreeInfoFromIdentifierExt(leveldir_first,
+                                                     identifier,
+                                                     TREE_NODE_TYPE_COPY);
+    return (node_new != NULL ? node_new : node);
+  }
+}
+
+void StoreLastPlayedLevels(TreeInfo *node)
+{
+  StoreOrRestoreLastPlayedLevels(node, TRUE);
+}
+
+void RestoreLastPlayedLevels(TreeInfo **node)
+{
+  *node = StoreOrRestoreLastPlayedLevels(*node, FALSE);
+}
+
 void LoadLevelSetup_LastSeries(void)
 {
   // --------------------------------------------------------------------------