TLDR: After having owned the controller for a while I noticed that every time you install a new kernel update the fixes are undone again, and have to be re-applied. I also discovered that the controller UID is the same for all SN30 Pro+ controllers. So I’ve made the following script that fixes everything automatically instead. Save it somewhere, check that the config file paths are correct, install xpadneo using the github instructions, then run the script as root.
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
# Config file paths
MP_PATH="/etc/modprobe.d/99-xpadneo-bluetooth.conf"
UDEV_PATH="/etc/udev/rules.d/99-xpadneo.rules"
ENV_PATH="/etc/environment"
# Look for already applied fixes
MPFIXED=$(grep -c "disable_ff=2" $MP_PATH)
UDEVFIXED=$(grep -c "RUN+=\"/bin/sh -c 'echo xpadneo udev: \$kernel > /dev/kmsg && { echo \$kernel > /sys/bus/hid/drivers/hid-generic/unbind; echo \$kernel > /sys/bus/hid/drivers/microsoft/unbind; echo \$kernel > /sys/bus/hid/drivers/xpadneo/bind; }; '\"" $UDEV_PATH)
ENVFIXED=$(grep -c "8BitDo SN30 Pro+" $ENV_PATH)
if [[ $MPFIXED -eq 0 ]]; then
# Turn off trigger rumble
echo "options hid_xpadneo debug_level=0 disable_ff=2 trigger_rumble_damping=4 fake_dev_version=4400 combined_z_axis=n" >> $MP_PATH
echo "Applied fix to $MP_PATH."
else
echo "Fix already applied to $MP_PATH. Skipping."
fi
if [[ $UDEVFIXED -eq 0 ]]; then
# Apply dirty fix to udev rules
sed -i 's/RUN/#RUN/g' $UDEV_PATH
echo "RUN+=\"/bin/sh -c 'echo xpadneo udev: \$kernel > /dev/kmsg && { echo \$kernel > /sys/bus/hid/drivers/hid-generic/unbind; echo \$kernel > /sys/bus/hid/drivers/microsoft/unbind; echo \$kernel > /sys/bus/hid/drivers/xpadneo/bind; }; '\"" >> $UDEV_PATH
echo "Applied fix to $UDEV_PATH"
else
echo "Fix already applied to $UDEV_PATH. Skipping."
fi
if [[ $ENVFIXED -eq 0 ]]; then
# Add SDL_CONTROLLERCONFIG environment variable
echo "SDL_GAMECONTROLLERCONFIG=\"050000005e040000e002000030110000,8BitDo SN30 Pro+,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,\"" >> $ENV_PATH
echo "Added 'SDL_CONTROLLERCONFIG' variable to $ENV_PATH."
else
echo "'SDL_CONTROLLERCONFIG' variable already present in $ENV_PATH. Skipping."
fi
Original post follows:
I recently bought an 8BitDo SN30 Pro+ since my old gamepad was an ancient Logitech Dual Action. I wanted a gamepad that was wireless as well as having support for XInput. When I heard about the SN30 Pro+ I couldn’t contain myself, so I went and bought it the same day after reading a bit about it and how it works on Linux. It’s not officially supported, and there wasn’t really much definitive information regarding Linux compatibility, other than that the older SN30 Pro worked fine and it works on the raspberry pi. So I just took a gamble and bought it.
Continue reading “Getting rumble on the 8BitDo SN30 Pro+ to work properly with Linux”