joeylib2/scripts/verify-dvx-display.sh
2026-10-13 14:01:46 -05:00

127 lines
5 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-display.sh - Display parity gate for DVX: what the present puts
# where the stage is shown must be the stage, on every desktop depth, at
# every window scale and on the full screen.
#
# The golden hashes gate the stage, never the display. UBER's probe build
# (make dvx builds it: examples/uber with UBER_PROBE) ends with a row for DVX
# (P13) that draws one-pixel stripes in all 16 colours, bands and a small rect, moves
# rows to another palette and changes that palette, presenting after each,
# and asks the port after every present how many pixels differ from the
# stage (dvxPortProbeDisplayMismatch in src/dvx/hal.c): the window's content
# buffer in the desktop's own pixel format, every screen pixel of a stage
# pixel's scale x scale block, or the full-screen backbuffer and its
# palette; each pixel derived from the stage's palette entries, not through
# the present's tables. Each run is scripts/bench-dvx.sh --probe on one
# desktop (DVX.INI's video mode), about 8 s. Every count must be 0, every
# pixel must have been compared (64000 x scale^2, plus the 256 palette
# entries on the full screen), and DVX.LOG must show the program on the
# desktop asked for, at the scale asked for.
#
# The default desktops cover each pixel size the present writes (1, 2 and
# 4 bytes) at each window scale (1x, 2x, 3x), the 8-bit desktop's nearest
# colours and both 16-bit packings (5-5-5 and 5-6-5), then the full screen
# (320x200 at 8 bits, its palette the stage's 16).
#
# Usage: scripts/verify-dvx-display.sh [WxHxBPP:SCALE | full]...
# Requires: DOSBox Staging, Xvfb, the dvx component; the probe build
# (make dvx builds it, into build/dvx/probe).
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=uberprob
stageWidth=320
stageHeight=200
stagePixels=$((stageWidth * stageHeight))
paletteEntries=256
probeLine="UBER-PROBE: dvxDisplayMismatch"
fullSpec=full
benchSeconds=120 # one probe run, boot to done line
defaults=(640x480x8:1 800x600x8:2 1024x768x8:3
640x480x16:1 800x600x15:2 1024x768x16:3
640x480x32:1 800x600x32:2 1024x768x32:3
"$fullSpec")
specs=("$@")
[ ${#specs[@]} -gt 0 ] || specs=("${defaults[@]}")
if [ ! -f "$DVX_PROBE_DIR/apps/$DVX_VENDOR/$program/$program.app" ]; then
echo "verify-dvx-display: the probe build is missing; run: make dvx" >&2
exit 2
fi
log=$DVX_PROBE_DIR/$DVX_LOG_NAME
dvxLog=$DVX_PROBE_DIR/dvx.log
fails=""
passed=0
# fail SPEC WHAT -- note a failed run; the gate goes on with the rest.
fail() {
echo "verify-dvx-display: FAIL - $1: $2"
fails="${fails:+$fails; }$1"
}
for spec in "${specs[@]}"; do
benchArgs=(--probe)
if [ "$spec" = "$fullSpec" ]; then
w=$DVX_VIDEO_W
h=$DVX_VIDEO_H
bpp=$DVX_VIDEO_BPP
scale=1
want=$((stagePixels + paletteEntries))
benchArgs+=(--full-screen)
else
if ! [[ "$spec" =~ ^([0-9]+)x([0-9]+)x([0-9]+):([0-9]+)$ ]]; then
echo "verify-dvx-display: bad desktop \"$spec\" (WxHxBPP:SCALE or $fullSpec)" >&2
exit 2
fi
w=${BASH_REMATCH[1]}
h=${BASH_REMATCH[2]}
bpp=${BASH_REMATCH[3]}
scale=${BASH_REMATCH[4]}
want=$((stagePixels * scale * scale))
fi
DVX_VIDEO_W=$w DVX_VIDEO_H=$h DVX_VIDEO_BPP=$bpp TIMEOUT=$benchSeconds \
"$repo/scripts/bench-dvx.sh" "${benchArgs[@]}" > /dev/null 2>&1
row=$(grep -F "$probeLine" "$log" 2> /dev/null | tail -1)
if [ -z "$row" ]; then
fail "$spec" "no \"$probeLine\" line (DVX.LOG follows)"
tail -n 15 "$dvxLog" 2> /dev/null
continue
fi
counts=${row#*"$probeLine" }
echo "verify-dvx-display: $spec: $counts"
if ! grep -qF "JoeyLib: Uber Probe: $((stageWidth * scale))x$((stageHeight * scale)) at ${scale}x on a ${w}x${h} ${bpp}-bit desktop" "$dvxLog"; then
fail "$spec" "DVX.LOG does not show the window at ${scale}x on a ${w}x${h} ${bpp}-bit desktop: $(grep -F 'JoeyLib: Uber Probe:' "$dvxLog")"
continue
fi
if [ "$spec" = "$fullSpec" ] && ! grep -qF "$DVX_FULL_SCREEN_LOG" "$dvxLog"; then
fail "$spec" "DVX.LOG has no \"$DVX_FULL_SCREEN_LOG\""
continue
fi
bad=$(printf '%s\n' "$counts" | tr ' ' '\n' | grep '^after' | grep -v '=0$' | tr '\n' ' ')
compared=$(printf '%s\n' "$counts" | sed -n 's/.*compared=\([0-9]*\).*/\1/p')
if [ -n "$bad" ]; then
fail "$spec" "pixels differ from the stage: $bad"
elif [ "$compared" != "$want" ]; then
fail "$spec" "compared $compared, want $want"
else
passed=$((passed + 1))
fi
done
if [ -n "$fails" ]; then
echo "verify-dvx-display: FAIL - $fails"
exit 1
fi
echo "verify-dvx-display: PASS ($passed desktops: every pixel where the stage is shown matches it after every present)"