105 lines
3.9 KiB
Bash
Executable file
105 lines
3.9 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-dos-joy.sh - Joystick gate for DOS: both sticks, every direction,
|
|
# both buttons and every release, driven through DOSBox Staging's emulated
|
|
# game port and read back from what examples/joy draws; and no joystick at
|
|
# all when the game port is empty.
|
|
#
|
|
# The port (src/dos/input.c) reads the game port through the BIOS, INT 15h
|
|
# function 84h: the switches, then the four positions, both sticks connected
|
|
# while the BIOS answers. DOSBox's joysticktype 4axis gives it two sticks on
|
|
# one port, moved by host keys through a mapper file
|
|
# (scripts/lib/dosboxJoy.sh); the raw screenshots go through
|
|
# scripts/lib/joyScreen.py (scripts/lib/joyGate.sh). With joysticktype none
|
|
# the BIOS says there is no game port and JOY must show both sticks
|
|
# disconnected. Each run ends with Escape, which must end JOY (DOSBox exits
|
|
# after it).
|
|
#
|
|
# Usage: scripts/verify-dos-joy.sh
|
|
# Env: JOY_SHOTS also keep the screenshots in this folder
|
|
# Requires: DOSBox Staging, Xvfb, xdotool, python3 + PIL;
|
|
# build/dos/bin/JOY.EXE (make dos).
|
|
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/dosboxJoy.sh"
|
|
joeyNeed DOSBOX dosbox
|
|
|
|
JOY_LABEL=verify-dos-joy
|
|
program="$repo/build/dos/bin/JOY.EXE"
|
|
wall=240 # hard cap on each DOSBox run, whatever happens to this script
|
|
bootSeconds=12 # DOS booting and JOY drawing on the emulated 386SX-16
|
|
exitSeconds=10 # Escape until DOSBox, which exits after JOY, has gone
|
|
|
|
[ -f "$program" ] || { echo "$JOY_LABEL: build JOY.EXE first (make dos)" >&2; exit 2; }
|
|
|
|
JOY_WORK=$(mktemp -d -t joeylib-dos-joy.XXXXXX)
|
|
guard=""
|
|
dosbox=""
|
|
xvfb=""
|
|
cleanup() {
|
|
joeyStop "$dosbox" "$guard" "$xvfb" 2> /dev/null
|
|
rm -rf "$JOY_WORK"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
|
|
# boot RUN JOYTYPE -- JOY in DOSBox with joysticktype JOYTYPE; sets guard,
|
|
# dosbox and DOSBOX_JOY_WINDOW.
|
|
boot() {
|
|
local dir="$JOY_WORK/$1"
|
|
mkdir -p "$dir/xdg" "$dir/shots"
|
|
dosboxJoyMapper "$dir/mapper.txt"
|
|
DOSBOX_JOY_SHOTS="$dir/shots"
|
|
XDG_CONFIG_HOME="$dir/xdg" DISPLAY="$DOSBOX_JOY_DISPLAY" SDL_AUDIODRIVER=dummy \
|
|
timeout -s KILL "$wall" "$DOSBOX" "${JOEY_DOSBOX_ISOLATE[@]}" \
|
|
--conf "$repo/scripts/dosbox-386sx16.conf" --set "joysticktype=$2" \
|
|
--set "mapperfile=$dir/mapper.txt" --set "capture_dir=$dir/shots" \
|
|
-c "MOUNT C \"$(dirname "$program")\"" -c "C:" -c "$(basename "$program")" -c "EXIT" \
|
|
> "$dir/dosbox.log" 2>&1 &
|
|
guard=$!
|
|
dosbox=$(joeyChild "$guard")
|
|
sleep "$bootSeconds"
|
|
DOSBOX_JOY_WINDOW=$(joeyFindWindow "$DOSBOX_JOY_DISPLAY" "$dosbox")
|
|
[ -n "$DOSBOX_JOY_WINDOW" ] || return 1
|
|
DISPLAY="$DOSBOX_JOY_DISPLAY" xdotool windowactivate --sync "$DOSBOX_JOY_WINDOW" 2> /dev/null || true
|
|
}
|
|
|
|
|
|
# quit -- Escape, which must end JOY and with it DOSBox.
|
|
quit() {
|
|
local waited
|
|
dosboxJoyTap escape
|
|
for ((waited = 0; waited < exitSeconds; waited++)); do
|
|
joeyAlive "$guard" || break
|
|
sleep 1
|
|
done
|
|
joeyAlive "$guard" && joyFail "Escape did not end JOY"
|
|
joeyStop "$dosbox" "$guard" 2> /dev/null
|
|
dosbox=""
|
|
guard=""
|
|
}
|
|
|
|
|
|
DOSBOX_JOY_DISPLAY=":$((RANDOM % 400 + 4700))"
|
|
Xvfb "$DOSBOX_JOY_DISPLAY" -screen 0 1024x768x24 -nolisten tcp > /dev/null 2>&1 &
|
|
xvfb=$!
|
|
sleep 1
|
|
|
|
# 1. Both sticks on the game port.
|
|
boot sticks 4axis || { echo "$JOY_LABEL: FAIL - DOSBox with JOY did not come up" >&2; exit 1; }
|
|
joyCheck "rest" "A=$JOY_REST B=$JOY_REST"
|
|
joyRunSteps "${JOY_STEPS_TWO_STICKS[@]}"
|
|
quit
|
|
|
|
# 2. No game port.
|
|
boot none none || { echo "$JOY_LABEL: FAIL - DOSBox with JOY and no joystick did not come up" >&2; exit 1; }
|
|
joyCheck "no joystick" "A=$JOY_ABSENT B=$JOY_ABSENT"
|
|
quit
|
|
|
|
joyResult "$JOY_LABEL" "both sticks, every direction, both buttons and every release; no joystick without a game port; Escape ends JOY"
|