Enhancing Skills

How to Build a “System-Only” Control Panel for Batocera: Lock Your Joystick to Gameplay Only

If you want a professional arcade setup where your joystick controls gameplay and dedicated, hidden buttons handle the “technical” side (selecting, exiting, and locking the system), this guide is for you. We will use the Raspberry Pi’s GPIO pins to trigger system commands directly.


1. Hardware: The “Admin” Control Panel

Wire your buttons to these specific GPIO pins. Connect one side of each button to the GPIO pin and the other to a Ground (GND) pin.

FunctionGPIO Pin (BCM)Physical PinPurpose
Select / ConfirmGPIO 17Pin 11Launches games / Enter
Back / CancelGPIO 27Pin 13Goes back in menus / ESC
StartGPIO 22Pin 15Opens the Main Menu
HotkeyGPIO 23Pin 16Required for combo actions
Enter Kiosk ModeGPIO 24Pin 18Hidden (Lock UI)
Exit Kiosk ModeGPIO 25Pin 22Hidden (Unlock UI)
Ground (GND)Any GNDPin 6, 9, 14…Common Rail

2. Software Setup: GPIO-to-Keyboard

We need Batocera to use pins as keyboard presses rather than a joystick.

  1. Connect to your Pi via SSH (User: root / Pass: linux).
  2. Install the Adafruit Retrogame driver:
    curl https://raw.githubusercontent.com > retrogame.sh && sudo bash retrogame.sh
  3. Edit the configuration: nano /boot/retrogame.cfg and map your pins:
    • 17 ENTER (Confirm)
    • 27 ESC (Back / Exit)
    • 22 S (Start Menu)
    • 23 H (Hotkey)
    • 24 F7 (Lock Script)
    • 25 F8 (Unlock Script)

3. Scripting the Kiosk Toggle

Create two scripts to modify the system configuration on the fly.

Create the Enter Kiosk Script:
nano /userdata/system/enter_kiosk.sh

#!/bin/bash
sed -i 's/system.ui.mode=.*/system.ui.mode=Kiosk/' /userdata/system/batocera.conf
batocera-es-swissknife --restart

Create the Exit Kiosk Script:
nano /userdata/system/exit_kiosk.sh

#!/bin/bash
sed -i 's/system.ui.mode=.*/system.ui.mode=Full/' /userdata/system/batocera.conf
batocera-es-swissknife --restart

Make them executable:
chmod +x /userdata/system/*.sh


4. Forced Kiosk Mode on Startup

To make the system “Guest-Proof,” we will create a startup script that forces Kiosk mode (every time the Pi boots up).

  1. Create the custom startup script:
    nano /userdata/system/scripts/custom_start.sh
  2. Paste the following:
    #!/bin/bash case "$1" in start) sed -i 's/system.ui.mode=.*/system.ui.mode=Kiosk/' /userdata/system/batocera.conf ;; esac
  3. Make it executable:
    chmod +x /userdata/system/scripts/custom_start.sh

5. Linking Buttons to Actions (Triggerhappy)

We use Triggerhappy to link your GPIO pins to these new scripts.

  1. Create the config: nano /userdata/system/configs/multimedia_keys.conf
  2. Add these lines:
    • KEY_ESC 1 batocera-es-swissknife --emukill (Instant Exit from Game)
    • KEY_F7 1 /userdata/system/enter_kiosk.sh (Lock UI)
    • KEY_F8 1 /userdata/system/exit_kiosk.sh (Unlock UI)

6. Final Step: Lock the Joystick Out of the Menu

  1. Assign Player 1: In Controller Settings, set Player 1 to your GPIO/Keyboard device.
  2. Restrict Input: In System Settings > Frontend Developer Options, enable “Only Accept Input from Player 1.”
  3. Gameplay Swap: In Game Settings > Per-System Configuration, set the P1 Controller to your USB Joystick.

The Result

The system always boots into Kiosk Mode. Your joystick is disabled in the menus to prevent tampering. You navigate using the GPIO buttons. To change your settings, use your Hidden Unlock Button to reveal the full menus. When finished, hit Hidden Lock or reboot!


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.