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, 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, 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.