X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=72e4f051bf47a44f17b66d28be20fa693e151274;hp=be7fdc38e7819f5077fcfa223107d55081d511b2;hb=4a1cf573aae3a92b4ca910482d425e8b789b32eb;hpb=f2ddf39ad776c01f9b8a57818fe3ea9777649778 diff --git a/src/libgame/misc.c b/src/libgame/misc.c index be7fdc38..72e4f051 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -222,6 +222,18 @@ void Print(char *format, ...) va_end(ap); } +void PrintNoLog(char *format, ...) +{ + FILE *file = program.log_file_default[LOG_OUT_ID]; + va_list ap; + + va_start(ap, format); + vfprintf(file, format, ap); + va_end(ap); + + fflush(file); +} + void PrintLine(char *line_chars, int line_length) { int i; @@ -559,7 +571,7 @@ char *getLoginName() if (GetUserName(login_name, &buffer_size) == 0) strcpy(login_name, ANONYMOUS_NAME); } -#else +#elif defined(PLATFORM_UNIX) && !defined(PLATFORM_ANDROID) if (login_name == NULL) { struct passwd *pwd; @@ -569,6 +581,8 @@ char *getLoginName() else login_name = getStringCopy(pwd->pw_name); } +#else + login_name = ANONYMOUS_NAME; #endif return login_name; @@ -682,6 +696,7 @@ static char *getProgramMainDataPath() #if defined(PLATFORM_MACOSX) static char *main_data_binary_subdir = NULL; + static char *main_data_files_subdir = NULL; if (main_data_binary_subdir == NULL) { @@ -693,14 +708,37 @@ static char *getProgramMainDataPath() 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; @@ -949,10 +987,12 @@ void GetOptions(int argc, char *argv[], options.sounds_directory = getPath2(ro_base_path, SOUNDS_DIRECTORY); options.music_directory = getPath2(ro_base_path, MUSIC_DIRECTORY); options.docs_directory = getPath2(ro_base_path, DOCS_DIRECTORY); + options.conf_directory = getPath2(ro_base_path, CONF_DIRECTORY); options.execute_command = NULL; options.special_flags = NULL; + options.mytapes = FALSE; options.serveronly = FALSE; options.network = FALSE; options.verbose = FALSE; @@ -965,6 +1005,12 @@ void GetOptions(int argc, char *argv[], if (*options_left == NULL) /* no options given -- enable verbose mode */ options.verbose = TRUE; #endif +#endif + +#if DEBUG +#if defined(PLATFORM_ANDROID) + options.debug = TRUE; +#endif #endif while (*options_left) @@ -1026,6 +1072,7 @@ void GetOptions(int argc, char *argv[], options.sounds_directory = getPath2(ro_base_path, SOUNDS_DIRECTORY); options.music_directory = getPath2(ro_base_path, MUSIC_DIRECTORY); options.docs_directory = getPath2(ro_base_path, DOCS_DIRECTORY); + options.conf_directory = getPath2(ro_base_path, CONF_DIRECTORY); } else if (strncmp(option, "-levels", option_len) == 0) { @@ -1063,6 +1110,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; @@ -1169,6 +1220,10 @@ void Error(int mode, char *format, ...) ANDROID_LOG_UNKNOWN); #endif + /* display debug messages only when running in debug mode */ + if (mode & ERR_DEBUG && !options.debug) + return; + /* display warnings only when running in verbose mode */ if (mode & ERR_WARN && !options.verbose) return; @@ -1570,8 +1625,14 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) { KSYM_Page_Down, "XK_Page_Down", "page down" }, #if defined(TARGET_SDL2) + { KSYM_Select, "XK_Select", "select" }, { KSYM_Menu, "XK_Menu", "menu" }, /* menu key */ { KSYM_Back, "XK_Back", "back" }, /* back key */ + { KSYM_PlayPause, "XK_PlayPause", "play/pause" }, +#if defined(PLATFORM_ANDROID) + { KSYM_Rewind, "XK_Rewind", "rewind" }, + { KSYM_FastForward, "XK_FastForward", "fast forward" }, +#endif #endif /* ASCII 0x20 to 0x40 keys (except numbers) */ @@ -2068,20 +2129,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) @@ -2601,6 +2675,30 @@ char *get_special_base_token(struct ArtworkListInfo *artwork_info, char *token) { "global.anim_6" }, { "global.anim_7" }, { "global.anim_8" }, + { "global.anim_9" }, + { "global.anim_10" }, + { "global.anim_11" }, + { "global.anim_12" }, + { "global.anim_13" }, + { "global.anim_14" }, + { "global.anim_15" }, + { "global.anim_16" }, + { "global.anim_17" }, + { "global.anim_18" }, + { "global.anim_19" }, + { "global.anim_20" }, + { "global.anim_21" }, + { "global.anim_22" }, + { "global.anim_23" }, + { "global.anim_24" }, + { "global.anim_25" }, + { "global.anim_26" }, + { "global.anim_27" }, + { "global.anim_28" }, + { "global.anim_29" }, + { "global.anim_30" }, + { "global.anim_31" }, + { "global.anim_32" }, { NULL } }; @@ -2662,6 +2760,73 @@ static boolean string_has_parameter(char *s, char *s_contained) return string_has_parameter(substring, s_contained); } +int get_anim_parameter_value(char *s) +{ + char *pattern_1 = "click:anim_"; + char *pattern_2 = ".part_"; + char *matching_char = NULL; + char *s_ptr = s; + int result = ANIM_EVENT_NONE; + + matching_char = strstr(s_ptr, pattern_1); + if (matching_char == NULL) + return ANIM_EVENT_NONE; + + s_ptr = matching_char + strlen(pattern_1); + + // check for main animation number ("anim_X" or "anim_XX") + if (*s_ptr >= '0' && *s_ptr <= '9') + { + int gic_anim_nr = (*s_ptr++ - '0'); + + if (*s_ptr >= '0' && *s_ptr <= '9') + gic_anim_nr = 10 * gic_anim_nr + (*s_ptr++ - '0'); + + if (gic_anim_nr < 1 || gic_anim_nr > MAX_GLOBAL_ANIMS) + return ANIM_EVENT_NONE; + + result |= gic_anim_nr << ANIM_EVENT_ANIM_BIT; + } + else + { + // invalid main animation number specified + + return ANIM_EVENT_NONE; + } + + // check for animation part number ("part_X" or "part_XX") (optional) + if (strPrefix(s_ptr, pattern_2)) + { + s_ptr += strlen(pattern_2); + + if (*s_ptr >= '0' && *s_ptr <= '9') + { + int gic_part_nr = (*s_ptr++ - '0'); + + if (*s_ptr >= '0' && *s_ptr <= '9') + gic_part_nr = 10 * gic_part_nr + (*s_ptr++ - '0'); + + if (gic_part_nr < 1 || gic_part_nr > MAX_GLOBAL_ANIM_PARTS) + return ANIM_EVENT_NONE; + + result |= gic_part_nr << ANIM_EVENT_PART_BIT; + } + else + { + // invalid animation part number specified + + return ANIM_EVENT_NONE; + } + } + + /* discard result if next character is neither delimiter nor whitespace */ + if (!(*s_ptr == ',' || *s_ptr == '\0' || + *s_ptr == ' ' || *s_ptr == '\t')) + return ANIM_EVENT_NONE; + + return result; +} + int get_parameter_value(char *value_raw, char *suffix, int type) { char *value = getStringToLower(value_raw); @@ -2683,7 +2848,8 @@ int get_parameter_value(char *value_raw, char *suffix, int type) strEqual(value, "middle") ? POS_MIDDLE : strEqual(value, "lower") ? POS_LOWER : strEqual(value, "bottom") ? POS_BOTTOM : - strEqual(value, "any") ? POS_ANY : POS_UNDEFINED); + strEqual(value, "any") ? POS_ANY : + strEqual(value, "last") ? POS_LAST : POS_UNDEFINED); } else if (strEqual(suffix, ".align")) { @@ -2728,6 +2894,20 @@ int get_parameter_value(char *value_raw, char *suffix, int type) if (string_has_parameter(value, "static_panel")) result |= ANIM_STATIC_PANEL; } + else if (strEqual(suffix, ".init_event") || + strEqual(suffix, ".anim_event")) + { + result = ANIM_EVENT_DEFAULT; + + if (string_has_parameter(value, "any")) + result |= ANIM_EVENT_ANY; + + if (string_has_parameter(value, "click")) + result |= ANIM_EVENT_SELF; + + // add optional "click:anim_X" or "click:anim_X.part_X" parameter + result |= get_anim_parameter_value(value); + } else if (strEqual(suffix, ".class")) { result = (strEqual(value, ARG_UNDEFINED) ? ARG_UNDEFINED_VALUE : @@ -2742,6 +2922,9 @@ int get_parameter_value(char *value_raw, char *suffix, int type) if (string_has_parameter(value, "inner_corners")) result |= STYLE_INNER_CORNERS; + + if (string_has_parameter(value, "reverse")) + result |= STYLE_REVERSE; } else if (strEqual(suffix, ".fade_mode")) { @@ -2777,12 +2960,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++) @@ -2840,9 +3029,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) { @@ -2872,6 +3060,8 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list, Error(ERR_EXIT, "please fix"); } + freeSetupFileHash(ignore_tokens_hash); + return file_list; } @@ -3082,7 +3272,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 */