#!/usr/bin/env bash # Do ptloop01/02 ANIMATE on the settled main menu? # # sylpheed-port pinned a leaf phase for these and was explicit that doing so # picks ONE pose rather than the one the game shows -- "a capture question, not a # harness one". On the JP title, two captures from different sessions are # byte-identical over the ptloop rect (0 of 18 000), so they do not free-run # there. The menu is a different bundle and is where their row actually drifted. # # If the loops animate at all, consecutive frames of a SETTLED menu differ over # their rect. A whole-frame count runs alongside as the contrast control: if the # frame is entirely static the instrument cannot see motion and the zero is void. # # Usage: menu_loop_rest.sh OUTDIR set -u export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98 SD="$(cd "$(dirname "$0")" && pwd)" OUT="${1:-/sylph-home/re/menuloop}"; mkdir -p "$OUT" 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/mlr.png; python3 "$SD/screen_id.py" /tmp/mlr.png | awk '{print $1}'; } ps -o pid= -C xenia_canary | xargs -r kill -9 ( cd "$OUT" && nohup run-canary --mem_watch=false \ --logged_profile_slot_0_xuid=B13EBABEBABEBABE \ >"$OUT/canary.stdout" 2>"$OUT/canary.stderr" & ) sleep 8 deadline=$(( SECONDS + 900 )); s="" 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; } python3 "$SD/pad.py" tap A 0.5 for _ in 1 2 3 4 5 6; do sleep 4; s="$(screen)"; echo " after A: $s"; [ "$s" = "menu" ] && break; done [ "$s" = "menu" ] || { echo "NO MENU (screen=$s)"; exit 2; } sleep 6 # let the menu settle past its build-in for i in 0 1 2 3 4; do shot "$OUT/menu-$i.png"; sleep 2; done python3 - "$OUT" <<'PY' import sys, numpy as np from PIL import Image out=sys.argv[1] def load(i): a=np.asarray(Image.open(f"{out}/menu-{i}.png").convert("RGB"),dtype=int) return a, (45 if a.shape[0]>=716 else 0) a0,o0=load(0) print("\nptloop01/02 rect, 200x90 at design (441,270) -- do they move?") for i in (1,2,3,4): ai,oi=load(i) la=a0[o0+270:o0+360, 441:641]; lb=ai[oi+270:oi+360, 441:641] d=np.abs(la-lb) h=min(a0.shape[0]-o0, ai.shape[0]-oi); w=min(a0.shape[1], ai.shape[1]) dw=np.abs(a0[o0:o0+h,:w]-ai[oi:oi+h,:w]).sum(axis=2) print(f" frame {i} vs 0: loop rect {int((d.sum(axis=2)>0).sum()):6d}/18000 px max |d| {int(d.max()):3d}" f" | CONTRAST whole frame {int((dw>0).sum()):7d} px") PY echo "MENU LOOP PROBE DONE"