joeylib2/scripts/run-amiga-headless.sh
2026-09-24 22:01:56 -05:00

107 lines
3.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# run-amiga-headless.sh - Run one built Amiga example under FS-UAE with no
# window, wait, then hand back the example's joeylog.txt and a screenshot.
#
# This is the smoke test bench-amiga.sh cannot be: that script runs UBER
# and waits for its "press any key to exit" line, but a game never exits.
# Here the run is simply given N seconds and whatever it logged and drew
# is reported.
#
# The Amiga's joeylog.txt lands in the directory mounted as the hard
# drive, so it can be read straight off the host while the machine runs.
#
# Usage: scripts/run-amiga-headless.sh [example] [seconds] [fastKB]
# example binary name in build/amiga/bin, default Taxi
# seconds how long to let it run, default 90
# fastKB fast memory in KB, default 2048. Pass 0 for a
# genuinely bare 512 KB-chip A500 (slow memory off
# as well), which is the tight case.
# Requires: fs-uae, Xvfb, toolchains/emulators/support/kickstart.rom.
set -euo pipefail
prog=${1:-Taxi}
seconds=${2:-90}
fastKb=${3:-2048}
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
binDir=$repo/build/amiga/bin
support=$repo/toolchains/emulators/support
kickstart=$support/kickstart.rom
outDir=${AMIGA_OUT_DIR:-$repo/build/amiga/headless}
# Most examples are a bare binary in bin/; Space Taxi ships as its own
# drawer holding the binary and its DATA tree, so accept either shape.
if [ -d "$binDir/$prog" ]; then
progDir=$binDir/$prog
[ -f "$progDir/$prog" ] || { echo "run-amiga-headless: $progDir/$prog not built" >&2; exit 2; }
elif [ -f "$binDir/$prog" ]; then
progDir=""
else
echo "run-amiga-headless: $binDir/$prog not built" >&2
exit 2
fi
[ -f "$kickstart" ] || { echo "run-amiga-headless: missing $kickstart" >&2; exit 2; }
work=$(mktemp -d -t joeylib-amiga-run.XXXXXX)
mkdir -p "$work/s" "$outDir"
if [ -n "$progDir" ]; then
cp -r "$progDir/." "$work/"
else
find "$binDir" -maxdepth 1 -type f -executable -exec cp -t "$work/" {} +
[ -d "$binDir/DATA" ] && cp -r "$binDir/DATA" "$work/"
fi
printf 'stack 32768\n:%s\n' "$prog" > "$work/s/startup-sequence"
display=:$((90 + RANDOM % 9))
Xvfb "$display" -screen 0 800x600x24 -nolisten tcp >/dev/null 2>&1 &
xvfbPid=$!
sleep 1
fsArgs=(
--amiga_model=A500
--hard_drive_0="$work"
--hard_drive_0_label=JOEYLIB
--kickstart_file="$kickstart"
--automatic_input_grab=0
--fullscreen=0
--fade_out_duration=0
)
# Always pass the memory explicitly. Leaving --fast_memory off does NOT
# give a bare machine: FS-UAE's A500 default still fits the 512 KB
# trapdoor expansion, which AvailMem reports as ~300 KB of FAST. A real
# unexpanded A500 is 512 KB of CHIP and nothing else, so fastKB=0 has to
# turn the slow memory off too.
fsArgs+=(--fast_memory="$fastKb")
[ "$fastKb" = "0" ] && fsArgs+=(--slow_memory=0)
DISPLAY=$display fs-uae "${fsArgs[@]}" > "$work/fsuae.log" 2>&1 &
fsPid=$!
cleanup() {
kill "$fsPid" 2>/dev/null || true
kill "$xvfbPid" 2>/dev/null || true
wait 2>/dev/null || true
}
trap cleanup EXIT
echo "run-amiga-headless: $prog for ${seconds}s on an A500 with ${fastKb} KB fast..." >&2
elapsed=0
while [ "$elapsed" -lt "$seconds" ]; do
sleep 5
elapsed=$((elapsed + 5))
kill -0 "$fsPid" 2>/dev/null || { echo "run-amiga-headless: FS-UAE exited early" >&2; break; }
done
DISPLAY=$display import -window root "$outDir/$prog.png" 2>/dev/null || true
cp "$work/joeylog.txt" "$outDir/$prog-joeylog.txt" 2>/dev/null || true
cp "$work/fsuae.log" "$outDir/$prog-fsuae.log" 2>/dev/null || true
cleanup
trap - EXIT
rm -rf "$work"
echo "run-amiga-headless: wrote $outDir/$prog.png"
if [ -f "$outDir/$prog-joeylog.txt" ]; then
echo "--- joeylog.txt (last 25 lines)"
tail -25 "$outDir/$prog-joeylog.txt"
else
echo "run-amiga-headless: NO joeylog.txt -- the example never logged anything" >&2
fi