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
74 lines
4.0 KiB
Bash
Executable File
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"
|