RetroPie / EmulationStation

A Fork of Emulation Station for RetroPie. Emulation Station is a flexible emulator front-end supporting keyboardless navigation and custom system themes.
Other
856 stars 344 forks source link

Controllers with analog triggers won't configure properly #568

Open hzulla opened 5 years ago

hzulla commented 5 years ago

I installed the RetroPie v4.4 image and then ran the update script to update all Raspbian packages and RetroPie itself to the most recent version with EmulationStation 2.8.3RP.

After the update, input configuration will still work fine for my SNES clone controllers (Buffalo and Noname), but fail for my XBox360 controller and the BigBen PS3 Kids' controller.

The input configuration will accept the first trigger, but then just skip right over the next trigger with no chance for the user to correct this.

hzulla commented 5 years ago

This is the resulting configuration for the BigBen controller, slightly sorted for better readability.

Things to notice:

  <inputConfig type="joystick" deviceName="Bigben Interactive Bigben Game Pad" deviceGUID="030000006b1400000209000011010000">
    <input name="start" type="button" id="9" value="1"/>
    <input name="select" type="button" id="8" value="1"/>
    <input name="up" type="hat" id="0" value="1"/>
    <input name="down" type="hat" id="0" value="4"/>
    <input name="left" type="hat" id="0" value="8"/>
    <input name="right" type="hat" id="0" value="2"/>
    <input name="a" type="button" id="1" value="1"/>
    <input name="b" type="button" id="0" value="1"/>
    <input name="x" type="button" id="2" value="1"/>
    <input name="y" type="button" id="3" value="1"/>
    <input name="pageup" type="button" id="4" value="1"/>
    <input name="pagedown" type="button" id="5" value="1"/>
    <input name="leftanalogup" type="axis" id="1" value="-1"/>
    <input name="leftanalogdown" type="axis" id="1" value="1"/>
    <input name="leftanalogleft" type="axis" id="0" value="-1"/>
    <input name="leftanalogright" type="axis" id="0" value="1"/>
    <input name="rightanalogup" type="axis" id="4" value="-1"/>
    <input name="rightanalogdown" type="axis" id="4" value="1"/>
    <input name="rightanalogleft" type="axis" id="3" value="-1"/>
    <input name="rightanalogright" type="axis" id="3" value="1"/>
  </inputConfig>
hzulla commented 5 years ago

Finally, here's the information about the joystick layout:

jstest /dev/input/js0 
Driver version is 2.1.0.
Joystick (Bigben Interactive Bigben Game Pad) has 8 axes (X, Y, Z, Rx, Ry, Rz, Hat0X, Hat0Y)
and 13 buttons (BtnA, BtnB, BtnX, BtnY, BtnTL, BtnTR, BtnTL2, BtnTR2, BtnSelect, BtnStart, BtnMode, BtnThumbL, BtnThumbR).
Axes:  0:     0  1:     0  2:-32767  3:     0  4:     0  5:-32767  6:     0  7:     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 

The triggers are mapped to left: Axis 2 / Button 6 and right: Axis 5 / Button 7. The thumb buttons are mapped to left: Button 11 and right: Button 12.

Zanmato27 commented 5 years ago

I'm having problems where Emulationstation won't register Axis 2- of the right analog stick for whatever reason on an Xbox One controller and I know I have updated my Xbox controller drivers in retropie and retropie itself.

hzulla commented 5 years ago

Wanting to fix this, I tried the same game controller configuration with today's current git version 13819ec0d963f9faeb7bd6bb3992f04f51165e33 of EmulationStation on my Xubuntu 19.04 desktop with kernel 5.0.0-21-generic.

This time, this is the result:

        <inputConfig type="joystick" deviceName="Bigben Interactive Bigben Game Pad" deviceGUID="030000006b1400000209000011010000">
                <input name="start" type="button" id="9" value="1" />
                <input name="select" type="button" id="8" value="1" />
                <input name="up" type="hat" id="0" value="1" />
                <input name="down" type="hat" id="0" value="4" />
                <input name="left" type="hat" id="0" value="8" />
                <input name="right" type="hat" id="0" value="2" />
                <input name="a" type="button" id="1" value="1" />
                <input name="b" type="button" id="0" value="1" />
                <input name="x" type="button" id="2" value="1" />
                <input name="y" type="button" id="3" value="1" />
                <input name="leftanalogup" type="axis" id="1" value="-1" />
                <input name="leftanalogdown" type="axis" id="1" value="1" />
                <input name="leftanalogleft" type="axis" id="0" value="-1" />
                <input name="leftanalogright" type="axis" id="0" value="1" />
                <input name="rightanalogup" type="axis" id="4" value="-1" />
                <input name="rightanalogdown" type="axis" id="4" value="1" />
                <input name="rightanalogleft" type="axis" id="3" value="-1" />
                <input name="rightanalogright" type="axis" id="3" value="1" />
                <input name="leftthumb" type="button" id="11" value="1" />
                <input name="rightthumb" type="button" id="12" value="1" />
                <input name="leftshoulder" type="button" id="4" value="1" />
                <input name="rightshoulder" type="button" id="5" value="1" />
                <input name="lefttrigger" type="button" id="6" value="1" />
                <input name="righttrigger" type="button" id="7" value="1" />
        </inputConfig>

Things to observe between the Retropie Raspberry Pi version (RRPV) and the git Desktop version (GDV):

  1. The RRPV identified and stored the shoulder buttons as "pageup" / "pagedown", while the GDV identified and stored them as "leftshoulder" / "leftshoulder", which seems to be the more correct label.
  2. The RRPV didn't store the configuration for the thumb buttons at all, while the GDV correctly identified and stored them as "leftthumb" / "rightthumb".
  3. The RRPV didn't store the configuration for the triggers at all, while the GDV stored them.
  4. During configuration, both the RRPV and the GDV prefer the trigger button values to the trigger axis values, which is not wrong but the axis value would be better for games that offer finer control (such as the gas pedal in racing games).

I do not understand the reason for these differences in behaviour, especially 1 seems odd. Can it be the kernel version differences between an (updated) Retropie distribution and a standard Xubuntu desktop? Or have there been internal fixes in EmulationStation already to fix 1, 2 and 3? I may have missed it, but didn't find these fixes in the git log for them.

Anyway, I will try to offer a patch to fix 4 some time later.

hzulla commented 5 years ago

I now see that my problem is related to https://github.com/RetroPie/EmulationStation/pull/554 and https://github.com/RetroPie/EmulationStation/pull/558 's filterTrigger and will try to offer a patch later.

hzulla commented 5 years ago

Hey @psyke83, I don't quite get the intention of filterTrigger().

It appears that it now forces the configuration of Axis 2+ and 5+ for the triggers, but that would mean that only half of the trigger value range is actually used in the game. To use a game-related analogy, it apparently means that the racing car ignores half of the way the race car driver can push down the gas pedal and only then begins to accelerate.

Is that intended? Wouldn't it be better to use the full axis range from -32767 to 32767?

psyke83 commented 5 years ago

@hzulla,

Yes, that's an intended workaround (to limit the axis range - not the bug you're seeing in which configuration fails).

My DualShock3 controller's trigger axis values rest at -32767, half-press at 0 and full press at +32767, but applications on Linux - such as RetroArch - aren't capable of utilizing the full axis range for a single trigger.

Since we can't set the axis number without polarity in mapping configuration, we have to choose either the negative or positive pole. Choosing the positive pole means that a firm press is needed, but the negative pole will cause triggers to be too sensitive. I chose the positive pole to keep it in line with the default PS3 controller mapping seen in software such as Kodi.

If there was a way to calibrate the axes to normalize the range from 0-32767 at a driver level, we could avoid this issue, but I'm not aware of a way to do it using the available evdev userspace tools.

Can you confirm that reverting #558 (but leaving #554 applied) at least fixes the issue with controller mapping for you?

hzulla commented 5 years ago

For now, I tried

git diff
diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp
index 29111a4..cac3a69 100755
--- a/es-core/src/guis/GuiInputConfig.cpp
+++ b/es-core/src/guis/GuiInputConfig.cpp
@@ -343,6 +343,7 @@ bool GuiInputConfig::filterTrigger(Input input, InputConfig* config, int inputId
        if((strstr(config->getDeviceName().c_str(), "PLAYSTATION") != NULL \
          || strstr(config->getDeviceName().c_str(), "PS3 Ga") != NULL \
          || strstr(config->getDeviceName().c_str(), "PS(R) Ga") != NULL) \
+         || strstr(config->getDeviceName().c_str(), "Bigben Interactive Bigben Game Pad") != NULL \
          && InputManager::getInstance()->getAxisCountByDevice(config->getDeviceId()) == 6)
        {
                // digital triggers are unwanted

and that worked. However, I do not know if "Bigben Interactive Bigben Game Pad" is a unique device name, since BigBen sells many different variations of USB gamepads, so it's probably not a good string identifier.

psyke83 commented 5 years ago

It looks as though that may be a unique descriptor: https://github.com/torvalds/linux/blob/master/drivers/hid/hid-bigbenff.c#L6

It's unfortunate that we need to whitelist controllers like this, but I'm not aware of a better way to detect DS3 clones (and this particular clone controller is unique in that it has its own dedicated hid kernel driver).

Unless you can think of something better, send a PR to add this to the whitelist. What about your xb360 controller? I received feedback that they were working OK with the filterTrigger function. I don't own a controller to test myself, so more detail would be appreciated.

hzulla commented 5 years ago

It looks as though that may be a unique descriptor.

I'm not perfectly sure about it. (I wrote bigbenff.c by reverse engineering the protocol without any help from BigBen and then submitted it to the mainline kernel.) The kernel detects the device by the USB id, only, and not by the human readable name it returns via HID. The HID name for this device is so blandly generic that I assume BigBen may have used it for other devices, too.

Will test the Xbox Controller for you tomorrow.

hzulla commented 5 years ago

What about your xb360 controller?

Tested with my Xbox Controller and configuration worked this time using the current git version of EmulationStation on my Ubuntu desktop.

Since we can't set the axis number without polarity in mapping configuration

Why is that so? Is that a limitation of retroarch?

Also, to test all this, can anyone recommend a game or application running on Retropie that one can use to properly test the analog trigger?

hzulla commented 5 years ago

I looked at mSkipAxis as a follow-up to this issue and am having some problems, see #577. Thanks.

psyke83 commented 5 years ago

@hzulla,

Thanks for testing and letting me know. I'll take a look at the issue with mSkipAxis soon.

Regarding the general issue with DS3 triggers and software on Linux: the Linux gamepad spec (https://www.kernel.org/doc/html/v4.13/input/gamepad.html) dictates that triggers should start at 0 and report positive values (so, 0-32727), but as you can see, DualShock3 and clones such as your BigBen violate this by using the resting position at -32767.

RetroArch was just one example of software that had issues dealing with a trigger that spans the full range of an axis. Here's an open issue discussing it: https://github.com/libretro/RetroArch/issues/6920

On Windows, it seems that the raw values reported by such controllers (-32767-32767) get mapped to the 0-255 range for the XInput API, but we have no equivalent kind of translation in Linux (via SDL2, for example), and since most software is designed to accept axis mapping based on a single pole, triggers aren't being recognized properly for the full pressure span.

hzulla commented 5 years ago

the Linux gamepad spec dictates that triggers should start at 0 and report positive values (so, 0-32727), but as you can see, DualShock3 and clones such as your BigBen violate this by using the resting position at -32767.

Interesting. The XBox 360 controller I have here also returns the trigger axis with a resting position at -32767, so it's not just PS3 and clones doing this. It may warrant asking the input maintainers about this discrepancy, as I also read the spec as you do here.

(Btw, the BigBen isn't a clone, it's a licensed 3rd party controller that is internally using a wholly different HID protocol than the Sony PS3 controllers. It appears that through licensing, they got a driver for it included with the PS3.)

hzulla commented 5 years ago

Hopefully the kernel input maintainers can clarify this.

hzulla commented 5 years ago

The Sony gamepad driver lead developer responds. The gist of the response is - yeah, it sucks, but that's the way it is now. Applications (like Retropie / RetroArch) will have to handle with trigger values going over the whole axis, not just starting at 0.

hzulla commented 5 years ago

Can anyone recommend a game or application running on Retropie that one can use to properly test the analog trigger?

pjft commented 5 years ago

I think that some racing games on MAME - OutRun, Super Hang-On or Chase HQ - might have had analog accelerators.

joolswills commented 5 years ago

Sorry. Late to the party. I had trouble configuring "left" on the right analog sticks of two of my 8bitdo controllers since the analog stick changes.

Reverting 93fdfaa9 makes it work again. I need to read through this whole thread in more detail and can provide more info later.

psyke83 commented 5 years ago

@joolswills,

Can you try this and see if it solves the issue? https://github.com/RetroPie/EmulationStation/compare/master...psyke83:mSkipAxis_fix

joolswills commented 5 years ago

Was able to configure fine with this change.

rileyinman commented 4 years ago

This problem is showing up for me on v2.9.3RP when trying to configure my 8bitdo controller in XInput mode. According to jstest the left and right triggers are axes 2/5 respectively, and return to "resting" at -32767. Neither one is recognized on the input configuration screen.

rileyinman commented 4 years ago

In case this is important:

$ jstest /dev/input/js0
Driver version is 2.1.0.
Joystick (8Bitdo SF30 Pro) has 8 axes (X, Y, Z, Rx, Ry, Rz, Hat0X, Hat0Y)
and 10 buttons (BtnA, BtnB, BtnC, BtnX, BtnY, BtnZ, BtnTL, BtnTR, BtnTL2, BtnTR2).
Testing ... (interrupt to exit)
Axes:  0:     0  1:     0  2:-32767  3:     0  4:     0  5:-32767  6:     0  7:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off
rileyinman commented 4 years ago

@psyke83 Sorry in advance for the ping if it's annoying, but you seem to have been involved the most directly with this part of the code. Is this an instance where another exception would need to be added to the axis skip function, since the controller doesn't seem to follow spec?

rileyinman commented 3 years ago

This is still an issue for me, and I haven't had any luck solving it in the interim. I'm starting to get the itch to play some more advanced games that use a larger amount of buttons, but I can't because my controller triggers don't work. Any help would be appreciated.

cmitu commented 3 years ago

@rileyinman please use the forum for support questions.