The multi-monitor support information below is based on personal experimentation and is not supported by the Batocera team. Please do not contact them for assistance with this setup.
-
Download the latest Batocera beta at: https://mirrors.o2switch.fr/batocera/x86_64/beta/last/
-
Write the
batocera-x86_64-x86_64-39-20240119.img.gz
file to a USB drive using Etcher -
Boot the computer off the flash drive
-
Verify playfield screen shows the EmulationStation interface.
-
If the playfield screen does not show the EmulationStation interface, rearrange the cables from your video card to all the monitors and repeat steps 3 and 4.
-
Rotate your playfield monitor if necessary in EmulationStation:
System Settings -> Screen Rotation -> 270 degrees
- Enable WiFi:
Network Settings -> Enable Wifi
After connecting, keep track of the IP Address
- Because Batocera and EmulationStation are really designed to support single monitor setups, we will need to extend the display.
- SSH into Batocera (using the IP Address from above)
ssh -l root 192.168.1.201
The password is linux
- Determine your playfield screen:
export DISPLAY=:0
batocera-resolution currentOutput && batocera-resolution currentResolution && batocera-resolution listOutputs
DP-1
1080x1920
DP-1
DP-2
DP-5
This means your playfield is on DP-1 and has a resolution of 1080x1920, and you have 3 screens connected, DP-1
, DP-2
, and DP-5
- Add the backglass screen:
Extend the display to include the backglass monitor by putting the backglass monitor DP-2
to right of the playfield monitor DP-1
xrandr --output DP-1 --auto --output DP-2 --right-of DP-1 --auto
Confirm by running:
batocera-resolution currentOutput && batocera-resolution currentResolution && batocera-resolution listOutputs
DP-1
DP-2
1024x768
DP-1
DP-2
DP-5
So now we know the resolution of our backglass monitor is 1024x768
- Add the dmd screen:
Extend the display to include the DMD monitor by putting the DMD monitor DP-5
to right of the Backglass monitor DP-2
xrandr --output DP-5 --auto --right-of DP-2 --auto
Confirm by running:
batocera-resolution currentOutput && batocera-resolution currentResolution && batocera-resolution listOutputs
DP-1
DP-2
DP-5
1360x768
DP-1
DP-2
DP-5
So now we know the resolution of our dmd monitor is 1360x768
- Create a
/userdata/system/custom.sh
script to automatically extend the desktop on startup:
#!/bin/bash
case "$1" in
start)
# give some time for the playfield monitor to setup and rotated properly
# you can adjust this value based on how fast this happens
sleep 10
export DISPLAY=:0
export PATH=.:$PATH
# Extend display to include backglass monitor to the right of the playfield monitor
xrandr --output DP-1 --auto --output DP-2 --right-of DP-1 --auto
# Extend display to also include dmd monitor to the right of the backglass monitor
xrandr --output DP-5 --auto --right-of DP-2 --auto
# Give some time for xrandr to finish
sleep 1
;;
esac
exit $?
- Adjust
/userdata/system/configs/vpinball/VPinballX.ini
to use these new displays:
PinMAMEWindowX = 2104
PinMAMEWindowY = 160
PinMAMEWindowWidth = 1360
PinMAMEWindowHeight = 340
.
.
.
FlexDMDWindowX = 2104
FlexDMDWindowY = 160
FlexDMDWindowWidth = 1360
FlexDMDWindowHeight = 340
.
.
.
B2SBackglassX = 1080
B2SBackglassY = 0
B2SBackglassWidth = 1024
B2SBackglassHeight = 768
B2SDMDX = 2104
B2SDMDY = 160
B2SDMDWidth = 1360
B2SDMDHeight = 340
You may have to launch a table once before this file is created.
- Reboot
reboot
If you want EmulationStation to change the backglass image when selecting games, you can use VPXDS
- SSH into Batocera (using the IP Address from above)
ssh -l root 192.168.1.201
- make two new
vpxds
directories:
mkdir /userdata/system/configs/vpinball/vpxds
mkdir /userdata/roms/vpinball/vpxds
- Download and extract the
vpxds
binary:
cd /userdata/system/configs/vpinball/vpxds
wget -q https://github.com/jsm174/vpxds/releases/download/vpxds-0.0.1/vpxds-0-0-1-linux-x64.tar.gz
tar -zxvf vpxds-0-0-1-linux-x64.tar.gz
rm vpxds-0-0-1-linux-x64.tar.gz
- update the
vpxds.ini
file to match the settings you derived earlier:
TableWidth=1080
TableHeight=1920
CachePath=/userdata/roms/vpinball/vpxds
Backglass=1
BackglassX=1080
BackglassY=0
BackglassWidth=1024
BackglassHeight=768
DMD=1
DMDX=2104
DMDY=0
DMDWidth=1360
DMDHeight=768
- update
/userdata/system/custom.sh
to launch thevpxds
executable on startup:
.
.
# Give some time for xrandr to finish
sleep 1
cd /userdata/system/configs/vpinball/vpxds
vpxds > /dev/null 2>&1 &
.
.
.
- In EmulationStation, enable the Web API access:
System Settings -> Frontend Developer Options -> Enable Public Web API Access
- Create an EmulationStation
game-selected.sh
script to callvpxds
when a game is selected:
/userdata/system/configs/emulationstation/scripts/game-selected/game-selected.sh
:
#!/bin/bash
Gamepath="${2}"
urlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}
vpx=$(urlencode "${Gamepath}")
curl -S "http://127.0.0.1:8111/update?display=backglass&path=${vpx}" > /dev/null 2>&1
Make sure to make this file executable:
chmod +x /userdata/system/configs/emulationstation/scripts/game-selected/game-selected.sh
- Reboot
reboot
-
Launch a Visual Pinball table
-
In a web browser, access
vpxds
by going to http://192.168.1.201:8111 -
Click the
Capture Backglass
button -
Exit back to EmulationStation
-
Verify the captured backglass appears when cycling through games
- SSH into Batocera (using the IP Address from above)
ssh -l root 192.168.1.201
- Update the
inputConfig
in/userdata/system/configs/emulationstation/es_input.cfg
:
<inputConfig type="keyboard" deviceName="Keyboard" deviceGUID="-1">
<input name="up" type="key" id="1073742049" value="1" />
<input name="down" type="key" id="1073742053" value="1" />
<input name="left" type="key" id="1073741904" value="1" />
<input name="right" type="key" id="1073741903" value="1" />
<input name="a" type="key" id="49" value="1" />
<input name="b" type="key" id="13" value="1" />
<input name="pagedown" type="key" id="1073742052" value="1" />
<input name="pageup" type="key" id="1073742048" value="1" />
<input name="select" type="key" id="8" value="1" />
<input name="start" type="key" id="50" value="1" />
<input name="x" type="key" id="61" value="1" />
<input name="y" type="key" id="45" value="1" />
</inputConfig>
This maps to:
<input name="up" type="key" id="1073742049" value="1" /> LEFT FLIPPER (Left Shift)
<input name="down" type="key" id="1073742053" value="1" /> RIGHT FLIPPER (Right Shift)
<input name="left" type="key" id="1073741904" value="1" />
<input name="right" type="key" id="1073741903" value="1" />
<input name="a" type="key" id="49" value="1" /> START BUTTON (1)
<input name="b" type="key" id="13" value="1" /> LAUNCH BALL (Return)
<input name="pagedown" type="key" id="1073742052" value="1" /> RIGHT MAGNA (Right Control)
<input name="pageup" type="key" id="1073742048" value="1" /> LEFT MAGNA (Left Control)
<input name="select" type="key" id="8" value="1" />
<input name="start" type="key" id="50" value="1" /> EXTRA BALL (2)
<input name="x" type="key" id="61" value="1" />
<input name="y" type="key" id="45" value="1" />
- Reboot
reboot