diff --git a/tools/re-capture/options_draw_capture.sh b/tools/re-capture/options_draw_capture.sh index 97bff30f..5de24757 100755 --- a/tools/re-capture/options_draw_capture.sh +++ b/tools/re-capture/options_draw_capture.sh @@ -1,6 +1,20 @@ #!/usr/bin/env bash -# Boot -> first title -> main menu -> OPTIONS, and capture the UI draw order -# there. OPTIONS is the fourth menu item, so: three d-pad steps down, then (A). +# Boot -> first title -> main menu -> OPTIONS, and capture the UI draw order and +# the BLEND STATE there. OPTIONS is the fourth menu item. +# +# 🔴 It used to say "so: three d-pad steps down, then (A)" and do exactly that. +# Counting presses does not work here -- presses get dropped, and a dropped one +# lands the cursor on TUTORIAL, whose (A) starts the tutorial. Two later attempts +# to avoid counting were worse: "press until the cursor stops moving" is +# unreachable on a menu that WRAPS, and an earlier version of it read the same +# row twice because the first press was lost and pressed (A) on NEW GAME. +# +# What works is to use the wrap as the landmark. Press down until the row +# DECREASES -- that is the wrap, and the cursor is now on item 1 whatever it +# started on -- then take exactly three verified steps, retrying any press that +# does not move the cursor. Geometry-free: it needs the row to be monotone in the +# item, not calibrated, and ring_row.py's ROW0/SPACING are x11grab constants that +# do not fit a `screenshot` grab (METHOD.md). # # The recipe for the first two hops is measured, not guessed (see # docs/re/canary-scripted-input-traps.md): the title that ENDS THE BOOT accepts a @@ -26,7 +40,7 @@ until xdotool search --name "Xenia-canary" >/dev/null 2>&1; do done win="$(xdotool search --name "Xenia-canary" | tail -1)" -deadline=$(( SECONDS + 420 )) +deadline=$(( SECONDS + ${DEADLINE:-1200} )) while [ $SECONDS -lt $deadline ]; do s="$(screen)"; echo "t=${SECONDS}s $s" [ "$s" = "title" ] && break @@ -40,8 +54,39 @@ for _ in 1 2 3 4 5 6 7 8; do sleep 3; s="$(screen)"; echo " $s"; [ "$s" = "menu shot "$OUT/menu.png" [ "$s" = "menu" ] || { echo "NO MENU (screen=$s)"; exit 2; } -echo "-> three d-pad steps down, then A (OPTIONS is the 4th item)" -for i in 1 2 3; do python3 "$SD/pad.py" dpad down 0.08; sleep 1.2; done +row(){ shot /tmp/odc_row.png; python3 - <<'PY' +from PIL import Image +import sys; sys.path.insert(0,"/work/tools/re-capture") +import ring_row +try: print("%.1f" % ring_row.ring_row(Image.open("/tmp/odc_row.png"))) +except Exception: print("nan") +PY +} +down(){ python3 "$SD/pad.py" tap DOWN 0.2; sleep 3; } + +echo "-> find the wrap, then take three verified steps to OPTIONS" +prev="$(row)"; echo " row $prev" +wrapped=0 +for _ in $(seq 1 12); do + down; cur="$(row)"; echo " row $cur" + if [ "$(python3 -c "print(1 if float('$cur') < float('$prev') - 5 else 0)")" = "1" ]; then + wrapped=1; prev="$cur"; break + fi + prev="$cur" +done +[ "$wrapped" = 1 ] || { echo "NEVER SAW THE WRAP -- not pressing (A)"; exit 3; } +echo " wrapped to item 1" +for step in 1 2 3; do + ok=0 + for _ in 1 2 3; do + down; cur="$(row)"; echo " step $step row $cur" + if [ "$(python3 -c "print(1 if float('$cur') > float('$prev') + 5 else 0)")" = "1" ]; then + ok=1; prev="$cur"; break + fi + echo " (press dropped, retrying)" + done + [ "$ok" = 1 ] || { echo "STEP $step NEVER LANDED -- not pressing (A)"; exit 3; } +done shot "$OUT/menu-on-options.png" python3 "$SD/pad.py" tap A 0.3 sleep 8 @@ -54,4 +99,5 @@ xdotool mousemove 900 400 click 1; sleep 2 shot "$OUT/options-armed.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 "OPTIONS CAPTURE DONE (emulator left running)" +echo "OPTIONS CAPTURE DONE" +pkill -x xenia_canary 2>/dev/null; sleep 2; echo "emulator killed"