#!/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. ONE tap on this title. Measured: the title that ends the boot sequence # accepts a single (A) (2 of 2 runs); the title the attract loop returns to # accepts nothing at all, and 40 taps at 1/s do not change that. So the tap must # land on the FIRST title, and repeating is pointless. python3 "$SD/pad.py" tap A 0.3 for _ in 1 2 3 4 5 6; do sleep 4; s="$(screen)"; echo " after A: $s" [ "$s" = "menu" ] && { echo "MENU"; break; } 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)"