This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/data/title-state-machine.txt
Sylpheed RE agent a98e96b0f0 re: the ten states are ONE PHASE of five -- and phase 0 is the splash
Chasing where the event code comes from turned up the level above and
corrected my own framing three sections running.

sub_821C6458 has exactly one caller, sub_821C7850, and that caller is
itself a dispatcher -- on a SECOND, outer state field at this+132, five
phases, gated on this+16 == 3. Phase 4 is the title/menu machine I have
been decoding. Phase 0 is sub_821C5690, which the iterate3E notes had
already fingered as the splash mechanics from a completely different
direction. That agreement is the useful check here.

So GamePart_Title has two nested state fields: a phase at this+132
choosing which sub-machine runs, and the state at this+136 inside phase
4. Everything I decoded over the last three iterations -- ten states,
eighteen edges, the event dispatch -- is phase 4 ONLY. Phases 1, 2 and 3
are untouched. I have called that out in REFUTED against my own earlier
wording rather than quietly restating it.

And the event code is forwarded, not created: all five phase handlers are
called with the same (this, r29, r28), where r28 is sub_821C7850's own
third argument passed through untouched. So the event vocabulary is
defined at least one level further up, and finding what 3, 5, 8, 10 and
25 mean means going up again. Not done.
2026-08-28 20:05:27 +00:00

98 lines
3.6 KiB
Plaintext

GamePart_Title has TWO nested state fields.
OUTER -- sub_821C7850, the part's dispatcher
821c786c lwz r11, 16(r30) ; only runs when this+16 == 3
821c7870 cmpwi cr6, r11, 3
821c7874 bne cr6, <exit>
821c787c lwz r11, 132(r30) ; phase = this+0x84
821c7880 cmplwi cr6, r11, 0x4 ; five phases, 0..4
821c7888 lis/addi r12, 0x821C78A0 ; jump table
821c789c bctr
phase 0 -> sub_821C5690 (the splash -- independently identified as the
splash mechanics in the iterate3E notes)
phase 1 -> inline block at 0x821c790c
phase 2 -> sub_821C5818
phase 3 -> sub_821C5EC0
phase 4 -> sub_821C6458 (the title/menu machine, below)
All four call sites forward the SAME three arguments: (this, r29, r28),
where r28 is this function's own third argument -- an EVENT CODE passed
through unchanged from ITS caller.
INNER -- sub_821C6458, the title/menu machine (phase 4 only)
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)
THE CONDITION ON STATE 4's EDGES -- decoded
sub_821C6458(this, ?, r5) takes an EVENT CODE in its third argument.
State 4 -- the input-waiting state -- dispatches on it:
821c6b5c cmplwi cr6, r27, 0x19 ; 26 events, 0..25
821c6b60 bgt cr6, <default>
821c6b68 addi r12, r12, 27516 ; table at 0x821c6b7c
821c6b78 bctr
Only 6 of the 26 are handled; the other 20 fall through with no state change.
event 0 -> block 0x821c6be4 -> state 0 (TITLE_SCREEN -- back to the title)
event 3 -> block 0x821c6e78 -> state 8 (LOADING)
event 5 -> block 0x821c6f84 -> state 8 (LOADING)
event 8 -> block 0x821c6f34 -> state 8 (LOADING)
event 10 -> block 0x821c6e28 -> state 5
event 25 -> block 0x821c6ed8 -> state 8 (LOADING)
WHAT IS NOT DECODED
* what the event NUMBERS mean -- they are forwarded unchanged from
sub_821C7850's caller, so the vocabulary is defined at least one level up -- button id, menu-item id or message id;
* the conditions on edges out of states other than 4;
* 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.