X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=93a62e07d1a55ad5bf4c2ca2627491b4ff83effb;hp=56978dccc9d3831e6af989f1f1ee1eaed15f955b;hb=730deaee1a38f75d749a21cddbb562c2b339cc73;hpb=4dad971280a07058d01449d5e6db2b036470015d diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 56978dcc..93a62e07 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -362,7 +362,7 @@ static void sleep_milliseconds(unsigned int milliseconds_delay) if (do_busy_waiting) { /* we want to wait only a few ms -- if we assume that we have a - kernel timer resolution of 10 ms, we would wait far to long; + kernel timer resolution of 10 ms, we would wait far too long; therefore it's better to do a short interval of busy waiting to get our sleeping time more accurate */ @@ -411,9 +411,10 @@ boolean DelayReached(unsigned int *counter_var, return TRUE; } -void WaitUntilDelayReached(unsigned int *counter_var, unsigned int delay) +int WaitUntilDelayReached(unsigned int *counter_var, unsigned int delay) { unsigned int actual_counter; + int skip_frames = 0; while (1) { @@ -426,7 +427,55 @@ void WaitUntilDelayReached(unsigned int *counter_var, unsigned int delay) break; } + if (*counter_var != 0 && + delay != 0 && + actual_counter >= *counter_var + delay) + { + int lag = actual_counter - (*counter_var + delay); + int delay2 = (delay + 1) / 2; + + if (lag >= delay2) + skip_frames = (lag + delay2) / delay; + } + *counter_var = actual_counter; + + return skip_frames; +} + +void SkipUntilDelayReached(unsigned int *counter_var, unsigned int delay, + int *loop_var, int last_loop_value) +{ + int skip_frames = WaitUntilDelayReached(counter_var, delay); + +#if 0 +#if DEBUG + printf("::: %d: %d ms", *loop_var, delay); + if (skip_frames) + printf(" -> SKIP %d FRAME(S) [%d ms]", skip_frames, skip_frames * delay); + printf("\n"); +#endif +#endif + + if (skip_frames == 0) + return; + + // when skipping frames, make sure to never skip the last frame, as + // this may be needed for animations to reach a defined end state; + // furthermore, we assume that this function is called at the end + // of a "for" loop, which continues by incrementing the loop variable + // by one before checking the loop condition again; therefore we have + // to check against the last loop value minus one here + + last_loop_value--; + + if (*loop_var < last_loop_value) // never skip the last frame + { + *loop_var += skip_frames; + + if (*loop_var > last_loop_value) // never skip the last frame + *loop_var = last_loop_value; + } } @@ -605,6 +654,23 @@ char *getBaseName(char *filename) return getStringCopy(getBaseNamePtr(filename)); } +char *getBaseNameNoSuffix(char *filename) +{ + char *basename = getStringCopy(getBaseNamePtr(filename)); + + // remove trailing suffix (separated by dot or hyphen) + if (basename[0] != '.' && basename[0] != '-') + { + if (strchr(basename, '.') != NULL) + *strchr(basename, '.') = '\0'; + + if (strchr(basename, '-') != NULL) + *strchr(basename, '-') = '\0'; + } + + return basename; +} + char *getBasePath(char *filename) { char *basepath = getStringCopy(filename); @@ -876,13 +942,18 @@ boolean strSuffixLower(char *s, char *suffix) /* command line option handling functions */ /* ------------------------------------------------------------------------- */ -void GetOptions(char *argv[], +void GetOptions(int argc, char *argv[], void (*print_usage_function)(void), void (*print_version_function)(void)) { char *ro_base_path = RO_BASE_PATH; char *rw_base_path = RW_BASE_PATH; - char **options_left = &argv[1]; + char **argvplus = checked_calloc((argc + 1) * sizeof(char **)); + char **options_left = &argvplus[1]; + + /* replace original "argv" with null-terminated array of string pointers */ + while (argc--) + argvplus[argc] = argv[argc]; /* if the program is configured to start from current directory (default), determine program package directory from program binary (some versions @@ -1068,6 +1139,12 @@ void GetOptions(char *argv[], /* when doing batch processing, always enable verbose mode (warnings) */ options.verbose = TRUE; } +#if defined(PLATFORM_MACOSX) + else if (strPrefix(option, "-psn")) + { + /* ignore process serial number when launched via GUI on Mac OS X */ + } +#endif else if (*option == '-') { Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str); @@ -1257,7 +1334,7 @@ void clear_mem(void *ptr, unsigned int size) /* various helper functions */ /* ------------------------------------------------------------------------- */ -inline void swap_numbers(int *i1, int *i2) +void swap_numbers(int *i1, int *i2) { int help = *i1; @@ -1265,7 +1342,7 @@ inline void swap_numbers(int *i1, int *i2) *i2 = help; } -inline void swap_number_pairs(int *x1, int *y1, int *x2, int *y2) +void swap_number_pairs(int *x1, int *y1, int *x2, int *y2) { int help_x = *x1; int help_y = *y1; @@ -2351,7 +2428,7 @@ DirectoryEntry *readDirectory(Directory *dir) dir->dir_entry->is_directory = (stat(dir->dir_entry->filename, &file_status) == 0 && - (file_status.st_mode & S_IFMT) == S_IFDIR); + S_ISDIR(file_status.st_mode)); return dir->dir_entry; } @@ -2378,7 +2455,7 @@ boolean directoryExists(char *dir_name) struct stat file_status; boolean success = (stat(dir_name, &file_status) == 0 && - (file_status.st_mode & S_IFMT) == S_IFDIR); + S_ISDIR(file_status.st_mode)); #if defined(PLATFORM_ANDROID) if (!success)