re: the GamePart_MainGame vtable names the code region; a stage-index lead

sub_821A6CF0 is reached only by a tail b from a run of adjustor thunks
whose vtable is at 0x820A319C.  Slot 1 is 'addi r3, r0, 17; blr' -- the
factory id -- so RegisterToFactory<17, class silph::GamePart_MainGame>
names the class, and every thunk's lwz r3, 8(r3) makes slots 4-10
GamePart_MainGame::Impl methods (9 = the per-frame Update
sub_821AA1B0).  Several iterations' worth of inference is now a read.

Lead, not adopted: the disc has 28 scripts numbered Stage01-16 and
Stage18-29 -- exactly one gap, Stage17 -- and the gate excludes exactly
one value, 16, which lines up 0-based.  Control comparison: the refuted
GamePart-id reading had 4 missing values (1-of-4, worthless), this is
1-of-1.  Tighter but still coincidence-shaped.  The Stage%02d
construction site would settle it; not found this pass.

Docs only; artefacts byte-identical.
This commit is contained in:
Sylpheed RE agent
2026-08-27 09:56:34 +00:00
parent abbd0cfb32
commit 084ce60bf7
2 changed files with 66 additions and 0 deletions

View File

@@ -478,6 +478,30 @@ unknown, what evidence exists, and what the first step would be. Move an item in
🟡 Not settled: what the kind **means**. The gate is read; the value's domain is
not, and chasing it needs another hop up (`sub_821A6CF0`'s caller).
* ✅🟡 **(2026-08-27) THE CODE REGION IS NAMED — `GamePart_MainGame` — and the
kind's domain has a better-controlled lead that I am NOT adopting.
[structures/isl-condition-builtins](structures/isl-condition-builtins.md).**
`sub_821A6CF0` has no `bl` callers, only a tail `b` from `0x821AC04C`, which
sits in a run of adjustor thunks fed by a **vtable at `0x820A319C`** (RTTI at
`0x820A3198`). **Slot 1 is `addi r3, r0, 17; blr`** — the factory id, and
`RegisterToFactory<17, class silph::GamePart_MainGame>` names it. Every thunk
does `lwz r3, 8(r3)` first, so slots 410 are **`GamePart_MainGame::Impl`
methods**: 4 → `sub_821A6CF0`, 5 → `sub_821A82A0`, 6 → `sub_821A8428`,
7 → `sub_821A9DC8`, 8 → `sub_821A9CF0`, **9 → `sub_821AA1B0` (the per-frame
Update)**, 10 → `sub_821AB570`. The region several iterations have been reading
is now *named* rather than inferred.
🟡 **The lead, with its control stated.** The disc carries **28 mission scripts
numbered `Stage01``Stage16` and `Stage18``Stage29` — exactly one gap,
Stage17** — and the gate excludes **exactly one value, 16**. Under 0-based
indexing `16 ↔ Stage17`, with `<= 32` bounding indices 0…28. Against the
refuted GamePart-id reading (**4** values missing from its domain, gate excludes
1 → 1-of-4, worthless) this is **1-of-1**. Much tighter — and still
coincidence-shaped, so **not adopted**. ▶️ What would settle it: the
`Stage%02d` construction site. The image has a generic `'%s%02d'` formatter at
`0x820A9C8C`; whether it is fed `index` or `index + 1` decides it outright. Not
found this pass, and `grep`ping the extracted disc does not help — the pak names
are hashed, so neither `Stage16` nor `Stage17` appears as a plain token.
## ✅✅ SOLVED — the mission freeze was a modal sign-in dialog (2026-08-26)
`XamShowSigninUI` opens a modal dialog and `xeXamDispatchDialog` blocks the

View File

@@ -177,6 +177,48 @@ gaps, not a unique one. Nothing distinguishes it. The reading is not adopted.
🟡 So what the kind **means** is still open — the gate is now read, but the
value's domain is not.
## ✅ (2026-08-27) The code region is NAMED: `GamePart_MainGame`
`sub_821A6CF0` has no `bl` callers, only a tail `b` from `0x821AC04C`. That
address sits in a run of adjustor thunks, and the table pointing at them is a
**vtable at `0x820A319C`** (RTTI locator at `0x820A3198` = `0x8210BB58`):
| slot | entry | resolves to |
|---|---|---|
| 0 | `sub_821ABFA8` | destructor |
| 1 | `0x821AC040` | **`addi r3, r0, 17; blr`** — returns the factory id |
| 4 | `0x821AC048` | `lwz r3, 8(r3); b sub_821A6CF0` |
| 5 | `0x821AC050` | `→ sub_821A82A0` |
| 6 | `0x821AC058` | `→ sub_821A8428` |
| 7 | `0x821AC060` | `→ sub_821A9DC8` |
| 8 | `0x821AC078` | `→ sub_821A9CF0` (guarded `r4 == 9`) |
| **9** | `0x821AC068` | **`→ sub_821AA1B0`** — the per-frame Update |
| 10 | `0x821AC070` | `→ sub_821AB570` |
Slot 1 returning **17** is decisive: `RegisterToFactory<17, class
silph::GamePart_MainGame>`. Every thunk does `lwz r3, 8(r3)` first, so these are
**`GamePart_MainGame::Impl` methods** reached through the outer class. The code
region this page has been reading is now named rather than inferred.
## 🟡 A lead on the kind's domain — better-controlled than the last one, still not adopted
The disc carries **28 mission scripts, numbered `Stage01``Stage16` and
`Stage18``Stage29`** (as extracted; the corpus's own "all 28 `StageNN.ssb`").
**Exactly one gap: Stage17.** The gate excludes **exactly one value: 16**. Under
0-based indexing `16 ↔ Stage17`, and `<= 32` comfortably bounds indices 0…28.
Compare the controls honestly:
| reading | values missing from the domain | gate excludes | match |
|---|---|---|---|
| GamePart id (refuted) | **4** — 1, 2, 16, 18 | 1 value | 1-of-4 — worthless |
| stage index (this) | **1** — Stage17 | 1 value | 1-of-1 |
That is a much tighter fit, and it is *still* coincidence-shaped. **Not adopted.**
What would settle it: the `Stage%02d` construction site — the image has a generic
`'%s%02d'` formatter at `0x820A9C8C`, and whether it is fed `index` or
`index + 1` decides the question outright. Not found this pass.
🟡 Its neighbours belong to the same cluster: `builtin103` reads
`[phase+10156]` and `[phase+10152]` (9 and 7 writers), and a sibling vtable stub
clears `[phase+10152]`. The shape is an engine→script status trio, but that is a