Merge pull request #12828 from jdgleaver/ff-override-runahead-fix

Fix RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE callback when runahead is enabled
This commit is contained in:
Autechre 2021-08-19 17:17:13 +02:00 committed by GitHub
commit 0c0de9f0ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 122 additions and 68 deletions

View File

@ -12223,6 +12223,18 @@ static void command_event_deinit_core(
p_rarch->current_core.retro_deinit(); p_rarch->current_core.retro_deinit();
} }
/* retro_deinit() may call
* RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE
* (i.e. to ensure that fastforwarding is
* disabled on core close)
* > Check for any pending updates */
if (runloop_state.fastmotion_override.pending)
{
runloop_apply_fastmotion_override(p_rarch,
&runloop_state, p_rarch->configuration_settings);
runloop_state.fastmotion_override.pending = false;
}
RARCH_LOG("[Core]: Unloading core symbols..\n"); RARCH_LOG("[Core]: Unloading core symbols..\n");
uninit_libretro_symbols(p_rarch, &p_rarch->current_core); uninit_libretro_symbols(p_rarch, &p_rarch->current_core);
p_rarch->current_core.symbols_inited = false; p_rarch->current_core.symbols_inited = false;
@ -12668,7 +12680,7 @@ static INLINE float retroarch_get_runloop_fastforward_ratio(
runloop_state_t *p_runloop) runloop_state_t *p_runloop)
{ {
struct retro_fastforwarding_override *fastmotion_override = struct retro_fastforwarding_override *fastmotion_override =
&p_runloop->fastmotion_override; &p_runloop->fastmotion_override.current;
return (fastmotion_override->fastforward && (fastmotion_override->ratio >= 0.0f)) ? return (fastmotion_override->fastforward && (fastmotion_override->ratio >= 0.0f)) ?
fastmotion_override->ratio : settings->floats.fastforward_ratio; fastmotion_override->ratio : settings->floats.fastforward_ratio;
@ -13508,14 +13520,21 @@ static void retroarch_fastmotion_override_free(struct rarch_state *p_rarch,
{ {
settings_t *settings = p_rarch->configuration_settings; settings_t *settings = p_rarch->configuration_settings;
float fastforward_ratio = settings->floats.fastforward_ratio; float fastforward_ratio = settings->floats.fastforward_ratio;
bool reset_frame_limit = p_runloop->fastmotion_override.fastforward && bool reset_frame_limit = p_runloop->fastmotion_override.current.fastforward &&
(p_runloop->fastmotion_override.ratio >= 0.0f) && (p_runloop->fastmotion_override.current.ratio >= 0.0f) &&
(p_runloop->fastmotion_override.ratio != fastforward_ratio); (p_runloop->fastmotion_override.current.ratio != fastforward_ratio);
p_runloop->fastmotion_override.ratio = 0.0f; p_runloop->fastmotion_override.current.ratio = 0.0f;
p_runloop->fastmotion_override.fastforward = false; p_runloop->fastmotion_override.current.fastforward = false;
p_runloop->fastmotion_override.notification = false; p_runloop->fastmotion_override.current.notification = false;
p_runloop->fastmotion_override.inhibit_toggle = false; p_runloop->fastmotion_override.current.inhibit_toggle = false;
p_runloop->fastmotion_override.next.ratio = 0.0f;
p_runloop->fastmotion_override.next.fastforward = false;
p_runloop->fastmotion_override.next.notification = false;
p_runloop->fastmotion_override.next.inhibit_toggle = false;
p_runloop->fastmotion_override.pending = false;
if (reset_frame_limit) if (reset_frame_limit)
retroarch_set_frame_limit(p_rarch, fastforward_ratio); retroarch_set_frame_limit(p_rarch, fastforward_ratio);
@ -17928,66 +17947,16 @@ static bool rarch_environment_cb(unsigned cmd, void *data)
struct retro_fastforwarding_override *fastforwarding_override = struct retro_fastforwarding_override *fastforwarding_override =
(struct retro_fastforwarding_override *)data; (struct retro_fastforwarding_override *)data;
/* Record new retro_fastforwarding_override parameters
* and schedule application on the the next call of
* runloop_check_state() */
if (fastforwarding_override) if (fastforwarding_override)
{ {
runloop_state_t *p_runloop = &runloop_state; memcpy(&runloop_state.fastmotion_override.next,
bool frame_time_counter_reset_after_fastforwarding = settings ?
settings->bools.frame_time_counter_reset_after_fastforwarding : false;
float fastforward_ratio_default = settings ?
settings->floats.fastforward_ratio : 0.0f;
float fastforward_ratio_last =
(p_runloop->fastmotion_override.fastforward &&
(p_runloop->fastmotion_override.ratio >= 0.0f)) ?
p_runloop->fastmotion_override.ratio :
fastforward_ratio_default;
float fastforward_ratio_current;
memcpy(&p_runloop->fastmotion_override,
fastforwarding_override, fastforwarding_override,
sizeof(p_runloop->fastmotion_override)); sizeof(runloop_state.fastmotion_override.next));
runloop_state.fastmotion_override.pending = true;
/* Check if 'fastmotion' state has changed */
if (p_runloop->fastmotion !=
p_runloop->fastmotion_override.fastforward)
{
p_runloop->fastmotion =
p_runloop->fastmotion_override.fastforward;
if (p_runloop->fastmotion)
p_rarch->input_driver_nonblock_state = true;
else
{
p_rarch->input_driver_nonblock_state = false;
p_rarch->fastforward_after_frames = 1;
}
driver_set_nonblock_state();
/* Reset frame time counter when toggling
* fast-forward off, if required */
if (!p_runloop->fastmotion &&
frame_time_counter_reset_after_fastforwarding)
p_rarch->video_driver_frame_time_count = 0;
/* Ensure fast forward widget is disabled when
* toggling fast-forward off
* (required if RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE
* is called during core de-initialisation) */
#if defined(HAVE_GFX_WIDGETS)
if (p_rarch->widgets_active && !p_runloop->fastmotion)
p_rarch->gfx_widgets_fast_forward = false;
#endif
}
/* Update frame limit, if required */
fastforward_ratio_current = (p_runloop->fastmotion_override.fastforward &&
(p_runloop->fastmotion_override.ratio >= 0.0f)) ?
p_runloop->fastmotion_override.ratio :
fastforward_ratio_default;
if (fastforward_ratio_current != fastforward_ratio_last)
retroarch_set_frame_limit(p_rarch, fastforward_ratio_current);
} }
break; break;
} }
@ -37213,6 +37182,68 @@ static bool menu_display_libretro(
} }
#endif #endif
static void runloop_apply_fastmotion_override(
struct rarch_state *p_rarch, runloop_state_t *p_runloop,
settings_t *settings)
{
bool frame_time_counter_reset_after_fastforwarding = settings ?
settings->bools.frame_time_counter_reset_after_fastforwarding : false;
float fastforward_ratio_default = settings ?
settings->floats.fastforward_ratio : 0.0f;
float fastforward_ratio_last =
(p_runloop->fastmotion_override.current.fastforward &&
(p_runloop->fastmotion_override.current.ratio >= 0.0f)) ?
p_runloop->fastmotion_override.current.ratio :
fastforward_ratio_default;
float fastforward_ratio_current;
memcpy(&p_runloop->fastmotion_override.current,
&p_runloop->fastmotion_override.next,
sizeof(p_runloop->fastmotion_override.current));
/* Check if 'fastmotion' state has changed */
if (p_runloop->fastmotion !=
p_runloop->fastmotion_override.current.fastforward)
{
p_runloop->fastmotion =
p_runloop->fastmotion_override.current.fastforward;
if (p_runloop->fastmotion)
p_rarch->input_driver_nonblock_state = true;
else
{
p_rarch->input_driver_nonblock_state = false;
p_rarch->fastforward_after_frames = 1;
}
driver_set_nonblock_state();
/* Reset frame time counter when toggling
* fast-forward off, if required */
if (!p_runloop->fastmotion &&
frame_time_counter_reset_after_fastforwarding)
p_rarch->video_driver_frame_time_count = 0;
/* Ensure fast forward widget is disabled when
* toggling fast-forward off
* (required if RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE
* is called during core de-initialisation) */
#if defined(HAVE_GFX_WIDGETS)
if (p_rarch->widgets_active && !p_runloop->fastmotion)
p_rarch->gfx_widgets_fast_forward = false;
#endif
}
/* Update frame limit, if required */
fastforward_ratio_current = (p_runloop->fastmotion_override.current.fastforward &&
(p_runloop->fastmotion_override.current.ratio >= 0.0f)) ?
p_runloop->fastmotion_override.current.ratio :
fastforward_ratio_default;
if (fastforward_ratio_current != fastforward_ratio_last)
retroarch_set_frame_limit(p_rarch, fastforward_ratio_current);
}
static enum runloop_state runloop_check_state( static enum runloop_state runloop_check_state(
struct rarch_state *p_rarch, struct rarch_state *p_rarch,
settings_t *settings, settings_t *settings,
@ -38130,12 +38161,21 @@ static enum runloop_state runloop_check_state(
return RUNLOOP_STATE_POLLED_AND_SLEEP; return RUNLOOP_STATE_POLLED_AND_SLEEP;
} }
/* Apply any pending fastmotion override
* parameters */
if (runloop_state.fastmotion_override.pending)
{
runloop_apply_fastmotion_override(
p_rarch, &runloop_state, settings);
runloop_state.fastmotion_override.pending = false;
}
/* Check if we have pressed the fast forward button */ /* Check if we have pressed the fast forward button */
/* To avoid continuous switching if we hold the button down, we require /* To avoid continuous switching if we hold the button down, we require
* that the button must go from pressed to unpressed back to pressed * that the button must go from pressed to unpressed back to pressed
* to be able to toggle between them. * to be able to toggle between them.
*/ */
if (!runloop_state.fastmotion_override.inhibit_toggle) if (!runloop_state.fastmotion_override.current.inhibit_toggle)
{ {
static bool old_button_state = false; static bool old_button_state = false;
static bool old_hold_button_state = false; static bool old_hold_button_state = false;
@ -38155,6 +38195,7 @@ static enum runloop_state runloop_check_state(
runloop_state.fastmotion = !check1; runloop_state.fastmotion = !check1;
if (check1) if (check1)
p_rarch->fastforward_after_frames = 1; p_rarch->fastforward_after_frames = 1;
driver_set_nonblock_state(); driver_set_nonblock_state();
/* Reset frame time counter when toggling /* Reset frame time counter when toggling
@ -38170,8 +38211,8 @@ static enum runloop_state runloop_check_state(
/* Display fast-forward notification, unless /* Display fast-forward notification, unless
* disabled via override */ * disabled via override */
if (!runloop_state.fastmotion_override.fastforward || if (!runloop_state.fastmotion_override.current.fastforward ||
runloop_state.fastmotion_override.notification) runloop_state.fastmotion_override.current.notification)
{ {
/* > Use widgets, if enabled */ /* > Use widgets, if enabled */
#if defined(HAVE_GFX_WIDGETS) #if defined(HAVE_GFX_WIDGETS)

View File

@ -1682,6 +1682,16 @@ typedef struct core_options_callbacks
retro_core_options_update_display_callback_t update_display; retro_core_options_update_display_callback_t update_display;
} core_options_callbacks_t; } core_options_callbacks_t;
/* Contains the current retro_fastforwarding_override
* parameters along with any pending updates triggered
* by RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE */
typedef struct fastmotion_overrides
{
struct retro_fastforwarding_override current;
struct retro_fastforwarding_override next;
bool pending;
} fastmotion_overrides_t;
struct runloop struct runloop
{ {
retro_usec_t frame_time_last; /* int64_t alignment */ retro_usec_t frame_time_last; /* int64_t alignment */
@ -1705,7 +1715,7 @@ struct runloop
unsigned max_frames; unsigned max_frames;
unsigned audio_latency; unsigned audio_latency;
struct retro_fastforwarding_override fastmotion_override; /* float alignment */ fastmotion_overrides_t fastmotion_override; /* float alignment */
bool missing_bios; bool missing_bios;
bool force_nonblock; bool force_nonblock;

View File

@ -70,6 +70,9 @@ static void retro_frame_null(const void *data, unsigned width,
unsigned height, size_t pitch); unsigned height, size_t pitch);
static void retro_run_null(void); static void retro_run_null(void);
static void retro_input_poll_null(void); static void retro_input_poll_null(void);
static void runloop_apply_fastmotion_override(
struct rarch_state *p_rarch, runloop_state_t *p_runloop,
settings_t *settings);
static uint64_t input_driver_get_capabilities(void); static uint64_t input_driver_get_capabilities(void);