#!/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"