Flatpak, Bluetooth Controller, udev, SDL and Linux Gaming

Theory, or Boring Stuff

Today I was trying Flatpak again after maybe two years of gap (and concluded that it’s still terrible) and was unable to use my 8Bitdo-Zero2 bluetooth controller (connected using D-Input mode) in PPSSPP on Void.

First, RTFM to have a general idea of the situation. In this case, Gamepad - Arch Wiki.

After reading boring docs with plenty of unwanted information since I don’t own most of those special cases, install some drivers, kernel modules, udev rules. As xow is not available in void-packages yet, just a bunch of packages containing the necessary udev rules and drivers for wired/wireless controllers and wireless dongles

# steam-udev-rules is just a werid rename of steam-devices in Void
xi steam-udev-rules xboxdrv xpadneo xone

Then I came across a (unanswered) question on r/linux_gaming X-Input, D-Input, Steam, Steam Big Picture, and Linux (and flatpak if relevant?) which addressed my confusion, sadly, none of these was answered in the replies.

Due to the unanswered confusion I said above and the trouble setting up xboxdri, I choose to use more native solution. And the detailed or probably lengthy instruction on Arch Wiki does not help as my 8BitDo controller just won’t appear in /dev/input/ at all.

Later on, reading through 8BitDo Ultimate 2.4GHz wifi working in linux made me wonder if it’s still a udev issue even if I installed steam-devices already. And after wasting more than an hour on searching and reading specifications, weird bugs, random inapplicable nonsense, I made the conclusion that it was.

Udev Rules

Things become easy now that I just need to write a udev rule for all my controllers, not really a big issue as I just did that for REDACTEDthe other day. And GPT-4o is both smart enough to give me a comprehensive checklist I may need for such rule, and dumb enough to not recognize a simple trick I’ll explain later.

First, connect the wireless controller. Some models offer many modes like Windows (usually X-Input), Android (usually D-Input), Switch (idk) or macOS. On Linux, it’s usually advised to use D-Input.

In my test, only D-Input would work so there is no choice. X-Input would throw out a silly warning message saying no audio device or whatever and the LED light just keeps flashing. macOS one would disconnect automatically just after a few seconds and throws another warning saying busy I/O or something like that.

After it was connected, find the MAC address and list its info:

$ bluetoothctl devices
Device 12:34:56:78:AA:CC 8BitDo M30 gamepad
Device 12:34:56:78:AA:BB TimeBox

$ bluetoothctl info 12:34:56:78:AA:CC
Device 12:34:56:78:AA:CC (public)
        Name: 8BitDo M30 gamepad
        Alias: 8BitDo M30 gamepad
        Class: 0x00002508 (9480)
        Icon: input-gaming
        Paired: yes
        Bonded: no
        Trusted: no
        Blocked: no
        Connected: yes
        WakeAllowed: yes
        LegacyPairing: no
        UUID: Human Interface Device... (00001124-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v2DC8p0651d0100

Then dumb GPT-4o suggested me using udevadm to find this device in /sys/class/bluetooth/ or wherever it just did not belong to. Actually, the Modalias already contains the necessary information (aka. vendor ID and product ID) so rush to write the udev rule now:

# write udev rule
/usr/bin/sudo -e /etc/udev/rules.d/82-8bitdo-bluetooth-gamepad.rules
# reload
sudo udevadm control --reload-rules
sudo udevadm trigger

Short version of /etc/udev/rules.d/82-8bitdo-bluetooth-gamepad.rules:

# M30 gamepad
SUBSYSTEM=="usb", ATTR{idVendor}=="2dc8", ATTR{idProduct}=="0651", MODE="0666"
# Zero 2 gamepad
SUBSYSTEM=="usb", ATTR{idVendor}=="2dc8", ATTR{idProduct}=="3230", MODE="0666"

Long version:

# 8BitDo Bluetooth Controller

# How to find ID:
# 1. bluetoothctl devices
# 2. bluetoothctl info 12:34:AB:DD:EE:FF | grep Modalias
#    (replace with the real MAC address)
# 3. The output looks like "usb:v2DC8p0651d0100",
#    where 2Dc8 is vendor ID and 0651 is product ID

# 8BitDo M30 gamepad (D-Input, aka. Android mode)
# Assign group plugdev, and give RW permission to users in that group
# You need to create group and add users first.
# SUBSYSTEM=="usb", ATTR{idVendor}=="2dc8", ATTR{idProduct}=="0651", MODE="0660", GROUP="plugdev"
# Alternatively, give everyone RW permission for Switch.
SUBSYSTEM=="usb", ATTR{idVendor}=="2dc8", ATTR{idProduct}=="0651", MODE="0666"

# 8BitDo Zero 2 gamepad (D-Input)
SUBSYSTEM=="usb", ATTR{idVendor}=="2dc8", ATTR{idProduct}=="3230", MODE="0666"

Then disconnect and reconnect the controller, now entering Suyu I can see the controller.

Bug

You may have noticed that I initially started with 8BitDo Zero 2 w/ PPSSPP and ended up with 8BitDo M30 w/ Suyu. That’s a nice catch. For some reason I can’t make 8BitDo Zero 2 work in the same way. Under the hood, PPSSPP uses SDL for this kind of task and utilizes SDL_GameControllerDB which already contains these two models. It’s probably a Flatpak issue as they intended to Reconsider udev support #961 and ended up with a wontfix, which I no longer have the energy to investigate further.

And I tried SDL2 Gamepad Mapper mentioned in SDL_GameControllerDB, but sadly it did not list my good old 8BitDo Zero 2 too. Maybe it’s time to upgrade to 8BitDo Micro.

Postscript

Gaming on Linux is hard (unless you only play retro games or Ren’Py games on itch, Patreon or wherever), sigh, especially considering wireless controllers. I really don’t know why it sucks so much presumably many big names in game industry have ambition to take on it, or portable Windows on ARM devices.

And I’m not even mentioning the pain of setting up Wine, even with the amazing work of Conty, or far worse, debugging the broken 3D acceleration on VirtualBox caused by their defunct Linux graphics controller :)

Vinfall's Geekademy

Sine īrā et studiō


Ô Lucifer! Oh laisse-moi rien qu'une fois Glisser mes doigts dans les cheveux d'Esméralda


Created 2024-06-05
Contain 875 words
GPG Key html asc

#gadget #game #linux #pkg