diff --git a/core.h b/core.h index 0925c7542b..9aba12461c 100644 --- a/core.h +++ b/core.h @@ -27,10 +27,6 @@ RETRO_BEGIN_DECLS -#ifdef HAVE_REWIND -bool core_set_rewind_callbacks(void); -#endif - #ifdef HAVE_NETWORKING bool core_set_netplay_callbacks(void); diff --git a/retroarch.c b/retroarch.c index 4d0403c5a1..6fbe928e46 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2017,7 +2017,8 @@ bool command_event(enum event_command cmd, void *data) if (core_type_is_dummy) return false; - state_manager_event_deinit(&runloop_st->rewind_st); + state_manager_event_deinit(&runloop_st->rewind_st, + &runloop_st->current_core); } #endif break; @@ -2779,7 +2780,8 @@ bool command_event(enum event_command cmd, void *data) /* Disable rewind & SRAM autosave if it was enabled * TODO/FIXME: Add a setting for these tweaks */ #ifdef HAVE_REWIND - state_manager_event_deinit(&runloop_st->rewind_st); + state_manager_event_deinit(&runloop_st->rewind_st, + &runloop_st->current_core); #endif #ifdef HAVE_THREADS autosave_deinit(); @@ -2815,7 +2817,8 @@ bool command_event(enum event_command cmd, void *data) /* Disable rewind if it was enabled TODO/FIXME: Add a setting for these tweaks */ #ifdef HAVE_REWIND - state_manager_event_deinit(&runloop_st->rewind_st); + state_manager_event_deinit(&runloop_st->rewind_st, + &runloop_st->current_core); #endif #ifdef HAVE_THREADS autosave_deinit(); @@ -2851,7 +2854,8 @@ bool command_event(enum event_command cmd, void *data) /* Disable rewind if it was enabled * TODO/FIXME: Add a setting for these tweaks */ #ifdef HAVE_REWIND - state_manager_event_deinit(&runloop_st->rewind_st); + state_manager_event_deinit(&runloop_st->rewind_st, + &runloop_st->current_core); #endif #ifdef HAVE_THREADS autosave_deinit(); diff --git a/runloop.c b/runloop.c index ae995180b2..bfc23f1819 100644 --- a/runloop.c +++ b/runloop.c @@ -7187,6 +7187,7 @@ static enum runloop_state_enum runloop_check_state( rewinding = state_manager_check_rewind( &runloop_st->rewind_st, + &runloop_st->current_core, BIT256_GET(current_bits, RARCH_REWIND), settings->uints.rewind_granularity, runloop_st->paused, @@ -7971,33 +7972,6 @@ bool core_set_default_callbacks(void *data) return true; } -#ifdef HAVE_REWIND -/** - * core_set_rewind_callbacks: - * - * Sets the audio sampling callbacks based on whether or not - * rewinding is currently activated. - **/ -bool core_set_rewind_callbacks(void) -{ - runloop_state_t *runloop_st = &runloop_state; - struct state_manager_rewind_state - *rewind_st = &runloop_st->rewind_st; - - if (rewind_st->frame_is_reversed) - { - runloop_st->current_core.retro_set_audio_sample(audio_driver_sample_rewind); - runloop_st->current_core.retro_set_audio_sample_batch(audio_driver_sample_batch_rewind); - } - else - { - runloop_st->current_core.retro_set_audio_sample(audio_driver_sample); - runloop_st->current_core.retro_set_audio_sample_batch(audio_driver_sample_batch); - } - return true; -} -#endif - #ifdef HAVE_NETWORKING /** * core_set_netplay_callbacks: diff --git a/state_manager.c b/state_manager.c index d11e9e2a2e..fdf9f2da1e 100644 --- a/state_manager.c +++ b/state_manager.c @@ -584,9 +584,17 @@ void state_manager_event_init( core_info_t *core_info = NULL; void *state = NULL; - if (!rewind_st || rewind_st->state) + if (!rewind_st || + rewind_st->init_attempted || + rewind_st->state) return; + rewind_st->size = 0; + rewind_st->frame_is_reversed = false; + rewind_st->init_attempted = true; + rewind_st->hotkey_was_checked = false; + rewind_st->hotkey_was_pressed = false; + /* We cannot initialise the rewind buffer * unless the core info struct for the current * core has been initialised (i.e. without this, @@ -603,7 +611,7 @@ void state_manager_event_init( if (audio_driver_has_callback()) { - RARCH_ERR("%s.\n", msg_hash_to_str(MSG_REWIND_INIT_FAILED)); + RARCH_ERR("%s.\n", msg_hash_to_str(MSG_REWIND_INIT_FAILED_THREADED_AUDIO)); return; } @@ -612,7 +620,7 @@ void state_manager_event_init( if (!rewind_st->size) { RARCH_ERR("%s.\n", - msg_hash_to_str(MSG_REWIND_INIT_FAILED_THREADED_AUDIO)); + msg_hash_to_str(MSG_REWIND_INIT_FAILED)); return; } @@ -634,18 +642,41 @@ void state_manager_event_init( } void state_manager_event_deinit( - struct state_manager_rewind_state *rewind_st) + struct state_manager_rewind_state *rewind_st, + struct retro_core_t *current_core) { + bool restore_callbacks = false; + if (!rewind_st) return; + restore_callbacks = rewind_st->init_attempted && + rewind_st->state && + current_core; + if (rewind_st->state) { state_manager_free(rewind_st->state); free(rewind_st->state); } - rewind_st->state = NULL; - rewind_st->size = 0; + + rewind_st->state = NULL; + rewind_st->size = 0; + rewind_st->frame_is_reversed = false; + rewind_st->init_attempted = false; + rewind_st->hotkey_was_checked = false; + rewind_st->hotkey_was_pressed = false; + + /* Restore regular (non-rewind) core audio + * callbacks if required */ + if (restore_callbacks) + { + if (current_core->retro_set_audio_sample) + current_core->retro_set_audio_sample(audio_driver_sample); + + if (current_core->retro_set_audio_sample_batch) + current_core->retro_set_audio_sample_batch(audio_driver_sample_batch); + } } /** @@ -656,20 +687,38 @@ void state_manager_event_deinit( **/ bool state_manager_check_rewind( struct state_manager_rewind_state *rewind_st, + struct retro_core_t *current_core, bool pressed, unsigned rewind_granularity, bool is_paused, char *s, size_t len, unsigned *time) { - bool ret = false; - static bool first = true; - static bool was_pressed = false; + bool ret = false; #ifdef HAVE_NETWORKING - bool was_reversed = false; + bool was_reversed = false; #endif - if (!rewind_st) + if (!rewind_st || + !rewind_st->init_attempted) return false; + if (!rewind_st->hotkey_was_checked) + { + rewind_st->hotkey_was_checked = true; + return false; + } + + if (!rewind_st->state) + { + if ((pressed && !rewind_st->hotkey_was_pressed) && + !core_info_current_supports_rewind()) + runloop_msg_queue_push(msg_hash_to_str(MSG_REWIND_UNSUPPORTED), + 1, 100, false, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + + rewind_st->hotkey_was_pressed = pressed; + return false; + } + if (rewind_st->frame_is_reversed) { #ifdef HAVE_NETWORKING @@ -679,24 +728,6 @@ bool state_manager_check_rewind( rewind_st->frame_is_reversed = false; } - if (first) - { - first = false; - return false; - } - - if (!rewind_st->state) - { - if ((pressed && !was_pressed) && - !core_info_current_supports_rewind()) - runloop_msg_queue_push(msg_hash_to_str(MSG_REWIND_UNSUPPORTED), - 1, 100, false, NULL, - MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - - was_pressed = pressed; - return false; - } - if (pressed) { const void *buf = NULL; @@ -767,8 +798,18 @@ bool state_manager_check_rewind( } } - core_set_rewind_callbacks(); + /* Update core audio callbacks */ + if (current_core) + { + if (current_core->retro_set_audio_sample) + current_core->retro_set_audio_sample(rewind_st->frame_is_reversed ? + audio_driver_sample_rewind : audio_driver_sample); - was_pressed = pressed; + if (current_core->retro_set_audio_sample_batch) + current_core->retro_set_audio_sample_batch(rewind_st->frame_is_reversed ? + audio_driver_sample_batch_rewind : audio_driver_sample_batch); + } + + rewind_st->hotkey_was_pressed = pressed; return ret; } diff --git a/state_manager.h b/state_manager.h index 94104babe7..cba9f4c248 100644 --- a/state_manager.h +++ b/state_manager.h @@ -24,6 +24,8 @@ #include #include +#include "dynamic.h" + RETRO_BEGIN_DECLS struct state_manager @@ -61,12 +63,16 @@ struct state_manager_rewind_state state_manager_t *state; size_t size; bool frame_is_reversed; + bool init_attempted; + bool hotkey_was_checked; + bool hotkey_was_pressed; }; bool state_manager_frame_is_reversed(void); void state_manager_event_deinit( - struct state_manager_rewind_state *rewind_st); + struct state_manager_rewind_state *rewind_st, + struct retro_core_t *current_core); void state_manager_event_init(struct state_manager_rewind_state *rewind_st, unsigned rewind_buffer_size); @@ -79,6 +85,7 @@ void state_manager_event_init(struct state_manager_rewind_state *rewind_st, **/ bool state_manager_check_rewind( struct state_manager_rewind_state *rewind_st, + struct retro_core_t *current_core, bool pressed, unsigned rewind_granularity, bool is_paused, char *s, size_t len, unsigned *time);