From 9e4cee5b307a1be1664d77c5ea999d2bfd19cc35 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 7 Aug 2013 22:24:12 +0200 Subject: [PATCH] Add support for fast forward frame limiting. --- config.def.h | 3 +++ general.h | 7 +++++++ retroarch.c | 20 ++++++++++++++++++++ retroarch.cfg | 6 ++++++ settings.c | 3 +++ 5 files changed, 39 insertions(+) diff --git a/config.def.h b/config.def.h index 6dcc5238b5..a677cc2778 100644 --- a/config.def.h +++ b/config.def.h @@ -381,6 +381,9 @@ static const bool savestate_auto_load = true; // Slowmotion ratio. static const float slowmotion_ratio = 3.0; +// Maximum fast forward ratio (Negative => no limit). +static const float fastforward_ratio = -1.0; + // Enable stdin/network command interface static const bool network_cmd_enable = false; static const uint16_t network_cmd_port = 55355; diff --git a/general.h b/general.h index 976cd0bd28..ca07012988 100644 --- a/general.h +++ b/general.h @@ -264,6 +264,7 @@ struct settings unsigned rewind_granularity; float slowmotion_ratio; + float fastforward_ratio; bool pause_nonactive; unsigned autosave_interval; @@ -367,6 +368,12 @@ struct global unsigned state_slot; + struct + { + rarch_time_t minimum_frame_time; + rarch_time_t last_frame_time; + } frame_limit; + struct { struct retro_system_info info; diff --git a/retroarch.c b/retroarch.c index ec66560d50..8c1ceed1cd 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2819,6 +2819,8 @@ void rarch_init_system_info(void) static void init_system_av_info(void) { pretro_get_system_av_info(&g_extern.system.av_info); + g_extern.frame_limit.last_frame_time = rarch_get_time_usec(); + g_extern.frame_limit.minimum_frame_time = (rarch_time_t)roundf(1000000.0f / (g_extern.system.av_info.timing.fps * g_settings.fastforward_ratio)); } static void verify_api_version(void) @@ -3021,6 +3023,23 @@ static inline void update_frame_time(void) g_extern.system.frame_time.callback(delta); } +static inline void limit_frame_time(void) +{ + if (g_settings.fastforward_ratio < 0.0f) + return; + + rarch_time_t current = rarch_get_time_usec(); + rarch_time_t target = g_extern.frame_limit.last_frame_time + g_extern.frame_limit.minimum_frame_time; + rarch_time_t to_sleep_ms = (target - current) / 1000; + if (to_sleep_ms > 0) + { + rarch_sleep(to_sleep_ms); + g_extern.frame_limit.last_frame_time += g_extern.frame_limit.minimum_frame_time; // Combat jitter a bit. + } + else + g_extern.frame_limit.last_frame_time = rarch_get_time_usec(); +} + bool rarch_main_iterate(void) { #ifdef HAVE_DYLIB @@ -3065,6 +3084,7 @@ bool rarch_main_iterate(void) update_frame_time(); pretro_run(); + limit_frame_time(); #ifdef HAVE_BSV_MOVIE if (g_extern.bsv.movie) diff --git a/retroarch.cfg b/retroarch.cfg index f25c051cff..0e09db086e 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -461,6 +461,12 @@ # Slowmotion ratio. When slowmotion, game will slow down by factor. # slowmotion_ratio = 3.0 +# The maximum rate at which games will be run when using fast forward. (E.g. 5.0 for 60 fps game => 300 fps cap). +# RetroArch will go to sleep to ensure that the maximum rate will not be exceeded. +# Do not rely on this cap to be perfectly accurate. +# A negative ratio equals no FPS cap. +# fastforward_ratio = -1.0 + # Enable stdin/network command interface. # network_cmd_enable = false # network_cmd_port = 55355 diff --git a/settings.c b/settings.c index 9280e6cfce..4cfc84e2da 100644 --- a/settings.c +++ b/settings.c @@ -209,6 +209,7 @@ void config_set_defaults(void) g_settings.rewind_buffer_size = rewind_buffer_size; g_settings.rewind_granularity = rewind_granularity; g_settings.slowmotion_ratio = slowmotion_ratio; + g_settings.fastforward_ratio = fastforward_ratio; g_settings.pause_nonactive = pause_nonactive; g_settings.autosave_interval = autosave_interval; @@ -678,6 +679,8 @@ bool config_load_file(const char *path) if (g_settings.slowmotion_ratio < 1.0f) g_settings.slowmotion_ratio = 1.0f; + CONFIG_GET_FLOAT(fastforward_ratio, "fastforward_ratio"); + CONFIG_GET_BOOL(pause_nonactive, "pause_nonactive"); CONFIG_GET_INT(autosave_interval, "autosave_interval");