172 lines
6.3 KiB
Bash
Executable file
172 lines
6.3 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-win16-display.sh - Display parity gate for Win16: what the window
|
|
# shows must be the stage, at every window scale and on the full screen.
|
|
#
|
|
# The golden hashes gate the stage, never the display. The Win16 backend
|
|
# draws only the rectangles that changed at each show, scaling them itself,
|
|
# so a stale or misplaced rectangle would never reach a hash. UBER's probe
|
|
# build (make win16 builds it, into build/win16/probe) ends with P13, the
|
|
# battery verify-dvx-display.sh runs on DVX, which after every step asks the
|
|
# backend (hostWin16ProbeDisplayMismatch in src/hosted/win16/win16Backend.c)
|
|
# how many pixels differ: the frame's against the stage, the window as the
|
|
# shows left it against the window fully repainted, and, at a whole-number
|
|
# scale, that repaint against GDI's own stretch of the frame. In the
|
|
# identity layout (a palette display, 14 palettes in use or fewer) it also
|
|
# checks every window pixel's screen index against the frame's and every
|
|
# colour of the palettes in use against the system palette, which is where
|
|
# an animated colour change shows (its win16Layout line gives that count).
|
|
# Every count must be 0, and every pixel must have been compared: 64000 for
|
|
# the frame, plus the window's pixels once, or twice at a whole-number
|
|
# scale, plus the identity checks.
|
|
#
|
|
# Each run is UBERPROB.EXE on Windows 3.11 under DOSBox
|
|
# (scripts/lib/win16Gate.sh) with JOEYLIB_SCALE / JOEYLIB_ASPECT /
|
|
# JOEYLIB_FULLSCREEN set as the spec asks, on its 800x600 desktop. With the
|
|
# wing component installed every spec runs twice, its Windows with WinG and
|
|
# without (WIN16_WING), and the probe must say it drew the window that way:
|
|
# through WinG's canvas, or through device bitmaps.
|
|
#
|
|
# Usage: scripts/verify-win16-display.sh [SCALE[:square] | full]...
|
|
# (default: 1:square 2:square 2 full)
|
|
# Requires: Windows on DOSBox (install.sh install emulator:win16);
|
|
# build/win16/probe/UBERPROB.EXE (make win16).
|
|
|
|
set -uo pipefail
|
|
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
source "$repo/scripts/lib/joeyEnv.sh"
|
|
source "$repo/scripts/lib/win16Gate.sh"
|
|
|
|
label=verify-win16-display
|
|
win16Need
|
|
folder=$repo/build/win16/probe
|
|
program=UBERPROB.EXE
|
|
probeLine="UBER-PROBE: win16DisplayMismatch"
|
|
layoutLine="UBER-PROBE: win16Layout"
|
|
doneLine="press any key to exit"
|
|
stageWidth=320
|
|
stageHeight=200
|
|
stagePixels=$((stageWidth * stageHeight))
|
|
desktopWidth=800
|
|
desktopHeight=600
|
|
fullSpec=full
|
|
runSeconds=120 # one probe run, boot to done line
|
|
defaults=(1:square 2:square 2 "$fullSpec")
|
|
specs=("$@")
|
|
[ ${#specs[@]} -gt 0 ] || specs=("${defaults[@]}")
|
|
|
|
if [ ! -f "$folder/$program" ]; then
|
|
echo "$label: the probe build is missing; run: make win16" >&2
|
|
exit 2
|
|
fi
|
|
|
|
work=""
|
|
cleanup() {
|
|
win16Stop
|
|
[ -n "$work" ] && rm -rf "$work"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
fails=""
|
|
passed=0
|
|
wingModes=(0)
|
|
[ "$WIN16_WING" = "1" ] && wingModes=(1 0)
|
|
|
|
|
|
# fail SPEC WHAT -- note a failed run; the gate goes on with the rest.
|
|
fail() {
|
|
echo "$label: FAIL - $1: $2"
|
|
fails="${fails:+$fails; }$1"
|
|
}
|
|
|
|
|
|
for wing in "${wingModes[@]}"; do
|
|
for spec in "${specs[@]}"; do
|
|
WIN16_WING=$wing
|
|
name="$spec (wing=$wing)"
|
|
if [ "$spec" = "$fullSpec" ]; then
|
|
settings=(JOEYLIB_FULLSCREEN=1)
|
|
# 4:3 on the whole 800x600 screen.
|
|
w=$desktopWidth
|
|
h=$desktopHeight
|
|
elif [[ "$spec" =~ ^([0-9]+)(:square)?$ ]]; then
|
|
scale=${BASH_REMATCH[1]}
|
|
w=$((stageWidth * scale))
|
|
if [ -n "${BASH_REMATCH[2]}" ]; then
|
|
settings=(JOEYLIB_SCALE="$scale" JOEYLIB_ASPECT=square)
|
|
h=$((stageHeight * scale))
|
|
else
|
|
settings=(JOEYLIB_SCALE="$scale")
|
|
h=$((w * 3 / 4))
|
|
fi
|
|
else
|
|
echo "$label: bad spec \"$spec\" (SCALE[:square] or $fullSpec)" >&2
|
|
exit 2
|
|
fi
|
|
want=$((stagePixels + w * h))
|
|
if [ $((w % stageWidth)) -eq 0 ] && [ $((h % stageHeight)) -eq 0 ]; then
|
|
want=$((want + w * h))
|
|
fi
|
|
|
|
win16Stop
|
|
[ -n "$work" ] && rm -rf "$work"
|
|
work=$(mktemp -d -t joeylib-win16-display.XXXXXX)
|
|
rm -f "$folder/JOEYLOG.TXT" "$folder/joeylog.txt"
|
|
win16Stage "$work" "$folder" "$program"
|
|
win16Start "$work" "${settings[@]}"
|
|
row=""
|
|
layout=""
|
|
for ((waited = 0; waited < runSeconds; waited++)); do
|
|
log=$(win16Log "$folder")
|
|
if [ -n "$log" ] && grep -q "$doneLine" "$log"; then
|
|
row=$(grep -F "$probeLine" "$log" | tr -d '\r' | tail -1)
|
|
layout=$(grep -F "$layoutLine" "$log" | tr -d '\r' | tail -1)
|
|
break
|
|
fi
|
|
joeyAlive "$WIN16_GUARD" || break
|
|
sleep 1
|
|
done
|
|
if [ -z "$row" ]; then
|
|
fail "$name" "no \"$probeLine\" line within ${runSeconds} s"
|
|
continue
|
|
fi
|
|
extra=$(printf '%s\n' "$layout" | sed -n 's/.*extra=\([0-9]*\).*/\1/p')
|
|
want=$((want + ${extra:-0}))
|
|
# The identity checks cover every window pixel and at least one palette.
|
|
if [[ "$layout" == *identity=1* ]] && [ "${extra:-0}" -lt $((w * h + 16)) ]; then
|
|
fail "$name" "the identity layout's checks compared only ${extra:-0}"
|
|
continue
|
|
fi
|
|
counts=${row#*"$probeLine" }
|
|
echo "$label: $spec (${w}x${h}, ${layout#*"$layoutLine" }): $counts"
|
|
if [[ "$layout" != *"wing=$wing "* ]]; then
|
|
fail "$name" "the probe did not draw with wing=$wing"
|
|
continue
|
|
fi
|
|
# Without WinG, the identity layout on this 8-bit desktop draws through
|
|
# device bitmaps.
|
|
if [ "$wing" = 0 ] && [[ "$layout" == *identity=1* ]] && [[ "$layout" != *"ddb=1 "* ]]; then
|
|
fail "$name" "the probe did not draw through device bitmaps"
|
|
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 "$name" "pixels differ: $bad"
|
|
elif [ "$compared" != "$want" ]; then
|
|
fail "$name" "compared $compared, want $want (is the window ${w}x${h}?)"
|
|
else
|
|
passed=$((passed + 1))
|
|
fi
|
|
done
|
|
done
|
|
|
|
if [ -n "$fails" ]; then
|
|
echo "$label: FAIL - $fails"
|
|
exit 1
|
|
fi
|
|
echo "$label: PASS ($passed runs, ${#specs[@]} window sizes with and without WinG as installed: every pixel shown matches the stage after every present)"
|