230 lines
8.8 KiB
Bash
Executable file
230 lines
8.8 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-dvx-fullscreen.sh - Full-screen gate for DVX: a program on the whole
|
|
# screen in DVX's exclusive mode (src/dvx/hal.c), started there by the port's
|
|
# own setting as Game > Full Screen leaves it (dvxFullScreen), and read back
|
|
# from DOSBox's raw screenshots of the VGA screen. Two runs of a scratch DVX
|
|
# in DOSBox Staging under Xvfb:
|
|
# 1. UBER on the whole screen, suspended part way (Ctrl+Esc: DVX's Task
|
|
# Manager takes the focus, the desktop comes back and UBER presents into
|
|
# its window) and resumed (the Task Manager's Switch To): the
|
|
# screenshots must be the 320x200 mode, the desktop, then 320x200 again;
|
|
# DVX.LOG must show the mode set twice; and UBER's hashes must equal
|
|
# the DOS port's (tests/goldens/uber/dos.txt): the stage is DOS's
|
|
# wherever it is shown.
|
|
# 2. KEYS on the whole screen: the typed string must reach jlInputGetChar
|
|
# (its log), and its verification row must read back off the 320x200
|
|
# screen at exactly the stage's own (0,198) (tests/gate/keysRow.c):
|
|
# the full-screen present, its palette and its placement. Alt+keypad
|
|
# Enter (DOSBox keeps Alt+Enter for its own full screen) takes KEYS back
|
|
# to its window, where the row must be found on the desktop; the same
|
|
# keys again, and the row must be at (0,198) once more. The setting must
|
|
# still say full screen.
|
|
#
|
|
# Usage: scripts/verify-dvx-fullscreen.sh
|
|
# Env: DVX_FULLSCREEN_SHOTS also copy the screenshots into this folder
|
|
# Requires: DOSBox Staging, Xvfb, xdotool, the dvx component;
|
|
# the uber and keys programs (make dvx).
|
|
set -uo pipefail
|
|
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
source "$repo/scripts/lib/joeyEnv.sh"
|
|
source "$repo/scripts/lib/dvxGate.sh"
|
|
joeyNeed DOSBOX dosbox
|
|
joeyNeed DVX_ROOT dvx
|
|
|
|
target="192.168.1.10:6510"
|
|
wall=180 # hard cap on each DOSBox run, whatever happens to this script
|
|
readySeconds=60 # DVX boot until its shell reports ready
|
|
settleSeconds=3 # then the program taking the screen
|
|
stepSeconds=2 # a key, then DVX and the program acting on it
|
|
shotSeconds=5 # Ctrl+F5 until DOSBox has written the screenshot
|
|
holdSeconds=0.3 # a key held that long: a quick tap can fall between two polls
|
|
uberSeconds=120 # UBER's run until its done line
|
|
logSeconds=30 # Escape until KEYS's typed line is in its log
|
|
fullSize=320x200 # DVX's full-screen mode for the stage: VGA mode 13h here
|
|
desktopSize="${DVX_VIDEO_W}x${DVX_VIDEO_H}"
|
|
rowAt=0,198 # KEYS's verification row at 1x: its place on the stage
|
|
uberDone="press any key to exit"
|
|
|
|
dvxNeedBuild uber keys
|
|
|
|
work=$(mktemp -d -t joeylib-dvx-fullscreen.XXXXXX)
|
|
guard=""
|
|
dosbox=""
|
|
xvfb=""
|
|
win=""
|
|
fails=""
|
|
# 2>/dev/null: bash reports the SIGKILLed timeout wrapper as "Killed".
|
|
cleanup() {
|
|
joeyStop "$dosbox" "$guard" "$xvfb" 2> /dev/null
|
|
rm -rf "$work"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
|
|
# boot PROGRAM -- DVX staged in $work/PROGRAM with PROGRAM its desktop, on the
|
|
# whole screen from the start; sets guard, dosbox and win.
|
|
boot() {
|
|
local dir="$work/$1"
|
|
local waited
|
|
dvxStage "$dir/c" "$(dvxAppDir "$1")"
|
|
dvxFullScreen "$dir/c" "$1"
|
|
dvxDosboxConf "$dir/dosbox.conf" "$dir/c"
|
|
printf '\n[capture]\ncapture_dir = %s\ndefault_image_capture_formats = raw\n' "$dir/shots" >> "$dir/dosbox.conf"
|
|
mkdir -p "$dir/xdg" "$dir/shots"
|
|
XDG_CONFIG_HOME="$dir/xdg" DISPLAY="$display" SDL_AUDIODRIVER=dummy \
|
|
timeout -s KILL "$wall" "$DOSBOX" "${JOEY_DOSBOX_ISOLATE[@]}" \
|
|
--conf "$dir/dosbox.conf" > "$dir/dosbox.log" 2>&1 &
|
|
guard=$!
|
|
dosbox=$(joeyChild "$guard")
|
|
for ((waited = 0; waited < readySeconds; waited++)); do
|
|
if dvxDvxLog "$dir/c" 200 | grep -q "DVX Shell ready"; then
|
|
sleep "$settleSeconds"
|
|
win=$(joeyFindWindow "$display" "$dosbox")
|
|
[ -n "$win" ] || return 1
|
|
DISPLAY="$display" xdotool windowactivate --sync "$win" 2> /dev/null || true
|
|
return 0
|
|
fi
|
|
joeyAlive "$guard" || return 1
|
|
sleep 1
|
|
done
|
|
return 1
|
|
}
|
|
|
|
|
|
# fail WHAT -- note a failed check; the gate goes on to report the rest.
|
|
fail() {
|
|
echo "verify-dvx-fullscreen: FAIL - $1"
|
|
fails="${fails:+$fails; }$1"
|
|
}
|
|
|
|
|
|
# fullScreenSets PROGRAM -- how often DVX.LOG says the full-screen mode was set.
|
|
fullScreenSets() {
|
|
dvxDvxLog "$work/$1/c" 400 | grep -c "$DVX_FULL_SCREEN_LOG"
|
|
}
|
|
|
|
|
|
# hold KEY... -- press the keys in order, each held holdSeconds before the
|
|
# next (a chord's modifier goes down first), release them in reverse, then
|
|
# give DVX and the program time to act.
|
|
hold() {
|
|
local k
|
|
local i
|
|
for k in "$@"; do
|
|
DISPLAY="$display" xdotool keydown --window "$win" "$k"
|
|
sleep "$holdSeconds"
|
|
done
|
|
for ((i = $#; i >= 1; i--)); do
|
|
DISPLAY="$display" xdotool keyup --window "$win" "${!i}"
|
|
done
|
|
sleep "$stepSeconds"
|
|
}
|
|
|
|
|
|
# shot PROGRAM NAME SIZE -- a DOSBox screenshot (Ctrl+F5: the raw VGA picture)
|
|
# as $work/NAME.png, which must be SIZE.
|
|
shot() {
|
|
local png
|
|
local size
|
|
local waited
|
|
DISPLAY="$display" xdotool key --window "$win" ctrl+F5
|
|
for ((waited = 0; waited < shotSeconds; waited++)); do
|
|
sleep 1
|
|
png=$(ls "$work/$1/shots/"*.png 2> /dev/null | head -1)
|
|
if [ -n "$png" ]; then
|
|
mv "$png" "$work/$2.png"
|
|
size=$("$(joeyTool pngProbe)" size "$work/$2.png")
|
|
echo "verify-dvx-fullscreen: $2: $size"
|
|
[ "$size" = "$3" ] || fail "$2 is $size, want $3"
|
|
return 0
|
|
fi
|
|
done
|
|
fail "no screenshot for $2"
|
|
}
|
|
|
|
|
|
# stop -- end the DOSBox run.
|
|
stop() {
|
|
joeyStop "$dosbox" "$guard" 2> /dev/null
|
|
dosbox=""
|
|
guard=""
|
|
}
|
|
|
|
|
|
display=":$((RANDOM % 400 + 3700))"
|
|
Xvfb "$display" -screen 0 1024x768x24 -nolisten tcp > /dev/null 2>&1 &
|
|
xvfb=$!
|
|
sleep 1
|
|
|
|
# 1. UBER: the hashes on the whole screen, through a suspend and a resume.
|
|
if ! boot uber; then
|
|
echo "verify-dvx-fullscreen: FAIL - DVX with UBER did not come up (DVX.LOG follows)" >&2
|
|
dvxDvxLog "$work/uber/c" >&2
|
|
exit 1
|
|
fi
|
|
shot uber uberFull "$fullSize"
|
|
hold ctrl Escape
|
|
shot uber uberSuspended "$desktopSize"
|
|
hold alt s
|
|
shot uber uberResumed "$fullSize"
|
|
log=$(dvxAwaitLog "$work/uber/c" uber "$uberDone" "$uberSeconds" "$guard")
|
|
sets=$(fullScreenSets uber)
|
|
stop
|
|
echo "verify-dvx-fullscreen: UBER: full-screen mode set $sets times"
|
|
[ "$sets" -ge 2 ] || fail "UBER: DVX set the full-screen mode $sets times, want 2 (start, resume)"
|
|
if [ -z "$log" ]; then
|
|
fail "UBER wrote no \"$uberDone\" within ${uberSeconds}s"
|
|
else
|
|
tr -d '\r' < "$log" > "$work/uber.txt"
|
|
if hashes=$("$(joeyTool diffUberHashes)" "$repo/tests/goldens/uber/dos.txt" "$work/uber.txt"); then
|
|
echo "verify-dvx-fullscreen: UBER hashes: $(printf '%s\n' "$hashes" | tail -1)"
|
|
else
|
|
printf '%s\n' "$hashes"
|
|
fail "UBER's hashes on the whole screen differ from the DOS port's"
|
|
fi
|
|
fi
|
|
|
|
# 2. KEYS: the typed row read off the screen, full screen, window, full again.
|
|
if ! boot keys; then
|
|
echo "verify-dvx-fullscreen: FAIL - DVX with KEYS did not come up (DVX.LOG follows)" >&2
|
|
dvxDvxLog "$work/keys/c" >&2
|
|
exit 1
|
|
fi
|
|
DISPLAY="$display" xdotool type --window "$win" --delay 150 -- "$target"
|
|
sleep "$stepSeconds"
|
|
shot keys keysFull "$fullSize"
|
|
"$(joeyTool keysRow)" "$work/keysFull.png" "$target" --at "$rowAt" || fail "KEYS's row on the whole screen"
|
|
hold alt KP_Enter
|
|
shot keys keysWindow "$desktopSize"
|
|
"$(joeyTool keysRow)" "$work/keysWindow.png" "$target" || fail "KEYS's row in its window after leaving the whole screen"
|
|
hold alt KP_Enter
|
|
shot keys keysFullAgain "$fullSize"
|
|
"$(joeyTool keysRow)" "$work/keysFullAgain.png" "$target" --at "$rowAt" || fail "KEYS's row on the whole screen again"
|
|
hold Escape
|
|
log=$(dvxAwaitLog "$work/keys/c" keys '^typed=' "$logSeconds" "$guard")
|
|
sets=$(fullScreenSets keys)
|
|
stop
|
|
echo "verify-dvx-fullscreen: KEYS: full-screen mode set $sets times"
|
|
[ "$sets" -ge 2 ] || fail "KEYS: DVX set the full-screen mode $sets times, want 2 (start, Alt+Enter)"
|
|
if [ -z "$log" ]; then
|
|
fail "KEYS logged no typed line within ${logSeconds}s of Escape"
|
|
else
|
|
dvxKeysTyped "$log" "$target" || fail "KEYS's typed log"
|
|
fi
|
|
setting=$(find "$work/keys/c/DVX" -ipath "*/config/apps/$DVX_VENDOR/keys/$DVX_SETTINGS_FILE" -print -quit)
|
|
tr -d '\r' < "$setting" 2> /dev/null | grep -qi "^$DVX_SETTINGS_FULL_SCREEN *= *true" || fail "the setting does not say full screen after switching back ($setting)"
|
|
|
|
if [ -n "${DVX_FULLSCREEN_SHOTS:-}" ]; then
|
|
mkdir -p "$DVX_FULLSCREEN_SHOTS"
|
|
cp "$work"/*.png "$DVX_FULLSCREEN_SHOTS/"
|
|
fi
|
|
if [ -n "$fails" ]; then
|
|
echo "verify-dvx-fullscreen: FAIL - $fails"
|
|
exit 1
|
|
fi
|
|
echo "verify-dvx-fullscreen: PASS (UBER's hashes on the whole screen through a suspend and resume; KEYS's typed row read off the 320x200 screen at (0,198), in its window, and full screen again)"
|