1
General / Smart joystick auto configuration mapping (raspberry -retropie - attract mode)
« on: January 21, 2023, 02:04:41 PM »
THE PROBLEM
I have 1 joystick and 1 gamepad (well, actually two and two), and every time i change that kind of peripherals on my Raspberry Pi (from joystick to gamepad and vice versa) I have to re-map the controllers for Attractmode (and also attach a keyboard to hit TAB).
In short, Attractmode actually (at least, my version) is not plug-and-play and does not "remember" the joysticks/joypads that I have configured in the past to navigate inside the frontend.
Pretty much frustrating, isn't it?
THE WORKAROUND (MORE THAN THE SOLUTION)
I have decided to solve this tedious problem and I share with you how I did it.
the script is not beautiful, i know (try chat GPT if you prefer ): I did it very quickly but it works for now... (maybe improve it!).
Consider it an alpha version at the moment.
ASSUMING:
The joystick/joypad that will control Attractmode will always be the one inserted in the upper left USB port of the Raspberry Pi and no others. No matter what model or brand it is, the number of buttons ecc. We need to find a rule that defines the main controller that will navigate into attractmode menus, games and options. This rule is that it will be always plugged to the upper left USB port (but obviously you can change if you want).
1. Turn off the raspberry (mine is 4 but should work for all versions)
2. Remove all USB devices
3. Plug in one kind of joystick/joypad into the upper left USB port
4. Start Attractmode
5. Configure your device in Attractmode (select, start, previous page, next letter etc.)
6. Discover the name of the joystick/joypad with the ssh command:
the name after the string:
is what is we are looking for.
in my case is 0079_Generic_USB_Joystick
7. Create the file /home/pi/.attract/[nameofthejoystick].txt (in my case /home/pi/.attract/0079_Generic_USB_Joystick.txt)
8. Restart your raspberry
8. Copy the content of /home/pi/.attract/attract.cfg between 'input_map' and 'general' (be careful that the configurations called 'general' in the attract.cfg file are actually under the rules called 'input_map')
in my case:
Here is a working example of a right formatted file if you want to check:
https://www.cdlab.it/0079_Generic_USB_Joystick.txt
Save it to your Desktop and open it with e.g. notepad++ to check the formatting
9. Write this content in the file /home/pi/.attract/[nameofthejoystick].txt
10. Save the file /home/pi/.attract/[nameofthejoystick].txt
11. Do all the 1-10 steps for all your different type of USB CONTROLLERS (virtually infinity).
OK: last few things
1. CHECK THAT THERE ARE NO LINE BREAKS AT THE END OF YOUR /home/pi/.attract/attract.cfg FILE! IF THERE ARE, REMOVE THEM!
2. BACKUP YOUR attract.cfg (just in case).
3. Create a file called 99-joypad.rules in /etc/udev/rules.d/
4. Write inside this file the string:
and save it.
This will execute the script /home/pi/.attract/changejoypad.sh at boot and every time a USB joypad/joystick (and ONLY joypads/joysticks: no HDD, NO USB PEN etc.) is plugged into the upper left USB port.
5. Make this file executable
6. Create the file /home/pi/.attract/changejoypad.sh
7 Write inside this file this script
5. Make this file executable
6. Restart.
Now.
At boot and every time a gamepad/joystick is inserted into the upper left USB port of the Raspberry Pi, this script is executed and auto-changes attractmode configs for the pad plugged in and changes ONLY joypad/joystick input settings.
So you can change ALL other parameters in attract.cfg (either manually either via the TAB graphic menu settings of attractmode) without thinking about all of the things we are doing here!
If you are in attractmode and you change the joypad in the upper left usb port the raspberry reboots automatically with new input settings (but you can comment the command
in changejoypad.sh and do everytime a manual restart if you prefer)
Note: IF any emulator is running when you change the joystick/joypad, input configs will be still modified by the script but raspberry will not auto restart (so you can complete your Bubble Boble's round 99 safely).
In this case and only in this case you should reboot manually after you exit the game because settings are changed but attractmode has not restarted so didnt reload settings.
Feel free to improve and...
if you have better solutions you are welcome to share!
I have 1 joystick and 1 gamepad (well, actually two and two), and every time i change that kind of peripherals on my Raspberry Pi (from joystick to gamepad and vice versa) I have to re-map the controllers for Attractmode (and also attach a keyboard to hit TAB).
In short, Attractmode actually (at least, my version) is not plug-and-play and does not "remember" the joysticks/joypads that I have configured in the past to navigate inside the frontend.
Pretty much frustrating, isn't it?
THE WORKAROUND (MORE THAN THE SOLUTION)
I have decided to solve this tedious problem and I share with you how I did it.
the script is not beautiful, i know (try chat GPT if you prefer ): I did it very quickly but it works for now... (maybe improve it!).
Consider it an alpha version at the moment.
ASSUMING:
The joystick/joypad that will control Attractmode will always be the one inserted in the upper left USB port of the Raspberry Pi and no others. No matter what model or brand it is, the number of buttons ecc. We need to find a rule that defines the main controller that will navigate into attractmode menus, games and options. This rule is that it will be always plugged to the upper left USB port (but obviously you can change if you want).
1. Turn off the raspberry (mine is 4 but should work for all versions)
2. Remove all USB devices
3. Plug in one kind of joystick/joypad into the upper left USB port
4. Start Attractmode
5. Configure your device in Attractmode (select, start, previous page, next letter etc.)
6. Discover the name of the joystick/joypad with the ssh command:
Code: [Select]
udevadm info --query=all --name=/dev/input/js0
the name after the string:
Code: [Select]
ID_SERIAL=
is what is we are looking for.
in my case is 0079_Generic_USB_Joystick
7. Create the file /home/pi/.attract/[nameofthejoystick].txt (in my case /home/pi/.attract/0079_Generic_USB_Joystick.txt)
8. Restart your raspberry
8. Copy the content of /home/pi/.attract/attract.cfg between 'input_map' and 'general' (be careful that the configurations called 'general' in the attract.cfg file are actually under the rules called 'input_map')
in my case:
Code: [Select]
configure Tab
add_favourite F
left Joy0 Left
left Left
right Joy0 Right
right Right
prev_letter Joy0 Button3
next_letter Joy0 Button7
next_page Joy0 Button6
prev_page Joy0 Button2
up Up
up Joy0 Up
up Joy0 PovYneg
down Down
down Joy0 Down
down Joy0 PovYpos
select Return
select Joy0 Button4
back Escape
back Joy0 Button5
default back exit
default up prev_game
default down next_game
default left prev_filter
default right next_filter
Be CAREFUL: at the end of the file, there MUST be two line breaks and NONE at the beginning!Here is a working example of a right formatted file if you want to check:
https://www.cdlab.it/0079_Generic_USB_Joystick.txt
Save it to your Desktop and open it with e.g. notepad++ to check the formatting
9. Write this content in the file /home/pi/.attract/[nameofthejoystick].txt
10. Save the file /home/pi/.attract/[nameofthejoystick].txt
11. Do all the 1-10 steps for all your different type of USB CONTROLLERS (virtually infinity).
OK: last few things
1. CHECK THAT THERE ARE NO LINE BREAKS AT THE END OF YOUR /home/pi/.attract/attract.cfg FILE! IF THERE ARE, REMOVE THEM!
2. BACKUP YOUR attract.cfg (just in case).
3. Create a file called 99-joypad.rules in /etc/udev/rules.d/
4. Write inside this file the string:
Code: [Select]
ACTION=="add", SUBSYSTEM=="input", KERNEL=="js[0-9]*", ENV{ID_PATH}=="platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0", RUN+="/home/pi/.attract/changejoypad.sh"
and save it.
This will execute the script /home/pi/.attract/changejoypad.sh at boot and every time a USB joypad/joystick (and ONLY joypads/joysticks: no HDD, NO USB PEN etc.) is plugged into the upper left USB port.
5. Make this file executable
6. Create the file /home/pi/.attract/changejoypad.sh
7 Write inside this file this script
Code: [Select]
#!/bin/bash
# Get the joypad path e.g. js0, js1, js2, js3
ID_PATH="platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0"
input_device=$(basename $(udevadm info --query=all --name=/dev/input/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0-joystick | grep "N: input/" | awk '{print $2}'))
joypadSlot=$(echo $input_device | sed 's/event[0-9]*$//')
# Set joystick name into a variable
joypadName=$(udevadm info --query=all --name=/dev/input/$joypadSlot | grep ID_SERIAL= | awk -F= '{print $2}')
sudo chown pi:pi '/home/pi/.attract/attract.cfg'
sudo chmod 775 '/home/pi/.attract/attract.cfg'
file=/home/pi/.attract/attract.cfg
# Controller_Controller_Controller 8bitdo joypad name
# 0079_Generic_USB_Joystick generic usb joystick name
replace_file="/home/pi/.attract/$joypadName.txt"
if test -f "$replace_file"; then
if test -f /home/pi/.attract/tmpjoyfile; then
sudo rm /home/pi/.attract/tmpjoyfile;
fi
touch /home/pi/.attract/tmpjoyfile
sudo chown pi:pi '/home/pi/.attract/tmpjoyfile'
sudo chmod 775 '/home/pi/.attract/tmpjoyfile'
sed -i 's/input_map.*\n\n//g' /home/pi/.attract/attract.cfg
sed -e '
/input_map/,/general/!b
//!d;/general/!b
r '"$replace_file"'
N
' /home/pi/.attract/attract.cfg > /home/pi/.attract/tmpjoyfile
mv /home/pi/.attract/tmpjoyfile /home/pi/.attract/attract.cfg
fi
# restart retropie if is not on boot mode ( so Xorg is a running service ) && no emulator is running
if pgrep -f "xorg/Xorg" &> /dev/null && ! pgrep -f "RetroPie/roms" &> /dev/null
then
#comment this if you dont want restart after a joypad is plugged in
sudo shutdown -r now
fi
5. Make this file executable
6. Restart.
Now.
At boot and every time a gamepad/joystick is inserted into the upper left USB port of the Raspberry Pi, this script is executed and auto-changes attractmode configs for the pad plugged in and changes ONLY joypad/joystick input settings.
So you can change ALL other parameters in attract.cfg (either manually either via the TAB graphic menu settings of attractmode) without thinking about all of the things we are doing here!
If you are in attractmode and you change the joypad in the upper left usb port the raspberry reboots automatically with new input settings (but you can comment the command
Code: [Select]
sudo shutdown -r now
in changejoypad.sh and do everytime a manual restart if you prefer)
Note: IF any emulator is running when you change the joystick/joypad, input configs will be still modified by the script but raspberry will not auto restart (so you can complete your Bubble Boble's round 99 safely).
In this case and only in this case you should reboot manually after you exit the game because settings are changed but attractmode has not restarted so didnt reload settings.
Feel free to improve and...
if you have better solutions you are welcome to share!