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.
65 lines
2.8 KiB
Bash
Executable File
65 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Play one TUTORIAL and photograph what it teaches.
|
|
#
|
|
# The OPTIONS key-config screen names the in-flight actions but not the buttons
|
|
# they sit on, and probing the pad found the weapons only (an action that does
|
|
# not fire a gun is invisible in the ammo counters). The tutorials state the
|
|
# mapping outright — `ADVANCED CONTROLS` is index 5 and is where Change Target
|
|
# and Padlock Mode live — so read it from the game instead of guessing.
|
|
#
|
|
# Boot + nav is launch_mission.sh's route as far as the main menu, then TUTORIAL
|
|
# instead of LOAD GAME. Everything stays a CHILD of this script (no setsid): a
|
|
# detached process is not a survivable one here, see the session-lifetime note.
|
|
set -u
|
|
N="${1:-5}" # 0 BASIC, 1 HUD, 2 RADAR, 3 SUPPLY, 4 RADIO, 5 ADVANCED
|
|
SECS="${2:-150}"
|
|
TAG="${3:-tut}"
|
|
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}'; }
|
|
step(){ vgamepad dpad "$1"; sleep 0.25; vgamepad dpad center; sleep 0.7; }
|
|
shot(){ screenshot "$SHOTS/$TAG-$1.png" >/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
|
|
|
|
if ! xdpyinfo -display "$DISPLAY" >/dev/null 2>&1; then
|
|
rm -f "/tmp/.X${DISPLAY#:}-lock" 2>/dev/null || true
|
|
nohup Xvfb "$DISPLAY" -screen 0 1280x720x24 -ac -nolisten tcp \
|
|
+extension GLX +extension RANDR </dev/null >/tmp/xvfb98.log 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
|
|
|
|
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; step down # NEW GAME -> LOAD GAME -> TUTORIAL
|
|
vgamepad tap A 250; sleep 8
|
|
shot "list"
|
|
i=0; while [ "$i" -lt "$N" ]; do step down; i=$((i+1)); done
|
|
shot "pick"
|
|
vgamepad tap A 250; sleep 6
|
|
shot "sub" # some tutorials offer Level 1 / Level 2
|
|
vgamepad tap A 250
|
|
|
|
# Then just watch. The lesson drives itself and prints its instructions; tap A
|
|
# periodically to advance any prompt, and photograph often enough to catch the
|
|
# caption before it is replaced.
|
|
end=$(( SECONDS + SECS )); n=0
|
|
while [ $SECONDS -lt $end ]; do
|
|
n=$((n+1)); shot "$(printf '%02d' $n)"
|
|
[ -n "$(alive)" ] || { echo "EMULATOR GONE at ${SECONDS}s"; exit 4; }
|
|
sleep 5
|
|
[ $((n % 3)) -eq 0 ] && vgamepad tap A 250
|
|
done
|
|
echo "TUTORIAL CAPTURE DONE ($n frames)"
|