atar-axis / xpadneo

Advanced Linux Driver for Xbox One Wireless Controller (shipped with Xbox One S)
https://atar-axis.github.io/xpadneo/
GNU General Public License v3.0
1.86k stars 110 forks source link

Steam deck support (haptics) #478

Open blazini36 opened 1 week ago

blazini36 commented 1 week ago

Version of xpadneo

Controller Model

Steamdeck

Connection mode

internal

Describe your feature request

support for Steamdeck controller haptics

Additional context This is mostly just a feeler to see if I can get some info. I've been using xpadneo for a long time and it's the best xbox-type driver for Linux and I was really impressed by the Guilikit support. Some people have been discussing the haptics of the steam deck on Discord, including the addition of Switch Joycon haptics motors which people have done but it gets odd as the stock actuators are there there to give the trackpads some minor haptics as well. There are probably multiple things that can be done there but first question is, is it even reasonable to assume that something like xpadneo can work in a steam deck with it's multiple different interfaces? I have no idea how a deck works software wise as opposed to a normal controller, just figured this would be a good question to ask here.

kakra commented 1 week ago

I'm not sure what the question is.

Do you intent to use xpadneo for the built-in deck controls? That doesn't make a lot of sense...

Do you ask if - whatever Steam does to create these "haptics" - we could use this for xpadneo, too, to create haptics, e.g., for the triggers?

In the latter case: In theory it could be possible if we know the interface, and if Steam actually sends such data to non-deck controls. But in practice, I'm pretty sure that these haptics are just synthesized from input data and influenced by some settings. I think the Steam Deck (I own one myself) also uses the haptic vibrators to intensify some sounds (especially bass), but rumble can only roughly be emulated using haptics. In the end, haptic vibrators are just speakers without a cone.

For xpadneo, I'm actually planning to implement a haptic mode because the rumble engine can be used to emulate haptic feedback (and only genuine Xbox models, most other third-party controllers do not support the haptic parameters). Since rumble motors are rotating vibrators (and thus don't work like speakers without a cone), this emulation can only do impulses and short slight vibration bursts before they begin to shake the whole device.

blazini36 commented 1 week ago

Well I suppose the question is can xpadneo do anything for the steam deck haptics without interfering with the stock controls?

You're right in that it doesn't make much sense to use xpadneo for the controller inputs, they are fine.

The Deck has only the 2 haptic transducers under the trackpads, these also function for in-game "rumble". You mentioned that these are basically just acting off the sound and not whatever "rumble" signal games typically use? I think that's where I'm looking to explore. People are talking about using hardware mods to get actual rumble into the deck and I suppose that's where I'm looking at xpadneo for support, but I don't know how it works in a typical controller.

For example a you can hijack the I2C bus and get whatever rumble commands independent of the haptics transducers. That would require some type of driver as I'm not sure of that works on the Linux side. I've been looking at using a DRV2605 which is a haptic motor controller IC for this. The interesting thing about this chip is that it has an audio mode where it uses a low pass filter to turn sub 200hz audio into PWM for a vibration motor. The signals going to the touchpad transducers are AC audio signals already, it seems that the touch haptics are somewhat in the range of ~380hz while some in-game rumble signals were about 150hz. If that is more or less always the case the chip will ignore the touch haptics and only work with slower rumble signals which is perfect. I mention this because that chip also has a mode where the vibration can be streamed over I2C, as well as play "pre-recorded" vibration samples.

So the point is this chip (and some extra motors) may find it's way into some decks and work in audio mode without any software mods. If there is software support the chip will work more deliberately for in-game vibration as a normal controller would. Obviously nobody wants to add software support for something 5 people are using so the idea is it can work as is then work better with some software support. Main reason I guess I posted this was to get some guidance on how software control over extra motors could work in the above scenario and if it's something that could come from xpadneo.

kakra commented 1 week ago

You mentioned that these are basically just acting off the sound and not whatever "rumble" signal games typically use?

No, not exactly. I just said that it feels like these haptic actuators are fed by sound additionally to input and game rumble commands. That way, you can feel the "bass" of the sound that the sound speakers actually cannot provide on their own, I think. OTOH, I've never opened my Deck to see how it works internally.

What you're probably looking for is a pure rumble driver which attaches to the existing input controls of the Deck. I'm not sure if this can be done in kernel, it provides a lot of hooks but probably nothing to intercept rumble commands.

The next best thing may be to implement that in user-space: a library could hook into the SDL functions for rumble. This can be easily done by preloading a stub lib with LD_PRELOAD and hijacking the SDL function, modify or read whatever the game sends, and then call into the original SDL function. But be careful: anti-cheat systems may detect that and ban you from online games. That said, SDL already works in a similar way by dynamically loading more current SDL versions if a game ships with an older version. This also means that it already has a very stable API and hooking infrastructure.

If you use such a lib to intercept device detection (to know which input device you want to handle), and then hook into the rumble API calls, you can stop the original rumble command and send your own instead directly to the Deck hardware, or some other hardware you stick into that.

xpadneo doesn't help you much here: it really does nothing special with rumble, we just pass it over to the ff_memless driver which does sine/square/sawtooth wave emulation for us. Actually, I'm going to remove that because I don't see any games using such fancy effects, plain FF_RUMBLE should be enough. This removes a pretty bad interaction because ff_memless works with 20hz sampling rate to generate rumble commands and the controller firmware becomes unstable at 50hz or higher, and games even send their very own sampling rates for effects. So we get a lot of aliasing effects, and matching up the sampling rates creates a lot of complicated overhead. If you want to learn more about it, look into the ff_memless.c driver in the kernel, xpadneo is just the messenger here.

But: xpadneo currently drives the trigger rumble motors by combining the trigger pressure and the main motors into a synthesized value per each trigger. So it's not actually completely true that xpadneo does nothing special with rumble, but OTOH it just adds a pair of values which are otherwise unused. It changes nothing about how we handle rumble in xpadneo: We just get the value from ff_memless and pass it to the hardware - that's it.

You may also want to looks into the hidraw example folder in xpadneo to see how rumble commands work on the hardware level. It's a basic structure of some values just being sent unmodified over the HID bus. Keep in mind: most third-party controllers don't support the haptic timings on the commands, just the strength values.