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