System: Improve rewind behaviour
- Fix crash when rewinding before first state is saved. - Always save a rewind state immediately after normal save state load. - Don't toss the last rewind state when rewinding, that way there is always at least one state to rewind to.
This commit is contained in:
parent
d25cffebd5
commit
29934d62c4
|
@ -2562,7 +2562,13 @@ void System::ClearMemorySaveStates(bool reallocate_resources, bool recycle_textu
|
|||
s_state.memory_save_state_count = 0;
|
||||
|
||||
if (reallocate_resources && !s_state.memory_save_states.empty())
|
||||
AllocateMemoryStates(s_state.memory_save_states.size(), recycle_textures);
|
||||
{
|
||||
if (!AllocateMemoryStates(s_state.memory_save_states.size(), recycle_textures))
|
||||
return;
|
||||
}
|
||||
|
||||
// immediately save a rewind state next frame
|
||||
s_state.rewind_save_counter = (s_state.rewind_save_frequency > 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
void System::FreeMemoryStateStorage(bool release_memory, bool release_textures, bool recycle_textures)
|
||||
|
@ -4962,7 +4968,8 @@ bool System::LoadOneRewindState()
|
|||
if (s_state.memory_save_state_count == 0)
|
||||
return false;
|
||||
|
||||
LoadMemoryState(PopMemoryState(), true);
|
||||
// keep the last state so we can go back to it with smaller frequencies
|
||||
LoadMemoryState((s_state.memory_save_state_count > 1) ? PopMemoryState() : GetFirstMemoryState(), true);
|
||||
|
||||
// back in time, need to reset perf counters
|
||||
GPUThread::RunOnThread(&PerformanceCounters::Reset);
|
||||
|
@ -4977,10 +4984,10 @@ bool System::IsRewinding()
|
|||
|
||||
void System::SetRewinding(bool enabled)
|
||||
{
|
||||
const bool was_enabled = IsRewinding();
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
const bool was_enabled = IsRewinding();
|
||||
|
||||
// Try to rewind at the replay speed, or one per second maximum.
|
||||
const float load_frequency = std::min(g_settings.rewind_save_frequency, 1.0f);
|
||||
s_state.rewind_load_frequency = static_cast<s32>(std::ceil(load_frequency * s_state.video_frame_rate));
|
||||
|
@ -4988,8 +4995,10 @@ void System::SetRewinding(bool enabled)
|
|||
|
||||
if (!was_enabled && s_state.system_executing)
|
||||
{
|
||||
// Drop the save we just created, since we don't want to rewind to where we are.
|
||||
PopMemoryState();
|
||||
// Drop the last save if we just created it, since we don't want to rewind to where we are.
|
||||
if (s_state.rewind_save_counter == s_state.rewind_save_frequency && s_state.memory_save_state_count > 0)
|
||||
PopMemoryState();
|
||||
|
||||
s_state.system_interrupted = true;
|
||||
}
|
||||
}
|
||||
|
@ -4997,6 +5006,15 @@ void System::SetRewinding(bool enabled)
|
|||
{
|
||||
s_state.rewind_load_frequency = -1;
|
||||
s_state.rewind_load_counter = -1;
|
||||
|
||||
if (was_enabled)
|
||||
{
|
||||
// reset perf counters to avoid the spike
|
||||
GPUThread::RunOnThread(&PerformanceCounters::Reset);
|
||||
|
||||
// and wait the full frequency before filling a new rewind slot
|
||||
s_state.rewind_save_counter = s_state.rewind_save_frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5017,6 +5035,10 @@ void System::DoRewind()
|
|||
Host::PumpMessagesOnCPUThread();
|
||||
IdlePollUpdate();
|
||||
|
||||
// get back into it straight away if we're no longer rewinding
|
||||
if (!IsRewinding())
|
||||
return;
|
||||
|
||||
Throttle(Timer::GetCurrentValue(), s_state.next_frame_time);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue