re: the title's state machine is decoded -- ten states, eighteen edges
Q6's last open piece was which state leads to which, and it turned out to be a plain switch. state = this+136, compared against 9, dispatched through a jump table at 0x821C6498. The ten words at that address disassemble as lwz r16,N(r28) instructions and are nothing of the kind -- they are the table. That is the same "self-reference" I flagged two iterations ago as looking like a jump table; it is one, and the disassembler was decoding its data. Three states install a named screen: 0 is TITLE_SCREEN, 2 is TITLE_MENU, 8 is LOADING. Eighteen transitions, every one a literal li/stw pair into the state field, giving the full graph. It lines up with the behaviour measured weeks of iterations ago without either side knowing about the other: boot reaches state 0 and A opens state 2; B at the main menu returns to the title, and 4 -> 0 is the ONLY edge back to state 0, reached from 2 -> 4; entering a submenu goes through LOADING and comes back, which is 4 -> 8 at four separate sites then 8 -> 2. I have marked that as corroboration and said plainly it is me matching a graph to observations -- the conditions on the edges are not decoded, so nothing here proves which input picks which branch. Still open and written down as such: the condition on each edge, what states 1/3/5/6/7/9 do, and the fact that state 3 is never a destination in this function, so something outside sets it.
This commit is contained in:
@@ -206,8 +206,14 @@ authored version can be deleted.
|
||||
`GAMMA_RGB`. An earlier version of this page claimed `DIFFICULTY` and
|
||||
`EXTRA_MENU` as corroborated screen names; **neither is ever the argument**, and
|
||||
only `TUTORIAL_MENU` survives.
|
||||
The port can transcribe the state **names**; the order still comes from
|
||||
measurement. The sequence itself is fully measured:
|
||||
✅ **And the state machine itself is decoded**: `state = this+136`, ten states
|
||||
dispatched through a jump table at `0x821C6498`, with **18 transitions** each a
|
||||
literal `li`/`stw`. States **0, 2, 8** install `TITLE_SCREEN`, `TITLE_MENU`,
|
||||
`LOADING`. `4 → 0` is the only edge back to the title, reached from `2 → 4` —
|
||||
which matches Ⓑ-returns-to-title as measured. Full graph in
|
||||
[`data/title-state-machine.txt`](../re/data/title-state-machine.txt).
|
||||
🟡 The **conditions** on the edges are not decoded, so the port still takes the
|
||||
order from measurement; the graph corroborates it rather than replacing it. The sequence itself is fully measured:
|
||||
splash → `ADV.wmv` → title + `PRESS Ⓐ` → (idle ~8–10 s → `ADV.wmv` in full →
|
||||
title) → Ⓐ → main menu, with Ⓑ from the main menu returning to the title.
|
||||
|
||||
@@ -284,7 +290,7 @@ here until 2026-08-28 and is now settled.)
|
||||
| ❔ | **the other ~319 SE cues** (Q8) | located one at a time by triggering them; only the three the menu needs have been done |
|
||||
| 🟡 | **the paint-order tie-break** (Q3) | eight candidates refuted; costs one element's blend on one screen |
|
||||
| 🟡 | **GamePart ids behind the buttons** (Q4) | the *screens* are measured; the ids are a name match onto the executable's class names |
|
||||
| 🟡 | **the boot transitions in code** (Q6) | a title-side transition is a **screen lookup by NAME** — `sub_821CC860(…, "TITLE_SCREEN"/"TITLE_MENU"/"LOADING", 0)` then install. A candidate name vocabulary of ~12 screens falls out, 3 of them corroborated by measurement. Which state leads to which is still unread |
|
||||
| 🟡 | **the boot transitions in code** (Q6) | **the state machine is decoded** — `state = this+136`, ten states, jump table at `0x821C6498`, 18 literal transitions; states 0/2/8 install `TITLE_SCREEN`/`TITLE_MENU`/`LOADING`. Still unread: the **condition** on each edge |
|
||||
| ❔ | **builds 0/1 and 10/11**, the `DELTASABER` plates (Q2) | never seen anywhere in the boot path, the title-side screens or the attract loop. A mission load is the remaining candidate and this container kills runs before one completes |
|
||||
|
||||
(An earlier version of this table called the audio items blocked on "an emulator
|
||||
|
||||
@@ -298,3 +298,55 @@ That weakens nothing about the title finding itself — `sub_821C6458` really do
|
||||
transition by calling this with `TITLE_SCREEN` / `TITLE_MENU` / `LOADING` — but it
|
||||
removes the inference that the 28 names are a screen vocabulary. They are a
|
||||
**lookup-key vocabulary**, mostly config.
|
||||
|
||||
|
||||
## ✅ The title's state machine — decoded
|
||||
|
||||
The last open piece of Q6 was *which state leads to which*. It is a plain
|
||||
`switch` and it is now read.
|
||||
|
||||
```
|
||||
821c6474 lwz r11, 136(r30) ; state = this+0x88
|
||||
821c6478 cmplwi cr6, r11, 0x9 ; ten states, 0..9
|
||||
821c647c bgt cr6, <default>
|
||||
821c6480 lis/addi r12, 0x821C6498 ; jump table
|
||||
821c648c lwzx r0, r12, r0
|
||||
821c6494 bctr
|
||||
```
|
||||
|
||||
⚠️ The table at `0x821C6498` disassembles as ten `lwz r16, N(r28)` instructions.
|
||||
**It is data.** That is the "self-reference" this page flagged two sections ago as
|
||||
*looking* like a jump table — it is one, and the disassembler was decoding its
|
||||
words as code.
|
||||
|
||||
**Three of the ten states install a named screen**: **0 → `TITLE_SCREEN`**,
|
||||
**2 → `TITLE_MENU`**, **8 → `LOADING`**.
|
||||
|
||||
**Eighteen transitions**, every one a literal `li rX, N ; stw rX, 136(r30)`:
|
||||
|
||||
```
|
||||
0 → 1, 2 2 → 4 4 → 0, 5, 8×4 6 → 7, 9, 2 8 → 2
|
||||
1 → 2, 2 3 → 4 5 → 6 7 → 9 9 → (none)
|
||||
```
|
||||
|
||||
Full table with addresses in
|
||||
[`data/title-state-machine.txt`](data/title-state-machine.txt).
|
||||
|
||||
### 🟡 It lines up with what was measured — read as corroboration, not proof
|
||||
|
||||
The boot reaches the title (state 0) and Ⓐ opens the main menu (state 2); the
|
||||
graph has `0 → 2` directly and `0 → 1 → 2`. Ⓑ at the main menu returns to the
|
||||
title, and `4 → 0` is the **only** edge back to state 0, reached from `2 → 4`.
|
||||
Entering a submenu goes through `LOADING` and comes back, and `4 → 8` (four
|
||||
separate sites) then `8 → 2` is exactly that shape.
|
||||
|
||||
Those readings are **mine, matching a graph to observed behaviour** — the
|
||||
conditions on the edges are not decoded, so nothing here proves which input picks
|
||||
which branch.
|
||||
|
||||
### What is still not decoded
|
||||
|
||||
* **the condition on each edge** — which input or event selects it;
|
||||
* **states 1, 3, 5, 6, 7, 9** install no named screen, so what they do is unknown;
|
||||
* **state 3 is never a destination** in this function, so something outside sets
|
||||
it.
|
||||
|
||||
55
docs/re/data/title-state-machine.txt
Normal file
55
docs/re/data/title-state-machine.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
GamePart_Title's screen state machine -- sub_821C6458, decoded statically.
|
||||
|
||||
DISPATCH
|
||||
821c6474 lwz r11, 136(r30) ; state = this+0x88
|
||||
821c6478 cmplwi cr6, r11, 0x9 ; 10 states, 0..9
|
||||
821c647c bgt cr6, 0x821C75B8 ; out of range -> default
|
||||
821c6480 lis r12, 0x821C
|
||||
821c6484 addi r12, r12, 25752 ; jump table at 0x821C6498
|
||||
821c6488 slwi r0, r11, 2
|
||||
821c648c lwzx r0, r12, r0
|
||||
821c6490 mtctr r0
|
||||
821c6494 bctr
|
||||
|
||||
NOTE: a disassembler decodes 0x821C6498..0x821C64BC as `lwz r16, N(r28)`
|
||||
instructions. They are the jump TABLE's ten words, not code.
|
||||
|
||||
STATES
|
||||
case 0 -> 0x821c64c0 installs "TITLE_SCREEN"
|
||||
case 1 -> 0x821c65d0
|
||||
case 2 -> 0x821c66e4 installs "TITLE_MENU"
|
||||
case 3 -> 0x821c6b18
|
||||
case 4 -> 0x821c6b5c nested switch, table at 0x821c6b7c (live: 0,3,5,8)
|
||||
case 5 -> 0x821c6fd4
|
||||
case 6 -> 0x821c7028
|
||||
case 7 -> 0x821c72dc
|
||||
case 8 -> 0x821c733c installs "LOADING"
|
||||
case 9 -> 0x821c7558
|
||||
|
||||
TRANSITIONS -- every `li rX,N ; stw rX,136(r30)` in the function
|
||||
from to at
|
||||
0 1 0x821c6598
|
||||
0 2 0x821c65c8
|
||||
1 2 0x821c66a4
|
||||
1 2 0x821c66dc
|
||||
2 4 0x821c6afc
|
||||
3 4 0x821c6b54
|
||||
4 0 0x821c6e00
|
||||
4 5 0x821c6e70
|
||||
4 8 0x821c6ed0
|
||||
4 8 0x821c6f20
|
||||
4 8 0x821c6f7c
|
||||
4 8 0x821c6fcc
|
||||
5 6 0x821c7020
|
||||
6 7 0x821c725c
|
||||
6 9 0x821c72a8
|
||||
6 2 0x821c72d4
|
||||
7 9 0x821c7334
|
||||
8 2 0x821c7548
|
||||
(state 9 stores nothing -- terminal within this function)
|
||||
|
||||
WHAT IS NOT DECODED
|
||||
* the CONDITION on each edge -- which input or event selects it;
|
||||
* what states 1, 3, 5, 6, 7 and 9 do (they install no named screen);
|
||||
* state 3 is never a destination here, so something outside this function
|
||||
sets it.
|
||||
Reference in New Issue
Block a user