Files
psxrecomp/tools/divergence/waitf.py
Matthew Stanley 1252c61c9d tools/divergence: persist the native-vs-interp first-divergence toolkit
Dev tooling only (never shipped: tools/ is not bundled in releases, and the
debug-server commands it drives are all PSX_NO_DEBUG_TOOLS-stripped in release
builds). Saved so the first-divergence workflow that root-caused the Tomba2
logo->FMV stall is never re-invented.

- t2probe.py   layer 1 fingerprint cap/diff; layer 2 unified-recorder dump +
               recdiff/recdiff_state (state fork, addr/val only); resolves the
               debug_client import relative to tools/.
- waitf.py     retry-connect + poll-until-frame (survives socket aborts).
- shot.py      screenshot to PNG for VISUAL end-state verification.
- README.md    the 3-layer method (always-on fingerprint ring -> divergent
               frame; frame-gated recorder -> divergent access; read-watch +
               per-entry cyc -> value/pointer/timing), env seeds, and the Tomba2
               worked example.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 23:23:15 -07:00

34 lines
1.1 KiB
Python

#!/usr/bin/env python3
"""waitf.py <port> <target_frame> [timeout_s=180] - retry-connect, poll `frame`
until >= target, print progress. The debug server may abort a persistent socket
between commands under load; this reconnects and keeps polling. Dev tooling."""
import sys, time, os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from debug_client import connect, send_cmd
port = int(sys.argv[1]); target = int(sys.argv[2])
deadline = time.time() + (float(sys.argv[3]) if len(sys.argv) > 3 else 180)
s = None
while time.time() < deadline and s is None:
try:
s = connect(port=port, timeout=10)
except OSError:
time.sleep(0.3)
if not s:
print("ERR connect"); sys.exit(1)
last = -1
while time.time() < deadline:
try:
f = send_cmd(s, {"cmd": "frame"}).get("frame")
except Exception:
time.sleep(0.3)
try: s = connect(port=port, timeout=10)
except OSError: pass
continue
if f != last:
print("frame", f, flush=True); last = f
if isinstance(f, int) and f >= target:
print("REACHED", f); break
time.sleep(0.5)
s.close()