higan-emu / higan

higan is a multi-system emulator focused on accuracy, preservation, and configurability.
Other
1.18k stars 112 forks source link

Two gamepads on the same USB device are treated as one on Linux #156

Open ParticleMon opened 3 years ago

ParticleMon commented 3 years ago

Connected to a SNES-to-USB adapter, gamepads 1 and 2 are recognized as gamepad 1 in at least v106 and nightly 2021-02-15 (v115) higan-ubuntu. However, other emulators, including Snes9x and MAME, recognize separate gamepads.

higan v106 lists both controller ports as Joypad(ba889cef0e8f3013).

The two devices and their symlinks are as follows:

gamepad 1: /dev/input/by-path/pci-0000\:00\:14.0-usb-0\:3.4.3\:1.0-event-joystick -> ../event15

gamepad 2: /dev/input/by-path/pci-0000\:00\:14.0-usb-0\:3.4.3\:1.0-joystick -> ../input/js1

Although the symlink specifies otherwise, js0 is also gamepad 1.

Linux Mint 20.1, kernel 5.4

Screwtapello commented 3 years ago

The *-event-joystick and *-joystick symlinks aren't separate gamepads, they're the same gamepad but present data in different ways: the *-event-joystick device uses the modern event API (used for keyboards, mice, golf clubs, etc.), and the *-joystick device uses the legacy joystick-specific API.

Is there nothing in /dev/input/by-path that links to ../input/js0?

ParticleMon commented 3 years ago

Correct: Nothing in /dev/input/by-path links to ../input/js0.

However, it seems clear that *-event-joystick and *-joystick are actually separate gamepads because doing a cat on each device, or its symlink, followed by button pressing displays input from each gamepad individually, as indicated.

Screwtapello commented 3 years ago

I suspect something is saying "hey, there's a USB joystick connected via 'pci-0000:00:14.0-usb-0:3.4.3:1.0', I'll make a symlink for it" and symlinking to js0, then saying "hey, there's another USB joystick connected via 'pci-0000:00:14.0-usb-0:3.4.3:1.0', I'll make a symlink for it", and overwriting the same symlink but pointing to js1 instead.

If /dev/input/event15 is gamepad 1, I bet there's another event device (event16?) that's gamepad 2. I wonder why higan isn't picking it up.

ParticleMon commented 3 years ago

Indeed, event16 is also gamepad 2 but there is no symlink to it.

Screwtapello commented 3 years ago

Can you please:

Hopefully the output will include information about both gamepads, we can compare them to see how they differ, and then look at the bsnes code to figure out why it might be confusing them.

ParticleMon commented 3 years ago

snes-to-usb.txt

Screwtapello commented 3 years ago

Here's the difference between the two event devices:

--- event15.txt 2021-02-24 11:05:16.299895190 +1100
+++ event16.txt 2021-02-24 11:05:28.152417953 +1100
@@ -1,10 +1,10 @@
-UDEV  [211764.391804] add      /devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3.4/1-3.4.3/1-3.4.3:1.0/0003:0E8F:3013.000F/input/input43/event15 (input)
+UDEV  [211764.358904] add      /devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3.4/1-3.4.3/1-3.4.3:1.0/0003:0E8F:3013.000F/input/input44/event16 (input)
 ACTION=add
-DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3.4/1-3.4.3/1-3.4.3:1.0/0003:0E8F:3013.000F/input/input43/event15
+DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3.4/1-3.4.3/1-3.4.3:1.0/0003:0E8F:3013.000F/input/input44/event16
 SUBSYSTEM=input
-DEVNAME=/dev/input/event15
-SEQNUM=26116
-USEC_INITIALIZED=211764391383
+DEVNAME=/dev/input/event16
+SEQNUM=26119
+USEC_INITIALIZED=211764358575
 ID_INPUT=1
 ID_INPUT_JOYSTICK=1
 ID_VENDOR=HuiJia
@@ -26,6 +26,6 @@
 ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_3_4_3_1_0
 LIBINPUT_DEVICE_GROUP=3/e8f/3013:usb-0000:00:14.0-3.4
 MAJOR=13
-MINOR=79
+MINOR=80
 DEVLINKS=/dev/input/by-id/usb-HuiJia_USB_GamePad-event-joystick /dev/input/by-path/pci-0000:00:14.0-usb-0:3.4.3:1.0-event-joystick
 TAGS=:seat:uaccess:

The SEQNUM and USEC_INITIALIZED fields are just timestamps, they're not useful to bsnes. The DEVPATH, DEVNAME and MINOR fields just give a temporary unique identifier to this device. So far as I can tell, there's no permanent unique identifier for each of the different gamepads.

If I recall correctly, bsnes tries to come up with a permanent unique identifier for each gamepad you map so that, for example, the SNES controller 1 "A" button is "the circle button on my Dualshock", not "button 3 on the fifth gamepad I connected since booting my PC". This works great if nobody ever has more than one gamepad of the same type, but unfortunately you do.

I really should dig into the code and verify that my understanding is correct, but I'm not sure what the best path forward would be.

ParticleMon commented 3 years ago

That would seem to describe what's happening with this adapter. Thanks for noting this!

Would it be worth examining other emulators that successfully detect separate gamepads, such as those mentioned?

bobosch commented 2 years ago

I have the same problem with two identical Bluetooth controller - two devices in the KDE settings, recognized with the same ID in higan :-(

dolanor commented 6 months ago

same here. 2 ps3 controller, 2 devices show in bluetooth gnome settings panel, but same ID in Higan.