Emulator Issues #12956
openGC adapter uses incorrect controller origin
0%
Description
What's the problem? Describe what went wrong.
A real console sends an "origin" (0x41) SI command when requesting the controller's origin. Currently, Dolphin uses the result of the first "status" command (0x40) as the controller's origin. This causes controllers that expect the origin to be whatever was queried by the origin command to behave differently on Dolphin compared to console.
The current GC adapter code only utilizes a subset of its functionality. It enables polling (write 0x13 to out-endpoint), reads status data (read in-endpoint), and writes rumble data (write 0x11 to out-endpoint). The "origin" functionality (write 0x12 to out-endpoint) should be added. From my testing, in order to use the "origin" command reliably you must first stop polling the controller (write 0x14 to out-endpoint), read the result of that operation, issue the "origin" command (write 0x12 to out-endpoint), read the result, then resume polling (write 0x13 to out-endpoint).
I've tested the adapter and can document the following about its state machine:
When adapter is initially powered on, it does not communicate with the controllers.
- Once a "start polling" (0x13) command is issued, the adapter will send a ID (0x00) SI command to the controllers then repeatedly send the "origin" (0x41) SI command to the controller.
- Once controller status has been read from the adapter (read to in-endpoint) at least one time, the adapter will stop repeatedly sending the "origin" (0x41) SI command and start repeatedly sending the "status" (0x40) SI command.
- (Also worth noting: if a controller is hot-plugged, it is put into the "repeated origin" state until controller status has been read from the adapter, even if a status read has already been issued).
- Once controllers are in the "status" command state, the only way (that I've found) to put them back into the "repeated origin" state is to issue the "hard reset" (write 0x15 to out-endpoint) command to the adapter.
The following should happen instead of the current behavior:
- Put controllers into "repeated origin" state until a game is started.
- Read origins from the adapter's "origin" command instead of the "status" command
Is the issue present in the latest development version? For future reference, please also write down the version number of the latest development version.
5.0-16380
Is the issue present in the latest stable version?
Yes (5.0)
Updated by Billiard26 about 2 years ago
I don't see this "write 0x12 to out-endpoint" in my USB dumps of attaching a Wii-U GC adapter to a Nintendo switch.
All I see is reading of the descriptors and the write of 0x13.
If I remember correctly I tried sending every single 1 byte command to the out-endpoint and only received responses for those that we currently use in dolphin.
Are you testing with the official adapter?
Updated by jeff.a.longo about 2 years ago
Billiard26 wrote:
I don't see this "write 0x12 to out-endpoint" in my USB dumps of attaching a Wii-U GC adapter to a Nintendo switch.
All I see is reading of the descriptors and the write of 0x13.If I remember correctly I tried sending every single 1 byte command to the out-endpoint and only received responses for those that we currently use in dolphin.
Are you testing with the official adapter?
Yes I'm using an official Wii-U GC adapter. I first noticed it documented here with the official adapter: https://gbatemp.net/threads/wii-u-gamecube-adapter-reverse-engineering-cont.388169/
I also wrote up a more thorough article about this here: https://jefflongo.dev/posts/gc-adapter-reverse-engineering/
You could also try using this simple libusb based Python driver I used to test and validate my findings here with your adapter: https://github.com/jefflongo/gcadapter-python/