joeylib2/scripts/verify-win32-display.sh

136 lines
4.4 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-win32-display.sh - Display parity gate for Win32: 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 Win32 backend
# keeps the frame in a DIB section and draws only the rectangles that
# changed at each show, so a stale or misplaced rectangle would never reach
# a hash. UBER's probe build (make win32 builds it, into build/win32/probe)
# ends with P13, the battery verify-dvx-display.sh and
# verify-win16-display.sh run, which after every step asks the backend
# (jlHostWin32ProbeDisplayMismatch in src/hosted/win32/win32Backend.c) how
# many pixels differ: the frame's against the stage, the window as the
# shows left it against the window fully repainted, and that repaint
# against GDI stretching the core's frame itself. Every count must be 0,
# and every pixel must have been compared: 64000 for the frame, plus the
# window's pixels twice.
#
# Each run is UBERPROB.EXE under Wine (scripts/lib/wineGate.sh, a
# 1280x1024 screen) with JOEYLIB_SCALE / JOEYLIB_ASPECT / JOEYLIB_FULLSCREEN
# set as the spec asks. It checks Wine's GDI, not a real Windows'.
#
# Usage: scripts/verify-win32-display.sh [SCALE[:square] | full]...
# (default: 1:square 2:square 3 full)
# Requires: Wine (install.sh install emulator:win32);
# build/win32/probe/UBERPROB.EXE (make win32).
set -uo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
source "$repo/scripts/lib/joeyEnv.sh"
source "$repo/scripts/lib/wineGate.sh"
label=verify-win32-display
wineNeed
folder=$repo/build/win32/probe
program=$folder/UBERPROB.EXE
log=$folder/joeylog.txt
probeLine="UBER-PROBE: win32DisplayMismatch"
doneLine="press any key to exit"
stageWidth=320
stageHeight=200
stagePixels=$((stageWidth * stageHeight))
screenWidth=1280
screenHeight=1024
fullSpec=full
runSeconds=120 # one probe run, start to done line
defaults=(1:square 2:square 3 "$fullSpec")
specs=("$@")
[ ${#specs[@]} -gt 0 ] || specs=("${defaults[@]}")
if [ ! -f "$program" ]; then
echo "$label: the probe build is missing; run: make win32" >&2
exit 2
fi
work=""
cleanup() {
wineStop
[ -n "$work" ] && rm -rf "$work"
}
trap cleanup EXIT
fails=""
passed=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 spec in "${specs[@]}"; do
unset JOEYLIB_SCALE JOEYLIB_ASPECT JOEYLIB_FULLSCREEN
if [ "$spec" = "$fullSpec" ]; then
export JOEYLIB_FULLSCREEN=1
# 4:3 across the whole screen.
w=$screenWidth
h=$((screenWidth * 3 / 4))
elif [[ "$spec" =~ ^([0-9]+)(:square)?$ ]]; then
scale=${BASH_REMATCH[1]}
export JOEYLIB_SCALE=$scale
w=$((stageWidth * scale))
if [ -n "${BASH_REMATCH[2]}" ]; then
export JOEYLIB_ASPECT=square
h=$((stageHeight * scale))
else
h=$((w * 3 / 4))
fi
else
echo "$label: bad spec \"$spec\" (SCALE[:square] or $fullSpec)" >&2
exit 2
fi
want=$((stagePixels + 2 * w * h))
wineStop
[ -n "$work" ] && rm -rf "$work"
work=$(mktemp -d -t joeylib-win32-display.XXXXXX)
rm -f "$log"
wineStart "$work"
wineRun "$program"
row=""
for ((waited = 0; waited < runSeconds; waited++)); do
if grep -q "$doneLine" "$log" 2> /dev/null; then
row=$(grep -F "$probeLine" "$log" | tr -d '\r' | tail -1)
break
fi
sleep 1
done
if [ -z "$row" ]; then
fail "$spec" "no \"$probeLine\" line within ${runSeconds} s"
continue
fi
counts=${row#*"$probeLine" }
echo "$label: $spec (${w}x${h}): $counts"
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: $bad"
elif [ "$compared" != "$want" ]; then
fail "$spec" "compared $compared, want $want (is the window ${w}x${h}?)"
else
passed=$((passed + 1))
fi
done
if [ -n "$fails" ]; then
echo "$label: FAIL - $fails"
exit 1
fi
echo "$label: PASS ($passed window sizes: every pixel shown matches the stage after every present)"