#!/usr/bin/env bash # launch.sh - boot the IIgs in MAME and launch a demo OMF interactively. # # Unlike runViaFinder.sh (which is the headless smoke harness), # this script: # - Shows the MAME window so you can see the demo run # - Plays audio so SysBeep is audible # - Runs at real (throttled) speed # - No timeout - close MAME when done (Esc, then Cmd-Q) # # Usage: # bash demos/launch.sh helloBeep # bash demos/launch.sh helloWindow # # The script first builds the demo if its .omf is missing or older # than its .c source, then injects it onto a fresh ProDOS disk image # and boots GS/OS 6.0.2 with the Finder driven via Lua keyboard # automation to launch the app. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" [ $# -ge 1 ] || { echo "usage: $0 (e.g. helloBeep, helloWindow)" >&2; exit 2; } BASE="$1" SRC="$SCRIPT_DIR/$BASE.c" OMF="$SCRIPT_DIR/$BASE.omf" [ -f "$SRC" ] || { echo "no source: $SRC" >&2; exit 2; } # Rebuild if needed. if [ ! -f "$OMF" ] || [ "$SRC" -nt "$OMF" ]; then echo "Building $BASE..." bash "$SCRIPT_DIR/build.sh" "$BASE" fi CADIUS=${CADIUS:-$PROJECT_ROOT/tools/cadius/cadius} SYSDISK=${SYSDISK:-$PROJECT_ROOT/tools/gsos/sys602.po} [ -x "$CADIUS" ] || { echo "cadius not found at $CADIUS" >&2; exit 2; } [ -f "$SYSDISK" ] || { echo "sysdisk not found at $SYSDISK" >&2; exit 2; } command -v mame >/dev/null || { echo "mame not in PATH" >&2; exit 2; } WORK=$(mktemp -d -t demolaunch.XXXXXX) trap 'rm -rf "$WORK"' EXIT cp "$SYSDISK" "$WORK/disk.po" "$CADIUS" CREATEVOLUME "$WORK/data.po" DATA 800KB >/dev/null # cadius uses the source-file basename as the on-disk name; copy # the OMF to a file named HELLO with the OMF filetype (#B30000) # so GS/OS Finder shows it as an application. cp "$OMF" "$WORK/HELLO#B30000" "$CADIUS" ADDFILE "$WORK/data.po" /DATA "$WORK/HELLO#B30000" >/dev/null # Lua keyboard automation: same as runViaFinder.sh - open the Data # volume from the Finder and Cmd-O the HELLO icon. After launch # the demo runs uninterrupted until the user closes MAME. cat > "$WORK/finder.lua" <<'LUA' local nat = manager.machine.natkeyboard local frame = 0 local idx = 1 local function get_field(port, name) local p = manager.machine.ioport.ports[port] if p == nil then return nil end return p.fields[name] end local key_cmd = get_field(":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 local steps = { {3300, function() nat:post("D") end}, -- select Data {3540, function() press(key_cmd) end}, {3546, function() nat:post("o") end}, -- Cmd-O opens volume {3600, function() release(key_cmd) end}, {4200, function() nat:post("H") end}, -- select HELLO {4500, function() press(key_cmd) end}, {4506, function() nat:post("o") end}, -- Cmd-O launches {4560, function() release(key_cmd) end}, } emu.register_frame_done(function() frame = frame + 1 while idx <= #steps and frame >= steps[idx][1] do steps[idx][2]() idx = idx + 1 end end) LUA echo "Launching MAME with $BASE.omf..." echo "Close the MAME window (or hit Esc, then Cmd-Q) to exit." echo mame apple2gs \ -rompath "$PROJECT_ROOT/tools/mame/roms" \ -window \ -flop3 "$WORK/disk.po" -flop4 "$WORK/data.po" \ -autoboot_script "$WORK/finder.lua"