diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 32b732e6d2c4..69d9772556ad 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -5674,7 +5674,7 @@ enum retro_savestate_context * therefore, internal pointers to code or data are acceptable. * May still be loaded or saved at any time. * - * @note This context generally implies the use of runahead or rewinding, + * @note This context generally implies the use of runahead, * which may work by taking savestates multiple times per second. * Savestate code that runs in this context should be fast. */ @@ -5706,6 +5706,10 @@ enum retro_savestate_context */ RETRO_SAVESTATE_CONTEXT_ROLLBACK_NETPLAY = 3, + /** + * Same as \c RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_INSTANCE, but for rewinding. + */ + RETRO_SAVESTATE_CONTEXT_REWIND_SAME_INSTANCE = 4, /** * @private Defined to ensure sizeof(retro_savestate_context) == sizeof(int). * Do not use. diff --git a/runloop.c b/runloop.c index fcdc7862cc61..d51139f22e0d 100644 --- a/runloop.c +++ b/runloop.c @@ -3150,29 +3150,37 @@ bool runloop_environment_cb(unsigned cmd, void *data) { int result = RETRO_SAVESTATE_CONTEXT_NORMAL; -#if defined(HAVE_RUNAHEAD) || defined(HAVE_NETWORKING) - if (runloop_st->flags & RUNLOOP_FLAG_REQUEST_SPECIAL_SAVESTATE) +#ifdef HAVE_REWIND + if (runloop_st->rewind_st.flags & + STATE_MGR_REWIND_ST_FLAG_IS_REWIND_SERIALIZE) + result = RETRO_SAVESTATE_CONTEXT_REWIND_SAME_INSTANCE; + else +#endif { +#if defined(HAVE_RUNAHEAD) || defined(HAVE_NETWORKING) + if (runloop_st->flags & RUNLOOP_FLAG_REQUEST_SPECIAL_SAVESTATE) + { #ifdef HAVE_NETWORKING - if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL)) - result = RETRO_SAVESTATE_CONTEXT_ROLLBACK_NETPLAY; - else + if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL)) + result = RETRO_SAVESTATE_CONTEXT_ROLLBACK_NETPLAY; + else #endif - { + { #ifdef HAVE_RUNAHEAD #if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB) - settings_t *settings = config_get_ptr(); - if ( settings->bools.run_ahead_secondary_instance - && (runloop_st->flags & RUNLOOP_FLAG_RUNAHEAD_SECONDARY_CORE_AVAILABLE) - && secondary_core_ensure_exists(runloop_st, settings)) - result = RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_BINARY; - else + settings_t *settings = config_get_ptr(); + if ( settings->bools.run_ahead_secondary_instance + && (runloop_st->flags & RUNLOOP_FLAG_RUNAHEAD_SECONDARY_CORE_AVAILABLE) + && secondary_core_ensure_exists(runloop_st, settings)) + result = RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_BINARY; + else #endif result = RETRO_SAVESTATE_CONTEXT_RUNAHEAD_SAME_INSTANCE; #endif + } } - } #endif + } if (data) *(int*)data = result; diff --git a/state_manager.c b/state_manager.c index ce84f91d20fa..6724122b7251 100644 --- a/state_manager.c +++ b/state_manager.c @@ -606,7 +606,9 @@ void state_manager_event_init( state_manager_push_where(rewind_st->state, &state); + rewind_st->flags |= STATE_MGR_REWIND_ST_FLAG_IS_REWIND_SERIALIZE; content_serialize_state_rewind(state, rewind_st->size); + rewind_st->flags &= ~STATE_MGR_REWIND_ST_FLAG_IS_REWIND_SERIALIZE; state_manager_push_do(rewind_st->state); } @@ -783,7 +785,9 @@ bool state_manager_check_rewind( void *state = NULL; state_manager_push_where(rewind_st->state, &state); + rewind_st->flags |= STATE_MGR_REWIND_ST_FLAG_IS_REWIND_SERIALIZE; content_serialize_state_rewind(state, rewind_st->size); + rewind_st->flags &= ~STATE_MGR_REWIND_ST_FLAG_IS_REWIND_SERIALIZE; state_manager_push_do(rewind_st->state); } diff --git a/state_manager.h b/state_manager.h index ac1408384323..d7193c169d59 100644 --- a/state_manager.h +++ b/state_manager.h @@ -33,7 +33,8 @@ enum state_manager_rewind_st_flags STATE_MGR_REWIND_ST_FLAG_FRAME_IS_REVERSED = (1 << 0), STATE_MGR_REWIND_ST_FLAG_INIT_ATTEMPTED = (1 << 1), STATE_MGR_REWIND_ST_FLAG_HOTKEY_WAS_CHECKED = (1 << 2), - STATE_MGR_REWIND_ST_FLAG_HOTKEY_WAS_PRESSED = (1 << 3) + STATE_MGR_REWIND_ST_FLAG_HOTKEY_WAS_PRESSED = (1 << 3), + STATE_MGR_REWIND_ST_FLAG_IS_REWIND_SERIALIZE = (1 << 4) }; struct state_manager