added functions for integer hash keys
[rocksndiamonds.git] / src / libgame / setup.c
index 6886e101d343e5e63d14bcb640f70d7806019be2..e34ed89adcf198497e92c2f8ca948982f1f793c0 100644 (file)
@@ -725,7 +725,7 @@ char *getScoreTapeBasename(char *name)
 
   sprintf(timestamp, "%s", getCurrentTimestamp());
   sprintf(basename_raw, "%s-%s", timestamp, name);
-  sprintf(basename, "%s-%08x", timestamp, get_hash_from_key(basename_raw));
+  sprintf(basename, "%s-%08x", timestamp, get_hash_from_string(basename_raw));
 
   return basename;
 }
@@ -1709,30 +1709,56 @@ static void cloneTree(TreeInfo **ti_new, TreeInfo *ti, boolean skip_empty_sets)
   *ti_new = ti_cloned;
 }
 
-static boolean adjustTreeGraphicsForEMC(TreeInfo *node)
+static boolean adjustTreeArtworkForEMC(char **artwork_set_1,
+                                      char **artwork_set_2,
+                                      char **artwork_set, boolean prefer_2)
 {
-  boolean settings_changed = FALSE;
+  // do nothing if neither special artwork set 1 nor 2 are defined
+  if (!*artwork_set_1 && !*artwork_set_2)
+    return FALSE;
 
-  while (node)
+  boolean want_1 = (prefer_2 == FALSE);
+  boolean want_2 = (prefer_2 == TRUE);
+  boolean has_only_1 = (!*artwork_set && !*artwork_set_2);
+  boolean has_only_2 = (!*artwork_set && !*artwork_set_1);
+  char *artwork_set_new = NULL;
+
+  // replace missing special artwork 1 or 2 with (optional) standard artwork
+
+  if (!*artwork_set_1)
+    setString(artwork_set_1, *artwork_set);
+
+  if (!*artwork_set_2)
+    setString(artwork_set_2, *artwork_set);
+
+  // set standard artwork to either special artwork 1 or 2, as requested
+
+  if (*artwork_set_1 && (want_1 || has_only_1))
+    artwork_set_new = *artwork_set_1;
+
+  if (*artwork_set_2 && (want_2 || has_only_2))
+    artwork_set_new = *artwork_set_2;
+
+  if (artwork_set_new && !strEqual(*artwork_set, artwork_set_new))
   {
-    boolean want_ecs = (setup.prefer_aga_graphics == FALSE);
-    boolean want_aga = (setup.prefer_aga_graphics == TRUE);
-    boolean has_only_ecs = (!node->graphics_set && !node->graphics_set_aga);
-    boolean has_only_aga = (!node->graphics_set && !node->graphics_set_ecs);
-    char *graphics_set = NULL;
+    setString(artwork_set, artwork_set_new);
 
-    if (node->graphics_set_ecs && (want_ecs || has_only_ecs))
-      graphics_set = node->graphics_set_ecs;
+    return TRUE;
+  }
 
-    if (node->graphics_set_aga && (want_aga || has_only_aga))
-      graphics_set = node->graphics_set_aga;
+  return FALSE;
+}
 
-    if (graphics_set && !strEqual(node->graphics_set, graphics_set))
-    {
-      setString(&node->graphics_set, graphics_set);
-      settings_changed = TRUE;
-    }
+static boolean adjustTreeGraphicsForEMC(TreeInfo *node)
+{
+  boolean settings_changed = FALSE;
 
+  while (node)
+  {
+    settings_changed |= adjustTreeArtworkForEMC(&node->graphics_set_ecs,
+                                               &node->graphics_set_aga,
+                                               &node->graphics_set,
+                                               setup.prefer_aga_graphics);
     if (node->node_group != NULL)
       settings_changed |= adjustTreeGraphicsForEMC(node->node_group);
 
@@ -1748,24 +1774,10 @@ static boolean adjustTreeSoundsForEMC(TreeInfo *node)
 
   while (node)
   {
-    boolean want_default = (setup.prefer_lowpass_sounds == FALSE);
-    boolean want_lowpass = (setup.prefer_lowpass_sounds == TRUE);
-    boolean has_only_default = (!node->sounds_set && !node->sounds_set_lowpass);
-    boolean has_only_lowpass = (!node->sounds_set && !node->sounds_set_default);
-    char *sounds_set = NULL;
-
-    if (node->sounds_set_default && (want_default || has_only_default))
-      sounds_set = node->sounds_set_default;
-
-    if (node->sounds_set_lowpass && (want_lowpass || has_only_lowpass))
-      sounds_set = node->sounds_set_lowpass;
-
-    if (sounds_set && !strEqual(node->sounds_set, sounds_set))
-    {
-      setString(&node->sounds_set, sounds_set);
-      settings_changed = TRUE;
-    }
-
+    settings_changed |= adjustTreeArtworkForEMC(&node->sounds_set_default,
+                                               &node->sounds_set_lowpass,
+                                               &node->sounds_set,
+                                               setup.prefer_lowpass_sounds);
     if (node->node_group != NULL)
       settings_changed |= adjustTreeSoundsForEMC(node->node_group);
 
@@ -2269,7 +2281,7 @@ DEFINE_HASHTABLE_REMOVE(remove_hash_entry, char, char);
 #define remove_hash_entry hashtable_remove
 #endif
 
-unsigned int get_hash_from_key(void *key)
+unsigned int get_hash_from_string(void *key)
 {
   /*
     djb2
@@ -2299,15 +2311,27 @@ unsigned int get_hash_from_key(void *key)
   return hash;
 }
 
-int hash_keys_are_equal(void *key1, void *key2)
+unsigned int get_hash_from_integer(void *key)
+{
+  unsigned int hash = PTR_TO_UINT(key);
+
+  return hash;
+}
+
+int hash_key_strings_are_equal(void *key1, void *key2)
 {
   return (strEqual((char *)key1, (char *)key2));
 }
 
+int hash_key_integers_are_equal(void *key1, void *key2)
+{
+  return (key1 == key2);
+}
+
 SetupFileHash *newSetupFileHash(void)
 {
   SetupFileHash *new_hash =
-    create_hashtable(16, 0.75, get_hash_from_key, hash_keys_are_equal);
+    create_hashtable(16, 0.75, get_hash_from_string, hash_key_strings_are_equal);
 
   if (new_hash == NULL)
     Fail("create_hashtable() failed -- out of memory");
@@ -4582,6 +4606,12 @@ static boolean AddTreeSetToTreeInfoExt(TreeInfo *tree_node_old, char *tree_dir,
   TreeInfo *tree_node_new = getTreeInfoFromIdentifier(*tree_node_first,
                                                      tree_subdir_new);
 
+  // if not found, check if added node is level group or artwork group
+  if (tree_node_new == NULL)
+    tree_node_new = getTreeInfoFromIdentifierExt(*tree_node_first,
+                                                tree_subdir_new,
+                                                TREE_NODE_TYPE_GROUP);
+
   if (tree_node_new == NULL)           // should not happen
     return FALSE;