joeylib2/scripts/verify-sdl3-joy.sh
2026-10-13 14:01:46 -05:00

91 lines
3.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
# verify-sdl3-joy.sh - Joystick gate for the SDL3 port: both sticks, every
# direction, both buttons and every release, driven through two virtual
# gamepads and read back from what examples/joy draws; then the pads
# unplugged while JOY runs.
#
# The port (src/hosted/sdl3/sdl3Backend.c) opens the first two gamepads SDL
# offers as JOYSTICK_0 and JOYSTICK_1: the left stick, the south button as
# button 0 and the east as button 1, plugged and unplugged as they come and
# go. The pads are Linux uinput devices laid out as Xbox 360 pads
# (scripts/lib/padGate.sh), the only ones SDL is let see; JOY runs on a
# private Xvfb display through SDL's X11 driver at one window pixel per
# stage pixel, and window grabs go through scripts/lib/joyScreen.py
# (scripts/lib/joyGate.sh). Removing the pads must leave both sticks
# disconnected, and Escape must then end JOY.
#
# Usage: scripts/verify-sdl3-joy.sh
# Env: JOY_SHOTS also keep the screenshots in this folder
# Requires: write access to /dev/uinput, Xvfb, xdotool, ImageMagick,
# python3 + PIL; build/sdl3/bin/JOY (make sdl3).
set -uo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
source "$repo/scripts/lib/joeyEnv.sh"
source "$repo/scripts/lib/joyGate.sh"
source "$repo/scripts/lib/padGate.sh"
JOY_LABEL=verify-sdl3-joy
JOY_SCALE=1
program=$(joeyExampleProgram joy sdl3)
wall=120 # hard cap on JOY, whatever happens to this script
readySeconds=10 # JOY's window up and drawn, with both pads open
exitSeconds=5 # Escape until JOY has gone
[ -f "$program" ] || { echo "$JOY_LABEL: build JOY first (make sdl3)" >&2; exit 2; }
JOY_WORK=$(mktemp -d -t joeylib-sdl3-joy.XXXXXX)
guard=""
xvfb=""
display=""
win=""
cleanup() {
padStop
joeyStop "$guard" "$xvfb" 2> /dev/null
rm -rf "$JOY_WORK"
}
trap cleanup EXIT
joyShot() {
DISPLAY="$display" import -window "$win" "$1" 2> /dev/null
}
display=":$((RANDOM % 400 + 5900))"
Xvfb "$display" -screen 0 1024x768x24 -nolisten tcp > /dev/null 2>&1 &
xvfb=$!
sleep 1
padStart "$JOY_WORK"
(cd "$(dirname "$program")" && exec env DISPLAY="$display" SDL_VIDEO_DRIVER=x11 SDL_AUDIO_DRIVER=dummy \
JOEYLIB_SCALE=1 JOEYLIB_ASPECT=square "${PAD_ONLY_ENV[@]}" timeout -s KILL "$wall" "$program") \
> "$JOY_WORK/joy.log" 2>&1 &
guard=$!
for ((waited = 0; waited < readySeconds; waited++)); do
sleep 1
win=$(joeyFindWindow "$display" "$(joeyChild "$guard")") && break
done
[ -n "$win" ] || { echo "$JOY_LABEL: FAIL - JOY's window did not come up" >&2; cat "$JOY_WORK/joy.log" >&2; exit 1; }
DISPLAY="$display" xdotool windowfocus --sync "$win" 2> /dev/null || true
sleep 1
padOrder
joyCheck "rest" "A=$JOY_REST B=$JOY_REST"
joyRunSteps "${JOY_STEPS_TWO_STICKS[@]}"
padStop
sleep "$JOY_PRESS_SECONDS"
joyCheck "pads unplugged" "A=$JOY_ABSENT B=$JOY_ABSENT"
DISPLAY="$display" xdotool key Escape
for ((waited = 0; waited < exitSeconds; waited++)); do
joeyAlive "$guard" || break
sleep 1
done
joeyAlive "$guard" && joyFail "Escape did not end JOY"
joyResult "$JOY_LABEL" "both pads, every direction, both buttons and every release; unplugged, both sticks gone; Escape ends JOY"