.set rC, 3 # SHOULD NOT BE USE UNTIL checkAreaLock ENDS .set r817F, 4 .set rBtn, 5 .set rC4, 5 .set rIdx, 6 .set rAns, 7 .set rAnsEp, 8 .set rD, 9 # BL trick .set rApp, 31 .set rFM, 11 # FlagManager .set rTmp, 10 .set crAreaLock, 7 .L.prepare: ## prepare registers lis r817F, 0x817F lwz rFM, TFlagManager_smInstance$r13(r13) ## read button input: [M]*1 [C]*1 [btn]*2 lis r12, JUTGamePad_mPadButton@ha lwz rBtn, JUTGamePad_mPadButton@l(r12) /** NOTE: DO NOT CHANGE r12 UNTIL checkAreaLock ENDS */ .L.checkAreaLock: ## r0 = 0x22 - btn subfic r0, rBtn, 0x22 ### (lower 16 bit of r0 & ~1) == 0 => use r0&1 as AreaLock enable state rlwinm. rTmp, r0, 0, 0x10, 0x1E beq .L.checkAreaLock.1 ### else, load r0 = current state from RAM lbz r0, $LevelSelect.AreaLock@l(r817F) .L.checkAreaLock.1: ## !cr0.eq: AreaLock enabled rlwinm. r0, r0, 0, 0x1 ## write current enable state to RAM stb r0, $LevelSelect.AreaLock@l(r817F) ## activate AreaLock only if director finished (r29 > 1) cmplwi cr1, r3, 1 crandc eq, 4*cr1+gt, eq bne+ .L.checkAreaLock.done ## set button input to (handleRestartN) if AreaLock enabled li rBtn, 0x208 stw rBtn, JUTGamePad_mPadButton@l(r12) .L.checkAreaLock.done: ## orig mr. r29, r3 ## return now if still setting up beq .L.done ## Level Select bl .L.LevelSelect .D: .D.Special: # 8 bit/entry: [1bit] epFlag==7 | [7bit] area .long 0x00141516 .long 0x0017181D .long 0x34000090 # Red coin fish@NB8: 0x80|0x10 .D.Secrets: # 8 bit/entry: [1bit] ep==1 | [7bit] area .long 0x2F2E3020 .long 0x32293328 .long 0x2A1FBA3C .D.Sublevels: # 8 bit/entry .long 0x371E213A .long 0x0E2C3900 .D.Plaza: .long 0x00010507 .long 0x08090200 .D.Extra: .D.PinnaPark: ## ep: 0,1,2,3,4,5,7 | area=D ## epFlag: 0,2,4,5,6,7,0 .long 0x123457D0 .long 0x24567000 .D.SirenaHotel: ## ep: 0,1,2,2,3,4 | area=7 ## episo: 1,2,3,4,6,7 .long 0x12234070 .long 0x23467001 .L.LevelSelect: mflr rD .L.checkDisabled: ## check input ### goto done if r0!=0x208 andi. r0, rBtn, 0x208 cmplwi r0, 0x208 bne+ .L.done .L.main: ## calc index ## btn: S YXZA -LRZ ---- ## XZRL=8,4,2,1 rlwinm rIdx, rBtn, 32-7, 0x8 # X=8 rlwimi rIdx, rBtn, 32-2, 0x4 # Z=4 rlwimi rIdx, rBtn, 32-4, 0x2 # R=2 rlwimi rIdx, rBtn, 32-6, 0x1 # L=1 ## YSY=8,4,2 rlwinm r0, rBtn, 32- 8, 0x8 # Y=+8 rlwimi r0, rBtn, 32-10, 0x6 # S,Y=4,+2 ## merge XZRL and YSY- or rIdx, rIdx, r0 # TODO? handle rIdx>=12 ## check C==0(Special) or 9(Secrets) rlwinm. rC, rBtn, 32-16, 0xF beq handleSpecial cmpwi rC, 9 beq handleSecrets ## calc C index ### [(*), 6, 2, (*); 4, 5, 3, (*); 0, (*), 1] ### 110 0/10 00/0 100/ 101 0|11 00/0 000/ 000 0/01 00 .set CIdxMagic, 06204530001<<(32-3*10) ### CIdx = magic <<(3*C) &7 lis r0, CIdxMagic@h ori r0, r0, CIdxMagic@l mulli rC, rC, 3 rlwnm rC, r0, rC, 0x7 ## prepare CIdx<<2 (destroy rBtn) slwi rC4, rC, 2 ## Y+Z(14) -> SirenaHotel ## X+Z(12) -> PinnaPark cmpwi rIdx, 12 bge handleExtra ## Y(10) -> Plaza cmpwi rIdx, 10 bge handlePlaza ## X(8) -> Sublevels cmpwi rIdx, 8 bge handleSublevels ## stage ### area: [2, 3, 4, 5, 6, 8, 9, (*)] ### magic = 0x34568902 rotl sizeof(0xFF) ### ans = idx | (magic<<(Cidx<<2)) &0x0F00 ### ep = idx lis r0, 0x5689 ori r0, r0, 0x0234 slwi r12, rC, 2 rlwnm r12, r0, r12, 0x0F00 or rAns, rIdx, r12 rlwinm rAnsEp, rIdx, 0, 0x7 b .L.loadStage handleSpecial: lhz rAns, 0xE(rApp) # backup for handleRestartN ## neutral cmpwi rIdx, 0 beq handleRestartN ## Z restart cmpwi rIdx, 4 beq handleRestartZ ## Y restart cmpwi rIdx, 10 beq handleRestartY ## Special # rD = .D.Special lbzx r0, rD, rIdx # offset = idx rlwinm rAns, r0, 8, 0x3F00 rlwinm rAnsEp, r0, 32-7, 0x1 mulli rAnsEp, rAnsEp, 7 b .L.loadStage handleRestartN: ## set prevMap = curMap lhz r0, 0xA(rApp) sth r0, 0xE(rApp) handleRestartZ: ## load curMap, ep lbz rAnsEp, 0xDF(rFM) b .L.loadStageWithoutBackup handleRestartY: # load 817F0000 lhz rAns, $LevelSelect.area@l(r817F) lbz rAnsEp, $LevelSelect.epFlag@l(r817F) b .L.loadStage handleSecrets: la r12, .D.Secrets-.D(rD) lbzx r0, r12, rIdx rlwinm rAns, r0, 8, 0x3F00 rlwimi rAns, r0, 32-7, 0x0001 # ep: 2,5,3,0,1,5,1,3,4,5,0,* .set SecretEpMagic, 05301513450<<2 | 02 lis r0, SecretEpMagic@h ori r0, r0, SecretEpMagic@l mulli r12, rIdx, 3 rlwnm rAnsEp, r0, r12, 0x7 b .L.loadStage handleSublevels: la r12, .D.Sublevels-.D(rD) lbzx r0, r12, rC # Cidx as index rlwinm rAns, r0, 8, 0x3F00 # ep: 1,1,3,7,3,2,3 .set SublevelEpMagic, 0x13732301 lis r0, SublevelEpMagic@h ori r0, r0, SublevelEpMagic@l rlwnm rAnsEp, r0, rC4, 0x7 b .L.loadStage handleExtra: la r12, .D.Extra-.D-12*4(rD) rlwinm r0, rIdx, 2, 0x38 # offset: {12,14}<<2 lwzux r0, r12, r0 rlwnm rAns, r0, rC4, 0x7 # ep rlwimi rAns, r0, 4, 0x0F00 # a0 => aEE lwz r0, 4(r12) rlwnm rAnsEp, r0, rC4, 0x7 b .L.loadStage handlePlaza: ## [0, 1, 5, 7; 8, 9, 2, (*)] ## 15789200 ## ans == 0x0100 | (magic << (arr:=CIdx<<2) &0xF) .set PlazaEpMagic, 0x15789200 lis r0, PlazaEpMagic@h ori r0, r0, PlazaEpMagic@l rlwnm rAns, r0, rC4, 0xF ori rAns, rAns, 0x0100 li rAnsEp, 0 .L.loadStage: ### backup to 817F0000 (for Y) sth rAns, $LevelSelect.area@l(r817F) stb rAnsEp, $LevelSelect.epFlag@l(r817F) /* rAns, rAnsEp, rFM, rApp, r817F */ .L.loadStageWithoutBackup: ## reset QFT li r0, 1 stb r0, 0xB3(r817F) ## FlagManager ### epFlag(40003) stb rAnsEp, 0xDF(rFM) ### reset coin counter(40002) li r0, 0 stw r0, 0xD8(rFM) ##### set SGT Stop Stopwatch Flag = 0 # stw r0, 0x10C(r817F) ### set flag lhz r0, 0xCC(rFM) #### Got a Shine in previous stage (30006) ori r0, r0, 0x4000 #### clear watched Pinna kidnap FMV flag (prevent spawn in PP unlocked position) rlwinm r0, r0, 0, 0x14, 0x12 sth r0, 0xCC(rFM) ## rApp = gpApplication ### write nextArea sth rAns, 0x12(rApp) .set rMGP, 12 # SirenaHotel(0x07) or Casino(0x0E) ? 59 : 0 rlwinm r0, rAns, 32-8, 0xFF # area lwz rMGP, 0x20(rApp) # TMarioGamePad* cmpwi r0, 0x07 # SirenaHotel cmpwi cr1, r0, 0x0E # Casino cror eq, eq, 4*cr1+eq li r0, 59 beq- .L.handleStickCD li r0, 0 .L.handleStickCD: sth r0, 0xe4(rMGP) .L.handleStickFlag: ## clear 0x2 bit of 0xe2 flag lhz r0, 0xe2(rMGP) rlwinm r0, r0, 0, 31, 29 sth r0, 0xe2(rMGP) ## nextGameMode = nextArea == (shine select) ? 8 : 5 ### (Note: all valid area id < 0x40) rlwinm r29, rAns, 32-6, 0x3 # 0xC0 => 0x03 addi r29, r29, 5 .L.done: