#if defined(PLATFORM_MACOSX)
static char *main_data_binary_subdir = NULL;
+ static char *main_data_files_subdir = NULL;
if (main_data_binary_subdir == NULL)
{
program.program_title, MAC_APP_BINARY_SUBDIR);
}
- // cut relative path to Mac OS X application binary directory from path
+ if (main_data_files_subdir == NULL)
+ {
+ main_data_files_subdir = checked_malloc(strlen(program.program_title) + 1 +
+ strlen("app") + 1 +
+ strlen(MAC_APP_FILES_SUBDIR) + 1);
+
+ sprintf(main_data_files_subdir, "%s.app/%s",
+ program.program_title, MAC_APP_FILES_SUBDIR);
+ }
+
if (strSuffix(main_data_path, main_data_binary_subdir))
+ {
+ char *main_data_path_old = main_data_path;
+
+ // cut relative path to Mac OS X application binary directory from path
main_data_path[strlen(main_data_path) -
strlen(main_data_binary_subdir)] = '\0';
- // cut trailing path separator from path (but not if path is root directory)
- if (strSuffix(main_data_path, "/") && !strEqual(main_data_path, "/"))
- main_data_path[strlen(main_data_path) - 1] = '\0';
+ // cut trailing path separator from path (but not if path is root directory)
+ if (strSuffix(main_data_path, "/") && !strEqual(main_data_path, "/"))
+ main_data_path[strlen(main_data_path) - 1] = '\0';
+
+ // replace empty path with current directory
+ if (strEqual(main_data_path, ""))
+ main_data_path = ".";
+
+ // add relative path to Mac OS X application resources directory to path
+ main_data_path = getPath2(main_data_path, main_data_files_subdir);
+
+ free(main_data_path_old);
+ }
#endif
return main_data_path;
options.execute_command = NULL;
options.special_flags = NULL;
+ options.mytapes = FALSE;
options.serveronly = FALSE;
options.network = FALSE;
options.verbose = FALSE;
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;
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)
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;
}
return result;
}
-struct ScreenModeInfo *get_screen_mode_from_string(char *screen_mode_string)
-{
- static struct ScreenModeInfo screen_mode;
- char *screen_mode_string_x = strchr(screen_mode_string, 'x');
- char *screen_mode_string_copy;
- char *screen_mode_string_pos_w;
- char *screen_mode_string_pos_h;
-
- if (screen_mode_string_x == NULL) /* invalid screen mode format */
- return NULL;
-
- screen_mode_string_copy = getStringCopy(screen_mode_string);
-
- screen_mode_string_pos_w = screen_mode_string_copy;
- screen_mode_string_pos_h = strchr(screen_mode_string_copy, 'x');
- *screen_mode_string_pos_h++ = '\0';
-
- screen_mode.width = atoi(screen_mode_string_pos_w);
- screen_mode.height = atoi(screen_mode_string_pos_h);
-
- return &screen_mode;
-}
-
-void get_aspect_ratio_from_screen_mode(struct ScreenModeInfo *screen_mode,
- int *x, int *y)
-{
- float aspect_ratio = (float)screen_mode->width / (float)screen_mode->height;
- float aspect_ratio_new;
- int i = 1;
-
- do
- {
- *x = i * aspect_ratio + 0.000001;
- *y = i;
-
- aspect_ratio_new = (float)*x / (float)*y;
-
- i++;
- }
- while (aspect_ratio_new != aspect_ratio && *y < screen_mode->height);
-}
-
static void FreeCustomArtworkList(struct ArtworkListInfo *,
struct ListNodeInfo ***, int *);
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++)
}
/* 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)
{
Error(ERR_EXIT, "please fix");
}
+ freeSetupFileHash(ignore_tokens_hash);
+
return file_list;
}
int num_ext2_suffixes = artwork_info->num_ext2_suffixes;
int num_ext3_suffixes = artwork_info->num_ext3_suffixes;
int num_ignore_tokens = artwork_info->num_ignore_tokens;
- SetupFileHash *setup_file_hash, *valid_file_hash;
+ SetupFileHash *setup_file_hash, *valid_file_hash, *valid_file_hash_tmp;
SetupFileHash *extra_file_hash, *empty_file_hash;
char *known_token_value = KNOWN_TOKEN_VALUE;
char *base_token_value = UNDEFINED_FILENAME;
/* at this point, we do not need the setup file hash anymore -- free it */
freeSetupFileHash(setup_file_hash);
- /* map deprecated to current tokens (using prefix match and replace) */
+ /* prevent changing hash while iterating over it by using a temporary copy */
+ valid_file_hash_tmp = newSetupFileHash();
BEGIN_HASH_ITERATION(valid_file_hash, itr)
+ {
+ setHashEntry(valid_file_hash_tmp,
+ HASH_ITERATION_TOKEN(itr),
+ HASH_ITERATION_VALUE(itr));
+ }
+ END_HASH_ITERATION(valid_file_hash, itr)
+
+ /* (iterate over same temporary hash, as modifications are independent) */
+
+ /* map deprecated to current tokens (using prefix match and replace) */
+ BEGIN_HASH_ITERATION(valid_file_hash_tmp, itr)
{
char *token = HASH_ITERATION_TOKEN(itr);
char *mapped_token = get_mapped_token(token);
free(mapped_token);
}
}
- END_HASH_ITERATION(valid_file_hash, itr)
+ END_HASH_ITERATION(valid_file_hash_tmp, itr)
/* add special base tokens (using prefix match and replace) */
- BEGIN_HASH_ITERATION(valid_file_hash, itr)
+ BEGIN_HASH_ITERATION(valid_file_hash_tmp, itr)
{
char *token = HASH_ITERATION_TOKEN(itr);
char *base_token = get_special_base_token(artwork_info, token);
free(base_token);
}
}
- END_HASH_ITERATION(valid_file_hash, itr)
+ END_HASH_ITERATION(valid_file_hash_tmp, itr)
+
+ /* free temporary hash used for iteration */
+ freeSetupFileHash(valid_file_hash_tmp);
/* read parameters for all known config file tokens */
for (i = 0; i < num_file_list_entries; i++)