re: the Japanese title at rest -- the capture MISSION has wanted since 2026-08-29
Asked for by the port: its title_jp row drifted, localized to a 350x396 block at (405,74) -- the logo stack -- and with no JP capture in the corpus it could say the renderers moved apart but not which one moved. Three earlier attempts failed to reach the interactive title in either locale. The reason is now known and was never the locale: A at the title needs a signed-in profile, and no run had one. Locale set through canary's own persisted XConfig and restored afterwards, verified back at language=1. INDEPENDENT confirmation it took: the XMA probe logged a different voice-context set from every English run (ja 1112064 / 1150976 / 1177600 against en 1294336 / 1118208 / 1171456), so the switch reached the guest rather than being a menu-language cosmetic. 'At rest' is demonstrated rather than assumed. Five frames ~1.5 s apart after the plate pulse says the screen has settled: the port's ROI is byte-identical across all of them, max |delta| 0 over 138 600 px, while the WHOLE FRAME moves 39 584 to 71 927 px -- the plate pulse and sweeps. That contrast is the control: the instrument can see motion and the ROI still shows none. The capture shows what the English title does not -- the katakana subtitle, and a crystalline burst behind the wordmark, the ptlogo3a/b/c + ptlogo_back2eff* stack that this corpus records as transparent at rest in English. Exactly the region the port's drift is localized to. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
45
docs/re/data/jp-title-at-rest.txt
Normal file
45
docs/re/data/jp-title-at-rest.txt
Normal file
@@ -0,0 +1,45 @@
|
||||
# The JAPANESE title (GP_TITLE build 7) at rest -- captured 2026-08-30.
|
||||
#
|
||||
# Asked for by the port agent: its title_jp row drifted (155/20498 ->
|
||||
# 233/61208), localized to a 350x396 block at (405,74) -- the logo stack --
|
||||
# and with NO capture of the JP title in the corpus it could say the two
|
||||
# renderers had moved apart but not which one moved.
|
||||
#
|
||||
# MISSION.md has carried this as 'needs one more run' since 2026-08-29.
|
||||
# Three earlier attempts failed to reach the interactive title in either
|
||||
# locale. The reason is now known and was not the locale: A at the title
|
||||
# needs a signed-in profile (title-a-press-fault.md), and no run had one.
|
||||
#
|
||||
# LOCALE: tools/re-capture/set_console_language.py ja -- canary's own
|
||||
# persisted XConfig, offset located from struct landmarks. Restored to en
|
||||
# afterwards; verified back at language=1.
|
||||
#
|
||||
# ✅ INDEPENDENT CONFIRMATION THE LOCALE TOOK: the XMA probe logged a
|
||||
# DIFFERENT voice-context set from every English run --
|
||||
# ja: 1112064, 1150976, 1177600
|
||||
# en: 1294336, 1118208, 1171456
|
||||
# The Japanese voice region is a different set of streams, so the switch
|
||||
# reached the guest and is not just a menu-language cosmetic.
|
||||
#
|
||||
# 'AT REST' IS DEMONSTRATED, NOT ASSUMED. Five frames ~1.5 s apart after the
|
||||
# plate pulse says the screen has settled:
|
||||
#
|
||||
# the port's ROI, 350x396 at (405,74) design space:
|
||||
# frame 1 vs 0: max |d| 0, pixels differing >8: 0 / 138600
|
||||
# frame 2 vs 0: max |d| 0, pixels differing >8: 0 / 138600
|
||||
# frame 3 vs 0: max |d| 0, pixels differing >8: 0 / 138600
|
||||
# frame 4 vs 0: max |d| 0, pixels differing >8: 0 / 138600
|
||||
#
|
||||
# the whole frame, as a CONTRAST CONTROL (the plate pulses, so this must
|
||||
# move or the instrument is blind):
|
||||
# frame 1 vs 0: 39584 px frame 3 vs 0: 71927 px
|
||||
# frame 2 vs 0: 58303 px frame 4 vs 0: 69604 px
|
||||
#
|
||||
# So the logo stack is byte-identical across 6 s while 5-8 % of the frame is
|
||||
# moving. The ROI is at rest and the instrument can see motion.
|
||||
#
|
||||
# WHAT THE CAPTURE SHOWS that the English title does not: the katakana
|
||||
# subtitle under the wordmark, and a crystalline burst BEHIND the wordmark --
|
||||
# the ptlogo3a/b/c + ptlogo_back2eff* stack, which ui-forced-backdrop and
|
||||
# the tie-break work record as TRANSPARENT at rest on the English title.
|
||||
# That is exactly the region the port's drift is localized to.
|
||||
88
tools/re-capture/jp_title_capture.py
Executable file
88
tools/re-capture/jp_title_capture.py
Executable file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Capture the JAPANESE title (`GP_TITLE` build 7) at rest.
|
||||
|
||||
Asked for by the port agent: its `title_jp` row drifted and it can say the two
|
||||
renderers moved apart but not which moved, because **no capture of the JP title
|
||||
exists in this corpus**. `MISSION.md` has carried this as "needs one more run" —
|
||||
the locale route is `set_console_language.py`, and the reason the earlier runs
|
||||
failed (Ⓐ needs a signed-in profile) is now known.
|
||||
|
||||
"At rest" is **demonstrated, not assumed**: after the plate pulse says the title
|
||||
has settled, five frames are taken ~1.5 s apart and the port's own region of
|
||||
interest — 350×396 at (405, 74) in design space — is compared across them. If the
|
||||
logo stack is still moving, the frames will say so.
|
||||
|
||||
⚠️ The frames are display-space 1280×720 with the game surface at y=45
|
||||
(`tbm-submenu-reached.txt`), so the design-space box is offset by that.
|
||||
|
||||
jp_title_capture.py OUTDIR [wait_s]
|
||||
"""
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
OUT = sys.argv[1]
|
||||
WAIT = float(sys.argv[2]) if len(sys.argv) > 2 else 480
|
||||
W, H = 1280, 720
|
||||
NEED, CEIL, HOLD = 500, 2500, 12
|
||||
SURF_Y = 45
|
||||
ROI = (405, 74, 350, 396) # design-space x, y, w, h — the port's drifting block
|
||||
|
||||
|
||||
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 glyph(a):
|
||||
r, g, b = a[:, :, 0], a[:, :, 1], a[:, :, 2]
|
||||
return int(((g > 130) & (g - r > 45) & (g - b > 45)).sum())
|
||||
|
||||
|
||||
T0 = time.time()
|
||||
p, n, seg, streak = _open(), W * H * 3, time.time(), 0
|
||||
frames = []
|
||||
while True:
|
||||
el = time.time() - T0
|
||||
if el > WAIT:
|
||||
print("TIMEOUT — the title never settled", flush=True); break
|
||||
if time.time() - seg > 30:
|
||||
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(np.uint8)
|
||||
c = glyph(a.astype(int))
|
||||
streak = streak + 1 if NEED <= c <= CEIL else 0
|
||||
if streak >= HOLD:
|
||||
print(f"[{el:7.1f}s] TITLE SETTLED (plate pulse, glyph {c}) — taking 5 frames", flush=True)
|
||||
for k in range(5):
|
||||
t0 = time.time()
|
||||
while time.time() - t0 < 1.5:
|
||||
b2 = p.stdout.read(n)
|
||||
if len(b2) < n:
|
||||
p.kill(); p = _open(); break
|
||||
a = np.frombuffer(b2, np.uint8).reshape(H, W, 3).astype(np.uint8)
|
||||
Image.fromarray(a).save(f"{OUT}/jp-title-{k}.png")
|
||||
frames.append(a.astype(int))
|
||||
print(f" frame {k}: glyph {glyph(a.astype(int))}", flush=True)
|
||||
break
|
||||
p.kill()
|
||||
if len(frames) == 5:
|
||||
x, y, w, h = ROI
|
||||
rois = [f[SURF_Y + y:SURF_Y + y + h, x:x + w] for f in frames]
|
||||
print("\nROI stability — the port's 350x396 block at (405,74), design space:")
|
||||
for i in range(1, 5):
|
||||
d = np.abs(rois[i] - rois[0])
|
||||
print(f" frame {i} vs 0: max |Δ| {d.max():3d}, pixels differing >8: "
|
||||
f"{int((d.max(axis=2) > 8).sum()):6d} / {d.shape[0]*d.shape[1]}", flush=True)
|
||||
full = [np.abs(frames[i] - frames[0]).max(axis=2) for i in range(1, 5)]
|
||||
print(" whole frame, for contrast (the plate pulses, so this SHOULD move):")
|
||||
for i, d in enumerate(full, 1):
|
||||
print(f" frame {i} vs 0: pixels differing >8: {int((d > 8).sum()):7d}", flush=True)
|
||||
Reference in New Issue
Block a user