Refactor Lanmola sprite functions for improved readability and maintainability

This commit is contained in:
scawful
2025-03-20 18:41:48 -04:00
parent 56c098a884
commit 706dcc0710
2 changed files with 477 additions and 565 deletions

View File

@@ -23,487 +23,326 @@ org $1DF614 : Sprite_ConvertVelocityToAngle:
org $05A377 ; replace vanilla sprite_lanmola.asm org $05A377 ; replace vanilla sprite_lanmola.asm
Lanmola_FinishInitialization: Lanmola_FinishInitialization:
{ {
PHB : PHK : PLB PHB : PHK : PLB
LDA.l .starting_delay, X : STA.w SprTimerA, X
LDA.b #$FF : STA.w SprHeight, X
LDA.l .starting_delay, X : STA.w SprTimerA, X PHX
LDY.b #$3F
LDA $7EEA00, X : TAX ;.sprite_regions
LDA.b #$FF
LDA.b #$FF : STA.w SprHeight, X .reset_extended_sprites
STA $7FFE00, X
INX
DEY : BPL .reset_extended_sprites
PLX
LDA.b #$07 : STA $7FF81E, X
JSL Sprite_Lanmola_Init_DataLONG
PLB
RTL
PHX .starting_delay
LDY.b #$3F
LDA $7EEA00, X : TAX ;.sprite_regions
LDA.b #$FF
.reset_extended_sprites
STA $7FFE00, X
INX
DEY : BPL .reset_extended_sprites
PLX
LDA.b #$07 : STA $7FF81E, X
JSL Sprite_Lanmola_Init_DataLONG
PLB
RTL
.starting_delay
db $80, $CF, $FF, $60 db $80, $CF, $FF, $60
} }
Sprite_Lanmola: Sprite_Lanmola:
{ {
;JSR Sprite2_CheckIfActivePermissive ;JSR Sprite2_CheckIfActivePermissive
LDA $0D80, X LDA $0D80, X
JSL JumpTableLocal
JSL JumpTableLocal dw Lanmola_Wait ;0x00
dw Lanmola_Mound ;0x01
dw Lanmola_Wait ;0x00 dw Lanmola_Fly ;0x02
dw Lanmola_Mound ;0x01 dw Lanmola_Dive ;0x03
dw Lanmola_Fly ;0x02 dw Lanmola_Reset ;0x04
dw Lanmola_Dive ;0x03 dw Lanmola_Death ;0x05
dw Lanmola_Reset ;0x04
dw Lanmola_Death ;0x05
} }
Lanmola_Wait: ;0x00 Lanmola_Wait: ;0x00
{ {
JSR Lanmola_Draw JSR Lanmola_Draw
LDA.w SprTimerA, X : BNE .delay ; ORA $0F00, X :
LDA.b #$7F : STA.w SprTimerA, X
INC $0D80, X
LDA.w SprTimerA, X : BNE .delay ; ORA $0F00, X : ; Play rumbling sound
LDA.b #$7F : STA.w SprTimerA, X LDA.b #$35 : JSL Sound_SetSfx2PanLong
.delay
INC $0D80, X RTS
;Play rumbling sound
LDA.b #$35 : JSL Sound_SetSfx2PanLong
.delay
RTS
} }
Lanmola_Mound: ;0x01 Lanmola_Mound: ;0x01
{ {
JSL Lanmola_MoveSegment JSL Lanmola_MoveSegment
JSR Lanmola_DrawMound JSR Lanmola_DrawMound
JSL CheckIfActive : BCS Lanmola_Wait_delay JSL CheckIfActive : BCS Lanmola_Wait_delay
LDA.w SprTimerA, X : BNE .return LDA.w SprTimerA, X : BNE .return
JSL Lanmola_SpawnShrapnel JSL Lanmola_SpawnShrapnel
LDA.b #$13 : STA $012D LDA.b #$13 : STA $012D
TXY TXY
JSL GetRandomInt : AND.b #$07 : TAX JSL GetRandomInt : AND.b #$07 : TAX
LDA $7EEAA8, X : STA.w SprMiscA, Y ; Get random X pos to have the lanmola fly to. ;.randXPos LDA $7EEAA8, X : STA.w SprMiscA, Y ; Get random X pos to have the lanmola fly to. ;.randXPos
JSL GetRandomInt : AND.b #$07 : TAX JSL GetRandomInt : AND.b #$07 : TAX
LDA $7EEAB0, X : STA.w SprMiscB, Y ; Get random Y pos to have the lanmola fly to. ;.randYPos LDA $7EEAB0, X : STA.w SprMiscB, Y ; Get random Y pos to have the lanmola fly to. ;.randYPos
TYX TYX
INC $0D80, X INC $0D80, X
LDA.b #$18 : STA $0F80, X LDA.b #$18 : STA $0F80, X
STZ.w SprMiscF, X STZ.w SprMiscF, X
STZ.w SprMiscG, X STZ.w SprMiscG, X
; ALTERNATE ENTRY POINT ; ALTERNATE ENTRY POINT
.Lanmola_SetScatterSandPosition .Lanmola_SetScatterSandPosition
LDA.w SprXH, X : STA $0DC0, X LDA.w SprXH, X : STA $0DC0, X
LDA.w SprYH, X : STA.w SprMiscE, X LDA.w SprYH, X : STA.w SprMiscE, X
LDA.w SprX, X : STA.w SprMiscC, X LDA.w SprX, X : STA.w SprMiscC, X
LDA.w SprY, X : STA $0E70, X LDA.w SprY, X : STA $0E70, X
LDA.b #$4A : STA.w SprTimerB, X LDA.b #$4A : STA.w SprTimerB, X
.return .return
RTS RTS
} }
Lanmola_Fly: ;0x02 Lanmola_Fly: ;0x02
{ {
JSR Lanmola_Draw JSR Lanmola_Draw
JSL Lanmola_DrawDirtLONG JSL Lanmola_DrawDirtLONG
JSL CheckIfActive : BCS Lanmola_Mound_return JSL CheckIfActive : BCS Lanmola_Mound_return
JSR Sprite2_CheckDamage JSR Sprite2_CheckDamage
JSR Sprite2_MoveAltitude JSR Sprite2_MoveAltitude
; Slowly decrease the Y speed when first coming out of the ground ; Slowly decrease the Y speed when first coming out of the ground
LDA.w SprMiscF, X : BNE .notRising LDA.w SprMiscF, X : BNE .notRising
LDA $0F80, X : SEC : SBC.b #$01 : STA $0F80, X : BNE .beta LDA $0F80, X : SEC : SBC.b #$01 : STA $0F80, X : BNE .beta
INC.w SprMiscF, X INC.w SprMiscF, X
.beta .beta
BRA .dontSwitchDirections BRA .dontSwitchDirections
.notRising .notRising
; Use the Y speed to bob up and down ; Use the Y speed to bob up and down
LDA $1A : AND.b #$01 : BNE .dontSwitchDirections ; Every other frame. LDA $1A : AND.b #$01 : BNE .dontSwitchDirections ; Every other frame.
TXY TXY
LDA.w SprMiscG, X : AND.b #$01 : TAX LDA.w SprMiscG, X : AND.b #$01 : TAX
LDA $0F80, Y : CLC : ADC $7EEA9C, X : STA $0F80, Y : CMP $7EEA9E, X : BNE .dontSwitchDirections2 ;.y_speed_slope ;.y_speeds LDA $0F80, Y : CLC : ADC $7EEA9C, X : STA $0F80, Y : CMP $7EEA9E, X : BNE .dontSwitchDirections2 ;.y_speed_slope ;.y_speeds
TYX : INC.w SprMiscG, X ; Switch direction TYX : INC.w SprMiscG, X ; Switch direction
.dontSwitchDirections2 .dontSwitchDirections2
TYX TYX
.dontSwitchDirections .dontSwitchDirections
LDA.w SprMiscA, X : STA $04 LDA.w SprMiscA, X : STA $04
LDA.w SprXH, X : STA $05 LDA.w SprXH, X : STA $05
LDA.w SprMiscB, X : STA $06 LDA.w SprMiscB, X : STA $06
LDA.w SprYH, X : STA $07 LDA.w SprYH, X : STA $07
LDA.w SprX, X : STA $00 LDA.w SprX, X : STA $00
LDA.w SprXH, X : STA $01 LDA.w SprXH, X : STA $01
LDA.w SprY, X : STA $02 LDA.w SprY, X : STA $02
LDA.w SprYH, X : STA $03 LDA.w SprYH, X : STA $03
REP #$20 REP #$20
; If our position is 0x0002 away from the random X and Y pos we chose earlier go to the next stage. ; If our position is 0x0002 away from the random X and Y pos we chose earlier go to the next stage.
LDA $00 : SEC : SBC $04 : CLC : ADC.w #$0002 : CMP.w #$0004 : BCS .notCloseEnough LDA $00 : SEC : SBC $04 : CLC : ADC.w #$0002 : CMP.w #$0004 : BCS .notCloseEnough
LDA $02 : SEC : SBC $06 : CLC : ADC.w #$0002 : CMP.w #$0004 : SEP #$20 : BCS .notCloseEnough LDA $02 : SEC : SBC $06 : CLC : ADC.w #$0002 : CMP.w #$0004 : SEP #$20 : BCS .notCloseEnough
INC $0D80, X INC $0D80, X
.notCloseEnough .notCloseEnough
SEP #$20 SEP #$20
LDA.b #$0A LDA.b #$0A
JSL Sprite_ProjectSpeedTowardsEntityLong JSL Sprite_ProjectSpeedTowardsEntityLong
LDA $00 : STA.w SprYSpeed, X LDA $00 : STA.w SprYSpeed, X
LDA $01 : STA.w SprXSpeed, X LDA $01 : STA.w SprXSpeed, X
JSR Sprite2_Move JSR Sprite2_Move
.return .return
RTS RTS
} }
Lanmola_Dive: ;0x03 Lanmola_Dive: ;0x03
{ {
JSR Lanmola_Draw JSR Lanmola_Draw
JSL Lanmola_DrawDirtLONG JSL Lanmola_DrawDirtLONG
JSL CheckIfActive : BCS Lanmola_Fly_return JSL CheckIfActive : BCS Lanmola_Fly_return
JSR Sprite2_CheckDamage JSR Sprite2_CheckDamage
JSR Sprite2_Move JSR Sprite2_Move
JSR Sprite2_MoveAltitude JSR Sprite2_MoveAltitude
LDA $0F80, X : CMP.b #$EC : BMI .alpha LDA $0F80, X : CMP.b #$EC : BMI .alpha
SEC : SBC.b #$01 : STA $0F80, X SEC : SBC.b #$01 : STA $0F80, X
.alpha
.alpha ; If we are under the ground go to the reset stage
LDA.w SprHeight, X : BPL .notUnderGroundYet
INC $0D80, X
; If we are under the ground go to the reset stage LDA.b #$80 : STA.w SprTimerA, X
LDA.w SprHeight, X : BPL .notUnderGroundYet
INC $0D80, X
LDA.b #$80 : STA.w SprTimerA, X JSR Lanmola_Mound_Lanmola_SetScatterSandPosition
JSR Lanmola_Mound_Lanmola_SetScatterSandPosition .notUnderGroundYet
RTS
.notUnderGroundYet
RTS
} }
Lanmola_Reset: ;0x04 Lanmola_Reset: ;0x04
{ {
JSR Lanmola_Draw JSR Lanmola_Draw
JSL Lanmola_DrawDirtLONG JSL Lanmola_DrawDirtLONG
JSL CheckIfActive : BCS Lanmola_Dive_notUnderGroundYet JSL CheckIfActive : BCS Lanmola_Dive_notUnderGroundYet
LDA.w SprTimerA, X : BNE .wait LDA.w SprTimerA, X : BNE .wait
STZ $0D80, X ; Go back to wait phase STZ $0D80, X ; Go back to wait phase
TXY TXY
JSL GetRandomInt : AND.b #$07 : TAX JSL GetRandomInt : AND.b #$07 : TAX
LDA $7EEAA8, X : STA.w SprX, Y ; Get random X pos to have the lanmola fly to. ;.randXPos LDA $7EEAA8, X : STA.w SprX, Y ; Get random X pos to have the lanmola fly to. ;.randXPos
JSL GetRandomInt : AND.b #$07 : TAX JSL GetRandomInt : AND.b #$07 : TAX
LDA $7EEAB0, X : STA.w SprY, Y ; Get random Y pos to have the lanmola fly to. ;.randYPos LDA $7EEAB0, X : STA.w SprY, Y ; Get random Y pos to have the lanmola fly to. ;.randYPos
TYX TYX
.wait .wait
RTS RTS
} }
Lanmola_Death: ;0x05 Lanmola_Death: ;0x05
{ {
JSR Lanmola_Draw JSR Lanmola_Draw
LDA.w SprTimerA, X : BNE .timerNotDone
STZ.w SprState, X
LDA.w SprTimerA, X : BNE .timerNotDone ; Y is the index where we write in RAM
STZ.w SprState, X PHX ; keep X
TYX ; Since we'll need X for long we move Y in X
LDA $7EEAB8, X : ORA $00 : STA $7EEAB8, X
PLX ; pull back x because sprite will crash otherwise even if it's dying...
; Y is the index where we write in RAM ; There can only be 4 so we only need to check for 4
PHX ; keep X PHX : LDX.b #$03
TYX ; Since we'll need X for long we move Y in X
LDA $7EEAB8, X : ORA $00 : STA $7EEAB8, X
PLX ; pull back x because sprite will crash otherwise even if it's dying...
; There can only be 4 so we only need to check for 4 .next_sprite
PHX : LDX.b #$03 LDA $0E20, X : CMP.b #$54 : BNE .notLanmola
LDA.w SprState, X : BNE .oneIsntDead
.next_sprite .notLanmola
LDA $0E20, X : CMP.b #$54 : BNE .notLanmola
LDA.w SprState, X : BNE .oneIsntDead
.notLanmola DEX : BPL .next_sprite
TYX : LDA.b #$0F : STA $7EEAB8, X
LDA.b #$1A : STA $012F
.oneIsntDead
PLX
DEX : BPL .next_sprite .timerNotDone
TYX : LDA.b #$0F : STA $7EEAB8, X
LDA.b #$1A : STA $012F
.oneIsntDead LDA.w SprTimerA, X : CMP.b #$20 : BCC Lanmola_Reset_wait
PLX CMP.b #$A0 : BCS Lanmola_Reset_wait
AND.b #$0F : BNE Lanmola_Reset_wait
TXY
LDA $7FF81E, X : TAX
.timerNotDone LDA $0E80, Y : SEC : SBC $7EEAA0, X ;.dataDeath
LDA.w SprTimerA, X : CMP.b #$20 : BCC Lanmola_Reset_wait PHY : TXY : PLX
CMP.b #$A0 : BCS Lanmola_Reset_wait AND.b #$3F : CLC : ADC $7EEA00, X : PHX : TAX ;.sprite_regions
AND.b #$0F : BNE Lanmola_Reset_wait
TXY
LDA $7FF81E, X : TAX
LDA $0E80, Y : SEC : SBC $7EEAA0, X ;.dataDeath LDA $7FFC00, X : STA $0A
LDA $7EE800, X : STA $0B
PHY : TXY : PLX LDA $7FFD00, X : SEC : SBC $7FFE00, X : STA $0C
AND.b #$3F : CLC : ADC $7EEA00, X : PHX : TAX ;.sprite_regions LDA $7EE900, X : STA $0D
LDA $7FFC00, X : STA $0A REP #$20
LDA $7EE800, X : STA $0B LDA $0A : SEC : SBC $E2 : STA $0A
LDA $0C : SEC : SBC $E8 : STA $0C
SEP #$20
LDA $7FFD00, X : SEC : SBC $7FFE00, X : STA $0C PLX
LDA $7EE900, X : STA $0D
REP #$20 ; Spawn a sprite that instantly dies as a boss explosion.
LDA $0A : SEC : SBC $E2 : STA $0A LDA.b #$00 : JSL Sprite_SpawnDynamically : BMI .spawn_failed
LDA $0C : SEC : SBC $E8 : STA $0C LDA.b #$0B : STA $0AAA
SEP #$20
PLX LDA.b #$04 : STA.w SprState, Y
; Spawn a sprite that instantly dies as a boss explosion. LDA.b #$1F : STA.w SprTimerA, Y : STA $0D90, Y
LDA.b #$00 : JSL Sprite_SpawnDynamically : BMI .spawn_failed
LDA.b #$0B : STA $0AAA
LDA.b #$04 : STA.w SprState, Y LDA $0A : STA.w SprX, Y
LDA $0B : STA.w SprXH, Y
LDA $0C : STA.w SprY, Y
LDA $0D : STA.w SprYH, Y
LDA.b #$1F : STA.w SprTimerA, Y : STA $0D90, Y LDA.b #$03 : STA.w SprNbrOAM, Y
LDA $0A : STA.w SprX, Y LDA.b #$0C : STA.w SprProps, Y
LDA $0B : STA.w SprXH, Y
LDA $0C : STA.w SprY, Y
LDA $0D : STA.w SprYH, Y
LDA.b #$03 : STA.w SprNbrOAM, Y LDA.b #$0C : JSL Sound_SetSfx2PanLong
LDA.b #$0C : STA.w SprProps, Y LDA $7FF81E, X : BMI .beta
DEC A : STA $7FF81E, X
LDA.b #$0C : JSL Sound_SetSfx2PanLong .beta
.spawn_failed
LDA $7FF81E, X : BMI .beta .return
DEC A : STA $7FF81E, X RTS
.beta
.spawn_failed
.return
RTS
} }
Lanmola_Draw: Lanmola_Draw:
{ {
JSL Lanmola_MoveSegment JSL Lanmola_MoveSegment
LDA $0B89, X : STA $03
LDA $7FF81E, X : BPL .beta
RTS
.beta
LDA $0B89, X : STA $03 PHX
STA $0F
LDA.w SprYSpeed, X : ASL A : ROL A : AND.b #$01 : TAX
LDA $7EEA06, X : STA $0C ;.data2
LDA $7EEA04, X : TAY ;.data1
LDX $0F
LDA $7FF81E, X : BPL .beta .loopBody
RTS PHX : STX $0D
LDA $02 : CLC : ADC $04 : TAX
LDA $02 : SEC : SBC.b #$08 : AND.b #$3F : STA $02
.beta LDA $7FFC00, X : STA $0A
LDA $7EE800, X : STA $0B
LDA $7FFD00, X : STA $08
LDA $7EE900, X : STA $09
LDA $7FFE00, X : STA $05
PHX PHX
STA $0F TYA : CLC : ADC.b #$20 : TAX
LDA.w SprYSpeed, X : ASL A : ROL A : AND.b #$01 : TAX
LDA $7EEA06, X : STA $0C ;.data2
LDA $7EEA04, X : TAY ;.data1
LDX $0F
.loopBody
PHX : STX $0D
LDA $02 : CLC : ADC $04 : TAX
LDA $02 : SEC : SBC.b #$08 : AND.b #$3F : STA $02
LDA $7FFC00, X : STA $0A
LDA $7EE800, X : STA $0B
LDA $7FFD00, X : STA $08
LDA $7EE900, X : STA $09
LDA $7FFE00, X : STA $05
PHX
TYA : CLC : ADC.b #$20 : TAX
REP #$20
LDA $0A : SEC : SBC $E2 : STA ($90), Y ;Body X byte
STZ $37
BPL .notNegative
INC $37
.notNegative
PHY : TXY : PLX
STA ($90), Y ;Shadow X byte
PHY : TXY : PLX
INY : INX
CLC : ADC.w #$0040 : CMP.w #$0140 : SEP #$20 : BCS .out_of_boundsX
LDA $05 : BMI .out_of_boundsX
STA $06 : STZ $07
REP #$20
LDA $08 : SEC : SBC $06 : SEC : SBC $E8 : STA ($90), Y ;Body Y byte
CLC : ADC.w #$0010 : CMP.w #$0100
BCC .on_screen_y1
SEP #$20
LDA.b #$F0 : STA ($90), Y ;Body offscreen Y Byte
REP #$20
.on_screen_y1
PHY : TXY : PLX
LDA $08 : CLC : ADC.w #$000A : SEC : SBC $E8 : STA ($90), Y ;Shadow Y byte
CLC : ADC.w #$0010 : CMP.w #$0100
SEP #$20
PHY : TXY : PLX
BCC .on_screen_y2
PHY : TXY : PLX
LDA.b #$F0 : STA ($90), Y ;Shadow offscreen Y Byte
PHY : TXY : PLX
.on_screen_y2
BRA .skip
.out_of_boundsX
LDA.b #$F0 : STA ($90), Y ;Body offscreen Y Byte
PHY : TXY : PLX
LDA.b #$F0 : STA ($90), Y ;Shadow offscreen Y Byte
PHY : TXY : PLX
.skip
PLX
PHY
LDA $7FFF00, X : TAX
LDY $0D
LDA $0F : CMP.b #$07 : BNE .dontDrawTail
CPY.b #$00 : BNE .dontDrawTail
LDA $7EEA18, X ;.chrTail
BRA .notHead
.dontDrawTail
LDA.b #$C6
CPY $0F : BNE .notHead
LDA $7EEA08, X ;.chrHead
.notHead
PLY : INY : STA ($90), Y ;Body chr
PHY
TYA : CLC : ADC.b #$20 : TAY
LDA.b #$6C : STA ($90), Y ;Shadow chr
LDA.b #$36 : INY : STA ($90), Y ;Shadow properties
PLY
INY
LDA $7EEA28, X : ORA $03 : STA ($90), Y ;Body properties ;.propertiesBody
TYA : PHY : LSR #2 : TAY
CLC : ADC.b #$08 : TAX
LDA.b #$02 : ORA $37 : STA ($92), Y ;Body size and extra X bit
PHY : TXY : PLX : STA ($92), Y ;Shadow size and extra X bit
PLA : CLC : ADC $0C : TAY
PLX : DEX : BMI .bodyDone
JMP .loopBody
.bodyDone
PLX
RTS
}
Lanmola_DrawMound:
{
LDA.b #$04 : JSL OAM_AllocateFromRegionB
PHX
LDA.w SprTimerA, X : LSR #3 : TAX
LDA $7EEA54, X : TAX ;.frameMound
LDY.b #$00
REP #$20 REP #$20
LDA.w SprCachedY : SEC : SBC $E8 : STA $02 LDA $0A : SEC : SBC $E2 : STA ($90), Y ;Body X byte
LDA.w SprCachedX : SEC : SBC $E2 : STA ($90), Y
STZ $37 STZ $37
BPL .notNegative BPL .notNegative
@@ -511,30 +350,138 @@ Lanmola_DrawMound:
.notNegative .notNegative
INY PHY : TXY : PLX
STA ($90), Y ;Shadow X byte
PHY : TXY : PLX
CLC : ADC.w #$0040 : CMP.w #$0140 : BCS .out_of_boundsx INY : INX
LDA $02 : STA ($90), Y CLC : ADC.w #$0040 : CMP.w #$0140 : SEP #$20 : BCS .out_of_boundsX
LDA $05 : BMI .out_of_boundsX
STA $06 : STZ $07
CLC : ADC.w #$0010 : CMP.w #$0100 REP #$20
BCC .on_screen_y LDA $08 : SEC : SBC $06 : SEC : SBC $E8 : STA ($90), Y ;Body Y byte
.out_of_boundsx CLC : ADC.w #$0010 : CMP.w #$0100
LDA.w #$00F0 : STA ($90), Y
.on_screen_y BCC .on_screen_y1
SEP #$20 SEP #$20
LDA.b #$F0 : STA ($90), Y ;Body offscreen Y Byte
REP #$20
LDA $7EEA48, X : INY : STA ($90), Y ;.chrMound .on_screen_y1
LDA $7EEA4E, X : INY : STA ($90), Y ;.propertiesMound
TYA : LSR #2 : TAY PHY : TXY : PLX
LDA.b #$02 : ORA $37 : STA ($92), Y ;.sizesMound LDA $08 : CLC : ADC.w #$000A : SEC : SBC $E8 : STA ($90), Y ;Shadow Y byte
CLC : ADC.w #$0010 : CMP.w #$0100
SEP #$20
PHY : TXY : PLX
BCC .on_screen_y2
PHY : TXY : PLX
LDA.b #$F0 : STA ($90), Y ;Shadow offscreen Y Byte
PHY : TXY : PLX
.on_screen_y2
BRA .skip
.out_of_boundsX
LDA.b #$F0 : STA ($90), Y ;Body offscreen Y Byte
PHY : TXY : PLX
LDA.b #$F0 : STA ($90), Y ;Shadow offscreen Y Byte
PHY : TXY : PLX
.skip
PLX PLX
RTS PHY
LDA $7FFF00, X : TAX
LDY $0D
LDA $0F : CMP.b #$07 : BNE .dontDrawTail
CPY.b #$00 : BNE .dontDrawTail
LDA $7EEA18, X ;.chrTail
BRA .notHead
.dontDrawTail
LDA.b #$C6
CPY $0F : BNE .notHead
LDA $7EEA08, X ;.chrHead
.notHead
PLY : INY : STA ($90), Y ;Body chr
PHY
TYA : CLC : ADC.b #$20 : TAY
LDA.b #$6C : STA ($90), Y ;Shadow chr
LDA.b #$36 : INY : STA ($90), Y ;Shadow properties
PLY
INY
LDA $7EEA28, X : ORA $03 : STA ($90), Y ;Body properties ;.propertiesBody
TYA : PHY : LSR #2 : TAY
CLC : ADC.b #$08 : TAX
LDA.b #$02 : ORA $37 : STA ($92), Y ;Body size and extra X bit
PHY : TXY : PLX : STA ($92), Y ;Shadow size and extra X bit
PLA : CLC : ADC $0C : TAY
PLX : DEX : BMI .bodyDone
JMP .loopBody
.bodyDone
PLX
RTS
}
Lanmola_DrawMound:
{
LDA.b #$04 : JSL OAM_AllocateFromRegionB
PHX
LDA.w SprTimerA, X : LSR #3 : TAX
LDA $7EEA54, X : TAX ;.frameMound
LDY.b #$00
REP #$20
LDA.w SprCachedY : SEC : SBC $E8 : STA $02
LDA.w SprCachedX : SEC : SBC $E2 : STA ($90), Y
STZ $37
BPL .notNegative
INC $37
.notNegative
INY
CLC : ADC.w #$0040 : CMP.w #$0140 : BCS .out_of_boundsx
LDA $02 : STA ($90), Y
CLC : ADC.w #$0010 : CMP.w #$0100
BCC .on_screen_y
.out_of_boundsx
LDA.w #$00F0 : STA ($90), Y
.on_screen_y
SEP #$20
LDA $7EEA48, X : INY : STA ($90), Y ;.chrMound
LDA $7EEA4E, X : INY : STA ($90), Y ;.propertiesMound
TYA : LSR #2 : TAY
LDA.b #$02 : ORA $37 : STA ($92), Y ;.sizesMound
PLX
RTS
} }
assert pc() <= $05A880 assert pc() <= $05A880
@@ -542,55 +489,43 @@ assert pc() <= $05A880
org $1DCFCB org $1DCFCB
Sprite_Shrapnel: Sprite_Shrapnel:
{ {
; This sprite manifests as a boulder outdoors, and as shrapnel indoors. ; This sprite manifests as a boulder outdoors, and as shrapnel indoors.
LDA $1B : BEQ $5B ;Boulder_Main LDA $1B : BEQ $5B ; Boulder_Main
; Check if we can draw. ; Check if we can draw.
LDA $0FC6 : CMP.b #$03 : BCS .invalid_gfx_loaded LDA $0FC6 : CMP.b #$03 : BCS .invalid_gfx_loaded
JSL $06DBF8 ;Sprite_PrepAndDrawSingleSmallLong JSL $06DBF8 ; Sprite_PrepAndDrawSingleSmallLong
.invalid_gfx_loaded
.invalid_gfx_loaded
;JSR $E8A2 ;Sprite4_CheckIfActive
JSL CheckIfActive : BCC .active
RTS
.active
LDA $1A : ASL #2 : AND.b #$C0 : STA.w SprProps, X ; : ORA.b #$00
JSR $E948 ;Sprite4_MoveXyz
TXA : EOR $1A : AND.b #$03 : BNE .noTileCollision
REP #$20
LDA.w SprCachedX : SEC : SBC $22 : CLC : ADC.w #$0004
CMP.w #$0010 : BCS .player_not_close
LDA.w SprCachedY : SEC : SBC $20 : CLC : ADC.w #$FFFC
CMP.w #$000C : BCS .player_not_close
SEP #$20
JSL $06F41F ;Sprite_AttemptDamageToPlayerPlusRecoilLong
.player_not_close
SEP #$20
;JSR $8094 : BEQ .noTileCollision ;Sprite4_CheckTileCollision
;STZ.w SprState, X
.noTileCollision
LDA.w SprTimerA, X : BNE .timerNotDone
STZ.w SprState, X
.timerNotDone
;JSR $E8A2 Sprite4_CheckIfActive
JSL CheckIfActive : BCC .active
RTS RTS
.active
LDA $1A : ASL #2 : AND.b #$C0 : STA.w SprProps, X ; : ORA.b #$00
JSR $E948 ; Sprite4_MoveXyz
TXA : EOR $1A : AND.b #$03 : BNE .noTileCollision
REP #$20
LDA.w SprCachedX
SEC : SBC $22
CLC : ADC.w #$0004
CMP.w #$0010 : BCS .player_not_close
LDA.w SprCachedY
SEC : SBC $20
CLC : ADC.w #$FFFC
CMP.w #$000C : BCS .player_not_close
SEP #$20
JSL $06F41F ; Sprite_AttemptDamageToPlayerPlusRecoilLong
.player_not_close
SEP #$20
;JSR $8094 : BEQ .noTileCollision ;Sprite4_CheckTileCollision
;STZ.w SprState, X
.noTileCollision
LDA.w SprTimerA, X : BNE .timerNotDone
STZ.w SprState, X
.timerNotDone
RTS
} }
assert pc() <= $1DD02A assert pc() <= $1DD02A

View File

@@ -12,132 +12,114 @@ pullpc
Ancilla_SpawnFallingPrize: Ancilla_SpawnFallingPrize:
PHX PHX
TAX TAX
LDY.b #$04 LDY.b #$04
LDA.b #$29 ; ANCILLA 29 LDA.b #$29 ; ANCILLA 29
JSL AncillaAdd_FallingPrize JSL AncillaAdd_FallingPrize
PLX PLX
RTL RTL
; =========================================================
Lanmola_DrawDirtLONG: Lanmola_DrawDirtLONG:
{ {
PHB : PHK : PLB PHB : PHK : PLB
JSR Lanmola_DrawDirt
JSR Lanmola_DrawDirt PLB
RTL
PLB
RTL
} }
; =========================================================
Lanmola_DrawDirt: Lanmola_DrawDirt:
{ {
LDA.w SprTimerB, X : BNE .timerNotDone LDA.w SprTimerB, X : BNE .timerNotDone
RTS RTS
.timerNotDone
.timerNotDone ; Determine weather the dirt should draw in front of or behind the body
; based on its y velocity.
LDA.w SprYSpeed, X : ASL A : ROL A : ASL A : EOR $0D80, X : AND.b #$02 : BEQ .nu
LDA.b #$08 : JSL OAM_AllocateFromRegionB
BRA .xi
; Determine weather the dirt should draw in front of or behind the body .nu
; based on its y velocity. LDA.b #$08 : JSL OAM_AllocateFromRegionC
LDA.w SprYSpeed, X : ASL A : ROL A : ASL A : EOR $0D80, X : AND.b #$02 : BEQ .nu
LDA.b #$08 : JSL OAM_AllocateFromRegionB
BRA .xi
.nu .xi
LDA.b #$08 : JSL OAM_AllocateFromRegionC
.xi LDY.b #$00
LDY.b #$00 LDA.w SprTimerB, X : LSR #2 : AND.b #$03 : EOR.b #$03 : ASL A : STA $06
LDA $0DC0, X : XBA
LDA.w SprMiscC, X
REP #$20 : SEC : SBC $E2 : STA $00 : SEP #$20
STZ $37
BPL .notNegative3
INC $37
LDA.w SprTimerB, X : LSR #2 : AND.b #$03 : EOR.b #$03 : ASL A : STA $06 .notNegative3
LDA $0DC0, X : XBA LDA.w SprMiscE, X : XBA
LDA.w SprMiscC, X LDA $0E70, X
REP #$20 : SEC : SBC $E2 : STA $00 : SEP #$20 REP #$20 : SEC : SBC $E8 : STA $02 : SEP #$20
PHX
STZ $37 LDX.b #$01
BPL .notNegative3
INC $37
.notNegative3
LDA.w SprMiscE, X : XBA
LDA $0E70, X
REP #$20 : SEC : SBC $E8 : STA $02 : SEP #$20
.dirtLoop
PHX PHX
LDX.b #$01 TXA : CLC : ADC $06 : ASL : TAX
.dirtLoop REP #$20
PHX LDA $00 : CLC : ADC $7EEA64, X : STA ($90), Y ;dirt x ;.xDirt
TXA : CLC : ADC $06 : ASL : TAX STZ $36
BPL .notNegative4
INC $36
REP #$20 .notNegative4
LDA $00 : CLC : ADC $7EEA64, X : STA ($90), Y ;dirt x ;.xDirt
STZ $36 INY
BPL .notNegative4
INC $36
.notNegative4 CLC : ADC.w #$0040 : CMP.w #$0140 : BCS .out_of_bounds3
INY LDA $02 : CLC : ADC $7EEA74, X : STA ($90), Y ;dirt y ;.yDirt
CLC : ADC.w #$0040 : CMP.w #$0140 : BCS .out_of_bounds3 REP #$20
CLC : ADC.w #$0010 : CMP.w #$0100
SEP #$20
LDA $02 : CLC : ADC $7EEA74, X : STA ($90), Y ;dirt y ;.yDirt BCC .on_screen_y
.out_of_bounds3
SEP #$20
LDA.b #$F0 : STA ($90), Y
REP #$20 .on_screen_y
CLC : ADC.w #$0010 : CMP.w #$0100
SEP #$20
BCC .on_screen_y TXA : LSR : TAX
.out_of_bounds3
SEP #$20
LDA.b #$F0 : STA ($90), Y
.on_screen_y LDA $7EEA84, X : INY : STA ($90), Y ;dirt chr ;.chrDirt
LDA $7EEA8C, X : INY : STA ($90), Y ;dirt properties ;.propertiesDirt
TXA : LSR : TAX PHY
LDA $7EEA84, X : INY : STA ($90), Y ;dirt chr ;.chrDirt TYA : LSR #2 : TAY
LDA $7EEA8C, X : INY : STA ($90), Y ;dirt properties ;.propertiesDirt
PHY LDA $7EEA94, X : ORA $37 : ORA $36 : STA ($92), Y ;.sizesDirt
TYA : LSR #2 : TAY PLY : INY
LDA $7EEA94, X : ORA $37 : ORA $36 : STA ($92), Y ;.sizesDirt PLX : DEX : BPL .dirtLoop
PLY : INY PLX
PLX : DEX : BPL .dirtLoop RTS
PLX
RTS
} }
; ========================================================= ; =========================================================
Sprite_Lanmola_Init_DataLONG: Sprite_Lanmola_Init_DataLONG:
{ {
PHB : PHK : PLB PHB : PHK : PLB
JSR Sprite_Lanmola_Init_Data
JSR Sprite_Lanmola_Init_Data PLB
RTL
PLB
RTL
} }
; ========================================================= ; =========================================================
@@ -148,7 +130,7 @@ Sprite_Lanmola_Init_Data:
LDX.b #$00 LDX.b #$00
.loop .loop
LDA .sprite_regions, X : STA $7EEA00, X LDA .sprite_regions, X : STA $7EEA00, X
INX : CPX.b #$B8 : BCC .loop INX : CPX.b #$B8 : BCC .loop
@@ -271,88 +253,83 @@ Sprite_Lanmola_Init_Data:
Lanmola_MoveSegment: Lanmola_MoveSegment:
{ {
PHX PHX
TXA : ASL A : TAX TXA : ASL A : TAX
REP #$20 REP #$20
LDA $7EEA38, X : STA $90 ;.oamCoord90 LDA $7EEA38, X : STA $90 ;.oamCoord90
LDA $7EEA40, X : STA $92 ;.oamCoord92 LDA $7EEA40, X : STA $92 ;.oamCoord92
SEP #$20 SEP #$20
PLX PLX
LDA.w SprYSpeed, X : SEC : SBC $0F80, X : STA $00 LDA.w SprYSpeed, X : SEC : SBC $0F80, X : STA $00
LDA.w SprXSpeed, X : STA $01 LDA.w SprXSpeed, X : STA $01
JSL Sprite_ConvertVelocityToAngle : STA $0F JSL Sprite_ConvertVelocityToAngle : STA $0F
LDA $7EEA00, X : STA $04 ;.sprite_regions LDA $7EEA00, X : STA $04 ;.sprite_regions
PHX PHX
; Store the current position, angle, and hieght of the sprite ; Store the current position, angle, and hieght of the sprite
; so that we can set the other segments to them later. ; so that we can set the other segments to them later.
LDA.w SprXH, X : PHA ;high x LDA.w SprXH, X : PHA ;high x
LDA.w SprYH, X : PHA ;high y LDA.w SprYH, X : PHA ;high y
LDA.w SprX, X : PHA ;lower x LDA.w SprX, X : PHA ;lower x
LDA.w SprY, X : PHA ;lower y LDA.w SprY, X : PHA ;lower y
LDA.w SprHeight, X : PHA ;height LDA.w SprHeight, X : PHA ;height
LDA $0F : PHA ;angle LDA $0F : PHA ;angle
LDA $0E80, X : STA $02 : STA $05 LDA $0E80, X : STA $02 : STA $05
CLC : ADC $04 : TAX CLC : ADC $04 : TAX
PLA : STA $7FFF00, X ;angle PLA : STA $7FFF00, X ;angle
PLA : STA $7FFE00, X ;height PLA : STA $7FFE00, X ;height
PLA : STA $7FFD00, X ;lower y PLA : STA $7FFD00, X ;lower y
PLA : STA $7FFC00, X ;lower x PLA : STA $7FFC00, X ;lower x
PLA : STA $7EE900, X ;high y PLA : STA $7EE900, X ;high y
PLA : STA $7EE800, X ;high x PLA : STA $7EE800, X ;high x
PLX PLX
LDA.w SprState, X : CMP.b #$09 : BNE .notActive LDA.w SprState, X : CMP.b #$09 : BNE .notActive
LDA $11 : ORA.w SprFreeze : BNE .notActive LDA $11 : ORA.w SprFreeze : BNE .notActive
LDA $10 : CMP #$0E : BEQ .notActive LDA $10 : CMP #$0E : BEQ .notActive
LDA $5D : CMP #$08 : BEQ .notActive ;in medallion cut scene LDA $5D : CMP #$08 : BEQ .notActive ;in medallion cut scene
CMP #$09 : BEQ .notActive ;in medallion cut scene CMP #$09 : BEQ .notActive ;in medallion cut scene
CMP #$0A : BEQ .notActive ;in medallion cut scene CMP #$0A : BEQ .notActive ;in medallion cut scene
LDA $05 : INC A : AND.b #$3F : STA $0E80, X LDA $05 : INC A : AND.b #$3F : STA $0E80, X
.notActive
.notActive RTL
RTL
} }
; ========================================================= ; =========================================================
SetShrapnelTimer: SetShrapnelTimer:
{ {
LDA.b #$40 : STA.w SprTimerA, Y LDA.b #$40 : STA.w SprTimerA, Y
JSL GetRandomInt ; replaced code
JSL GetRandomInt ; replaced code RTL
RTL
} }
; ========================================================= ; =========================================================
CheckIfActive: CheckIfActive:
{ {
SEC SEC
;Check if sprite is active (pause menu, etc...) ;Check if sprite is active (pause menu, etc...)
LDA $10 : CMP #$0E : BEQ .inMenu LDA $10 : CMP #$0E : BEQ .inMenu
LDA $5D : CMP #$08 : BEQ .inMenu ;in medallion cut scene LDA $5D : CMP #$08 : BEQ .inMenu ;in medallion cut scene
CMP #$09 : BEQ .inMenu ;in medallion cut scene CMP #$09 : BEQ .inMenu ;in medallion cut scene
CMP #$0A : BEQ .inMenu ;in medallion cut scene CMP #$0A : BEQ .inMenu ;in medallion cut scene
CLC CLC
.inMenu .inMenu
RTL RTL
} }
; =========================================================