Xidi icon indicating copy to clipboard operation
Xidi copied to clipboard

[Enhancement] Xbox One's Impulse triggers support

Open eVenent opened this issue 1 year ago • 3 comments

We have already #19 rumble support, but Xbox controllers evolved a bit and Xbox One controllers have Impulse triggers too. Is it possible to have Impulse Trigger Vibration support directly in Xidi?

My idea is that DirectInput vibration could activate every available motor - left motor, right motor, left trigger and right trigger when vibration is defined.

From configuration side it can have config flag which can decide about activation of these vibrations. If flag enabled - rumble motors + triggers are vibrating, if disabled only rumble motors are working. Optional option can be mode when only triggers are vibrating, disabling motors.

Similar implementation has already X1nput hook.

eVenent avatar Sep 28 '22 12:09 eVenent

Actually, Xidi already implements all of the code needed to support the impulse triggers, I just haven't hooked it up yet because they are not officially supported by XInput.

It shouldn't be too hard to get this working. It would either be take the approach used by X1nput, use some undocumented XInput functions directly, or switch to something even more modern than XInput.

samuelgr avatar Oct 08 '22 18:10 samuelgr

Windows.Gaming.Input API has impulse trigger support documented, also Xinput 1.4 has it officially documented, Xinput 1.3 and lower did not support it, and Xinput 1.4 is only awailable for Win 10 and up, so it was not very popular and devs mostly did not implement impulse triggers in pc version of games to keep it compatible with xinput 1.3 on Win 7 and 8.

You really should read this it may help you not just with impulse triggers but with many other thing as well: https://github.com/MicrosoftDocs/windows-dev-docs/blob/docs/uwp/gaming/gamepad-and-vibration.md

Basically triggers vibration is done identical to regular motors but instead of using vibration.LeftMotor you should use vibration.LeftTrigger and thats it.

I suggest to add 3 FFD output modes to Xidi - usual motors, swap of usual motors for triggers, combination of motors and triggers by basically mirroring ffd signal to both. Also its good idea to have separate settings for maximum and minimum vibration for each of 4 motors because 1 = 1 signal rerouting may feel not right, alsi its good idea to add upper mid and lower tresholds ranges for triggers, to filter out some signals and make more interesting mirroring.

Lets say we copy FFD from motor to trigger, but we dont want trigger to vibrate always at the same time and only want to mirror strong or weak or middle signals - we can set allowed range of signals, lets say we only want very strong signals like of 90-100% range to be mirrored to triggers, so we set low range to 0, mid range to 0 and high range = 90-100 (start point 90 end point 100). In other case we may isolate only mid range signals and set low to 0, high to 0 and mid to 40-60%, so triggers will only mirror vibration that gets into this range. I use here same logic as with sounds, where we may want to isolated low freq, mid freq and high freq sounds. This may also help you as starting point for sound based FFD emulation i suggested you in 2021.

v00d00m4n avatar Aug 22 '23 09:08 v00d00m4n

I know that Windows.Gaming.Input has documented support for the impulse triggers, but I haven't been able to find it anywhere for XInput 1.4. Do you have a link to the specific impulse trigger documentation for XInput 1.4?

As for the usual motors vs swapping to triggers, support for that is already implemented and can be enabled via configuration file. So to swap between motors and impulse triggers you would just need to disable the motors and enable the triggers instead, or to combine motors and triggers just enable all of them. At the moment, the problem is that impulse triggers aren't supported by the backend (XInput 1.4, as far as I know), but the code in Xidi is all already there for all four motors. Intensity range selection is interesting, and I would have to think about it more.

One option, of course, is to switch to Windows.Gaming.Input, which would be pretty simple given that Microsoft already provides a wrapper called XInputOnGameInput. It just hasn't been high enough of a priority to go look into it and do it, plus this might introduce other dependencies for users that I haven't investigated yet.

samuelgr avatar Sep 08 '23 01:09 samuelgr