Ryochan7 / DS4Windows

Like those other ds4tools, but sexier
https://ryochan7.github.io/ds4windows-site/
GNU General Public License v3.0
6.99k stars 808 forks source link

[Enhancement] Support Joy-Cons connected via USB-C using the Joy-Con Charging Grip (`HAC-012`) #2739

Closed akemin-dayo closed 1 year ago

akemin-dayo commented 1 year ago

This is a really low-priority enhancement, but it would be nice to see DS4Windows eventually support this feature.

Steam and Chromium (as of this commit) are the only two applications I'm aware of that are able to properly initialise and read input from the Joy-Con Charging Grip.

Any other application that attempts to read the Joy-Con Charging Grip's HID reports (such as XOutput, SDL2, Parsec, etc.) will only receive broken data. (※ Please exercise caution when testing this — it is extremely easy for the controller to very rapidly navigate UIs and press things you do not intend to!)

Ryochan7 commented 1 year ago

Been trying this out with no success. On the rare occasion, I can get one JoyCon to complete the handshake and send input reports. It would be nice to use the Charging Grip like this but I am about ready to give up.

Also ended up trying the Steam Input implementation. The new beta Deck UI update is trash on my system. Extremely unstable. Also, it does not seem like gyro is implemented when the JoyCons are docking in the grip. The profile editor becomes unusable when I try to map anything to the gyro and I have to start a fresh profile to do anything else.

Ryochan7 commented 1 year ago

Haven't entirely given up yet. Something is wrong with the handshake procedure when the JoyCons are docked in the Charging Grip. I have gotten both JoyCons to complete the handshake and send input reports by accident a few times. Never any consistency as to when it will decide to succeed though. Mapping works fine when the JoyCons are actually working. To be fair, it does not seem like Steam Input connects every time either.

Ryochan7 commented 1 year ago

Looks like I finally got the handshake to work consistently. Mapping works in DS4Windows and gyro and other extra JoyCon features work like they do in Bluetooth mode.

Ryochan7 commented 1 year ago

Test branch with the changes. Too bad the poll rate is still limited to 16 ms when connected to the Charging Grip.

https://github.com/Ryochan7/DS4Windows/tree/joycon_grip

akemin-dayo commented 1 year ago

Just built and tested the joycon_grip branch (specifically, commit SHA1 bfa32bde2c6778451bbf524eb879e4c2afcd40c7) — I can confirm that Joy-Cons connected via USB work pretty much about as well as they do over Bluetooth!

The only potentially user-expectation-subverting behaviour I can really comment on is the fact that connecting/removing Joy-Cons while the USB device is still connected results in a completely non-working controller until the USB device is fully disconnected and then reconnected. But this… might just be a limitation of the charging grip itself. (※ I haven't dumped and looked at the USB traffic yet with my OpenVizsla — this is all pure, baseless speculation.)

※ EDIT: Actually, I just noticed another issue. When the controller is in the above state, trying to stop DS4Windows will cause ControlService to get stuck somewhere here (I'll look into debugging this properly sometime later): https://github.com/Ryochan7/DS4Windows/blob/bfa32bde2c6778451bbf524eb879e4c2afcd40c7/DS4Windows/DS4Control/ControlService.cs#L1638-L1691


Aside from that, the only other issues I've noticed are really minor ones that occur with Bluetooth Joy-Cons as well (which I should file as proper issues sometime later):


Too bad the poll rate is still limited to 16 ms when connected to the Charging Grip.

Huh, that is kinda odd. Kinda wonder why — as far as I can tell, the actual Switch/horizonOS will never accept input from the Joy-Con Charging Grip over USB either (it only does this for Pro Controllers).

The most it'll do is pair with the Joy-Cons in the grip, and then attempt to connect to them via Bluetooth. (※ You can test this by disabling Bluetooth via Airplane Mode.)

It's possible that accepting input via the Joy-Con Charging Grip was never meant to be a feature (or was scrapped during development for some reason), hence the strange behaviour.

Ryochan7 commented 1 year ago

EDIT: Actually, I just noticed another issue. When the controller is in the above state, trying to stop DS4Windows will cause ControlService to get stuck somewhere here (I'll look into debugging this properly sometime later):

Got this fixed already. The routine would hang in the StopUpdate method waiting for the JoyCon input thread to exit. That input thread would be stuck waiting for the next report from the HID device. Had to add an explicit IO cancel to make sure Windows stops trying to read from the dead device so the input thread can exit.

Might test it a bit more but I am thinking that JoyCon hotplugging is not going to be an option when using the grip. You would have to disconnect the USB cable from the grip to have DS4Windows disconnect the devices. Haven't looked if the grip sends any form of report when a device is disconnected. This is a small edge case so I am not too worried about it.

UPDATE: Looks like the grip does send a report when a JoyCon is disconnected or reconnected

Ryochan7 commented 1 year ago

Don't think I will take the code much further so I merged it into the master branch. I doubt I will use the functionality myself. I mostly use the JoyCon controllers split with JoyCon R being used for Gyro. I would rather use the Switch Pro for having a single device for emulating an Xbox 360 controller or mapping KB+M controls to sticks.

akemin-dayo commented 1 year ago

Yeah, that's fair — I pretty much only use my DS5 and DS4v2 anyway (as I greatly prefer the ergonomics on those compared to… pretty much anything else ;P)

I just figured it would be nice if DS4Windows also supported Joy-Cons over USB, hence why I created this issue.

In any case, I've tested the latest commit (SHA1 6f0413b883a543b67329f7d40e0821e29367ccf6) and all seems well (pretty much the same as BT Joy-Cons)!