Fix savestates if a device is changed after a savestate is made

This commit is contained in:
Chris Burgener 2016-02-23 20:04:18 -05:00
parent 6513062144
commit 7991605ad9
3 changed files with 19 additions and 6 deletions

View File

@ -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<ISIDevice> 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

View File

@ -35,6 +35,7 @@ void AddDevice(std::unique_ptr<ISIDevice> device);
void ChangeDeviceCallback(u64 userdata, int cyclesLate);
void ChangeDevice(SIDevices device, int channel);
void ChangeDeviceDeterministic(SIDevices device, int channel);
SIDevices GetDeviceType(int channel);

View File

@ -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");