tools: a menu-capture session that encodes the two input traps

Boot -> title -> main menu -> arm the UI draw-order capture there. What it
encodes is what cost time to learn:

* it does NOT tap (A) during the boot. A version that did delivered 88 presses
  over the intro and left the guest on a black screen that never came back —
  no crash, no throw, emulator healthy. The intro is ~3.5 minutes and reaches
  the title on its own.
* it taps at the title until the screen stops being the title, rather than
  pressing once and concluding, because acceptance is intermittent.
* after F10 it clicks the game surface, because F10 also opens the emulator's
  menu bar and any Xenia UI makes IsUIActive() true, which swallows every later
  guest keystroke.

It does not currently reach the menu — see docs/re/canary-scripted-input-traps.md
for the measurements. Committed because the traps are worth keeping encoded, and
because the next experiment (capture the draws in each title state) needs the
same scaffolding.
This commit is contained in:
Sylpheed RE agent
2026-08-18 22:45:08 +00:00
parent f5603aa107
commit 243835719f

View File

@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Boot -> title -> MAIN MENU -> arm the UI draw-order capture there.
#
# Two things this handles that a naive script does not:
#
# * (A) at the title is accepted only intermittently (see
# docs/re/canary-scripted-input-traps.md), so tap once a second until the
# screen stops being the title rather than pressing once and concluding.
# * F10 arms the capture AND opens the emulator's menu bar, and any Xenia UI
# makes IsUIActive() true, which swallows every later guest keystroke. So
# click the game surface right after F10 to dismiss it.
#
# Usage: menu_draw_capture.sh [out_dir]
set -u
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98
SD="$(cd "$(dirname "$0")" && pwd)"
OUT="${1:-/sylph-home/re/menucap}"
mkdir -p "$OUT"; rm -f "$OUT"/xenia_re_ui_draws_*.log
alive(){ ps -o pid=,stat= -C xenia_canary 2>/dev/null | awk '$2 !~ /^Z/ {print $1}'; }
shot(){ screenshot "$1" >/dev/null 2>&1; }
screen(){ shot /tmp/mdc.png; python3 "$SD/screen_id.py" /tmp/mdc.png | awk '{print $1}'; }
( cd "$OUT" && nohup run-canary --mem_watch=false --log_ui_draws=true \
--ui_draw_capture_frames="${FRAMES:-4}" --ui_draw_capture_max="${MAXDRAWS:-4000}" \
--logged_profile_slot_0_xuid=B13EBABEBABEBABE \
>"$OUT/canary.stdout" 2>"$OUT/canary.stderr" & )
sleep 8
until xdotool search --name "Xenia-canary" >/dev/null 2>&1; do
[ -n "$(alive)" ] || { echo "EMULATOR GONE"; exit 4; }; sleep 1
done
win="$(xdotool search --name "Xenia-canary" | tail -1)"
# 1. WAIT for the title. Do NOT tap to skip movies: a run that tapped (A) every
# 4 s through the boot delivered 88 presses and ended on a black screen that
# never came back — the intro is ~3.5 minutes and it gets there on its own.
deadline=$(( SECONDS + 420 ))
while [ $SECONDS -lt $deadline ]; do
s="$(screen)"; echo "t=${SECONDS}s $s"
[ "$s" = "title" ] && break
sleep 4
done
[ "$s" = "title" ] || { echo "NEVER REACHED THE TITLE"; exit 1; }
# 2. tap until it takes
taps=0
while [ $taps -lt 40 ]; do
python3 "$SD/pad.py" tap A 0.2; taps=$((taps+1))
sleep 1
s="$(screen)"
if [ "$s" != "title" ]; then
sleep 3; s="$(screen)"
[ "$s" = "menu" ] && { echo "MENU after $taps taps"; break; }
fi
done
shot "$OUT/menu.png"
[ "$s" = "menu" ] || { echo "NO MENU after $taps taps (screen=$s)"; exit 2; }
# 3. arm, then dismiss the menu bar F10 opened
xdotool windowactivate --sync "$win"; sleep 1
xdotool key F10; sleep 3
xdotool mousemove 900 400 click 1; sleep 2
shot "$OUT/menu-after-f10.png"
ls -l "$OUT"/xenia_re_ui_draws_*.log 2>/dev/null || echo "NO CAPTURE LOG"
grep -i "UI-CAP" "$OUT/canary.stdout" | tail -3
echo "MENU CAPTURE DONE (emulator left running)"