Files
Sylpheed/tools/re-capture/which_title_screen.py
sylph-decoder 2a1ecc1c63 re: a menu/EXTRAS discriminator that failed its control, and the fix
sylpheed-port's BLOCKED.md ask #1 -- does (B) from EXTRAS also show no black
interval, or is "(B) has no black" one screen pair -- needs the harness to know
it is on EXTRAS. screen_id.py cannot tell: both are dark blue GP_TITLE screens
and it reports `menu` for either.

which_title_screen.py correlates a grab against our build 5 / build 6 renders.
First version FAILED its control: it called live-main-menu.png "extras" and
live-extras.png "main_menu", both backwards, margins under 1.1 on RMSE ~33.
Cause: it applied the y=45 game-surface offset unconditionally, but only a full
1280x720 display frame has the menu bar -- a 1279x675 grab IS the surface, and
two of the three reference captures are surface-sized. Offset made conditional;
the control now passes 4/4 with margins 9.9-11.7 against ~18 within-class.

The tool is a navigation aid for driving the emulator and says so: it identifies
a screen by agreeing with our own renders, so nothing measured may rest on it.

Also records the METHOD entry sylpheed-port offered from their own wedged check
script: an absence of output is not a status. They reported "still running, two
lines, both ok" for three iterations while the first attempt had died silently
under its own timeout with block-buffered output -- zero information, reported
as patience. An orphan from an older form of the same script was found running
after 9.5 hours. Line-buffer and bound long jobs, and check the artifact rather
than the exit code: the artifact reached its correct duration while the process
never returned.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-30 13:59:47 +00:00

45 lines
1.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""Is this screenshot the MAIN MENU or EXTRAS? screen_id.py cannot tell them apart.
Both are dark-blue `GP_TITLE` screens, so `screen_id.py` reports `menu` for
either. This correlates the grab against our own build 5 / build 6 renders and
reports which is closer, plus the margin -- a small margin means "cannot tell",
not "the closer one".
⚠️ These are OUR renders, so this identifies a screen by agreeing with our
decoding. It is a navigation aid for driving the emulator, NOT evidence about the
game. Nothing measured is allowed to rest on it.
which_title_screen.py <grab.png> [ref_dir]
"""
import sys
import numpy as np
from PIL import Image
def load(p, shape=None):
im = Image.open(p).convert("RGB")
a = np.asarray(im, dtype=float)
return a
def main():
grab = load(sys.argv[1])
d = sys.argv[2] if len(sys.argv) > 2 else "/sylph-home/re/ref"
# The game surface sits at y=45 ONLY in a full 1280x720 display frame; a
# 1279x675 grab is the surface already. Hard-coding the 45 made this tool fail
# its own control -- it called the main menu "extras" and extras "main_menu",
# because two of the three reference captures are surface-sized.
off = 45 if grab.shape[0] >= 716 else 0
best = []
for b, name in ((5, "main_menu"), (6, "extras")):
r = load(f"{d}/build{b}.png")
h = min(grab.shape[0] - off, r.shape[0]); w = min(grab.shape[1], r.shape[1])
g = grab[off:off + h, :w]; rr = r[:h, :w]
best.append((float(np.sqrt(((g - rr) ** 2).mean())), name))
best.sort()
margin = best[1][0] - best[0][0]
print(f"{best[0][1]} rmse={best[0][0]:.2f} (other {best[1][1]} {best[1][0]:.2f}, margin {margin:.2f})")
return 0
if __name__ == "__main__":
raise SystemExit(main())