re: a title negative that survives its own cross-check
Three earlier "the title never appears" claims came from instruments later found broken -- a stale pixel oracle, a 41 s sampling interval, a freezing stream. This one carries its own evidence. title_probe_xchecked.py restarts its capture stream every 30 s AND prints its reading beside an independent `import` grab every 60 s: 1851 frames in 560.2 s = 3.30 fps cross-checks 9, disagreements 1 max glyph 0 t= 62s stream 6.05 | import 0.07 disagree (a fade, logos mid-transition) t=123s stream 7.40 | import 7.49 agree t=183s stream 8.18 | import 8.29 agree t=243s stream 0.23 | import 0.10 agree t=311s stream 89.68 | import 89.51 agree t=371s stream 80.97 | import 81.58 agree t=426s stream 117.43 | import 117.72 agree t=487s stream 77.71 | import 76.25 agree t=546s stream 70.43 | import 70.55 agree Eight of nine agree within 2%, fps held at 3.30 with no collapse to 1.60, and the surface moved through dark and bright phases. So the frames were live: over 560 continuous seconds from launch, sampled 3.3 times a second, the interactive title's green (A) plate never appears while the game renders throughout. The final frame correlates 0.0145 / -0.0047 / 0.0102 with our title / main menu / EXTRAS renders -- attract-movie content, not a UI screen. Why remains unknown. live-title-press-a.png with its 753 glyph pixels proves the title was reachable from this container on 2026-08-28, and clearing the shader cache fixed the black surface but not this. The two emulator-side questions (gamma control, 8AX vs ptbase) are therefore blocked on a characterised failure rather than a suspicion. Neither blocks the five menu screens, so I am returning to static work; the probe is committed for whoever picks it up. METHOD: a probe that cross-checks itself turns "no result" into a result.
This commit is contained in:
50
tools/re-capture/title_probe_xchecked.py
Executable file
50
tools/re-capture/title_probe_xchecked.py
Executable file
@@ -0,0 +1,50 @@
|
||||
"""Fixed probe + a live cross-check against an independent grabber.
|
||||
|
||||
Stream is restarted every 30 s (a single long-lived one freezes). Every 60 s an
|
||||
`import` grab of the same display is taken and compared: if the two disagree by
|
||||
more than a few percent, the stream is lying and the run's numbers are void.
|
||||
"""
|
||||
import subprocess, sys, time, os
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
W,H,SURF = 1280,720,45
|
||||
LIMIT = float(sys.argv[1]) if len(sys.argv)>1 else 540
|
||||
RESTART = 30
|
||||
def _open():
|
||||
return subprocess.Popen(["ffmpeg","-loglevel","error","-f","x11grab","-draw_mouse","0",
|
||||
"-video_size",f"{W}x{H}","-i",":98","-r","4","-f","rawvideo","-pix_fmt","rgb24","-"],
|
||||
stdout=subprocess.PIPE, bufsize=W*H*3*2)
|
||||
def independent():
|
||||
subprocess.run(["/usr/local/bin/screenshot","/tmp/xcheck.png"],capture_output=True)
|
||||
try: return float(np.asarray(Image.open("/tmp/xcheck.png").convert("RGB")).astype(int)[SURF:].mean())
|
||||
except Exception: return -1.0
|
||||
p=_open(); n=W*H*3
|
||||
t0=time.time(); seg=t0; lastx=t0; lastr=-1
|
||||
frames=0; best=0; disagree=0; checks=0
|
||||
while time.time()-t0 < LIMIT:
|
||||
if time.time()-seg > RESTART:
|
||||
p.kill(); p=_open(); seg=time.time()
|
||||
buf=p.stdout.read(n)
|
||||
if len(buf)<n:
|
||||
p.kill(); p=_open(); seg=time.time(); continue
|
||||
a=np.frombuffer(buf,np.uint8).reshape(H,W,3).astype(int)
|
||||
frames+=1
|
||||
sm=float(a[SURF:].mean())
|
||||
r,g,b=a[:,:,0],a[:,:,1],a[:,:,2]
|
||||
c=int(((g>130)&(g-r>45)&(g-b>45)).sum())
|
||||
if c>best:
|
||||
best=c
|
||||
if c>=400:
|
||||
Image.fromarray(a[SURF:].astype(np.uint8)).save("/sylph-home/re/shots/probe3-title.png")
|
||||
print(f"*** TITLE t={time.time()-t0:.1f}s glyph={c}",flush=True)
|
||||
if time.time()-lastx > 60:
|
||||
lastx=time.time(); checks+=1
|
||||
iv=independent()
|
||||
bad = iv>=0 and abs(iv-sm) > max(3.0, 0.15*max(iv,sm))
|
||||
if bad: disagree+=1
|
||||
print(f" t={int(time.time()-t0):4d}s stream {sm:7.2f} | import {iv:7.2f} "
|
||||
f"{'<-- DISAGREE' if bad else 'agree'} glyph {c}",flush=True)
|
||||
p.kill(); dt=time.time()-t0
|
||||
print(f"{frames} frames in {dt:.1f}s = {frames/dt:.2f} fps")
|
||||
print(f"cross-checks {checks}, disagreements {disagree}")
|
||||
print(f"max glyph {best}")
|
||||
Reference in New Issue
Block a user