improved performance of artwork config initialization (InitArtworkConfig)
[rocksndiamonds.git] / src / libgame / misc.c
index 5a12dbe3006650a8eba03a9bf8e10015b566b089..559fd3859a69b443e9a95267d269c92118780c5c 100644 (file)
@@ -953,6 +953,7 @@ void GetOptions(int argc, char *argv[],
   options.execute_command = NULL;
   options.special_flags = NULL;
 
+  options.mytapes = FALSE;
   options.serveronly = FALSE;
   options.network = FALSE;
   options.verbose = FALSE;
@@ -1063,6 +1064,10 @@ void GetOptions(int argc, char *argv[],
       if (option_arg == next_option)
        options_left++;
     }
+    else if (strncmp(option, "-mytapes", option_len) == 0)
+    {
+      options.mytapes = TRUE;
+    }
     else if (strncmp(option, "-network", option_len) == 0)
     {
       options.network = TRUE;
@@ -2068,20 +2073,33 @@ void deleteNodeFromList(ListNode **node_first, char *key,
 
   if (strEqual((*node_first)->key, key))
   {
-    checked_free((*node_first)->key);
+    // after first recursion, (*node_first)->prev->next == *node_first,
+    // so *node_first would be overwritten with (*node_first)->next
+    // => use a copy of *node_first (and later of (*node_first)->next)
+    ListNode *node = *node_first;
+    ListNode *node_next = node->next;
+
+    checked_free(node->key);
 
     if (destructor_function)
-      destructor_function((*node_first)->content);
+      destructor_function(node->content);
+
+    if (node->prev)
+      node->prev->next = node->next;
 
-    if ((*node_first)->next)
-      (*node_first)->next->prev = (*node_first)->prev;
+    if (node->next)
+      node->next->prev = node->prev;
 
-    checked_free(*node_first);
+    checked_free(node);
 
-    *node_first = (*node_first)->next;
+    // after removing node, set list pointer to next valid list node
+    // (this is important if the first node of the list was deleted)
+    *node_first = node_next;
   }
   else
+  {
     deleteNodeFromList(&(*node_first)->next, key, destructor_function);
+  }
 }
 
 ListNode *getNodeFromKey(ListNode *node_first, char *key)
@@ -2564,6 +2582,27 @@ char *get_mapped_token(char *token)
       return getStringCat2(map_token_prefix[i][1], &token[len_token_prefix]);
   }
 
+  // change tokens containing ".gfx" by moving the "gfx" part to the very left
+  char *gfx_substring = ".gfx";
+  char *gfx_prefix = "gfx.";
+  if (strstr(token, gfx_substring) != NULL)
+  {
+    char *token_prefix = getStringCopy(token);
+    char *token_gfx_pos = strstr(token_prefix, gfx_substring);
+    char *token_suffix = &token_gfx_pos[strlen(gfx_substring)];
+    char *mapped_token;
+
+    // cut off token string at ".gfx" substring position
+    *token_gfx_pos = '\0';
+
+    // put together prefix "gfx." and token prefix and suffix without ".gfx"
+    mapped_token = getStringCat3(gfx_prefix, token_prefix, token_suffix);
+
+    free(token_prefix);
+
+    return mapped_token;
+  }
+
   return NULL;
 }
 
@@ -2756,12 +2795,18 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
                                           char **ignore_tokens,
                                           int num_file_list_entries)
 {
+  SetupFileHash *ignore_tokens_hash;
   struct FileInfo *file_list;
   int num_file_list_entries_found = 0;
   int num_suffix_list_entries = 0;
   int list_pos;
   int i, j;
 
+  /* create hash from list of tokens to be ignored (for quick access) */
+  ignore_tokens_hash = newSetupFileHash();
+  for (i = 0; ignore_tokens[i] != NULL; i++)
+    setHashEntry(ignore_tokens_hash, ignore_tokens[i], "");
+
   file_list = checked_calloc(num_file_list_entries * sizeof(struct FileInfo));
 
   for (i = 0; suffix_list[i].token != NULL; i++)
@@ -2819,9 +2864,8 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
     }
 
     /* the following tokens are no file definitions, but other config tokens */
-    for (j = 0; ignore_tokens[j] != NULL; j++)
-      if (strEqual(config_list[i].token, ignore_tokens[j]))
-       is_file_entry = FALSE;
+    if (getHashEntry(ignore_tokens_hash, config_list[i].token) != NULL)
+      is_file_entry = FALSE;
 
     if (is_file_entry)
     {
@@ -2851,6 +2895,8 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
     Error(ERR_EXIT,   "please fix");
   }
 
+  freeSetupFileHash(ignore_tokens_hash);
+
   return file_list;
 }
 
@@ -3061,7 +3107,7 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
   }
   END_HASH_ITERATION(valid_file_hash_tmp, itr)
 
-    /* free temporary hash used for iteration */
+  /* free temporary hash used for iteration */
   freeSetupFileHash(valid_file_hash_tmp);
 
   /* read parameters for all known config file tokens */