1
0
Fork 0

[ILS] add src and README

This commit is contained in:
sup39 2022-08-31 21:12:06 +09:00
parent 1592d20bf2
commit 278b60ced5
4 changed files with 390 additions and 2 deletions

View file

@ -3,10 +3,13 @@
||NTSC-J 1.0|NTSC-J 1.1|NTSC-U|PAL|
|-|:-:|:-:|:-:|:-:|
|[Pattern Selector](#pattern-selector)|◎|◎|[](https://twitter.com/torcnein/status/1518614922850148353)||
|[Instant Level Select](#instant-level-select)|◎||||
|[Instant Restart](#instant-restart)|◎|◎|[](https://twitter.com/torcnein/status/1518614922850148353)||
|[Fast Forward](#fast-forward)|◎|◎|||
|[Skip Stage Intro](#skip-stage-intro)|◎|◎|||
|[Mirror Mode](#mirror-mode)|◎|◎|[Source](https://discord.com/channels/83214196182880256/273126568795176960/960281550275104768)||
|[Spawn Yoshi](#spawn-yoshi)|◎||||
|[Load flags for Any%](#load-flags-for-any)|◎||||
◎: tested by sup39
: tested by others
@ -19,10 +22,21 @@
Note: **you need to enable `drawText` as well**
### Instant Level Select
- Press `B + D-Pad Up` to **restart the current area**
- The **respawn position** will be the same. It can be used to practice Honey Skip or stage movement in Delfino Plaza
- Press `{button of Level Select} + B + D-Pad Up` to activate Level Select immediately
- For `Z + B + D-Pad Up`, the current area will be restarted, but the **respawn position will be reset**. It is like B+DPad_Up, but the respawn position will be the default position instead of the previous one
- For `Y + B + D-Pad Up`, it will restart from the **previous selected area**. For example, if you select SB4 with this code, and enter hotel/casino then press Y+B+DPad_Up, it will restart from SB4 beach (instead of hotel/casino if you use B+DPad_Up or Z+B+DPad_Up)
- NOTE: **Z menu will be disabled**
- Press `R + D-Pad Left/Right` to enable/disable **Area Lock**
- With Area Lock, warps will restart the current area instead of sending Mario to other areas, which can be used to practice specific area (e.g. outside of BH2 wildmill, secret stage entering)
- Restarting acts like B+DPad_Up, and therefore can be used to practice Honey Skip, etc.
### Instant Restart
- press `Y + D-Pad Up` to restart without pausing + exit area
You can change the `0808` in the 3rd line to the button input value you want.
You can change the `0808` in the 3rd line to the [button input value](https://app.sms.sup39.dev/code/button-calculator/) you want.
### Fast Forward
- press `B + D-Pad Down` to fast forward 4x
@ -56,7 +70,7 @@ Press `Y +` the following button to spawn Yoshi with specific color and make Mar
- `D-Pad Down`: Pink
- `D-Pad Up`: Green
### Load flags for Any%
### Load Flags for Any%
Press `L + R +` C stick with the following direction `+ D-Pad Left` to load a preset file (flags) for Any% and spawn Mario in plaza
C Stick|State

View file

@ -0,0 +1,24 @@
__baseAddr__ = 0x817f9800;
$LevelSelect.area = 0x817f0000;
$LevelSelect.epFlag = 0x817f0002;
$LevelSelect.en = 0x817f0004;
$AreaLock.en = 0x817f0005;
$b$.TMarioGamePad.onNeutralMarioKey = 0x800fbad8;
$b$.Mar.changeState = 0x800ec420;
.Mar.changeState.applied = 0x800ecb28;
$b$.Mar.moveStage = 0x800eab80;
/* TMarDirector::fireStreamingMovie */
$bl$.Mar.disable.PinnaFMV = 0x800ed64c;
$b$.gameLoop.preDirect = 0x800f9b60;
$b$.gameLoop.preReturn = 0x800f9d68;
$b$.Movie.direct = 0x8010b100;
$b$.Movie.decideNextMode = 0x8010b3cc;
.Movie.decideNextMode.applied = 0x8010b534;
$b$.ShineSelect.direct = 0x80236600;
.ShineSelect.direct.applied = 0x80236620;

View file

@ -0,0 +1,92 @@
.set FULL, 1 # FULL InstantLevelSelect
.include "LevelSelect.s"
.Mar.changeState:
## Level Select
#lbz r0, 0x64(r31)
#cmpwi r0, 0
#beq- .Mar.changeState.done
bl LevelSelect
bne+ cr1, .Mar.changeState.done # not activated
mr r3, r31
bl TMarDirector_moveStage
li r28, 9 # nextState = LevelTransition
b .Mar.changeState.applied
.Mar.changeState.done:
lbz r0, 0x64(r31)
b 4+$b$.Mar.changeState
.Mar.moveStage:
lis r817F, 0x817F
lhz r0, $LevelSelect.en@l(r817F) # [LS, AL]
cmpwi r0, 1 # AL only
bne .Mar.moveStage.done
## clear FMV flag
lhz r0, 0x4c(r31)
rlwinm r0, r0, 0, 0x18, 0x16
sth r0, 0x4c(r31)
## store nextArea and set flags
lwz rFM, TFlagManager_smInstance$r13(r13)
mr rApp, r28
lhz rAns, 0xE(rApp)
bl handleRestartN
## set curArea = prevArea # TODO
lhz rAns, 0xa(r28)
sth rAns, 0xe(r28)
.Mar.moveStage.done:
## orig
li r0, 0xff
addi r4, r1, 0x54
b 4+$b$.Mar.moveStage
.Mar.disable.PinnaFMV:
lis r12, 0x817F
lbz r4, $AreaLock.en@l(r12)
xori r4, r4, 1 # locked ? false : true
b TFlagManager_setBool
.if FULL == 1
.Movie.direct:
bl LevelSelect
bne+ cr1, .Movie.direct.done # not activated
li r3, 2
stw r3, 0x12c(r1)
.Movie.direct.done:
## orig
lwz r3, 0x20(r31)
b 4+$b$.Movie.direct
.Movie.decideNextMode:
lis r817F, 0x817F
lbz r0, $LevelSelect.en@l(r817F)
cmpwi r0, 1 # test if LS activated
bne .Movie.moveStage.done
## return
b .Movie.decideNextMode.applied
.Movie.moveStage.done:
## orig
cmplwi r5, 0xe
b 4+$b$.Movie.decideNextMode
.ShineSelect.direct:
bl LevelSelect
bne+ cr1, .ShineSelect.direct.done # not activated
b .ShineSelect.direct.applied
.ShineSelect.direct.done:
## orig
lwz r3, 0x20(r30)
subi r5, r31, 0x34
lbz r0, 0x13b(r3)
b 4+$b$.ShineSelect.direct
.endif
.gameLoop.preReturn:
## reset LevelSelect.en
lis r3, 0x817F
li r0, 0
stb r0, $LevelSelect.en@l(r3)
## orig
mr r3, r29
b 4+$b$.gameLoop.preReturn

View file

@ -0,0 +1,258 @@
.set r817F, 3 # 817F0000
.set rC, 4
.set rBtn, 5
.set rC4, 5
.set rIdx, 6
.set rAns, 7
.set rAnsEp, 8
.set rD, 9 # BL trick
.set rApp, 10 # gpApplication
.set rFM, 11 # FlagManager
.set rArr, 12 # tmp
LevelSelect: # cr1.EQ: activated
## read button input: [M]*1 [C]*1 [btn]*2
lis rBtn, JUTGamePad_mPadButton@ha
lwz rBtn, JUTGamePad_mPadButton@l(rBtn)
## check input
andi. r0, rBtn, 0x208
cmplwi cr1, r0, 0x208
## check if already activated
lis r817F, 0x817F
lbz r0, $LevelSelect.en@l(r817F)
mr. r0, r0
## return if needed
# cr1.eq && cr0.eq
crand 4*cr1+eq, 4*cr1+eq, eq
bnelr+ cr1
## Level Select
mflr r12
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
mtlr r12
## prepare registers
lis rApp, gpApplication@ha
la rApp, gpApplication@l(rApp)
lwz rFM, TFlagManager_smInstance$r13(r13)
## 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 rArr, rC, 2
rlwnm rArr, r0, rArr, 0x0F00
or rAns, rIdx, rArr
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 rArr, .D_Secrets-.D(rD)
lbzx r0, rArr, 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 rArr, rIdx, 3
rlwnm rAnsEp, r0, rArr, 0x7
b .L_loadStage
handleSublevels:
la rArr, .D_Sublevels-.D(rD)
lbzx r0, rArr, 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 rArr, .D_Extra-.D-12*4(rD)
rlwinm r0, rIdx, 2, 0x38 # offset: {12,14}<<2
lwzux r0, rArr, r0
rlwnm rAns, r0, rC4, 0x7 # ep
rlwimi rAns, r0, 4, 0x0F00 # a0 => aEE
lwz r0, 4(rArr)
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)
### Ingame Timer: Reset Stopwatch Flag
stb r0, 0x100(r817F)
### set SGT Disable Custom IG Timer Flag = 1 TODO
#stb r0, 0x101(r817F)
### en flag
stb r0, $LevelSelect.en@l(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 TODO
#stw r0, 0x10C(r817F)
### Got a Shine in previous stage (30006)
#### + watched AP, court, peach kidnap, FLUDD theft flag
lhz r0, 0xCC(rFM)
ori r0, r0, 0x40FF
#### clear watched Pinna kidnap FMV flag
rlwinm r0, r0, 0, 0x14, 0x12
sth r0, 0xCC(rFM)
## rApp = gpApplication
### write nextArea
sth rAns, 0x12(rApp)
# SirenaHotel(0x07) or Casino(0x0E) ? 59 : 0
rlwinm r0, rAns, 32-8, 0xFF # area
lwz rArr, 0x20(rApp) # TMarioGamePad*
li rC, 59
cmpwi r0, 0x07 # SirenaHotel
beq- .L_handleStickCD
cmpwi r0, 0x0E # Casino
beq- .L_handleStickCD
li rC, 0
.L_handleStickCD:
sth rC, 0xe4(rArr)
blr
# disable TMarioGamePad::onNeutralMarioKey when LevelSelect is activated
.TMarioGamePad.onNeutralMarioKey:
lis r12, $LevelSelect.en@ha
lbz r0, $LevelSelect.en@l(r12)
mr. r0, r0
bnelr # return if LevelSelect is activated
li r0, 60
b 4+$b$.TMarioGamePad.onNeutralMarioKey