Flatpak, Bluetooth Controller, udev, SDL and Linux Gaming

🚨 DEPRECATED

Steam Deck greatly improves Linux gaming in general, and this post is not that relevant nowadays. You’d better skip it.

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

🚨 Warning

The previous udev rules have syntax error and thus do not work for me. The typo stayed undetected under my radar and was not fixed until 2025-12 when I’m fiddlin with NixOS and configure services.udev.extraRules. That being said, my gamepads still won’t work with the fix so it does not really matter…

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=="input", ATTRS{idVendor}=="2dc8", ATTR{idProduct}=="0651", MODE="0660"
# Micro gamepad
SUBSYSTEM=="input", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="9020", MODE="0660"

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)
# Give RW permission to everyone
ACTION!="remove", SUBSYSTEM=="input", ATTRS{name}=="8Bitdo M30 gamepad", ENV{ID_INPUT_JOYSTICK}="1", TAG+="uaccess"
ACTION!="remove", SUBSYSTEM=="input", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="0651", ENV{ID_INPUT_JOYSTICK}="1", TAG+="uaccess"

# 8BitDo Micro gamepad (D-Input)
SUBSYSTEM=="input", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="9020", MODE="0666"

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

Bug

ℹ️ Info

Looks like SDL1 uses evdev and SDL2/SDL3 uses hidapi, which may relate to the issue, but I need more information and time to figure it more.

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.~~Someday in the afternoon my Zero 2 finally died so I did the upgrade.

Postscript

Gaming on Linux is hard (unless you only play retro games or random SLG made in Ren’Py or Godot 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 Vbox reworked on 3D acceleration support and it’s slightly better as of 2025-12.

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
Updated 2025-12-05
Contain 985 words
GPG Key html asc

#controller #game #linux #pkg