#!/usr/bin/env bash # verify-dvx-input.sh - Typed-character and present gate for DVX. Runs KEYS # (examples/keys) as the desktop of a scratch DVX in DOSBox Staging under # Xvfb and types the RetroNet definition-of-done string with xdotool (real X # key events: ':' needs Shift, which DVX's keyboard layout applies before the # window's onKey hands the character to jlInputGetChar). Two checks: # 1. the present: a raw screenshot of the desktop must show KEYS's # verification scanline (row 198: sentinel, count, every received # character as two pixel nibbles) somewhere -- the window's content, # expanded from the stage through the port's palette tables into DVX's # 16-bit desktop -- decoding to exactly the typed bytes # (scripts/lib/keysRow.py); # 2. the typed history: after Escape, KEYS logs every received character # as hex to its joeylog.txt (in its settings folder), which must equal # the typed ASCII. # # Usage: scripts/verify-dvx-input.sh # Requires: DOSBox Staging, Xvfb, xdotool, python3 + PIL, the dvx component; # the keys program (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 program=keys target="192.168.1.10:6510" wall=180 # hard cap on DOSBox, whatever happens to this script readySeconds=60 # DVX boot until its shell reports ready settleSeconds=3 # then KEYS opening its window and taking the focus logSeconds=30 # Escape until KEYS's typed line is in its log dvxNeedBuild "$program" work=$(mktemp -d -t joeylib-dvx-input.XXXXXX) guard="" dosbox="" xvfb="" # 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 dvxStage "$work/c" "$(dvxAppDir "$program")" dvxDosboxConf "$work/dosbox.conf" "$work/c" printf '\n[capture]\ncapture_dir = %s\ndefault_image_capture_formats = raw\n' "$work/shots" >> "$work/dosbox.conf" mkdir -p "$work/xdg" "$work/shots" display=":$((RANDOM % 400 + 2500))" Xvfb "$display" -screen 0 1024x768x24 -nolisten tcp > /dev/null 2>&1 & xvfb=$! sleep 1 XDG_CONFIG_HOME="$work/xdg" DISPLAY="$display" SDL_AUDIODRIVER=dummy \ timeout -s KILL "$wall" "$DOSBOX" "${JOEY_DOSBOX_ISOLATE[@]}" \ --conf "$work/dosbox.conf" > "$work/dosbox.log" 2>&1 & guard=$! dosbox=$(joeyChild "$guard") ready="" for ((waited = 0; waited < readySeconds; waited++)); do if dvxDvxLog "$work/c" 200 | grep -q "DVX Shell ready"; then ready=1 break fi joeyAlive "$guard" || break sleep 1 done if [ -z "$ready" ]; then echo "verify-dvx-input: FAIL - DVX did not come up within ${readySeconds}s (DVX.LOG follows)" >&2 dvxDvxLog "$work/c" >&2 exit 1 fi sleep "$settleSeconds" win=$(joeyFindWindow "$display" "$dosbox") if [ -z "$win" ]; then echo "verify-dvx-input: FAIL - DOSBox window not found" >&2 exit 1 fi DISPLAY="$display" xdotool windowactivate --sync "$win" 2> /dev/null || true DISPLAY="$display" xdotool type --window "$win" --delay 150 -- "$target" sleep 2 # Ctrl+F5 = DOSBox screenshot hotkey. DISPLAY="$display" xdotool key --window "$win" ctrl+F5 sleep 2 DISPLAY="$display" xdotool key --window "$win" Escape log=$(dvxAwaitLog "$work/c" "$program" '^typed=' "$logSeconds" "$guard") cp "$log" "$work/joeylog.txt" 2> /dev/null joeyStop "$dosbox" "$guard" 2> /dev/null dosbox="" guard="" png=$(ls "$work"/shots/*.png 2> /dev/null | head -1) if [ -z "$png" ]; then echo "verify-dvx-input: FAIL - no screenshot captured" >&2 exit 1 fi if [ -z "$log" ]; then echo "verify-dvx-input: FAIL - KEYS logged no typed line within ${logSeconds}s of Escape" >&2 exit 1 fi fails="" python3 "$repo/scripts/lib/keysRow.py" "$png" "$target" || fails="the present" dvxKeysTyped "$work/joeylog.txt" "$target" || fails="${fails:+$fails, }the log" if [ -n "$fails" ]; then echo "verify-dvx-input: FAIL - $fails" exit 1 fi echo "verify-dvx-input: PASS (typed \"$target\": all ${#target} chars reached jlInputGetChar, and the present shows them)"