136 lines
4.4 KiB
Bash
Executable file
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)"
|