Xbox360 Controller Analog Trigger Only Digital
-
I am on x86 latest Retropie and I am using a wireless Xb360 Controller with the MS USB Receiver. The Wiki says that xpad driver is working best so that is what I am using.
When I configure the controller in ES and pressing left/right analog triggers it shows up as "Button 6" and "Button 7" which is indicating that is is recognized as digital buttons. I would have expected to have it as analog axis.
Also when using jstest and pressing the triggers they also do show up as buttons 4 and 5 only (not analog axis):vbs@wz-retro:~$ jstest /dev/input/js0 Driver version is 2.1.0. Joystick (Xbox 360 Wireless Receiver (XBOX)) has 6 axes (X, Y, Rx, Ry, Hat0X, Hat0Y) and 17 buttons (BtnX, BtnY, BtnTL, BtnTR, BtnTR2, BtnSelect, BtnStart, BtnMode, BtnThumbL, BtnThumbR, ?, ?, ?, (null), (null), (null), (null)). Testing ... (interrupt to exit) Axes: 0: 6091 1: -2430 2: 1616 3: -215 4: 0 5: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off 12:off 13:off 14:off 15:off 16:off
Just for testing I tried to use xboxdrv and with that driver the analog triggers show up as axis (in ES and also in jstest).
Is this behavior expected? I'm afraid also emulators won't be able to use the trigger buttons as analog inputs but just as digital buttons?Thank you guys!
-
That's the point of this driver - it treats them as digital, which works around an issue with them by default having a range from ~ -32768 to +32768 with 0 in the middle which messes with software that expects "0" to be the resting position like ES.
Why do you need them as analogue ?
-
If you really want them as analogue, remove the xpad driver, and use the kernel one - you may need to manually configure retroarch/es though.
-
Oh, I see. I guess it means you can only use the analog triggers as digital buttons also when emulating consoles that actually have analog triggers (like Dreamcast for example).
Well, not super critical for me but for racing games it might become important to be able to accelrate/brake "analogy" (that probably isn't a word :).Thanks for that quick info anyway!
-
It's possible to get around the issue @BuZz mentioned in xboxdrv by mapping only half the range of the physical controller to the full range of the virtual controller. After that, any software will see the triggers as 0 when at rest. I made use of this feature when mapping my Gamecube Wavebird controller and it really feels amazing in racing games. Unfortunately and ironically I believe this won't work when mapping an actual XBox controller due to a kernel conflict that arose this year. Still, it might be worth trying, as I believe it's currently the only available solution for mapping half axis ranges in Linux.
Edit: The addition to an xboxdrv config to achieve this is below. The * would of course be replaced by the specific name of the ABS event for your controller.
--evdev-absmap ABS_*+=LT,ABS_*+=RT
You could also choose to map the other half of the axis if needed by changing the
+
to a-
. -
@mediamogul
Thanks, I will try it as soon as I have Reicast running. -
Well, I got kinda stuck on this: I am trying to get xboxdrv running for me using that half-range mapping without luck. Some questions that came up for me:
- I read several times about that kernel issue regarding xboxdrv. But I didn't really understand what the actual problem is. In my first tests xboxdrv worked for me. Tested with two wireless Xbox360 pads in ES and also in retroarch cores.
This is my kernel (Lubuntu x64 16.04):
root@wz-retro:~# uname -a Linux wz-retro 4.4.0-45-generic #66-Ubuntu SMP Wed Oct 19 14:12:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
-
I tried the config option
evdev-absmap
to map only half range for the triggers to be able to use them correctly. But it does not seem to have any effect ( tried with jstest). As I understand it, xboxdrv can be used to emulate Xbox pads using existing joystick devices (option--evdev
) but also with native Xbox pads. I think that optionevdev-absmap
only works in the first mode (emulate Xbox pad). Any chance for me to map half range with actual Xbox pads? (Is this related to the kernel bug?) -
Is xpad driver generally prefered over xboxdrv? I think yes since xboxdrv is "only" a userspace driver. But I don't know if it makes actually a difference. On the other hand its quite nice of xboxdrv to always show 4 pads. So you can even hotplug a controller ingame without restarting (but every application sees 4 gamepads even if only 1 is connected).
Wouldn't it be possible to also implement that half-range mapping into xpad also? If yes, then I would give it a try maybe.
-
@vbs said in Xbox360 Controller Analog Trigger Only Digital:
I think that option evdev-absmaponly works in the first mode
I've been suspicious of that myself, but haven't had an actual XBox 360 controller to test with. Ironically that limits a lot of the xboxdrv functionality with the very controller for which it was originally intended.
Is xpad driver generally prefered over xboxdrv?
I believe it is, where genuine XBox 360 controllers are concerned, due to the kernel reasons you mentioned.
Wouldn't it be possible to also implement that half-range mapping into xpad also?
I've never heard mention of it having any advanced mapping options outside the default functionality, but I've never looked into it. I might read up on it later tonight.
-
@mediamogul
Hm, judging from the code I could naively try to just map the values here passed toinput_report_abs
(xpad.c
):static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) ... /* triggers left/right */ if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { input_report_key(dev, BTN_TL2, data[10]); input_report_key(dev, BTN_TR2, data[11]); } else { input_report_abs(dev, ABS_Z, data[10]); input_report_abs(dev, ABS_RZ, data[11]); } ...
But seems just too easy. Was the whole reason to use this
MAP_TRIGGERS_TO_BUTTONS
flag the problem with the negativ trigger values or also something else? -
Well, I tried that but I am not sure that it is a good idea. I "hacked" it so that only positive values are passed into the kernel API. This is what happened:
- jstest /dev/input/js0 shows a range of 268 to 32768 (instead of -32k to +32k.)
- evtest /dev/input/event10 shows ranges from 128 to 255 (instead of 0 to 255)
So I don't get 0 still. Might be a problem.
ES can be correctly configured on device configuration with the analog triggers.
But still for example Crazy Taxi on Dreamcast can't be correctly played with analog triggers. In fact, patching the value range didn't have an effect at all. When you accelerate using right trigger you only reach like 15 km/h :)I assume something like this: all the analog axis are signed 16 bit values ranging from -32k to +32k. The analog trigger is just 8 bit from 0 to 255. So I think that libretro also expects the 16 bit input range. But when the controller only delivers 8 bit you won't be able to trigger the full value range (only get values of a maximum of 255 instead of 32k).
I think they tried a fix here already:
https://github.com/libretro/beetle-psx-libretro/issues/40#issuecomment-252248501
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.