added safety check (should never happen style)
[rocksndiamonds.git] / src / libgame / setup.c
index e223a0b84bb2b66992746dbe8c6375d299016341..d867ebbae239e3245939f2a063261ae83fc97b33 100644 (file)
@@ -43,41 +43,6 @@ static char *levelclass_desc[NUM_LEVELCLASS_DESC] =
   "DX Boulderdash"
 };
 
-
-#define LEVELCOLOR(n)  (IS_LEVELCLASS_TUTORIAL(n) ?            FC_BLUE :    \
-                        IS_LEVELCLASS_CLASSICS(n) ?            FC_RED :     \
-                        IS_LEVELCLASS_BD(n) ?                  FC_YELLOW :  \
-                        IS_LEVELCLASS_EM(n) ?                  FC_YELLOW :  \
-                        IS_LEVELCLASS_SP(n) ?                  FC_YELLOW :  \
-                        IS_LEVELCLASS_DX(n) ?                  FC_YELLOW :  \
-                        IS_LEVELCLASS_SB(n) ?                  FC_YELLOW :  \
-                        IS_LEVELCLASS_CONTRIB(n) ?             FC_GREEN :   \
-                        IS_LEVELCLASS_PRIVATE(n) ?             FC_RED :     \
-                        FC_BLUE)
-
-#define LEVELSORTING(n)        (IS_LEVELCLASS_TUTORIAL(n) ?            0 :     \
-                        IS_LEVELCLASS_CLASSICS(n) ?            1 :     \
-                        IS_LEVELCLASS_BD(n) ?                  2 :     \
-                        IS_LEVELCLASS_EM(n) ?                  3 :     \
-                        IS_LEVELCLASS_SP(n) ?                  4 :     \
-                        IS_LEVELCLASS_DX(n) ?                  5 :     \
-                        IS_LEVELCLASS_SB(n) ?                  6 :     \
-                        IS_LEVELCLASS_CONTRIB(n) ?             7 :     \
-                        IS_LEVELCLASS_PRIVATE(n) ?             8 :     \
-                        9)
-
-#define ARTWORKCOLOR(n)        (IS_ARTWORKCLASS_CLASSICS(n) ?          FC_RED :     \
-                        IS_ARTWORKCLASS_CONTRIB(n) ?           FC_GREEN :   \
-                        IS_ARTWORKCLASS_PRIVATE(n) ?           FC_RED :     \
-                        IS_ARTWORKCLASS_LEVEL(n) ?             FC_YELLOW :  \
-                        FC_BLUE)
-
-#define ARTWORKSORTING(n) (IS_ARTWORKCLASS_CLASSICS(n) ?       0 :     \
-                          IS_ARTWORKCLASS_LEVEL(n) ?           1 :     \
-                          IS_ARTWORKCLASS_CONTRIB(n) ?         2 :     \
-                          IS_ARTWORKCLASS_PRIVATE(n) ?         3 :     \
-                          9)
-
 #define TOKEN_VALUE_POSITION_SHORT             32
 #define TOKEN_VALUE_POSITION_DEFAULT           40
 #define TOKEN_COMMENT_POSITION_DEFAULT         60
@@ -1546,6 +1511,8 @@ char *getHomeDir(void)
     if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir)))
       strcpy(dir, ".");
   }
+#elif defined(PLATFORM_EMSCRIPTEN)
+  dir = "/persistent";
 #elif defined(PLATFORM_UNIX)
   if (dir == NULL)
   {
@@ -2365,6 +2332,8 @@ static void saveSetupFileHash(SetupFileHash *hash, char *filename)
     return;
   }
 
+  fprintf(file, "%s\n\n", getFormattedSetupEntry("program.version",
+                                                program.version_string));
   for (i = 0; i < item_count; i++)
     fprintf(file, "%s\n", getFormattedSetupEntry(sort_array[i].token,
                                                 sort_array[i].value));
@@ -2504,7 +2473,6 @@ static struct TokenInfo artworkinfo_tokens[] =
   { 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                    },
@@ -2859,40 +2827,13 @@ static int compareTreeInfoEntries(const void *object1, const void *object2)
 {
   const TreeInfo *entry1 = *((TreeInfo **)object1);
   const TreeInfo *entry2 = *((TreeInfo **)object2);
-  int class_sorting1 = 0, class_sorting2 = 0;
-  int compare_result;
+  int tree_sorting1 = TREE_SORTING(entry1);
+  int tree_sorting2 = TREE_SORTING(entry2);
 
-  if (entry1->type == TREE_TYPE_LEVEL_DIR)
-  {
-    class_sorting1 = LEVELSORTING(entry1);
-    class_sorting2 = LEVELSORTING(entry2);
-  }
-  else if (entry1->type == TREE_TYPE_GRAPHICS_DIR ||
-          entry1->type == TREE_TYPE_SOUNDS_DIR ||
-          entry1->type == TREE_TYPE_MUSIC_DIR)
-  {
-    class_sorting1 = ARTWORKSORTING(entry1);
-    class_sorting2 = ARTWORKSORTING(entry2);
-  }
-
-  if (entry1->parent_link || entry2->parent_link)
-    compare_result = (entry1->parent_link ? -1 : +1);
-  else if (entry1->sort_priority == entry2->sort_priority)
-  {
-    char *name1 = getStringToLower(entry1->name_sorting);
-    char *name2 = getStringToLower(entry2->name_sorting);
-
-    compare_result = strcmp(name1, name2);
-
-    free(name1);
-    free(name2);
-  }
-  else if (class_sorting1 == class_sorting2)
-    compare_result = entry1->sort_priority - entry2->sort_priority;
+  if (tree_sorting1 != tree_sorting2)
+    return (tree_sorting1 - tree_sorting2);
   else
-    compare_result = class_sorting1 - class_sorting2;
-
-  return compare_result;
+    return strcasecmp(entry1->name_sorting, entry2->name_sorting);
 }
 
 static TreeInfo *createParentTreeInfoNode(TreeInfo *node_parent)
@@ -2915,7 +2856,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));
@@ -2938,14 +2879,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));
@@ -2990,6 +2931,17 @@ static void LoadArtworkInfoCache(void)
     // try to load artwork info hash from already existing cache file
     artworkinfo_cache_old = loadSetupFileHash(filename);
 
+    // try to get program version that artwork info cache was written with
+    char *version = getHashEntry(artworkinfo_cache_old, "program.version");
+
+    // check program version of artwork info cache against current version
+    if (!strEqual(version, program.version_string))
+    {
+      freeSetupFileHash(artworkinfo_cache_old);
+
+      artworkinfo_cache_old = NULL;
+    }
+
     // if no artwork info cache file was found, start with empty hash
     if (artworkinfo_cache_old == NULL)
       artworkinfo_cache_old = newSetupFileHash();
@@ -3509,8 +3461,6 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
   leveldir_new->user_defined =
     (leveldir_new->in_user_dir && IS_LEVELCLASS_PRIVATE(leveldir_new));
 
-  leveldir_new->color = LEVELCOLOR(leveldir_new);
-
   setString(&leveldir_new->class_desc, getLevelClassDescription(leveldir_new));
 
   leveldir_new->handicap_level =       // set handicap to default value
@@ -3754,9 +3704,6 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
   artwork_new->in_user_dir =
     (!strEqual(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type)));
 
-  // (may use ".sort_priority" from "setup_file_hash" above)
-  artwork_new->color = ARTWORKCOLOR(artwork_new);
-
   setString(&artwork_new->class_desc, getLevelClassDescription(artwork_new));
 
   if (setup_file_hash == NULL) // (after determining ".user_defined")
@@ -3774,9 +3721,6 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
        artwork_new->sort_priority = ARTWORKCLASS_CLASSICS;
       }
 
-      // set to new values after changing ".sort_priority"
-      artwork_new->color = ARTWORKCOLOR(artwork_new);
-
       setString(&artwork_new->class_desc,
                getLevelClassDescription(artwork_new));
     }
@@ -4034,7 +3978,7 @@ static void LoadArtworkInfoFromLevelInfoExt(ArtworkDirTree **artwork_node,
          setString(&artwork_new->name_sorting, level_node->name_sorting);
 
          artwork_new->sort_priority = level_node->sort_priority;
-         artwork_new->color = LEVELCOLOR(artwork_new);
+         artwork_new->in_user_dir = level_node->in_user_dir;
 
          update_artworkinfo_cache = TRUE;
        }
@@ -4564,9 +4508,11 @@ 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)");
+  setString(&leveldir_new->name_sorting, leveldir_new->name);
 
   pushTreeInfo(leveldir_top, leveldir_new);
 
@@ -4601,10 +4547,14 @@ 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