re: the EX_ selection is shown - a mode word at +184 tested against 3

result-screens.md left this explicitly open: "the selection has not been shown".
It is shown now. Both screens that reference EX_ names carry the same
five-instruction idiom immediately before the choice - sub_822814D8 at 0x822815b4
and sub_8227A3A0 at 0x8227a408:

  lwz    r11, 4(rX)              the owning object
  lwz    r11, 184(r11)           a mode word at +184
  addi   r11, r11, -3
  cntlzw r11, r11
  rlwinm r11, r11, 27, 31, 31    r11 = 1 iff [+184] == 3
  cmpli  cr6, 0, r11, 0x0
  bc     12, 4*cr6+eq, <plain>   not 3 -> STAGE_RESULT / OVERVIEW
                                 else  -> EX_STAGE_RESULT / EX_OVERVIEW

cntlzw of zero is 32, and rotating left 27 lifts bit 5 into bit 31, so the
sequence is a branchless equals-3 test. The equal-to-zero branch takes the plain
name, so EX_ is chosen exactly when the word is 3.

A partition over the three key-list loaders the corpus already names:

                        loads +184   does not
  references EX_ names       2           0
  does not                   0           1

sub_822814D8 and sub_8227A3A0 both load it; sub_82286BC8, which references no EX_
name, has no +184 access at all. Both off-diagonal cells are empty.

3 is the game's own EXTRA. challenge-mission-gate already established the
vocabulary for this constant at a three-way switch: == 3 is EXTRA, == 5 or 6 is
CHALLENGE, otherwise FILE. So the prefix reads literally - EX_ is the EXTRA
variant.

That REFINES the doc's tentative reading rather than confirming it. The section
proposed "EX_ = the challenge-mission debriefing" by analogy with _EXn on asset
names; the measured constant is EXTRA, which in the game's own three-way
vocabulary is a DIFFERENT kind from CHALLENGE (5/6).

Boundary of what was measured: the EXTRA = 3 constant is established at +144 of
the stage-loader class, while the word tested here is at +184 of [object + 4].
Same constant and the same EX/EXTRA naming, but two different offsets in what may
be two different objects - that the two fields are the same field is NOT shown,
only that both compare a mode word against 3.

All seventeen artefacts byte-identical.
This commit is contained in:
Sylpheed RE agent
2026-08-28 10:51:16 +00:00
parent 3412bf3a85
commit d391130577
2 changed files with 82 additions and 0 deletions

View File

@@ -6880,3 +6880,35 @@ in an `.xpr` and named, **0** named-but-unshipped, **0** shipped-but-unnamed. Th
holes (no `f103`, no `f203`). **No craft was cut.**
Written up in [arsenal-item-weapon-chain](structures/arsenal-item-weapon-chain.md).
---
## ✅ 2026-08-28 — the `EX_` selection is shown: a mode word at `+184` tested against 3
Item (a). `result-screens.md` left this explicitly open — "the selection has not
been shown". Both screens that reference `EX_` names carry the **same
five-instruction idiom** just before the choice (`sub_822814D8` @ `0x822815b4`,
`sub_8227A3A0` @ `0x8227a408`):
`lwz r11,4(rX)``lwz r11,184(r11)``addi r11,r11,-3``cntlzw`
`rlwinm r11,r11,27,31,31`, i.e. a branchless **"equals 3"** test, then
`cmpli …,0` with the equal branch taking the *plain* name. **`EX_` is chosen
exactly when `[+184] == 3`.**
| | loads `+184` | does not |
|---|---|---|
| **references `EX_`** | **2** | 0 |
| **does not** | 0 | **1** |
`sub_82286BC8` references no `EX_` name and has no `+184` access. Both
off-diagonals empty.
🔑 **3 is the game's own `EXTRA`** — [[challenge-mission-gate]] already has the
three-way switch: `3``EXTRA`, `5`/`6``CHALLENGE`, else `FILE`. So `EX_` =
the **EXTRA** variant. ⚠️ This **refines** the doc's tentative "`EX_` = the
challenge-mission debriefing": the measured constant is `EXTRA`, a *different*
kind from `CHALLENGE` in the game's own vocabulary.
⚠️ **Boundary**: `EXTRA = 3` is established at `+144` of the stage-loader class;
the word tested here is at `+184` of `[obj+4]`. Same constant, two offsets —
**that they are the same field is not shown**.

View File

@@ -81,3 +81,53 @@ And `PLAYER_AMMO_LESS_10` is unexplained.
**Reproduce:** parse `tables.pak` with `tools/re-capture/unitgroup.py` and count
the fields of the three records; take the key lists from the `sub_822814D8` /
`sub_8227A3A0` / `sub_82286BC8` sections of [`../data/name-block-bases.txt`](../data/name-block-bases.txt).
## ✅ The `EX_` selection, shown at last — a mode word tested against 3
The section above left this open: "**the selection has not been shown**". It is
shown now. Both screens that reference `EX_` names carry the *same five-instruction
idiom* immediately before the choice — `sub_822814D8` at `0x822815b4` and
`sub_8227A3A0` at `0x8227a408`:
```asm
lwz r11, 4(rX) ; the owning object
lwz r11, 184(r11) ; a mode word at +184
addi r11, r11, -3
cntlzw r11, r11
rlwinm r11, r11, 27, 31, 31 ; r11 = 1 iff [+184] == 3
cmpli cr6, 0, r11, 0x0
bc 12, 4*cr6+eq, <plain> ; not 3 -> STAGE_RESULT / OVERVIEW
; else -> EX_STAGE_RESULT / EX_OVERVIEW
```
`cntlzw` of zero is 32; rotating left 27 lifts bit 5 into bit 31, so the sequence
is a branchless **"equals 3"** test. The equal-to-zero branch takes the *plain*
name, so **`EX_` is chosen exactly when the word is 3**.
A small partition over the three key-list loaders the corpus already names:
| | loads `+184` | does not |
|---|---|---|
| **references `EX_` names** | **2** | 0 |
| **does not** | 0 | **1** |
`sub_822814D8` and `sub_8227A3A0` both load it; `sub_82286BC8`, which references
no `EX_` name, has no `+184` access at all. Both off-diagonal cells are empty.
### 🔑 3 is the game's own `EXTRA` — and that is *not* `CHALLENGE`
[[challenge-mission-gate]] already established the vocabulary for this constant
at a three-way switch: `== 3`**`EXTRA`**, `== 5 or 6`**`CHALLENGE`**,
otherwise `FILE`. So the prefix reads literally: **`EX_` is the `EXTRA` variant**.
⚠️ **This refines the tentative reading above rather than confirming it.** That
section proposed "`EX_` = the challenge-mission debriefing" by analogy with
`_EXn` on asset names. The measured constant is `EXTRA`, which in the game's own
three-way vocabulary is a *different* kind from `CHALLENGE` (5/6). `EX_` tracks
`EXTRA` specifically.
⚠️ **The boundary of what was measured:** the `EXTRA = 3` constant is established
at **`+144`** of the stage-loader class, while the word tested here is at
**`+184`** of `[object + 4]`. Same constant, same `EX`/`EXTRA` naming, two
different offsets in what may be two different objects — **that the two fields
are the same field is not shown**, only that both compare a mode word against 3.