Emulator Issues #10764
closedWhen using the GC adapter, loading a savestate made with the standard input, then loading one made with the GC adapter before the controller change from the original savestate is detected will break all input
0%
Description
Game Name?
Any Gamecube game (didn't test Wii)
Primarily tested on Twilight Princess but it happened on other games
Game ID? (right click the game in the game list, properties, info tab)
Does not apply
MD5 Hash? (right click the game in the game list, properties, info tab, MD5 Hash: Compute)
Does not apply
What's the problem? Describe what went wrong.
When you load a savestate made using a different control option, there's a short period of time after loading where all inputs wont work. This lasts about half a second.
If you're using the GC adapter, load a savestate made with the standard controller, then in that short period where inputs aren't recognized load a state which was made with the GC adapter, all input will break until you swap controller mode or restart the game.
What steps will reproduce the problem?
Load up a gamecube game with the standard controller as the input
Create a savestate
Quit the game
Load up a gamecube game with the Gamecube adapter for WiiU set
Create a savestate
Load the savestate made with the standard controller, then right after that (within the ~.5 second window of no input) load the savestate made with the gamecube adapter
All input should now be broken
Is the issue present in the latest development version? For future reference, please also write down the version number of the latest development version.
Yes
5.0-6112
Is the issue present in the latest stable version?
Yes
5.0 Stable
What are your PC specifications? (CPU, GPU, Operating System, more)
Windows 10 Fall Creator's Update
i7-6700k
GTX 1080 Ti
Is there anything else that can help developers narrow down the issue? (e.g. logs, screenshots,
configuration files, savefiles, savestates)
I don't know if this could affect it, but I'm using the Mayflash adapter, not the first party one.
Updated by NarryG almost 7 years ago
Update: Alternate method of triggering it
Load up a gamecube game with the Gamecube adapter for WiiU set
Create a savestate
Quit the game
Load up a gamecube game with the standard controller set
Load the savestate made with the GC controller, then within that small period, load the same savestate again
All input will now be broken
Updated by NarryG almost 7 years ago
Update: Alternate method of triggering it
Load up a gamecube game with the Gamecube adapter for WiiU set
Create a savestate
Quit the game
Load up a gamecube game with the standard controller set
Load the savestate made with the GC controller, then within that small period, load the same savestate again
All input will now be broken
This method is both simpler to execute, and more likely to happen to the average user. It's easy to accidentally push the button twice, resulting in broken input.
Updated by NarryG almost 7 years ago
I traced the code and found where the issue stems from. Not quite sure how you'd want this issue fixed so I'm not going to submit a pull request fixing it myself
Here's the important details
si.cpp
Within DoState()
else
{
// 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.
// 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);
}
And then in ChangeDeviceDeterministic
if (GetDeviceType(channel) != device)
{
CoreTiming::ScheduleEvent(0, s_change_device_event, ((u64)channel << 32) | SIDEVICE_NONE);
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_change_device_event,
((u64)channel << 32) | device);
}
This is where the issue lies.
When you call ChangeDeviceDeterministic the first time, it disconnects the currently connected controller. If you then load the state again before it initializes the correct controller, the code in DoState to grab the currently connected controller grabs SIDEVICE_NONE as the controller had previously been disconnected. It then swaps the active controller to SIDEVICE_NONE instead of the correct device.
Updated by Billiard26 almost 6 years ago
- Status changed from Accepted to Fix pending
- Assignee set to Billiard26
Updated by Billiard26 almost 6 years ago
- Status changed from Fix pending to Fixed
- Fixed in set to 5.0-9514