Files
Sylpheed/tools/re-capture/menu_focus.py
Sylpheed RE agent 4e745c8177 re: the title menu wraps -- Q5 measured, Q4 driven, and one of my own
method lines withdrawn

Q5, measured off two boots: up/down move one item and WRAP at both ends
on the 5-item main menu and the 3-item EXTRAS alike; left/right do
nothing; B goes up one level and restores focus to the item you came
from (4/4); B on the main menu returns to the title; B on the title does
nothing. The menu opens on TUTORIAL -- the middle item -- 2/2, though a
third recorded run implies NEW GAME, so that one is reproducible rather
than invariant and says so.

Q4 by driving: LOAD GAME opens the save-slot list, TUTORIAL the lesson
list, OPTIONS the settings menu, EXTRAS build 6, MISSION SELECT the stage
list. NEW GAME is not tested -- A on it hangs the emulator and this
iteration needed the session. The GamePart ID behind each is NOT
measured: it is the entry of the decoded id table whose name matches the
screen I saw, and the page says so rather than wearing the badge.

And the withdrawal. Last iteration I wrote that these menus drop d-pad
presses shorter than ~0.3s. They do not. Once wrap is measured, every
press count I had is exactly right -- four presses moved four steps
THROUGH the bottom, which lands one above where a non-wrapping menu
would. I invented hardware flakiness instead of testing the ends of the
list. METHOD keeps the withdrawal rather than deleting the line.

Also: label brightness is not a cursor oracle here -- the background art
outshines the highlight on some rows. menu_focus.py reads the focus ring
instead, 254 vs <82, no tuning.
2026-08-28 17:53:46 +00:00

12 lines
469 B
Python

import sys
from PIL import Image
import numpy as np
names=["NEW GAME","LOAD GAME","TUTORIAL","OPTIONS","EXTRAS"]
ys=[166,241,315,390,465]
for p in sys.argv[1:]:
a=np.asarray(Image.open(p).convert("L"),dtype=float)
# the focus RING sits in the gutter left of the label; nothing else is bright there
v=[a[y-20:y+20,500:542].max() for y in ys]
i=int(np.argmax(v))
print(f"{p.split('/')[-1]:26s} -> {names[i]:10s} " + " ".join(f"{x:5.0f}" for x in v))