static void sleep_milliseconds(unsigned int milliseconds_delay)
{
- boolean do_busy_waiting = (milliseconds_delay < 5 ? TRUE : FALSE);
-
- 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;
- therefore it's better to do a short interval of busy waiting
- to get our sleeping time more accurate */
-
- unsigned int base_counter = Counter(), actual_counter = Counter();
-
- while (actual_counter < base_counter + milliseconds_delay &&
- actual_counter >= base_counter)
- actual_counter = Counter();
- }
- else
- {
- SDL_Delay(milliseconds_delay);
- }
+ SDL_Delay(milliseconds_delay);
}
void Delay(unsigned int delay) /* Sleep specified number of milliseconds */
sleep_milliseconds(delay);
}
-boolean FrameReached(unsigned int *frame_counter_var,
- unsigned int frame_delay)
+boolean DelayReachedExt(unsigned int *counter_var, unsigned int delay,
+ unsigned int actual_counter)
{
- unsigned int actual_frame_counter = FrameCounter;
-
- if (actual_frame_counter >= *frame_counter_var &&
- actual_frame_counter < *frame_counter_var + frame_delay)
+ if (actual_counter >= *counter_var &&
+ actual_counter < *counter_var + delay)
return FALSE;
- *frame_counter_var = actual_frame_counter;
+ *counter_var = actual_counter;
return TRUE;
}
-boolean DelayReached(unsigned int *counter_var,
- unsigned int delay)
+boolean FrameReached(unsigned int *frame_counter_var, unsigned int frame_delay)
{
- unsigned int actual_counter = Counter();
+ return DelayReachedExt(frame_counter_var, frame_delay, FrameCounter);
+}
- if (actual_counter >= *counter_var &&
- actual_counter < *counter_var + delay)
- return FALSE;
+boolean DelayReached(unsigned int *counter_var, unsigned int delay)
+{
+ return DelayReachedExt(counter_var, delay, Counter());
+}
- *counter_var = actual_counter;
+void ResetDelayCounterExt(unsigned int *counter_var,
+ unsigned int actual_counter)
+{
+ DelayReachedExt(counter_var, 0, actual_counter);
+}
- return TRUE;
+void ResetFrameCounter(unsigned int *frame_counter_var)
+{
+ FrameReached(frame_counter_var, 0);
}
-void WaitUntilDelayReached(unsigned int *counter_var, unsigned int delay)
+void ResetDelayCounter(unsigned int *counter_var)
+{
+ DelayReached(counter_var, 0);
+}
+
+int WaitUntilDelayReached(unsigned int *counter_var, unsigned int delay)
{
unsigned int actual_counter;
+ int skip_frames = 0;
while (1)
{
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;
+ }
}
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);
/* 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
/* 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);
/* various helper functions */
/* ------------------------------------------------------------------------- */
-inline void swap_numbers(int *i1, int *i2)
+void swap_numbers(int *i1, int *i2)
{
int help = *i1;
*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;
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;
}
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)
strEqual(value, "up") ? MV_UP :
strEqual(value, "down") ? MV_DOWN : MV_NONE);
}
+ else if (strEqual(suffix, ".position"))
+ {
+ result = (strEqual(value, "left") ? POS_LEFT :
+ strEqual(value, "right") ? POS_RIGHT :
+ strEqual(value, "top") ? POS_TOP :
+ strEqual(value, "upper") ? POS_UPPER :
+ strEqual(value, "middle") ? POS_MIDDLE :
+ strEqual(value, "lower") ? POS_LOWER :
+ strEqual(value, "bottom") ? POS_BOTTOM :
+ strEqual(value, "any") ? POS_ANY : POS_UNDEFINED);
+ }
else if (strEqual(suffix, ".align"))
{
result = (strEqual(value, "left") ? ALIGN_LEFT :
string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL :
string_has_parameter(value, "vertical") ? ANIM_VERTICAL :
string_has_parameter(value, "centered") ? ANIM_CENTERED :
+ string_has_parameter(value, "all") ? ANIM_ALL :
ANIM_DEFAULT);
if (string_has_parameter(value, "reverse"))
string_has_parameter(value, "fade") ? FADE_MODE_FADE :
string_has_parameter(value, "crossfade") ? FADE_MODE_CROSSFADE :
string_has_parameter(value, "melt") ? FADE_MODE_MELT :
+ string_has_parameter(value, "curtain") ? FADE_MODE_CURTAIN :
FADE_MODE_DEFAULT);
}
else if (strPrefix(suffix, ".font")) /* (may also be ".font_xyz") */
boolean unknown_tokens_found = FALSE;
boolean undefined_values_found = (hashtable_count(empty_file_hash) != 0);
- if ((setup_file_list = loadSetupFileList(filename)) == NULL)
- Error(ERR_EXIT, "loadSetupFileHash works, but loadSetupFileList fails");
+ /* list may be NULL for empty artwork config files */
+ setup_file_list = loadSetupFileList(filename);
BEGIN_HASH_ITERATION(extra_file_hash, itr)
{