X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=7051e28efa9f2a0379bd4cf67ac61a6797d47136;hb=61c3da024802ecc0268bab42d7499fc0346e4fd3;hp=b93c9bdeea4ee03056530b61aeced0a1c8d0d978;hpb=872cf2d86e73d185fcad1fac7b389e7d1dfcb839;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index b93c9bde..7051e28e 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -167,7 +168,7 @@ boolean getTokenValueFromString(char *string, char **token, char **value) /* ------------------------------------------------------------------------- */ #if defined(PLATFORM_MSDOS) -volatile unsigned long counter = 0; +volatile unsigned int counter = 0; void increment_counter() { @@ -181,12 +182,52 @@ END_OF_FUNCTION(increment_counter); /* maximal allowed length of a command line option */ #define MAX_OPTION_LEN 256 +#if 1 + +#ifdef TARGET_SDL +static unsigned int getCurrentMS() +{ + return SDL_GetTicks(); +} + +#else /* !TARGET_SDL */ + +#if defined(PLATFORM_UNIX) +static unsigned int getCurrentMS() +{ + struct timeval current_time; + + gettimeofday(¤t_time, NULL); + + return current_time.tv_sec * 1000 + current_time.tv_usec / 1000; +} +#endif /* PLATFORM_UNIX */ +#endif /* !TARGET_SDL */ + +static unsigned int mainCounter(int mode) +{ + static unsigned int base_ms = 0; + unsigned int current_ms; + + /* get current system milliseconds */ + current_ms = getCurrentMS(); + + /* reset base timestamp in case of counter reset or wrap-around */ + if (mode == INIT_COUNTER || current_ms < base_ms) + base_ms = current_ms; + + /* return milliseconds since last counter reset */ + return current_ms - base_ms; +} + +#else + #ifdef TARGET_SDL -static unsigned long mainCounter(int mode) +static unsigned int mainCounter(int mode) { - static unsigned long base_ms = 0; - unsigned long current_ms; - unsigned long counter_ms; + static unsigned int base_ms = 0; + unsigned int current_ms; + unsigned int counter_ms; current_ms = SDL_GetTicks(); @@ -202,11 +243,11 @@ static unsigned long mainCounter(int mode) #else /* !TARGET_SDL */ #if defined(PLATFORM_UNIX) -static unsigned long mainCounter(int mode) +static unsigned int mainCounter(int mode) { static struct timeval base_time = { 0, 0 }; struct timeval current_time; - unsigned long counter_ms; + unsigned int counter_ms; gettimeofday(¤t_time, NULL); @@ -222,6 +263,8 @@ static unsigned long mainCounter(int mode) #endif /* PLATFORM_UNIX */ #endif /* !TARGET_SDL */ +#endif + void InitCounter() /* set counter back to zero */ { #if !defined(PLATFORM_MSDOS) @@ -233,7 +276,7 @@ void InitCounter() /* set counter back to zero */ #endif } -unsigned long Counter() /* get milliseconds since last call of InitCounter() */ +unsigned int Counter() /* get milliseconds since last call of InitCounter() */ { #if !defined(PLATFORM_MSDOS) return mainCounter(READ_COUNTER); @@ -242,7 +285,7 @@ unsigned long Counter() /* get milliseconds since last call of InitCounter() */ #endif } -static void sleep_milliseconds(unsigned long milliseconds_delay) +static void sleep_milliseconds(unsigned int milliseconds_delay) { boolean do_busy_waiting = (milliseconds_delay < 5 ? TRUE : FALSE); @@ -253,7 +296,7 @@ static void sleep_milliseconds(unsigned long milliseconds_delay) therefore it's better to do a short interval of busy waiting to get our sleeping time more accurate */ - unsigned long base_counter = Counter(), actual_counter = Counter(); + unsigned int base_counter = Counter(), actual_counter = Counter(); while (actual_counter < base_counter + milliseconds_delay && actual_counter >= base_counter) @@ -277,15 +320,15 @@ static void sleep_milliseconds(unsigned long milliseconds_delay) } } -void Delay(unsigned long delay) /* Sleep specified number of milliseconds */ +void Delay(unsigned int delay) /* Sleep specified number of milliseconds */ { sleep_milliseconds(delay); } -boolean FrameReached(unsigned long *frame_counter_var, - unsigned long frame_delay) +boolean FrameReached(unsigned int *frame_counter_var, + unsigned int frame_delay) { - unsigned long actual_frame_counter = FrameCounter; + unsigned int actual_frame_counter = FrameCounter; if (actual_frame_counter >= *frame_counter_var && actual_frame_counter < *frame_counter_var + frame_delay) @@ -296,10 +339,10 @@ boolean FrameReached(unsigned long *frame_counter_var, return TRUE; } -boolean DelayReached(unsigned long *counter_var, - unsigned long delay) +boolean DelayReached(unsigned int *counter_var, + unsigned int delay) { - unsigned long actual_counter = Counter(); + unsigned int actual_counter = Counter(); if (actual_counter >= *counter_var && actual_counter < *counter_var + delay) @@ -310,9 +353,9 @@ boolean DelayReached(unsigned long *counter_var, return TRUE; } -void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay) +void WaitUntilDelayReached(unsigned int *counter_var, unsigned int delay) { - unsigned long actual_counter; + unsigned int actual_counter; while (1) { @@ -333,17 +376,30 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay) /* random generator functions */ /* ------------------------------------------------------------------------- */ -unsigned int init_random_number(int nr, long seed) +unsigned int init_random_number(int nr, int seed) { if (seed == NEW_RANDOMIZE) { -#if defined(TARGET_SDL) - seed = (long)SDL_GetTicks(); -#else + /* default random seed */ + seed = (int)time(NULL); // seconds since the epoch + +#if !defined(PLATFORM_WIN32) + /* add some more randomness */ struct timeval current_time; gettimeofday(¤t_time, NULL); - seed = (long)current_time.tv_usec; + + seed += (int)current_time.tv_usec; // microseconds since the epoch +#endif + +#if defined(TARGET_SDL) + /* add some more randomness */ + seed += (int)SDL_GetTicks(); // milliseconds since SDL init +#endif + +#if 1 + /* add some more randomness */ + seed += GetSimpleRandom(1000000); #endif } @@ -370,7 +426,7 @@ static char *get_corrected_real_name(char *real_name) char *to_ptr = real_name_new; /* copy the name string, but not more than MAX_USERNAME_LEN characters */ - while (*from_ptr && (long)(to_ptr - real_name_new) < MAX_USERNAME_LEN - 1) + while (*from_ptr && (int)(to_ptr - real_name_new) < MAX_USERNAME_LEN - 1) { /* the name field read from "passwd" file may also contain additional user information, separated by commas, which will be removed here */ @@ -402,7 +458,7 @@ char *getLoginName() #if defined(PLATFORM_WIN32) if (login_name == NULL) { - unsigned long buffer_size = MAX_USERNAME_LEN + 1; + unsigned int buffer_size = MAX_USERNAME_LEN + 1; login_name = checked_malloc(buffer_size); if (GetUserName(login_name, &buffer_size) == 0) @@ -431,7 +487,7 @@ char *getRealName() if (real_name == NULL) { static char buffer[MAX_USERNAME_LEN + 1]; - unsigned long buffer_size = MAX_USERNAME_LEN + 1; + unsigned int buffer_size = MAX_USERNAME_LEN + 1; if (GetUserName(buffer, &buffer_size) != 0) real_name = get_corrected_real_name(buffer); @@ -455,6 +511,16 @@ char *getRealName() return real_name; } +time_t getFileTimestampEpochSeconds(char *filename) +{ + struct stat file_status; + + if (stat(filename, &file_status) != 0) /* cannot stat file */ + return 0; + + return file_status.st_mtime; +} + /* ------------------------------------------------------------------------- */ /* path manipulation functions */ @@ -607,7 +673,7 @@ boolean strEqualN(char *s1, char *s2, int n) strncmp(s1, s2, n) == 0); } -boolean strEqualPrefix(char *s, char *prefix) +boolean strPrefix(char *s, char *prefix) { return (s == NULL && prefix == NULL ? TRUE : s == NULL && prefix != NULL ? FALSE : @@ -615,7 +681,7 @@ boolean strEqualPrefix(char *s, char *prefix) strncmp(s, prefix, strlen(prefix)) == 0); } -boolean strEqualSuffix(char *s, char *suffix) +boolean strSuffix(char *s, char *suffix) { return (s == NULL && suffix == NULL ? TRUE : s == NULL && suffix != NULL ? FALSE : @@ -624,6 +690,26 @@ boolean strEqualSuffix(char *s, char *suffix) strncmp(&s[strlen(s) - strlen(suffix)], suffix, strlen(suffix)) == 0); } +boolean strPrefixLower(char *s, char *prefix) +{ + char *s_lower = getStringToLower(s); + boolean match = strPrefix(s_lower, prefix); + + free(s_lower); + + return match; +} + +boolean strSuffixLower(char *s, char *suffix) +{ + char *s_lower = getStringToLower(s); + boolean match = strSuffix(s_lower, suffix); + + free(s_lower); + + return match; +} + /* ------------------------------------------------------------------------- */ /* command line option handling functions */ @@ -652,6 +738,7 @@ void GetOptions(char *argv[], void (*print_usage_function)(void)) options.display_name = NULL; options.server_host = NULL; options.server_port = 0; + options.ro_base_directory = ro_base_path; options.rw_base_directory = rw_base_path; options.level_directory = getPath2(ro_base_path, LEVELS_DIRECTORY); @@ -659,11 +746,15 @@ void GetOptions(char *argv[], void (*print_usage_function)(void)) 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.execute_command = NULL; + options.special_flags = NULL; + options.serveronly = FALSE; options.network = FALSE; options.verbose = FALSE; options.debug = FALSE; + options.debug_x11_sync = FALSE; #if !defined(PLATFORM_UNIX) if (*options_left == NULL) /* no options given -- enable verbose mode */ @@ -687,7 +778,7 @@ void GetOptions(char *argv[], void (*print_usage_function)(void)) if (strEqual(option, "--")) /* stop scanning arguments */ break; - if (strncmp(option, "--", 2) == 0) /* treat '--' like '-' */ + if (strPrefix(option, "--")) /* treat '--' like '-' */ option++; option_arg = strchr(option, '='); @@ -789,6 +880,29 @@ void GetOptions(char *argv[], void (*print_usage_function)(void)) { options.debug = TRUE; } + else if (strncmp(option, "-debug-x11-sync", option_len) == 0) + { + options.debug_x11_sync = TRUE; + } + else if (strPrefix(option, "-D")) + { +#if 1 + options.special_flags = getStringCopy(&option[2]); +#else + char *flags_string = &option[2]; + unsigned int flags_value; + + if (*flags_string == '\0') + Error(ERR_EXIT_HELP, "empty flag ignored"); + + flags_value = get_special_flags_function(flags_string); + + if (flags_value == 0) + Error(ERR_EXIT_HELP, "unknown flag '%s'", flags_string); + + options.special_flags |= flags_value; +#endif + } else if (strncmp(option, "-execute", option_len) == 0) { if (option_arg == NULL) @@ -910,7 +1024,7 @@ void Error(int mode, char *format, ...) /* checked memory allocation and freeing functions */ /* ------------------------------------------------------------------------- */ -void *checked_malloc(unsigned long size) +void *checked_malloc(unsigned int size) { void *ptr; @@ -922,7 +1036,7 @@ void *checked_malloc(unsigned long size) return ptr; } -void *checked_calloc(unsigned long size) +void *checked_calloc(unsigned int size) { void *ptr; @@ -934,7 +1048,7 @@ void *checked_calloc(unsigned long size) return ptr; } -void *checked_realloc(void *ptr, unsigned long size) +void *checked_realloc(void *ptr, unsigned int size) { ptr = realloc(ptr, size); @@ -950,6 +1064,19 @@ void checked_free(void *ptr) free(ptr); } +void clear_mem(void *ptr, unsigned int size) +{ +#if defined(PLATFORM_WIN32) + /* for unknown reason, memset() sometimes crashes when compiled with MinGW */ + char *cptr = (char *)ptr; + + while (size--) + *cptr++ = 0; +#else + memset(ptr, 0, size); +#endif +} + /* ------------------------------------------------------------------------- */ /* various helper functions */ @@ -1129,7 +1256,7 @@ int putFileVersion(FILE *file, int version) return 4; } -void ReadBytesFromFile(FILE *file, byte *buffer, unsigned long bytes) +void ReadBytesFromFile(FILE *file, byte *buffer, unsigned int bytes) { int i; @@ -1137,7 +1264,7 @@ void ReadBytesFromFile(FILE *file, byte *buffer, unsigned long bytes) buffer[i] = fgetc(file); } -void WriteBytesToFile(FILE *file, byte *buffer, unsigned long bytes) +void WriteBytesToFile(FILE *file, byte *buffer, unsigned int bytes) { int i; @@ -1145,13 +1272,13 @@ void WriteBytesToFile(FILE *file, byte *buffer, unsigned long bytes) fputc(buffer[i], file); } -void ReadUnusedBytesFromFile(FILE *file, unsigned long bytes) +void ReadUnusedBytesFromFile(FILE *file, unsigned int bytes) { while (bytes-- && !feof(file)) fgetc(file); } -void WriteUnusedBytesToFile(FILE *file, unsigned long bytes) +void WriteUnusedBytesToFile(FILE *file, unsigned int bytes) { while (bytes--) fputc(0, file); @@ -1348,7 +1475,7 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) while (translate_key[++i].x11name); if (!translate_key[i].x11name) - sprintf(name_buffer, "0x%04lx", (unsigned long)key); + sprintf(name_buffer, "0x%04x", (unsigned int)key); } *x11name = name_buffer; @@ -1378,7 +1505,7 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) Key key = KSYM_UNDEFINED; char *name_ptr = *x11name; - if (strncmp(name_ptr, "XK_", 3) == 0 && strlen(name_ptr) == 4) + if (strPrefix(name_ptr, "XK_") && strlen(name_ptr) == 4) { char c = name_ptr[3]; @@ -1389,14 +1516,14 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) else if (c >= '0' && c <= '9') key = KSYM_0 + (Key)(c - '0'); } - else if (strncmp(name_ptr, "XK_KP_", 6) == 0 && strlen(name_ptr) == 7) + else if (strPrefix(name_ptr, "XK_KP_") && strlen(name_ptr) == 7) { char c = name_ptr[6]; if (c >= '0' && c <= '9') key = KSYM_KP_0 + (Key)(c - '0'); } - else if (strncmp(name_ptr, "XK_F", 4) == 0 && strlen(name_ptr) <= 6) + else if (strPrefix(name_ptr, "XK_F") && strlen(name_ptr) <= 6) { char c1 = name_ptr[4]; char c2 = name_ptr[5]; @@ -1409,7 +1536,7 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) if (d >= 1 && d <= KSYM_NUM_FKEYS) key = KSYM_F1 + (Key)(d - 1); } - else if (strncmp(name_ptr, "XK_", 3) == 0) + else if (strPrefix(name_ptr, "XK_")) { i = 0; @@ -1423,9 +1550,9 @@ void translate_keyname(Key *keysym, char **x11name, char **name, int mode) } while (translate_key[++i].x11name); } - else if (strncmp(name_ptr, "0x", 2) == 0) + else if (strPrefix(name_ptr, "0x")) { - unsigned long value = 0; + unsigned int value = 0; name_ptr += 2; @@ -1549,9 +1676,13 @@ int get_integer_from_string(char *s) if (result == -1) { - if (strEqual(s_lower, "false")) + if (strEqual(s_lower, "false") || + strEqual(s_lower, "no") || + strEqual(s_lower, "off")) result = 0; - else if (strEqual(s_lower, "true")) + else if (strEqual(s_lower, "true") || + strEqual(s_lower, "yes") || + strEqual(s_lower, "on")) result = 1; else result = atoi(s); @@ -1578,6 +1709,24 @@ boolean get_boolean_from_string(char *s) return result; } +int get_switch3_from_string(char *s) +{ + char *s_lower = getStringToLower(s); + int result = FALSE; + + if (strEqual(s_lower, "true") || + strEqual(s_lower, "yes") || + strEqual(s_lower, "on") || + get_integer_from_string(s) == 1) + result = TRUE; + else if (strEqual(s_lower, "auto")) + result = AUTO; + + free(s_lower); + + return result; +} + /* ------------------------------------------------------------------------- */ /* functions for generic lists */ @@ -1724,7 +1873,7 @@ boolean FileIsMusic(char *filename) return TRUE; #if defined(TARGET_SDL) - if (fileHasPrefix(basename, "mod") || + if ((fileHasPrefix(basename, "mod") && !fileHasSuffix(basename, "txt")) || fileHasSuffix(basename, "mod") || fileHasSuffix(basename, "s3m") || fileHasSuffix(basename, "it") || @@ -1862,6 +2011,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, ".class")) + { + result = get_hash_from_key(value); + } + else if (strEqual(suffix, ".style")) + { + result = STYLE_DEFAULT; + + if (string_has_parameter(value, "accurate_borders")) + result |= STYLE_ACCURATE_BORDERS; + + if (string_has_parameter(value, "inner_corners")) + result |= STYLE_INNER_CORNERS; + } else if (strEqual(suffix, ".fade_mode")) { result = (string_has_parameter(value, "none") ? FADE_MODE_NONE : @@ -1871,7 +2034,7 @@ int get_parameter_value(char *value_raw, char *suffix, int type) FADE_MODE_DEFAULT); } #if 1 - else if (strEqualPrefix(suffix, ".font")) /* (may also be ".font_xyz") */ + else if (strPrefix(suffix, ".font")) /* (may also be ".font_xyz") */ #else else if (strEqualN(suffix, ".font", 5)) /* (may also be ".font_xyz") */ #endif @@ -1975,6 +2138,7 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list, file_list[i].redefined = FALSE; file_list[i].fallback_to_default = FALSE; + file_list[i].default_is_cloned = FALSE; } } @@ -2031,6 +2195,9 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list, printf("::: '%s' => '%s'\n", config_list[i].token, config_list[i].value); #endif } + + if (strSuffix(config_list[i].token, ".clone_from")) + file_list[list_pos].default_is_cloned = TRUE; } num_file_list_entries_found = list_pos + 1; @@ -2139,6 +2306,7 @@ static void add_dynamic_file_list_entry(struct FileInfo **list, new_list_entry->redefined = FALSE; new_list_entry->fallback_to_default = FALSE; + new_list_entry->default_is_cloned = FALSE; read_token_parameters(extra_file_hash, suffix_list, new_list_entry); } @@ -2640,11 +2808,21 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info) artwork_info->num_property_mapping_entries = 0; } +#if 1 + if (!GFX_OVERRIDE_ARTWORK(artwork_info->type)) +#else if (!SETUP_OVERRIDE_ARTWORK(setup, artwork_info->type)) +#endif { /* first look for special artwork configured in level series config */ filename_base = getCustomArtworkLevelConfigFilename(artwork_info->type); +#if 0 + printf("::: filename_base == '%s' [%s, %s]\n", filename_base, + leveldir_current->graphics_set, + leveldir_current->graphics_path); +#endif + if (fileExists(filename_base)) LoadArtworkConfigFromFilename(artwork_info, filename_base); } @@ -2691,6 +2869,22 @@ static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, basename = file_list_entry->default_filename; + /* fail for cloned default artwork that has no default filename defined */ + if (file_list_entry->default_is_cloned && + strEqual(basename, UNDEFINED_FILENAME)) + { + int error_mode = ERR_WARN; + + /* we can get away without sounds and music, but not without graphics */ + if (*listnode == NULL && artwork_info->type == ARTWORK_TYPE_GRAPHICS) + error_mode = ERR_EXIT; + + Error(error_mode, "token '%s' was cloned and has no default filename", + file_list_entry->token); + + return; + } + /* dynamic artwork has no default filename / skip empty default artwork */ if (basename == NULL || strEqual(basename, UNDEFINED_FILENAME)) return; @@ -2767,6 +2961,7 @@ static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, error_mode = ERR_EXIT; Error(error_mode, "cannot load artwork file '%s'", basename); + return; } } @@ -2898,7 +3093,7 @@ void NotifyUserAboutErrorFile() #if DEBUG -#define DEBUG_NUM_TIMESTAMPS 3 +#define DEBUG_NUM_TIMESTAMPS 5 #define DEBUG_TIME_IN_MICROSECONDS 0 #if DEBUG_TIME_IN_MICROSECONDS @@ -2922,35 +3117,53 @@ static double Counter_Microseconds() } #endif +char *debug_print_timestamp_get_padding(int padding_size) +{ + static char *padding = NULL; + int max_padding_size = 100; + + if (padding == NULL) + { + padding = checked_calloc(max_padding_size + 1); + memset(padding, ' ', max_padding_size); + } + + return &padding[MAX(0, max_padding_size - padding_size)]; +} + void debug_print_timestamp(int counter_nr, char *message) { -#if DEBUG_TIME_IN_MICROSECONDS - static double counter[DEBUG_NUM_TIMESTAMPS][2]; + int indent_size = 8; + int padding_size = 40; + float timestamp_interval; - if (counter_nr >= DEBUG_NUM_TIMESTAMPS) + if (counter_nr < 0) + Error(ERR_EXIT, "debugging: invalid negative counter"); + else if (counter_nr >= DEBUG_NUM_TIMESTAMPS) Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c"); - counter[counter_nr][0] = Counter_Microseconds(); - - if (message) - printf("%s %.3f ms\n", message, - (counter[counter_nr][0] - counter[counter_nr][1]) / 1000); +#if DEBUG_TIME_IN_MICROSECONDS + static double counter[DEBUG_NUM_TIMESTAMPS][2]; + char *unit = "ms"; - counter[counter_nr][1] = counter[counter_nr][0]; + counter[counter_nr][0] = Counter_Microseconds(); #else - static long counter[DEBUG_NUM_TIMESTAMPS][2]; - - if (counter_nr >= DEBUG_NUM_TIMESTAMPS) - Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c"); + static int counter[DEBUG_NUM_TIMESTAMPS][2]; + char *unit = "s"; counter[counter_nr][0] = Counter(); +#endif - if (message) - printf("%s %.3f s\n", message, - (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000); - + timestamp_interval = counter[counter_nr][0] - counter[counter_nr][1]; counter[counter_nr][1] = counter[counter_nr][0]; -#endif + + if (message) + printf("%s%s%s %.3f %s\n", + debug_print_timestamp_get_padding(counter_nr * indent_size), + message, + debug_print_timestamp_get_padding(padding_size - strlen(message)), + timestamp_interval / 1000, + unit); } void debug_print_parent_only(char *format, ...)