joeylib2/scripts/verify-dvx-icon.sh
2026-10-19 15:46:47 -05:00

109 lines
3.7 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-icon.sh - a DVX program's icon as Program Manager shows it.
#
# make gives every DVX program its icon (make/dvx.mk: tools/iconBake bmp,
# a 32x32 24-bit BMP on DVX's gray, appended by dvxres as the icon32
# resource). DVX is staged with DRAW (examples/draw) installed and Program
# Manager, DVX's own, as the desktop (scripts/lib/dvxGate.sh), and boots in
# DOSBox Staging; Program Manager draws each program by its icon32, so
# DOSBox's own screenshot must hold the baked icon: every pixel of it that
# is not the gray, in its color (give or take TOLERANCE: the desktop is
# 16-bit).
#
# Usage: scripts/verify-dvx-icon.sh
# Env: DVX_ICON_KEEP keep the last screenshot as build/dvx/dvx-icon.png
# Exit: 0 PASS, 1 FAIL, 2 SKIP (DOSBox or DVX not installed, or DRAW not
# built)
# Requires: DOSBox Staging, Xvfb, xdotool, the dvx
# component; DRAW (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
label=verify-dvx-icon
program=draw
# DVX's own desktop program, from its DVX.INI.
progman=apps/kpunch/progman/progman.app
wall=180 # hard cap on DOSBox, whatever happens to this script
readySeconds=60 # DVX boot until its shell reports ready
lookSeconds=60 # then screenshots until the icon shows
shotSeconds=3
dvxNeedBuild "$program"
icon=$repo/build/dvx/apps/$program/icon32.bmp
[ -f "$icon" ] || { echo "$label: build DRAW first (make dvx)" >&2; exit 2; }
work=$(mktemp -d -t joeylib-dvx-icon.XXXXXX)
guard=""
dosbox=""
xvfb=""
cleanup() {
joeyStop "$dosbox" "$guard" "$xvfb" 2> /dev/null
rm -rf "$work"
}
trap cleanup EXIT
# iconShown PNG -- true when PNG holds the icon; prints the verdict.
iconShown() {
"$(joeyTool iconFind)" dvx "$1" "$icon" "$label"
}
display=":$((RANDOM % 400 + 2500))"
Xvfb "$display" -screen 0 1024x768x24 -nolisten tcp > /dev/null 2>&1 &
xvfb=$!
sleep 1
dvxStage "$work/c" "$(dvxAppDir "$program")"
dvxIniSet "$(dvxIni "$work/c")" "$progman"
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"
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 "$label: FAIL - DVX did not come up within ${readySeconds}s (DVX.LOG follows)" >&2
dvxDvxLog "$work/c" >&2
exit 1
fi
win=$(joeyFindWindow "$display" "$dosbox")
[ -n "$win" ] || { echo "$label: FAIL - DOSBox window not found" >&2; exit 1; }
lookEnd=$((SECONDS + lookSeconds))
while [ "$SECONDS" -lt "$lookEnd" ]; do
sleep "$shotSeconds"
rm -f "$work/shots/"*.png
# Ctrl+F5: DOSBox's screenshot hotkey.
DISPLAY="$display" xdotool key --window "$win" ctrl+F5
sleep 1
png=$(find "$work/shots" -name '*.png' -print -quit)
[ -n "$png" ] || continue
[ -n "${DVX_ICON_KEEP:-}" ] && cp "$png" "$repo/build/dvx/dvx-icon.png"
if iconShown "$png" > "$work/verdict"; then
cat "$work/verdict"
exit 0
fi
done
cat "$work/verdict" 2> /dev/null || echo "$label: FAIL - DOSBox took no screenshot"
exit 1