RetroPie-Setup icon indicating copy to clipboard operation
RetroPie-Setup copied to clipboard

confusing controller detection

Open tome9111991 opened this issue 3 years ago • 25 comments

Hello I run retropie on a mini pc x64 with Ubuntu-Mate 21.04. I have connected a xbox controller via bluetooth.

Emulationstation detect the controller as "Xbox One S Controller"

RetroArch detect the controller as "Xbox Wireless Controller"

The issue is controller will not work ingame i got the message "Xbox Wireless Controlle 118/765 not configured"

I have only a auto-config for Xbox One S controller.

Workaround is Open /retropie/config/all/retroarch/autoconfig/Xbox One S controller.cfg Rename input_device to "Xbox Wireless Controller"

Maybe there is a fix for this issue?

tome9111991 avatar Sep 01 '21 18:09 tome9111991

Most likely because of the SDL2 HIDAPI drivers being enabled by default, hence the different name for the controller. See https://github.com/RetroPie/EmulationStation/pull/762. What SDL2 version do you have installed ?

cmitu avatar Sep 01 '21 18:09 cmitu

ok nice is allready a known issue

SDL 2.0.14 is installed

I have change input driver to SDL2 But mapping looks wrong

tome9111991 avatar Sep 01 '21 19:09 tome9111991

SDL 2.0.14 is installed

~~Ubuntu 20.04 comes with SDL 2.0.8, did you install SDL2 manually ?~~ Actually 21.04 does come with SDL2 2.0.14.

I have change input driver to SDL2 But mapping looks wrong

The SDL2 input driver for RetroArch is not so widely used and I don't think it was tested with the profile that's generated by EmulationStation's input scripts. You should disable the HIDAPI drivers in ES using the environment variable SDL_JOYSTICK_HIDAPI - set it to 0 in the EmulationStation startup script.

cmitu avatar Sep 01 '21 20:09 cmitu

I dont know where is the EmulationStation startup script.🤔

@cmitu I have clone your emulatorstaion hidapi branch But have still same issue

tome9111991 avatar Sep 02 '21 09:09 tome9111991

I dont know where is the EmulationStation startup script.🤔

It's in /usr/bin/emulationstation, but since it's root owned it might be easier to just add the environment variable to your $HOME/.profile.

@cmitu I have clone your emulatorstaion hidapi branch But have still same issue

You mean the controller is name is different in EmulationStation than in RetroArch ?

cmitu avatar Sep 02 '21 18:09 cmitu

It's in /usr/bin/emulationstation, but since it's root owned it might be easier to just add the environment variable to your $HOME/.profile.

Ok i will look later

You mean the controller is name is different in EmulationStation than in RetroArch ?

Yes still different name And mapping with autoconfig not working

tome9111991 avatar Sep 02 '21 19:09 tome9111991

I add export SDL_JOYSTICK_HIDAPI=0 to .profile But nothing change

I use this branch 20210903_140309

tome9111991 avatar Sep 03 '21 11:09 tome9111991

Then it must be a different issue and not related to the HIDAPI drivers from SDL2.

cmitu avatar Sep 03 '21 12:09 cmitu

I downgrade to SDL 2.0.4 Controller name is right in ES Should work now, ok not all button works, Select button and Hotkey button dont work in Emulatorstation with sdl2.0.4 🤔

I have compile latest SDL2 fron soucre (2.0.17) But name is wrong in ES

EDIT I installed SDL 2.0.8 Looks it works good now

tome9111991 avatar Sep 05 '21 15:09 tome9111991

If you can use your own SDL, then you can test the latest release (2.0.16) by compiling with --disable-hidapi and see if you can reproduce the issue. That would confirm my initial theory that it's related to SDL's HIDAPI drivers being enabled by default.

cmitu avatar Sep 05 '21 17:09 cmitu

I have sdl 2.0.16 with /configure --disable-hidapi compiled But not help . wrong controller name in ES

If i use SDL2 input driver in Retroarch. Retroarch detect controller as "Xbox One S | Xbox Wireless Controller" Only test with SDL2.0.14

Here a output from sdl2-jstest with SDL2.0.16

Joystick Name:     'Xbox One S Controller'
Joystick GUID:     050000005e040000fd02000003090000
Joystick Number:    0
Number of Axes:     6
Number of Buttons: 17
Number of Hats:     1
Number of Balls:    0
GameControllerConfig:
  Name:    'Xbox One Wireless Controller'
  Mapping: '050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,'

ES detect = Xbox One S Controller Retroarch = Xbox One Wireless Controller

tome9111991 avatar Sep 06 '21 05:09 tome9111991

I'm running into a similar issue but I'm using the input_joypad_driver = "udev" for retroarch and its set the same in my controller autoconfig

emulationstation (using the dev version) made an autoconfig with:

input_device = "NES30 Joystick"

input_driver = "udev"

and retroarch wants the controller to be named

input_device = "NES30              NES30 Joystick"

just to note, I get the same name

NES30              NES30 Joystick

when I look at the controller with evtest

theofficialgman avatar Oct 27 '21 16:10 theofficialgman

Just came over this issue kind of by accident, but I can at least chip in with some knowledge. I observed similar issues with FS-UAE, and at least one reason for device name confusion issue is that (newer versions of) SDL2 have started cleaning up ("fixing") devices name internally. Among other things, multiple spaces are collapsed, and repeat vendor name is removed. So SDL 2.0.16 internally renames

NES30              NES30 Joystick

to

NES30 Joystick

This behavior is hardcoded into SDL2.

See SDL_CreateJoystickName in SDL/src/joystick/SDL_joystick.c for more information.

For some devices, it even overrides the name completely based on vendor/product ID. For example for Xbox controllers, if I recall correctly.

FrodeSolheim avatar Nov 25 '21 18:11 FrodeSolheim

It should be fairly easy to created a patched version of SDL without this name "correction" btw.

FrodeSolheim avatar Nov 25 '21 18:11 FrodeSolheim

@FrodeSolheim Thank you for the heads up. That's ... not so great, to be honest. Not sure if it explains the original poster's issue, but it's clearly the issue noticed by @theofficialgman.

cmitu avatar Nov 25 '21 19:11 cmitu

It's not certain of course, but it sounds likely that RetroArch uses udev / linux native joystick support and gets "Xbox Wireless Controller" (the Xbox devices are usually called something that). While if Emulationstation uses SDL, then SDL has code to specifically detect Xbox 360/One controllers (and a few) more and completely replaces the name:

SDL_CreateJoystickName has:

custom_name = GuessControllerName(vendor, product);

GuessControllerName looks up in a list in controller_type.h which has entries like this (that's where the "Xbox One S Controller" name comes from):

{ MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad

FrodeSolheim avatar Nov 25 '21 19:11 FrodeSolheim

@FrodeSolheim you're right. For some reason, I thought GuessControllerName was being using with the GameController sub-system, but it's called in the SDL_CreateJoystickName (as you noticed).

As far as RetroPie is concerned, we may be able to work around this in the EmulationStation input configuration scripts for RetroArch et. all, but it will break existing EmulationStation configs which stored the - former, full - joystick name.

cmitu avatar Nov 25 '21 19:11 cmitu

Or provide a patched SDL with RetroPie with the following lines removed:

custom_name = GuessControllerName(vendor, product);
if (custom_name) {
    return SDL_strdup(custom_name);
}

and

/* Trim trailing whitespace */
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
    /* continue */
}
name[len] = '\0';

/* Compress duplicate spaces */
for (i = 0; i < (len - 1); ) {
    if (name[i] == ' ' && name[i+1] == ' ') {
        SDL_memmove(&name[i], &name[i+1], (len - i));
        --len;
    } else {
        ++i;
    }
}

/* Perform any manufacturer replacements */
for (i = 0; i < SDL_arraysize(replacements); ++i) {
    size_t prefixlen = SDL_strlen(replacements[i].prefix);
    if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
        size_t replacementlen = SDL_strlen(replacements[i].replacement);
        if (replacementlen <= prefixlen) {
            SDL_memcpy(name, replacements[i].replacement, replacementlen);
            SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen)+1);
            len -= (prefixlen - replacementlen);
        } else {
            /* FIXME: Need to handle the expand case by reallocating the string */
        }
        break;
    }
}

/* Remove duplicate manufacturer or product in the name */
for (i = 1; i < (len - 1); ++i) {
    int matchlen = PrefixMatch(name, &name[i]);
    if (matchlen > 0 && name[matchlen-1] == ' ') {
        SDL_memmove(name, name+matchlen, len-matchlen+1);
        break;
    } else if (matchlen > 0 && name[matchlen] == ' ') {
        SDL_memmove(name, name+matchlen+1, len-matchlen);
        break;
    }
}

I did consider doing it for FS-UAE, but haven't decided to do that yet. In the related SDL issue https://github.com/libsdl-org/SDL/issues/4734 I did comment the same as here, that it isn't a bug. But I also added a comment suggestion that SDL_HINT_JOYSTICK_USE_ORIGINAL_NAMES or another way to disable the name "fixing" could be useful.

FrodeSolheim avatar Nov 25 '21 19:11 FrodeSolheim

We do have a couple patches in our SDL version we distribute, so adding a patch (+ optionally a hint to be used by ES) may be a solution.

Sadly, it won't help the original poster, since on Ubuntu we cannot ship a custom SDL. Some other packages have a hard dependency on the distro's SDL version, and replacing it will cause conflicts.

cmitu avatar Nov 25 '21 20:11 cmitu

I would support patching this for our SDL.

joolswills avatar Nov 25 '21 20:11 joolswills

I'll take a look at patching this, it would probably need to leave the SDL (clean) names exposed to the GameController sub-system so that the shipped gamecontrollerdb is not affected by it.

cmitu avatar Nov 25 '21 21:11 cmitu

OK thanks - no pressure - I'm happy to look at it also. I think having an ENV var is a good idea too so the behaviour can be enabled / disabled but whatever you think is best.

joolswills avatar Nov 26 '21 01:11 joolswills

@FrodeSolheim Thanks for this btw - big fan of fs-uae (and Amigas).

joolswills avatar Nov 26 '21 01:11 joolswills

We do have a couple patches in our SDL version we distribute, so adding a patch (+ optionally a hint to be used by ES) may be a solution.

Sadly, it won't help the original poster, since on Ubuntu we cannot ship a custom SDL. Some other packages have a hard dependency on the distro's SDL version, and replacing it will cause conflicts.

This would help me as well as the original poster. I already build sdl2 using the retropie fork myself

theofficialgman avatar Nov 26 '21 02:11 theofficialgman

I have also run into this issue in general. I installed Retropie (the build from January 12 2022) on Ubuntu 21.04 and EmulationStation recognized my Buffalo Classic USB Gamepad just fine - I could navigate the interface etc. Opening a game, however, I received the message "controller not configured" (it specifically listed the controller I was using, I just can't remember the exact text) and the controller would not work.

wolfgangrumpf avatar Jan 13 '22 14:01 wolfgangrumpf