89 lines
4.0 KiB
Markdown
89 lines
4.0 KiB
Markdown
# `_eff` glow layers are not focused-state records
|
|
|
|
**Status:** ✅ `CONFIRMED` by measurement over all 965 screen builds on the disc,
|
|
plus the draw capture of the developer-logo splash. 🟡 what actually marks a
|
|
focused state in the file is still unknown — the pairing rule below is a naming
|
|
convention, not a decoded field. ❔ no focus pair survives into a composable
|
|
build at all, so the flag currently matches nothing.
|
|
|
|
## The defect
|
|
|
|
`ui_layout::compose` skips elements flagged `focused` unless asked for them, on
|
|
the reasoning that a focused-state record is the highlighted variant of a button
|
|
and should not be painted over its base at rest. The flag was set by
|
|
|
|
```rust
|
|
focused: lname.ends_with("f.rat") || lname.ends_with("f.t32"),
|
|
```
|
|
|
|
which is not the convention. It is a letter, and `_eff` — this UI's name for a
|
|
glow or effect layer — ends in it.
|
|
|
|
## The measurement
|
|
|
|
Swept every RATC bundle on the disc, comparing the suffix match against the
|
|
element set of the same build:
|
|
|
|
| | count |
|
|
|---|---|
|
|
| elements matching the `f` suffix | **2 458** |
|
|
| …with the base element present (a real pair) | **54** |
|
|
| …with no base element (a false positive) | **2 404**, across **864 bundles** |
|
|
|
|
All 54 real pairs are `pgmenu_btnNNf.t32` beside `pgmenu_btnNN.t32` — the
|
|
convention exists, it just does not reach far. The false positives are glows:
|
|
|
|
```
|
|
1122 pb_name_eff.t32 18 pbmain_btn_eff.t32
|
|
132 pbmwindow_eff.t32 18 pghud_speed_cut_eff.t32
|
|
84 pb_warp_eff.t32 12 pghud_range_eff.t32
|
|
30 pblebendorf.t32 12 pgface_name_eff.t32
|
|
```
|
|
|
|
## Refuted on the way
|
|
|
|
**The `opt ` link is not a focus link.** The obvious replacement was "an element
|
|
is focused iff some other record's `opt ` link names it" — a decoded field rather
|
|
than a naming convention. Measured: 221 elements are `opt` targets, **2** of
|
|
which suffix-match, and the targets include `pjnet_bg.rat`, `pjeff02.rat` and
|
|
`pv_loading_loop1.rat`. Whatever `opt ` links, it is not a button's highlighted
|
|
state. The doc comment on `opt_link` that says otherwise is now known to be a
|
|
guess; the field's meaning is open.
|
|
|
|
## Independent confirmation from the running game
|
|
|
|
The developer-logo splash's paint order was read off the live child list. The
|
|
three `_eff` glows are **in it** — `palogo_gamearts_eff.t32` and its siblings
|
|
carry layer key `0xa100` and paint *before* their logos
|
|
([`ui-paint-order-key.md`](ui-paint-order-key.md)). The game paints them. They
|
|
cannot be focus states, which are by definition not painted at rest.
|
|
|
|
## The fix, and what it changed
|
|
|
|
`mark_focused_states` now requires the pair: the name minus its trailing `f` must
|
|
be another element of the same build. **587 glow layers** come back in the
|
|
builds the compositor accepts.
|
|
|
|
`GP_OPTIONS` is the clearest case. Without `pbmwindow_eff.t32` the options panel
|
|
had no window — two floating vertical brackets, no top or bottom edge, no glow:
|
|
|
|
* [before](../captures/ui-layout/options-without-its-glow-layer.png)
|
|
* [after](../captures/ui-layout/options-with-its-glow-layer.png) (209 400 pixels changed)
|
|
|
|
Checked for the opposite error too: the tutorial PAUSE menu and `GP_CHALLENGE`
|
|
render **byte-identical** before and after, so the change is confined to builds
|
|
that actually have a glow layer.
|
|
|
|
## What is not settled
|
|
|
|
* 🟡 **The pairing rule is still a naming convention.** It is defensible — a
|
|
focused state needs something to be the focused state *of* — but nothing in
|
|
the 60-byte declaration entry has been shown to mark it. The `kind` field's
|
|
`0x3002` is a button record; whether some bit of it marks the focused variant
|
|
is unchecked and is the cheapest next probe.
|
|
* ❔ **The flag now matches nothing in a composable build.** All 5 453 elements
|
|
in `is_build`-accepted bundles come out unfocused: the 54 real pairs live in
|
|
bundles the compositor rejects. So the skip is currently dead code, kept
|
|
because `include_focus` is the switch a menu renderer will need.
|
|
* ❔ **What `opt ` actually links.** Refuted as focus, unexplained otherwise.
|