Files
Sylpheed/tools/re-capture/boot_menu.sh
sylph-decoder 4d954a8d0a re: two boots failed because the title gate tests for stillness on a screen that never stills
skip_intro.sh admits a static screen at d <= 1500 between grabs 0.6 s apart. Over
72 samples of the failing boot the MINIMUM was 1551 -- zero could ever pass. The
timeout is unreachable by construction, not bad luck about intro length.

The premise is in the script's own comment ('the resting title barely changes')
and it is refuted by this session's own draw capture: the title free-runs two
full-screen-height sweep leaves and pulses the plate. HANDOFF already said a
settled screen is not a static screen. wait_plate_pulse.py, which counts glyph
pixels instead of demanding stillness, reached TITLE SETTLED at 245.6 s on the
same game the same day.

Threshold deliberately NOT raised: 7 of 72 samples fall under 2000, so a gate loose
enough to admit this title would also admit movie frames -- the confusion the
script's own header records paying for once already.

Cost recorded: the focus-persistence question it was booted for is unanswered.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-30 21:15:48 +00:00

74 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Boot to the TITLE MENU and stop there — no save is loaded.
#
# nav_probe.sh's boot half deliberately loads a save, which is wrong for any
# experiment that wants to *inspect* save slots rather than enter one: with
# several probe saves on disc the load picks one of them, and a probe value the
# game cannot make sense of turns into a long "NOW PROCESSING" (or a mission
# load, if a d-pad step is dropped and A lands on TAKE OFF).
#
# From the main menu, LOAD GAME is one d-pad step away and its slot list renders
# every slot's Details panel — STAGE, Game Status, Points, Times Cleared — which
# is read straight out of each save's payload. That makes this the cheap harness
# for save-field probes: write N slots, boot once, arrow through them.
#
# Run as ONE BLOCKING FOREGROUND call. Usage: boot_menu.sh [tag]
set -u
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98
SD="$(cd "$(dirname "$0")" && pwd)"
SHOTS=/sylph-home/re/shots
TAG="${1:-menu}"
mkdir -p "$SHOTS"
alive(){ ps -o pid=,stat= -C xenia_canary 2>/dev/null | awk '$2 !~ /^Z/ {print $1}'; }
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' "$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; }
}
[ -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
# KEEP the emulator's stdout. It used to go to /dev/null, which cost a session:
# the pad appeared dead at the title and the one log line that would have said
# why — "[RE-INPUT] XamInputGetKeystrokeEx swallowed by IsUIActive" — was being
# discarded. A boot harness that throws away the emulator's own account of
# itself can only ever report symptoms.
LOG="${BOOT_MENU_LOG:-$SHOTS/$TAG-canary.stdout}"
# Sign in the profile that EXISTS. Naming a XUID with no profile behind it is
# not a no-op: the title opens a sign-in dialog, xam_dialogs_shown_ goes to 1,
# and IsUIActive() then swallows every XamInputGetKeystrokeEx for the rest of
# the run — a pad that delivers keystrokes to an emulator that discards them.
# Measured: 8.4 MILLION swallowed calls in one boot, with the pad log showing
# `vk=5800 down/up` arriving normally the whole time.
XUID="${SYLPH_XUID:-$(ls "${XENIA_CONTENT:-$HOME/.local/share/Xenia/content}" 2>/dev/null | head -1)}"
[ -n "$XUID" ] || { echo "NO PROFILE — run once with --create_profile_if_none=Tag"; exit 2; }
echo "signing in profile $XUID"
# $LOG_MASK / $LOG_LEVEL / $EXTRA_FLAGS are overridable because the defaults
# hide most of the emulator. `log_mask` DISABLES categories (Kernel=1, Apu=2,
# Cpu=4, Gpu=8), so the long-standing 13 = Kernel+Cpu+Gpu off — which is why no
# kernel call has ever appeared in a boot log from this harness. Kernel calls
# also log at Debug, so seeing them needs BOTH `LOG_MASK=12 LOG_LEVEL=3`.
nohup run-canary --apu=sdl --log_mask="${LOG_MASK:-13}" \
--log_level="${LOG_LEVEL:-2}" ${EXTRA_FLAGS:-} \
--logged_profile_slot_0_xuid="$XUID" </dev/null >"$LOG" 2>&1 &
sleep 5
# ⚠️ 600 was hardcoded here and it is NOT always enough. On 2026-08-30 a boot was
# still reporting `movie (rmse 3019)` at 601 s and failed, where runs earlier the
# same day reached the title at ~245 s. The intro's length is not constant from
# this harness, so the budget is overridable rather than pinned.
"$SD/skip_intro.sh" "${SKIP_INTRO_BUDGET:-600}" \
|| { echo "BOOT FAILED (skip_intro exit $?)"; exit 1; }
sleep 14
screenshot "$SHOTS/$TAG-menu.png" >/dev/null 2>&1
echo "AT MAIN MENU (cursor on NEW GAME); LOAD GAME is one d-pad step down"
echo "emulator log: $LOG"