diff --git a/Source/Core/Core/HW/SI.cpp b/Source/Core/Core/HW/SI.cpp index 87db67b9e3..148fc217db 100644 --- a/Source/Core/Core/HW/SI.cpp +++ b/Source/Core/Core/HW/SI.cpp @@ -234,12 +234,12 @@ void DoState(PointerWrap &p) { // If no movie is active, we'll assume the user wants to keep their current devices // instead of the ones they had when the savestate was created. - if (!Movie::IsMovieActive()) - return; - + // But we need to restore the current devices first just in case. + SIDevices original_device = device->GetDeviceType(); std::unique_ptr save_device = SIDevice_Create(type, i); save_device->DoState(p); AddDevice(std::move(save_device)); + ChangeDeviceDeterministic(original_device, i); } } @@ -510,6 +510,16 @@ void ChangeDevice(SIDevices device, int channel) } } +void ChangeDeviceDeterministic(SIDevices device, int channel) +{ + // Called from savestates, so no need to make it thread safe. + if (GetDeviceType(channel) != device) + { + CoreTiming::ScheduleEvent(0, changeDevice, ((u64)channel << 32) | SIDEVICE_NONE); + CoreTiming::ScheduleEvent(500000000, changeDevice, ((u64)channel << 32) | device); + } +} + void UpdateDevices() { // Update inputs at the rate of SI diff --git a/Source/Core/Core/HW/SI.h b/Source/Core/Core/HW/SI.h index e8625b6ffc..f01e7b8fa3 100644 --- a/Source/Core/Core/HW/SI.h +++ b/Source/Core/Core/HW/SI.h @@ -35,6 +35,7 @@ void AddDevice(std::unique_ptr device); void ChangeDeviceCallback(u64 userdata, int cyclesLate); void ChangeDevice(SIDevices device, int channel); +void ChangeDeviceDeterministic(SIDevices device, int channel); SIDevices GetDeviceType(int channel); diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index df97809e16..a1aa0bc562 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 51; // Last changed in PR 3530 +static const u32 STATE_VERSION = 52; // Last changed in PR 3667 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, @@ -184,10 +184,12 @@ static std::string DoState(PointerWrap& p) PowerPC::DoState(p); p.DoMarker("PowerPC"); - HW::DoState(p); - p.DoMarker("HW"); + // CoreTiming needs to be restored before restoring Hardware because + // the controller code might need to schedule an event if the controller has changed. CoreTiming::DoState(p); p.DoMarker("CoreTiming"); + HW::DoState(p); + p.DoMarker("HW"); Movie::DoState(p); p.DoMarker("Movie");