Trying to read a third paint order off the running game turned up two bugs in the capture harness, both of which fail in ways that look like the game misbehaving rather than the script being wrong. 1. `--audio` is not a cvar in this tree, and eight boot scripts passed it. Xenia calls ShowSimpleMessageBox from ParseLaunchArguments, BEFORE logging is initialised, so the symptom is a 10x10 window, no log, no guest memory and a dialog that blocks on XIfEvent forever - i.e. a hang deep in the emulator. run-canary`s own header documents this exact trap; the scripts predate it. Removed from all eight. 2. `vgamepad` no longer exists - the uinput pad was replaced by the --hid=file driver and pad.py - but skip_intro.sh still called it. The script runs without `set -e`, so the call failed silently and the title branch pressed nothing while still exiting 0. A caller was told "TITLE -> A" with the game sitting on the title screen. It now presses through pad.py and exits 6 if that fails. The first bug is fixed and verified: the boot now reaches the title screen with PRESS (A) BUTTON. The second is fixed but does NOT unblock the title - see the next commit.
78 lines
3.5 KiB
Bash
Executable File
78 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Boot Canary and drive it into the Stage 02 mission from save slot 01, then
|
|
# LEAVE IT RUNNING (unlike grab_tutorial.sh, which snapshots and exits) so a
|
|
# live control loop can attach to /dev/shm.
|
|
#
|
|
# Nav is the verified route: title -> LOAD GAME -> slot 01 -> YES -> READY ROOM
|
|
# -> TAKE OFF. With `--hangar` it stops in the HANGAR instead so a loadout can
|
|
# be picked first.
|
|
set -u
|
|
MODE="${1:-fly}"
|
|
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98
|
|
SD="$(cd "$(dirname "$0")" && pwd)"
|
|
SHOTS=/sylph-home/re/shots
|
|
|
|
alive(){ ps -o pid=,stat= -C xenia_canary 2>/dev/null | awk '$2 !~ /^Z/ {print $1}'; }
|
|
|
|
# DO NOT `setsid` THE DISPLAY OR THE EMULATOR. They used to be detached into
|
|
# their own sessions so they would outlive the shell that started them. What
|
|
# that actually bought was the opposite: a process nothing owns is a process
|
|
# nothing keeps alive, and both were being reaped a couple of minutes in — the
|
|
# long-standing "Xvfb and the emulator die on their own every few minutes" note.
|
|
# MEASURED WRONG 2026-08-10: a harness-tracked BACKGROUND task does not protect
|
|
# them either — the display was lost 11 s in, at the turn boundary. Run this
|
|
# whole script as ONE BLOCKING FOREGROUND call and leave Xvfb, openbox
|
|
# and xenia as its children: they then live exactly as long as the session does.
|
|
# `nohup` still shields them from a stray HUP; the exit-status wrapper means a
|
|
# death is reported with the server's own account instead of being inferred.
|
|
ensure_display(){
|
|
if ! xdpyinfo -display "$DISPLAY" >/dev/null 2>&1; then
|
|
rm -f "/tmp/.X${DISPLAY#:}-lock" 2>/dev/null || true
|
|
nohup bash -c 'Xvfb "$0" -screen 0 1280x720x24 -ac -nolisten tcp \
|
|
+extension GLX +extension RANDR >/tmp/xvfb98.log 2>&1
|
|
echo "$(date +%T) XVFB EXIT $? (128+N means signal N)" >>/tmp/xvfb-exit.log' \
|
|
"$DISPLAY" </dev/null >/dev/null 2>&1 &
|
|
for _ in $(seq 1 50); do xdpyinfo -display "$DISPLAY" >/dev/null 2>&1 && break; sleep 0.2; done
|
|
nohup env DISPLAY="$DISPLAY" HOME=/sylph-home openbox </dev/null >/tmp/openbox98.log 2>&1 &
|
|
sleep 1
|
|
fi
|
|
xdpyinfo -display "$DISPLAY" >/dev/null 2>&1 || { echo "DISPLAY UNAVAILABLE"; exit 1; }
|
|
}
|
|
step(){ vgamepad dpad "$1"; sleep 0.25; vgamepad dpad center; sleep 0.7; }
|
|
shot(){ screenshot "$SHOTS/$1" >/dev/null 2>&1; }
|
|
|
|
pkill -x xenia_canary 2>/dev/null; sleep 2
|
|
[ -n "$(alive)" ] && { kill -9 $(alive) 2>/dev/null; sleep 2; }
|
|
rm -f /dev/shm/xenia_memory_* /dev/shm/xenia_code_cache_* 2>/dev/null
|
|
ensure_display
|
|
|
|
cd /sylph-home/re
|
|
nohup run-canary --apu=sdl --log_mask=13 \
|
|
--logged_profile_slot_0_xuid=E0300000EFBEA3D4 </dev/null >/dev/null 2>&1 &
|
|
sleep 5
|
|
"$SD/skip_intro.sh" 600 || { echo "BOOT FAILED (skip_intro exit $?)"; exit 1; }
|
|
sleep 14 # main menu is not input-ready before this
|
|
|
|
step down # NEW GAME -> LOAD GAME
|
|
vgamepad tap A 250; sleep 8 # save list, slot 01 preselected
|
|
vgamepad tap A 250; sleep 4 # "Load game?" -- cursor starts on NO
|
|
step up
|
|
vgamepad tap A 250
|
|
sleep 28 # -> READY ROOM
|
|
shot "lm-readyroom.png"
|
|
|
|
if [ "$MODE" = "--hangar" ]; then
|
|
step down; step down # BRIEFINGS -> HANGAR
|
|
vgamepad tap A 250; sleep 12
|
|
shot "lm-hangar.png"
|
|
echo "STOPPED IN HANGAR"; exit 0
|
|
fi
|
|
|
|
step up # BRIEFINGS -> TAKE OFF
|
|
vgamepad tap A 250
|
|
# The launch cinematic + stage load + objective card is NOT a fixed 75 s under
|
|
# lavapipe; wait for the flight HUD itself.
|
|
"$SD/wait_flight.sh" 300 || { echo "NEVER REACHED FLIGHT"; exit 1; }
|
|
shot "lm-flight.png"
|
|
echo "IN FLIGHT (emulator left running)"
|