114 lines
4.7 KiB
Bash
Executable file
114 lines
4.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# snapDemo.sh - boot a demo OMF in MAME and capture multiple SHR
|
|
# snapshots while it runs. Useful for verifying that a demo's window
|
|
# is actually drawn (vs the headless test which only checks the $99
|
|
# end-marker at $00:0070).
|
|
#
|
|
# Usage: bash scripts/snapDemo.sh <demo-name> [snap-frame-list]
|
|
# Default snap frames: 4800,5000,5200,5500,6000,6500.
|
|
# Optional env: SYSDISK=path/to/sys602.po (or other ProDOS .po).
|
|
#
|
|
# Snapshots land in a TMPDIR-rooted snapdir; the path is echoed at
|
|
# the end. The work disk image and Finder navigation script are
|
|
# cleaned up via trap.
|
|
|
|
set -euo pipefail
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
[ $# -ge 1 ] || { echo "usage: $0 <demo-name> [frames]" >&2; exit 2; }
|
|
BASE="$1"
|
|
FRAMES="${2:-4800,5000,5200,5500,6000,6500}"
|
|
|
|
CADIUS="${CADIUS:-$PROJECT_ROOT/tools/cadius/cadius}"
|
|
SYSDISK="${SYSDISK:-$PROJECT_ROOT/tools/gsos/sys602.po}"
|
|
OMF="$PROJECT_ROOT/demos/${BASE}.omf"
|
|
|
|
[ -x "$CADIUS" ] || { echo "cadius not found: $CADIUS" >&2; exit 2; }
|
|
[ -f "$SYSDISK" ] || { echo "sysdisk not found: $SYSDISK" >&2; exit 2; }
|
|
[ -f "$OMF" ] || { echo "OMF not found: $OMF (run demos/build.sh $BASE first)" >&2; exit 2; }
|
|
command -v mame >/dev/null || { echo "mame not in PATH" >&2; exit 2; }
|
|
|
|
WORK=$(mktemp -d -t snapDemo.XXXXXX)
|
|
SNAPDIR=$(mktemp -d -t snapDemoOut.XXXXXX)
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
|
|
cp "$SYSDISK" "$WORK/disk.po"
|
|
"$CADIUS" CREATEVOLUME "$WORK/data.po" DATA 800KB >/dev/null
|
|
cp "$OMF" "$WORK/HELLO#B30000"
|
|
"$CADIUS" ADDFILE "$WORK/data.po" /DATA "$WORK/HELLO#B30000" >/dev/null
|
|
|
|
# Build lua steps[] entries for each requested snap frame.
|
|
SNAP_STEPS=""
|
|
for f in ${FRAMES//,/ }; do
|
|
SNAP_STEPS="${SNAP_STEPS} {${f}, function() manager.machine.video:snapshot(); print(string.format(\"SNAP-FRAME=${f}\")) end},
|
|
"
|
|
done
|
|
|
|
cat > "$WORK/launch.lua" <<LUA
|
|
local cpu = manager.machine.devices[":maincpu"]
|
|
local mem = cpu.spaces["program"]
|
|
local nat = manager.machine.natkeyboard
|
|
local frame = 0; local idx = 1
|
|
local function gf(p,n) local pp = manager.machine.ioport.ports[p]; return pp and pp.fields[n] end
|
|
local kcmd = gf(":macadb:KEY3", "Command / Open Apple")
|
|
local function press(f) if f then f:set_value(1) end end
|
|
local function release(f) if f then f:set_value(0) end end
|
|
-- ADB mouse input ports (set when PARK_MOUSE is enabled to scroll the
|
|
-- IIgs cursor out of the snapshot region — otherwise the Finder-left
|
|
-- cursor sits on the menu bar and the inverted-XOR cursor shape leaves
|
|
-- a visible dark square in the captured screen).
|
|
local mx = gf(":macadb:MOUSE1", "Mouse X")
|
|
local my = gf(":macadb:MOUSE2", "Mouse Y")
|
|
local park_active = ${PARK_MOUSE:-0}
|
|
local park_frame_start = 5500 -- after the Cmd-O that launches the demo
|
|
local park_frame_end = 5900 -- stop nudging once well off screen
|
|
local steps = {
|
|
{3300, function() nat:post("D") end},
|
|
{3540, function() press(kcmd) end},
|
|
{3546, function() nat:post("o") end},
|
|
{3600, function() release(kcmd) end},
|
|
{4200, function() nat:post("H") end},
|
|
{4500, function() press(kcmd) end},
|
|
{4506, function() nat:post("o") end},
|
|
{4560, function() release(kcmd) end},
|
|
${SNAP_STEPS}
|
|
{8500, function()
|
|
local count = 0
|
|
for o = 0, 31999 do
|
|
if mem:read_u8(0xE12000 + o) ~= 0 then count = count + 1 end
|
|
end
|
|
print(string.format("SHR-NONZERO=%d", count))
|
|
print(string.format("MAME-READ 0x70=%02x", mem:read_u8(0x70)))
|
|
print(string.format("MAME-READ 0x71=%02x", mem:read_u8(0x71)))
|
|
print(string.format("MAME-READ 0x72=%02x", mem:read_u8(0x72)))
|
|
print(string.format("MAME-READ 0x73=%02x", mem:read_u8(0x73)))
|
|
manager.machine:exit()
|
|
end},
|
|
}
|
|
emu.register_frame_done(function()
|
|
frame = frame + 1
|
|
-- Park the cursor at the right edge of the screen when PARK_MOUSE=1.
|
|
-- ADB mouse takes deltas, so push X for a window of frames and the
|
|
-- cursor scrolls right until the IIgs cursor manager clamps it at
|
|
-- the screen edge. Don't push Y — that moves the cursor INTO the
|
|
-- demo's content area (most demos sit in the upper screen, so a
|
|
-- downward-parked cursor lands ON visible content).
|
|
if park_active == 1 and mx and my and
|
|
frame >= park_frame_start and frame <= park_frame_end then
|
|
mx:set_value(100); my:set_value(0)
|
|
end
|
|
while idx <= #steps and frame >= steps[idx][1] do
|
|
steps[idx][2](); idx = idx + 1
|
|
end
|
|
end)
|
|
LUA
|
|
|
|
timeout 200 mame apple2gs -rompath "$PROJECT_ROOT/tools/mame/roms" \
|
|
-window -nothrottle -sound none \
|
|
-snapshot_directory "$SNAPDIR" \
|
|
-seconds_to_run 180 -flop3 "$WORK/disk.po" -flop4 "$WORK/data.po" \
|
|
-autoboot_script "$WORK/launch.lua" </dev/null 2>&1 | \
|
|
grep -E "MAME-READ|SHR-|SNAP-" || true
|
|
echo "snaps in: $SNAPDIR"
|
|
find "$SNAPDIR" -name '*.png' | sort
|