re(ui): answer four of the port's five asks -- splash, fade-out, focus, gamma
1 SPLASH ADDRESSING (was blocking P3). No content predicate exists: design size fails (every extra composable bundle sampled is 1280x720, like every screen) and element count fails (fragments run 2..15, the splash halves are 3 and 7). But GP_TITLE needs none -- `--all` adds exactly four bundles there and all four are real screens, with the --all index equal to the pak entry index 1:1. And there are TWO splash screens: 11/14 are the developer logos, 10/13 are the SQUARE ENIX publisher wordmark, which the port did not have and which the boot shows first. 2 FADE-OUT (was blocking P3). It is (a), and it is bigger than the fade quad. Every element ends on exactly ONE untimed keyframe, which rules out (b); that block is where the screen plays out -- quad to a=255, buttons/labels/glows to a=0, frames hold. (c) is refuted by a null test that discriminates: a black quad alone holds the button/background brightness ratio constant, and through the fade it falls 6.50 -> 1.94, 3.4x monotonic. 3 FOCUS (saves P5 rework). Over-vs-instead is unobservable -- the focused sprite covers the base at 100.0% of base-visible pixels on three pairs once aligned (true offset (7,7); the centre alignment reads a misleading 78-84%), and compositing both ways differs by RMSE 1.1 inside the button rect. The real defect is the focus record's SECOND element: ptbtn0Nf.rat declares ptbtneff01.t32 (a 42x46 glowing ring, focus only) plus the bright label, where the base declares one sprite. That ring is the marker the port draws nowhere. 5 GAMMA. The capture is not neutral: capture ~ 255*(render/255)^g, g ~ 1.34-1.49, and the chain says it is a ramp the GAME installed, not a capture artefact. So RMSE against captures has a floor. Reach stated: the flat patches are all dark (render ~0-60), so midtones and highlights are unconstrained. 4 ROTATION is a human's call and is recorded in MISSION, not acted on -- the port rotating while the reference renderer does not would make verify-screen report a large diff meaning "the port is right". The RE half is answered: rotation is about the declared pivot, measured against a GPU capture. The focus record's +20 element-count word is marked 🟡 not ✅ -- read on GP_TITLE's ten button records only; the disc-wide check is written and still running.
This commit is contained in:
111
docs/re/structures/ui-button-focus-record.md
Normal file
111
docs/re/structures/ui-button-focus-record.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# ✅ A focused button is a **two-element record**, and the second element is the ring
|
||||
|
||||
**Status:** 🟡 `DECODED for GP_TITLE`, disc-wide check **not yet run**; the
|
||||
sprite contents and the ring are ✅ `MEASURED` against a live capture. Answers the
|
||||
port's *"focus: drawn over the base element, or instead of it?"*
|
||||
|
||||
⚠️ The element-count field at `+20` is read here on **`GP_TITLE`'s ten button
|
||||
records only** (five buttons × two language bundles). A disc-wide check —
|
||||
"does `+20` equal the number of resource names the leaf embeds, for every `.rat`
|
||||
leaf on the disc?" — is written and was still running when this was committed.
|
||||
Until it lands, treat `+20` as a **strong local reading, not a decoded field**:
|
||||
the *observable* claim below (the focus record carries a second sprite,
|
||||
`ptbtneff01.t32`, and the port must draw it) rests on the embedded names and the
|
||||
capture, not on that word.
|
||||
|
||||
**Short answer: it does not matter, and that is not the bug.** The focused sprite
|
||||
covers the base completely, so over-vs-instead is worth at most 12/255 on ~25
|
||||
pixels. What *is* missing is the focus record's **second element** — a glowing
|
||||
ring that only exists when focused.
|
||||
|
||||
## The record
|
||||
|
||||
A button's base and focused variants are both `.rat` leaves, and they are not the
|
||||
same shape:
|
||||
|
||||
```text
|
||||
ptbtn02.rat 164 B strings: RATC, ptbtn02.t32, opt ptbtn02f.rat
|
||||
ptbtn02f.rat 312 B strings: RATC, ptbtneff01.t32, ptbtn02f.t32, opt ptbtn02b.rat
|
||||
```
|
||||
|
||||
The header says so explicitly. A `.rat` leaf begins:
|
||||
|
||||
```text
|
||||
+0 "RATC"
|
||||
+16 u32 flags 0x00008110 (base) 0x00008112 (focused)
|
||||
+20 u32 ELEMENT COUNT 1 2
|
||||
+32 first element name
|
||||
```
|
||||
|
||||
So the focused record declares **two** elements — `ptbtneff01.t32` first, then
|
||||
`ptbtn0Nf.t32` — where the base declares one. Both `f` records of both language
|
||||
bundles read the same way, and the flag word differs only in bit `0x02`
|
||||
alongside the count.
|
||||
|
||||
⚠️ The `opt ` link on a `.rat` leaf is **not** simply "my focused variant". The
|
||||
chain runs `ptbtn01.rat → ptbtn01f.rat → ptbtn02.rat → ptbtn02f.rat →
|
||||
ptbtn02b.rat`, i.e. it threads base and focused records together in order. The
|
||||
corpus calls it the focus link and for a *base* record that reading works; do not
|
||||
generalise it to the `f` records.
|
||||
|
||||
## The three sprites
|
||||
|
||||
Decoded with `sylpheed-cli pak textures`, shown over a checkerboard in
|
||||
[`button-base-focus-ring-sprites.png`](../captures/ui-layout/button-base-focus-ring-sprites.png):
|
||||
|
||||
| sprite | size | what it is |
|
||||
|---|---|---|
|
||||
| `ptbtn02.t32` | 117×43 | the **dim** label, its underline, and a small dot-in-circle at the underline's left end |
|
||||
| `ptbtn02f.t32` | 130×56 | the **same label, bright and glowing** — a complete replacement, 13 px larger in each axis |
|
||||
| `ptbtneff01.t32` | 42×46 | a **glowing ring**, focus only |
|
||||
|
||||
The small dot-in-circle is on **every** button all the time; the large ring is
|
||||
the focus marker. They are different things and sit side by side on the focused
|
||||
row — visible in
|
||||
[`live-main-menu-options-focused.png`](../captures/title-builds/live-main-menu-options-focused.png)
|
||||
against
|
||||
[`live-main-menu.png`](../captures/title-builds/live-main-menu.png).
|
||||
|
||||
## Over or instead? Measured, and the answer is "unobservable"
|
||||
|
||||
Aligning base and focused by normalised cross-correlation of their alpha masks —
|
||||
the true offset is **(7,7)**, not the (6,6) that centring predicts —
|
||||
|
||||
| pair | base-visible px | `f` alpha ≥ base alpha there |
|
||||
|---|---|---|
|
||||
| `ptbtn02` / `f` (bundle `b58a0fe6`) | 1 444 | **100.0 %** |
|
||||
| `ptbtn01` / `f` (bundle `b58a0fe6`) | 1 898 | **100.0 %** |
|
||||
| `ptbtn02` / `f` (bundle `a715f485`) | 3 720 | **100.0 %** |
|
||||
|
||||
⚠️ **At the centre alignment it reads 78–84 %, and that number is an artefact.**
|
||||
A 1 px shift on strokes this thin manufactures a fifth of a sprite's worth of
|
||||
"the focused art is thinner here". Solve the alignment before trusting a coverage
|
||||
figure.
|
||||
|
||||
Coverage is not the same as hiding, though, because `f` is not fully opaque
|
||||
everywhere. Compositing both ways over the menu's own background colour:
|
||||
|
||||
| pair | max channel difference | px > 8/255 | RMSE over the button rect |
|
||||
|---|---|---|---|
|
||||
| `ptbtn02` | 12.5 | 23 | 1.09 |
|
||||
| `ptbtn01` | 12.2 | 27 | 1.08 |
|
||||
| `ptbtn02` (JP) | 12.2 | 27 | 1.05 |
|
||||
|
||||
So the two hypotheses differ by **~1.1 RMSE inside the button rectangle**, on a
|
||||
couple of dozen pixels — below the ≈ γ 1.4 tone gap
|
||||
([tone curve](ui-render-tone-curve.md)) and far below any frame-level RMSE this
|
||||
corpus can resolve. **Either choice is defensible; neither is measurable.**
|
||||
Replacing is the cheaper one and is what the file's structure suggests, since
|
||||
`ptbtn0Nf.t32` is a whole label rather than an overlay.
|
||||
|
||||
## ❔ Not established
|
||||
|
||||
* **Where `ptbtneff01.t32` is placed.** The record declares two elements; the
|
||||
per-element placement inside a `.rat` leaf was not decoded here. The capture
|
||||
shows the ring **left of** the label, roughly on the underline's left end.
|
||||
A port should take the offset from the record, and until it is decoded, from
|
||||
the capture.
|
||||
* **`ptbtn02b.t32`** — a third variant, `b`, exists for button 02 only, same size
|
||||
as the base. Not seen on any capture. Not chased.
|
||||
* Whether a **non-title** archive uses the same two-element convention. Checked
|
||||
on `GP_TITLE` only.
|
||||
Reference in New Issue
Block a user