port(exporter): 0x3003 is a button too -- the OPTIONS menu navigates
The Decoder decoded bit 0 of kind as the PARENT FLAG, disc-wide: kind & 1 agrees
with 'has a parent' on 15493 elements, zero disagreements. So 0x3003 is 0x3002
parented, and carries no role information -- the OPTIONS rows were never a
different class, they just have a parent.
Detector now matches 0x3002 | 0x3003 as TWO LISTED VALUES, not a mask.
kind & 0xFFFE == 0x3002 would also match 0x73002/0x73003 -- 160 elements whose
0x70000 bits are undecoded -- silently, on screens neither agent has looked at.
Excluded by construction until somebody decides deliberately.
Impact measured BEFORE re-exporting: exactly two screens gain buttons, options
and options_jp, five rows each. No existing screen changes.
Verified: main_menu -> down x3 -> (A) -> OPTIONS, then down x2 moves
po_menu_btn2 -> po_menu_btn3, focus ring rendering on the highlighted row.
📌 Waiting was right. The rule I rejected -- 'carries a focus record therefore is
a menu item' -- would have reached this answer by a second inference from
structure and reclassified elements on unseen screens. The field cost one
question and needed no inference.
This commit is contained in:
@@ -642,10 +642,23 @@ pub fn export_build(
|
||||
|
||||
// Navigation order is geometric: buttons top-to-bottom by resting Y. A
|
||||
// focused-state record is not itself a menu item.
|
||||
//
|
||||
// 🔴 `0x3003` IS `0x3002`. Bit 0 of `kind` is the PARENT FLAG and carries no
|
||||
// role information: decoded disc-wide over every `.pak` in `dat/`, `kind & 1`
|
||||
// agrees with "has a parent" on 15 493 elements with ZERO disagreements
|
||||
// (`docs/re/ui-kind-bit0-is-has-parent.md`). Matching only `0x3002` meant the
|
||||
// OPTIONS menu's five rows -- parented, hence `0x3003` -- were not buttons,
|
||||
// so the screen opened and could not be navigated.
|
||||
//
|
||||
// ⚠️ TWO VALUES, LISTED, NOT A MASK. `kind & 0xFFFE == 0x3002` would also
|
||||
// match `0x73002`/`0x73003` -- 160 elements whose `0x70000` bits nobody has
|
||||
// decoded -- and it would do it silently, on screens neither agent has
|
||||
// looked at. Those are excluded by construction until somebody decides about
|
||||
// them deliberately.
|
||||
let mut buttons: Vec<(i32, String)> = b
|
||||
.elements
|
||||
.iter()
|
||||
.filter(|e| e.kind == 0x3002 && !e.focused)
|
||||
.filter(|e| matches!(e.kind, 0x3002 | 0x3003) && !e.focused)
|
||||
.filter_map(|e| e.rest().map(|k| (k.y, id_of(&e.name))))
|
||||
.collect();
|
||||
buttons.sort_by(|a, b| a.0.cmp(&b.0).then_with(|| a.1.cmp(&b.1)));
|
||||
|
||||
@@ -50,7 +50,32 @@ anything beyond `main_menu → options` needs the real navigation.
|
||||
`main_menu` `ptbtn04` now has `goto: "options"`. Walked with the menu harness:
|
||||
main_menu → ⬇⬇⬇ → Ⓐ → the OPTIONS root renders. Ⓑ backs out.
|
||||
|
||||
## 🔴 The rows do not move, and the reason is a decode question
|
||||
## ✅ RESOLVED — the rows move. `0x3003` is `0x3002` with the parent bit set
|
||||
|
||||
The Decoder decoded it disc-wide: **bit 0 of `kind` is the PARENT FLAG**, and it
|
||||
carries no role information. Over every `.pak` in `dat/`, `kind & 1` agrees with
|
||||
"has a parent" on **15 493 elements with zero disagreements**
|
||||
(`docs/re/ui-kind-bit0-is-has-parent.md`). The OPTIONS rows are parented; the
|
||||
main-menu buttons are not. Same record class.
|
||||
|
||||
So the detector now matches `0x3002 | 0x3003` — **two values listed, not a
|
||||
mask**. `kind & 0xFFFE == 0x3002` would also catch `0x73002`/`0x73003`, 160
|
||||
elements whose high bits nobody has decoded, silently and on screens neither
|
||||
agent has seen.
|
||||
|
||||
**Impact measured before re-exporting, not after:** exactly two screens gain
|
||||
buttons — `options` and `options_jp`, five rows each. No existing screen changes.
|
||||
|
||||
Verified by walking it: `main_menu` → ⬇⬇⬇ → Ⓐ → OPTIONS, then ⬇⬇ moves
|
||||
`po_menu_btn2` → `po_menu_btn3` with the focus ring rendering on the highlighted
|
||||
row.
|
||||
|
||||
📌 **The port was right to wait.** The rejected rule — "carries a focus record ⇒
|
||||
menu item" — would have reached the same answer here by a second inference from
|
||||
structure, and would have reclassified elements on screens nobody had looked at.
|
||||
The field cost one question and needed no inference at all.
|
||||
|
||||
## The original section, kept for the shape of the block
|
||||
|
||||
The exporter's button detector is `kind == 0x3002 && !focused`. The OPTIONS rows
|
||||
are **`kind_raw = 0x3003`**, so `role` comes out `unknown`, the export's
|
||||
|
||||
Reference in New Issue
Block a user