joeylib2/scripts/captureDos.sh
2026-09-24 22:01:56 -05:00

65 lines
2 KiB
Bash
Executable file

#!/usr/bin/env bash
# captureDos.sh -- run a built DOS example in headless DOSBox via Xvfb
# and snap a PNG of the simulated screen. Lets us verify the runtime
# output without an interactive emulator session.
#
# scripts/captureDos.sh staxi /tmp/staxi.png # default 5s wait
# scripts/captureDos.sh staxi /tmp/staxi.png 12 # 12s wait
#
# The wait time gives the program enough cycles to boot, draw, and
# settle on a steady frame. Increase for slow boots / cold caches.
set -euo pipefail
if [[ $# -lt 2 || $# -gt 3 ]]; then
echo "usage: $0 <example-name> <out.png> [wait-seconds]" >&2
exit 2
fi
prog=$1
out=$2
wait_s=${3:-5}
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
bin_dir=$repo/build/dos/bin
conf=$repo/scripts/dosbox-386sx16.conf
file=${prog^^}.EXE
appdir=${prog^^}
if [[ -f "$bin_dir/$appdir/$file" ]]; then
mount_dir="$bin_dir/$appdir"
elif [[ -f "$bin_dir/$file" ]]; then
mount_dir="$bin_dir"
else
echo "captureDos: $file not found in $bin_dir" >&2
exit 1
fi
display=:$((90 + RANDOM % 9))
Xvfb "$display" -screen 0 800x600x24 -nolisten tcp &
xvfb_pid=$!
sleep 0.3
trap 'kill $xvfb_pid 2>/dev/null || true; kill $dosbox_pid 2>/dev/null || true' EXIT
# Mount with an explicit -c, not by handing DOSBox the directory as a
# positional argument: 0.74-3 ignored it here and dropped the program at
# "Drive C does not exist", which looks exactly like a program that
# failed to start. The cycles override has to be one argv entry too --
# unquoted it split into three words and ate the path.
dosboxArgs=(-conf "$conf" -set "mouse_capture=seamless")
if [[ -n ${CYCLES:-} ]]; then
dosboxArgs+=(-set "cpu cycles=${CYCLES}")
fi
dosboxArgs+=(-c "mount c \"$mount_dir\"" -c "C:" -c "$file")
DISPLAY=$display SDL_VIDEO_X11_VISUALID="" \
dosbox "${dosboxArgs[@]}" >/tmp/captureDos-dosbox.log 2>&1 &
dosbox_pid=$!
# Wait for DOSBox to boot the program and settle.
sleep "$wait_s"
DISPLAY=$display import -window root -screen "$out" 2>/dev/null
echo "captureDos: wrote $out"
# DOSBox is still running -- the trap will clean it up.