From cd601e32d020de30a6421d6a94f274abf26069c5 Mon Sep 17 00:00:00 2001 From: scawful Date: Fri, 17 Nov 2023 20:27:06 -0500 Subject: [PATCH] Sprite housekeeping --- Sprites/all_sprites.asm | 5 +- Sprites/bug_net_kid.asm | 6 +- Sprites/dark_link.asm | 1705 +++++++++++++++++++++++++++++++++++++ Sprites/impa.asm | 3 +- Sprites/minecart.asm | 183 ++-- Sprites/poltergeist.asm | 2 +- Sprites/portal_sprite.asm | 3 +- Sprites/twinrova.asm | 1 - 8 files changed, 1807 insertions(+), 101 deletions(-) create mode 100644 Sprites/dark_link.asm diff --git a/Sprites/all_sprites.asm b/Sprites/all_sprites.asm index 66e5060..f5b5a8c 100644 --- a/Sprites/all_sprites.asm +++ b/Sprites/all_sprites.asm @@ -56,14 +56,17 @@ incsrc "Sprites/minecart.asm" print "End of minecart.asm ", pc incsrc "Sprites/twinrova.asm" +print "End of twinrova.asm ", pc incsrc "Sprites/portal_sprite.asm" +print "End of portal_sprite.asm ", pc incsrc "Sprites/impa.asm" print "End of impa.asm ", pc +incsrc "Sprites/poltergeist.asm" +print "End of poltergeist.asm ", pc incsrc "Sprites/bug_net_kid.asm" - warnpc $2B8000 \ No newline at end of file diff --git a/Sprites/bug_net_kid.asm b/Sprites/bug_net_kid.asm index 764192e..f368659 100644 --- a/Sprites/bug_net_kid.asm +++ b/Sprites/bug_net_kid.asm @@ -1,3 +1,5 @@ +pushpc + org $07F4D0 Sprite_CheckIfPlayerPreoccupied: @@ -53,4 +55,6 @@ BugNetKid_GrantBugNet: STZ $02E4 RTS -} \ No newline at end of file +} + +pullpc \ No newline at end of file diff --git a/Sprites/dark_link.asm b/Sprites/dark_link.asm new file mode 100644 index 0000000..7ac9956 --- /dev/null +++ b/Sprites/dark_link.asm @@ -0,0 +1,1705 @@ +;============================================================================== +; Sprite Properties +;============================================================================== +!SPRID = $88 ; The sprite ID you are overwriting (HEX) +!NbrTiles = 4 ; Number of tiles used in a frame +!Harmless = 00 ; 00 = Sprite is Harmful, 01 = Sprite is Harmless +!HVelocity = 00 ; Is your sprite going super fast? put 01 if it is +!Health = 34 ; Number of Health the sprite have +!Damage = 0 ; (08 is a whole heart), 04 is half heart +!DeathAnimation = 00 ; 00 = normal death, 01 = no death animation +!ImperviousAll = 00 ; 00 = Can be attack, 01 = attack will clink on it +!SmallShadow = 00 ; 01 = small shadow, 00 = no shadow +!Shadow = 00 ; 00 = don't draw shadow, 01 = draw a shadow +!Palette = 0 ; Unused in this template (can be 0 to 7) +!Hitbox = 0 ; 00 to 31, can be viewed in sprite draw tool +!Persist = 00 ; 01 = your sprite continue to live offscreen +!Statis = 00 ; 00 = is sprite is alive?, (kill all enemies room) +!CollisionLayer = 00 ; 01 = will check both layer for collision +!CanFall = 00 ; 01 sprite can fall in hole, 01 = can't fall +!DeflectArrow = 00 ; 01 = deflect arrows +!WaterSprite = 00 ; 01 = can only walk shallow water +!Blockable = 00 ; 01 = can be blocked by link's shield? +!Prize = 0 ; 00-15 = the prize pack the sprite will drop from +!Sound = 00 ; 01 = Play different sound when taking damage +!Interaction = 00 ; ?? No documentation +!Statue = 00 ; 01 = Sprite is statue +!DeflectProjectiles = 01 ; 01 = Sprite will deflect ALL projectiles +!ImperviousArrow = 01 ; 01 = Impervious to arrows +!ImpervSwordHammer = 00 ; 01 = Impervious to sword and hammer attacks +!Boss = 00 ; 00 = normal sprite, 01 = sprite is a boss +%Set_Sprite_Properties(Sprite_DarkLink_Prep, Sprite_DarkLink_Long); + +;============================================================================== +; Sprite Long Hook for that sprite +; ----------------------------------------------------------------------------- +; This code can be left unchanged +; handle the draw code and if the sprite is active and should move or not +;============================================================================== +Sprite_DarkLink_Long: +{ + PHB : PHK : PLB + + ; ADD GANON CODE if subtype == 05 + LDA.w SprSubtype, X : CMP #$05 : BNE .NotGanon + JSR Sprite_Ganon_Draw + JSL Sprite_CheckActive ; Check if game is not paused (Prevent timers from running if game is paused) + BCC .SpriteIsNotActive2 ; Skip Main code is sprite is innactive + JSR Sprite_Ganon_Main ; do ganon instead + .SpriteIsNotActive2 + PLB ; Get back the databank we stored previously + RTL ; Go back to original code + + .NotGanon + LDA.w SprAction, X : CMP.b #$01 : BNE .normaldraw + ;JSR Sprite_DarkLink_Draw ; Call the draw code + .sworddraw + JSR Sprite_DarkLink_Draw_Sprite_SwordAttack_Draw + BRA .skipnormaldraw + .normaldraw + CMP.b #$09 : BEQ .sworddraw + LDA.w SprSubtype, X : BNE .skipnormaldraw + JSR Sprite_DarkLink_Draw + .skipnormaldraw + + LDA.w SprAction, X : CMP.b #11 : BCS .notdying + LDA.w SprHealth, X : CMP.b #$10 : BCS .notdying + + LDA.w SprMiscC, X : BNE + + ; check if action is 00 otherwise wait + LDA.w SprAction, X : BNE .notdying + ; enraging instead + %GotoAction(15) + BRA .SpriteIsNotActive + + + + LDA #$30 : STA.w SprTimerA, X + LDA #$08 : STA.w SprTimerB, X + STZ.w SprFrame, X + STZ.w SprMiscF, X + STZ.w SprMiscD, X + %GotoAction(11) + BRA .SpriteIsNotActive + .notdying + + + JSL Sprite_CheckActive ; Check if game is not paused + BCC .SpriteIsNotActive ; Skip Main code is sprite is innactive + + JSR Sprite_DarkLink_Main ; Call the main sprite code + + .SpriteIsNotActive + PLB ; Get back the databank we stored previously + RTL ; Go back to original code + +} + +;============================================================================== +; Sprite initialization +; ----------------------------------------------------------------------------- +; this code only get called once perfect to initialize sprites substate or timers +; this code as soon as the room transitions/ overworld transition occurs +;============================================================================== +Sprite_DarkLink_Prep: +{ + PHB : PHK : PLB + + REP #$20 ; P is still on stack, so we don't even need to fix this + LDX #$20 + -- + LDA dlinkPal, X : STA $7EC600, X + DEX : DEX : BNE -- + INC $15 ;Refresh Palettes + + SEP #$20 + + PLB + + JSL GanonInit + + LDA #$CF : STA.w SprTimerA, X ; wait timer before falling + LDA #$7F : STA.w SprHeight, X + + %GotoAction(4) + LDA #$78 : STA.w SprX, X + LDA #$58 : STA.w SprY, X + + LDA #$00 : STA.w SprMiscE, X + LDA #$00 : STA.w SprMiscC, X ; Enraging + LDA #$50 : STA.w SprHealth, X + + + RTL +} + +dlinkPal: +dw #$7FFF, #$14A5, #$2108, #$294A, #$1CF5, #$7E4E, #$3DEF, #$6FF4 + +;================================================================================================== +; Sprite Main routines code +; -------------------------------------------------------------------------------------------------- +; This is the main local code of your sprite +; This contains all the Subroutines of your sprites you can add more below +;================================================================================================== +Sprite_DarkLink_Main: +{ + LDA.w SprAction, X; Load the SprAction + JSL UseImplicitRegIndexedLocalJumpTable; Goto the SprAction we are currently in + dw Handler + dw SwordSlash + dw JumpBack + dw JumpAttackUp + dw JumpAttackDown + dw JumpAttackPrep + dw JumpAttackShake + dw WalkAction + dw Damaged + dw RecoilSword + dw SwordSubtype + dw DyingSpin + dw DeadDespawn + dw OpenDoor + dw Dead + dw Enraging + + Handler: + { + LDA.w SprSubtype, X : CMP #$01 : BNE + + %SetTimerA(16) + %GotoAction(10) + RTS + + + + LDA.w SprMiscF, X : BNE .nodamage + JSL Sprite_CheckDamageFromPlayer : BCC .nodamage + LDA.w SprTimerA, X : BNE .alreadytakingdamage + LDA.w $02B2 : CMP #$03 : BNE .notmoredamage + LDA.w SprHealth, X : SEC : SBC #$04 : STA.w SprHealth, X + .notmoredamage + .alreadytakingdamage + + + LDA #$20 + JSL Sprite_ApplySpeedTowardsPlayer + LDA.w SprXSpeed, X : EOR #$FF : STA.w SprXSpeed, X + LDA.w SprYSpeed, X : EOR #$FF : STA.w SprYSpeed, X + LDA.b #$10 : STA.w $0F80,X + LDA.b #$20 : STA.w SprTimerA, X + LDA #$26 : STA.w $012E + %GotoAction(8) + RTS + .nodamage + JSL Sprite_CheckDamageToPlayer + + + LDA #$10 + JSL Sprite_ApplySpeedTowardsPlayer + + REP #$20 + + LDA $0FD8 ; Sprite X + SEC : SBC $22 ; - Player X + BPL + + EOR #$FFFF + + + STA $00 ; Distance X (ABS) + + LDA $0FDA ; Sprite Y + SEC : SBC $20 ; - Player Y + BPL + + EOR #$FFFF + + + ; Add it back to X Distance + CLC : ADC $00 : STA $02 ; distance total X, Y (ABS) + + CMP #$0020 : BCS .toofarsword + .dosword + SEP #$20 + LDA.w SprTimerC, X : BNE ++ + ; attempt a slash if we can + + LDA.w SprMiscD, X : BNE + + STZ.w SprFrame, X + BRA .skipdirections + + + LDA.w SprMiscD, X : CMP #$01 : BNE + + LDA.b #06 : STA.w SprFrame, X + BRA .skipdirections + + + LDA.w SprMiscD, X : CMP #$02 : BNE + + LDA.b #12 : STA.w SprFrame, X + BRA .skipdirections + + + LDA.b #18 : STA.w SprFrame, X + + + + .skipdirections + + + JSR SpawnSwordDamage + + %GotoAction(1) + ++ + REP #$20 + .toofarsword + LDA $02 : CMP #$002B : BCS .toofardodge + SEP #$20 + + LDA.w SprMiscF : BNE .toofardodge + + + LDA.w $0354 : CMP #$27 : BEQ .attemptToDodge + CMP #$02 : BEQ .attemptToDodge + CMP #$06 : BEQ .attemptToDodge + CMP #$0F : BNE .toofardodge + + ; only once per slash ! + + .attemptToDodge + + ;check if we are using spin attack + LDA.b $3C : CMP #$90 : BNE .nospin + + ; determine if player is going to dodge it or not + LDA $1A : AND #$01 : BEQ .dodge + + .nospin + LDA.w SprMiscB, X : CMP.w $0354 : BEQ .toofardodge + + + LDA.w SprMiscC, X : BNE .enrageddodge + LDA $1A : AND #$03 : BEQ .toofardodge ; 50/50 chances of dodging + BRA .dodge + .enrageddodge + LDA $1A : AND #$07 : BEQ .toofardodge ; 50/50 chances of dodging + + .dodge + LDA #$16 + JSL Sprite_ApplySpeedTowardsPlayer + LDA.w SprXSpeed, X : EOR #$FF : STA.w SprXSpeed, X + LDA.w SprYSpeed, X : EOR #$FF : STA.w SprYSpeed, X + LDA.b #$1A : STA.w $0F80,X + + %GotoAction(2) + + RTS + + .toofardodge + + SEP #$20 + + + .linknotattacking + LDA.w $0354 : STA.w SprMiscB, X + + STZ $02 ; x direction if non zero = negative + STZ $03 ; y direction + + LDA.w SprXSpeed, X : BPL .positiveX + STA $02 + EOR #$FF + .positiveX + STA $00 ; X speed (abs) + + LDA.w SprYSpeed, X : BPL .positiveY + STA $03 + EOR #$FF + .positiveY + STA $01 ; Y speed (abs) + + + LDA.w SprXSpeed, X : CMP.b #$08 : BCC .zeroXSpeed + BPL .positiveXspeed + LDA #$F0 : STA.w SprXSpeed, X + BRA .doYspeed + .positiveXspeed + LDA #$10 : STA.w SprXSpeed, X + BRA .doYspeed + .zeroXSpeed + STZ.w SprXSpeed, X + .doYspeed + LDA.w SprYSpeed, X : CMP.b #$08 : BCC .zeroYSpeed + + BPL .positiveYspeed + LDA #$F0 : STA.w SprYSpeed, X + BRA .ignorezerospeed + .positiveYspeed + LDA #$10 : STA.w SprYSpeed, X + BRA .ignorezerospeed + .zeroYSpeed + STZ.w SprYSpeed, X + .ignorezerospeed + + LDA.w SprXSpeed, X : BEQ .nodiagonal + LDA.w SprYSpeed, X : BEQ .nodiagonal + BPL .diagoyspeedpositive + LDA #$F5 : STA.w SprYSpeed, X + BRA .dodiagox + .diagoyspeedpositive + LDA #$0B : STA.w SprYSpeed, X + + + .dodiagox + LDA.w SprXSpeed, X + BPL .diagoxspeedpositive + LDA #$F5 : STA.w SprXSpeed, X + BRA .nodiagonal + .diagoxspeedpositive + LDA #$0B : STA.w SprXSpeed, X + + .nodiagonal + + + LDA.w SprTimerD, X : BNE + + TXY ; save X in Y + JSL GetRandomInt : CMP #$3F : BCC .donothing + LDA.w SprMiscF, X : BEQ .notusingcape + JSR Cape + BRA .donothing + .notusingcape + JSL GetRandomInt : AND #$03 : ASL ; use that as jump table + TAX ; set X to do the jump table + JSR (ActionJumpTable, X) + + .donothing + LDA.w SprMiscC, X : BEQ .notenraged + JSL GetRandomInt : AND #$3F : CLC : ADC #$20 + BRA .settimer + .notenraged + JSL GetRandomInt : AND #$3F : CLC : ADC #$50 + .settimer + STA.w SprTimerD, X + ;RTS + + + + + + + .DoWalk + JSL Sprite_MoveLong + + LDA.b $01 : CMP.b $00 : BCC .xwassmaller + ; if X is smaller than y were moving on y axis + LDA $03 : BNE .up + ; down + STZ.w SprMiscD, X + LDA.w SprTimerB, X : BNE + + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #12 : BCC .noframereset1 + .resetframe1 + LDA.b #4 : STA.w SprFrame, X + .noframereset1 + CMP #4 : BCC .resetframe1 + LDA.b #4 : STA.w SprTimerB, X + LDA.w SprTimerA, X : BNE + + + + BRA .end + .up + LDA #$01 : STA.w SprMiscD, X + LDA.w SprTimerB, X : BNE + + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #20 : BCC .noframereset2 + .resetframe2 + LDA.b #12 : STA.w SprFrame, X + .noframereset2 + CMP #12 : BCC .resetframe2 + LDA.b #4 : STA.w SprTimerB, X + + + BRA .end + .xwassmaller + ; were moving on x axis + LDA $02 : BNE .left + ; right + LDA #$02 : STA.w SprMiscD, X + LDA.w SprTimerB, X : BNE + + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #24 : BCC .noframereset3 + .resetframe3 + LDA.b #20 : STA.w SprFrame, X + .noframereset3 + CMP #20 : BCC .resetframe3 + LDA.b #4 : STA.w SprTimerB, X + + + BRA .end + .left + LDA #$03 : STA.w SprMiscD, X + LDA.w SprTimerB, X : BNE + + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #28 : BCC .noframereset4 + .resetframe4 + LDA.b #24 : STA.w SprFrame, X + .noframereset4 + CMP #24 : BCC .resetframe4 + LDA.b #4 : STA.w SprTimerB, X + + + BRA .end + + .end + RTS + + + ActionJumpTable: + dw JumpAttack ;00 + dw Cape ;02 + dw Bomb ;04 + dw BombThrow ;04 + ;dw Walk ;06 + + + + Bomb: + TYX ; get back sprite index + + ;second guess itself because it can spawn too many bombs + LDA $1A : AND #$01 : BNE .spawn_failed ; 50/50 chances + + LDA.b #$4A + LDY.b #$0B + JSL $1DF65F : BMI .spawn_failed + + JSL $09AE64 + + ; ... but once spawned, transmute it to an enemy bomb. + JSL $06AD50 + JSL GetRandomInt : AND #$7F : CLC : ADC #$20 + STA $0E00, Y + .spawn_failed + RTS + + BombThrow: + TYX ; get back sprite index + + ;second guess itself because it can spawn too many bombs + LDA $1A : AND #$01 : BNE .spawn_failed ; 50/50 chances + + LDA.b #$4A + LDY.b #$0B + JSL $1DF65F : BMI .spawn_failed + JSL $09AE64 + ; ... but once spawned, transmute it to an enemy bomb. + JSL $06AD50 + + PHX + TYX + LDA.b #$28 : JSL Sprite_ApplySpeedTowardsPlayer + LDA.b #$01 : STA $0DB0, X + LDA.b #$16 : STA $0F80, X + JSL GetRandomInt : AND #$7F : CLC : ADC #$20 + STA $0E00, X + PLX + + .spawn_failed + RTS + + + Cape: + TYX ; get back sprite index + LDA.w SprMiscF, X : BNE + + LDA $1A : AND #$01 : BNE .nocape ; 50/50 chances + + + JSL $05AB9C + LDA.w SprMiscF, X : EOR #$01 : STA.w SprMiscF, X + .nocape + RTS + + Walk: + TYX ; get back sprite index + %GotoAction(7) + JSL GetRandomInt : AND #$1F : CLC : ADC #$18 + STA.w SprTimerA, X + JSL GetRandomInt + AND #$03 + TAY + LDA speedTableX, Y : STA SprXSpeed, X + LDA speedTableY, Y : STA SprYSpeed, X + + + RTS + + + JumpAttack: + TYX ; get back sprite index + LDA #$20 + JSL Sprite_ApplySpeedTowardsPlayer + LDA.b #$28 : STA.w $0F80,X + LDA.b #$10 : STA.w SprTimerA, X + %GotoAction(5) + JSL GetRandomInt : AND #$3F : CLC : ADC #$50 + STA.w SprTimerD, X + ; that one is popping the RTS to end sprite entirely + ;PLA : PLA + RTS + + + + SpawnSwordDamage: + + LDA #24 : STA.w SprTimerC, X + LDA.w SprMiscC, X : BEQ + + LDA #15 : STA.w SprTimerC, X ;faster if enraged + + + LDA #$06 : STA.w SprTimerB, X + LDA #$03 : STA.w $012E + + + LDA #$88 ; SET THE RIGHT SPRITE ID!! ======================CHANGE======================== + JSL Sprite_SpawnDynamically + JSL Sprite_SetSpawnedCoords + PHX + LDA #$01 : STA.w SprSubtype, Y + LDA.w SprMiscD, X + TYX + TAY + LDA.w SprX, X : CLC : ADC.w DirOffsetX, Y : STA.w SprX, X + LDA.w SprY, X : CLC : ADC.w DirOffsetY, Y : STA.w SprY, X + + + PLX + RTS + + DirOffsetX: + db $00, $00, $0E, $F2 + DirOffsetY: + db $0E, $F2, $00, $00 + } + + SwordSlash: + JSL Sprite_CheckDamageFromPlayer : BCC .nodamage + LDA.w SprTimerA, X : BNE .alreadytakingdamage + LDA.w $02B2 : CMP #$03 : BNE .notmoredamage + LDA.w SprHealth, X : SEC : SBC #$04 : STA.w SprHealth, X + .notmoredamage + .alreadytakingdamage + + LDA #$05 : STA.w $012E ; clinking sound + LDA #$20 + JSL Sprite_ApplySpeedTowardsPlayer + ;restore life removed by the checkdamage + STZ.w $0CE2, X + + + LDA #$20 : STA $29 : STA $C7 + + STZ $24 + STZ $25 + + LDA.w SprYSpeed, X : STA $27 : EOR #$FF : STA.w SprYSpeed, X + LDA.w SprXSpeed, X : STA $28 : EOR #$FF : STA.w SprXSpeed, X + LDA.b #$08 : STA.w $0F80, X + LDA.b #$10 : STA $47 : STA $46 + %SetTimerC(16) + %GotoAction(09) + + RTS + + .nodamage + + ;LDA.w SprTimerD, X : BEQ + + + ;RTS + ;+ + + LDA.w SprMiscD, X : BNE .notdown + LDA.w SprTimerB, X : BNE .notdown + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #6 : BCC .noframereset1 + .resetframe1 + LDA.b #0 : STA.w SprFrame, X + .noframereset1 + LDA.b #4 : STA.w SprTimerB, X + BRA .end + + .notdown + LDA.w SprMiscD, X : CMP #$01 : BNE .notup + LDA.w SprTimerB, X : BNE .notup + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #12 : BCC .noframereset2 + .resetframe2 + LDA.b #6 : STA.w SprFrame, X + .noframereset2 + CMP #6 : BCC .resetframe2 + LDA.b #4 : STA.w SprTimerB, X + BRA .end + .notup + LDA.w SprMiscD, X : CMP #$02 : BNE .notright + + LDA.w SprTimerB, X : BNE .notright + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #18 : BCC .noframereset3 + .resetframe3 + LDA.b #12 : STA.w SprFrame, X + .noframereset3 + CMP #12 : BCC .resetframe3 + LDA.b #4 : STA.w SprTimerB, X + BRA .end + + .notright + LDA.w SprMiscD, X : CMP #$03 : BNE .notleft + LDA.w SprTimerB, X : BNE .end + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #24 : BCC .noframereset4 + .resetframe4 + LDA.b #18 : STA.w SprFrame, X + .noframereset4 + CMP #18 : BCC .resetframe4 + LDA.b #4 : STA.w SprTimerB, X + .notleft + .end + + LDA.w SprTimerC, X : BNE + + %SetTimerC(20) + %GotoAction(00) + + + + + + RTS + + JumpBack: + JSL Sprite_MoveXyz + + DEC.w $0F80,X : DEC.w $0F80,X + + LDA.w $0F70,X : BPL .aloft + + STZ.w $0F70,X + %GotoAction(0) + + .aloft + + JSL Sprite_CheckTileCollision + + + RTS + + JumpAttackUp: + JSL Sprite_MoveXyz + LDA.w $0F80,X : BEQ + + DEC.w $0F80,X + + + LDA #36 : STA.w SprFrame, X + + REP #$20 + + LDA $20 : STA $06 + LDA $22 : STA $04 + + SEP #$20 + LDA.w SprMiscC, X : BEQ + + LDA #$28 : BRA .movespeed + + + LDA #$20 + .movespeed + JSL Sprite_ProjectSpeedTowardsEntityLong + LDA.b $01 : STA.w SprXSpeed, X + LDA.b $00 : STA.w SprYSpeed, X + + + REP #$20 + + LDA $0FD8 ; Sprite X + SEC : SBC $22 ; - Player X + BPL + + EOR #$FFFF + + + STA $00 ; Distance X (ABS) + + LDA $0FDA ; Sprite Y + SEC : SBC $20 ; - Player Y + BPL + + EOR #$FFFF + + + ; Add it back to X Distance + CLC : ADC $00 : STA $02 ; distance total X, Y (ABS) + + CMP #$0008 : BCS .toofar + SEP #$20 + STZ.w SprXSpeed, X + STZ.w SprYSpeed, X + %GotoAction(4) + .toofar + SEP #$20 + + + + + + RTS + + JumpAttackDown: + + LDA.w SprTimerA, X : BNE .wait + + + JSL Sprite_MoveXyz + JSL Sprite_CheckDamageToPlayer + + LDA #37 : STA.w SprFrame, X + + DEC.w $0F80,X : DEC.w $0F80,X : DEC.w $0F80,X : DEC.w $0F80,X + + LDA.w $0F70,X : BPL .aloft + + + STZ.w $0F70,X + + LDA.b #$90 : STA.w SprTimerC, X + LDA.b #$10 : STA.w SprTimerA, X + + LDA.b #$0C : STA $012E + %GotoAction(06) + + .aloft + + .wait + + RTS + + JumpAttackPrep: + LDA #35 : STA.w SprFrame, X + + LDA.w SprTimerA, X : BNE + + %GotoAction(3) + + + + RTS + + JumpAttackShake: + PHX + JSL Sprite_CheckDamageToPlayer + + REP #$20 + + ; Load the frame counter. + LDA $1A : AND.w #$0001 : ASL A : TAX + + ; Shake the earth! This is the earthquake type effect. + LDA.l $01C961, X : STA $011A + LDA.l $01C965, X : STA $011C + + SEP #$20 + PLX + LDA.w SprTimerA, X : BNE + + + LDA.w SprMiscA, X : BNE .nomessage + LDA #$01 : STA.w SprMiscA, X + %ShowUnconditionalMessage($016F) + + LDA.b #$1F : STA $012C + .nomessage + + + + ; IF health is a certain level spawn crumbling tiles + ;2, 3, 4, 5 + LDA.w SprMiscC, X : BEQ .tilesAreFallingAlready + LDA.w $0B00 : BNE .tilesAreFallingAlready + LDY.w SprMiscE, X + LDA.w CrumbleSpr, Y + STA.w $0B00 ; overlord index 00 + LDA.b $23 : STA.w $0B10 ; x high byte + LDA.b $21 : STA.w $0B20 ; y high byte + LDA.w CrumbleSprX, Y : STA.w $0B08 + LDA.w CrumbleSprY, Y : STA.w $0B18 + STZ.w $0B30 + STZ.w $0B38 + STZ.w $0B28 + INC.w SprMiscE, X + .tilesAreFallingAlready + + %GotoAction(0) + + + + + + + + RTS + + CrumbleSpr: + db $0C, $0D, $0E, $0F + + CrumbleSprX: + db $18, $D8, $D8, $18 + + CrumbleSprY: + db $28, $28, $D8, $D8 + + WalkAction: + + JSL Sprite_CheckDamageFromPlayer : BCC .nodamage + LDA.w SprTimerA, X : BNE .alreadytakingdamage + LDA.w $02B2 : CMP #$03 : BNE .notmoredamage + LDA.w SprHealth, X : SEC : SBC #$04 : STA.w SprHealth, X + .notmoredamage + .alreadytakingdamage + + LDA #$20 + JSL Sprite_ApplySpeedTowardsPlayer + LDA.w SprXSpeed, X : EOR #$FF : STA.w SprXSpeed, X + LDA.w SprYSpeed, X : EOR #$FF : STA.w SprYSpeed, X + LDA.b #$10 : STA.w $0F80,X + LDA.b #$20 : STA.w SprTimerA, X + + %GotoAction(8) + RTS + .nodamage + JSL Sprite_CheckDamageToPlayer + + + LDA.w SprTimerA, X : BNE + + + JSL GetRandomInt : AND #$3F : CLC : ADC #$50 + STA.w SprTimerA, X + %GotoAction(00) + + + + + + STZ $02 ; x direction if non zero = negative + STZ $03 ; y direction + + LDA.w SprXSpeed, X : BPL .positiveX + STA $02 + EOR #$FF + .positiveX + STA $00 ; X speed (abs) + + LDA.w SprYSpeed, X : BPL .positiveY + STA $03 + EOR #$FF + .positiveY + STA $01 ; Y speed (abs) + + JMP Handler_DoWalk + + RTS + + ; right + + + + speedTableX: + db 16, -16, 00, 00 + speedTableY: + db 00, 00, 16, -16 + + Damaged: + JSL Sprite_MoveXyz + + LDA.w SprYSpeed, X : BPL + + INC.w SprYSpeed, X + BRA .next + + + DEC.w SprYSpeed, X + + + .next + + + LDA.w SprXSpeed, X : BPL + + INC.w SprXSpeed, X + BRA .done + + + DEC.w SprXSpeed, X + .done + + DEC.w $0F80,X : DEC.w $0F80,X + + LDA.w $0F70,X : BPL .aloft + + STZ.w SprYSpeed, X + STZ.w SprXSpeed, X + + STZ.w $0F70,X + + .aloft + + LDA.w SprTimerA, X : BNE + + + %GotoAction(0) + STZ.w SprTimerD, X + STZ.w SprMiscF, X + RTS + + + AND #$01 : STA.w SprMiscF, X ; flashing code + + + RTS + + RecoilSword: + JSL Sprite_MoveLong + LDA.w SprTimerC, X : BNE + + %SetTimerC(20) + %GotoAction(00) + + + + JSL Sprite_CheckTileCollision + + RTS + + SwordSubtype: + + + LDA.w SprTimerA, X : BNE + + STZ.w SprState, X ; kill the sprite + + + CMP #$10 : BCS + ; only check for damage if sword has reached halfway + JSL Sprite_CheckDamageToPlayer + + + + + RTS + + DyingSpin: + STZ.w SprHeight, X + LDA.w SprTimerB, X : BNE ++ + + LDA.b #$08 : STA.w SprTimerB, X + LDA.w SprMiscD, X : INC : STA.w SprMiscD, X : CMP #$04 : BNE + + STZ.w SprMiscD, X + LDA #$00 + + + TAY + LDA.w dyingframes, Y : STA.w SprFrame, X + + ++ + + + + LDA.w SprTimerA, X : BNE + + LDA.b #$60 : STA.w SprTimerA, X + LDA.b #$12 : STA.w SprTimerB, X + LDA.b #44 : STA.w SprFrame, X + %GotoAction(12) + + + RTS + + dyingframes: + db $00, $02, $01, $03 + + DeadDespawn: + LDA.w SprTimerB, X : BNE + + LDA.b #45 : STA.w SprFrame, X + + + + + + LDA.w SprTimerA, X : CMP #$28 : BCS + + AND #$04 + STA.w SprMiscF, X + + + + + LDA.w SprTimerA, X : BNE + + %GotoAction(13) + + + + RTS + + OpenDoor: + INC.w SprMiscF, X + ;LDA #$1A : STA.b $11 ; ganon open door routine + ; handled by the room tag? + STZ.w $0DD0, X + + %GotoAction(14) + + RTS + + Dead: + + + RTS + + Enraging: + + PHX + REP #$20 ; P is still on stack, so we don't even need to fix this + LDX #$20 + -- + LDA dlinkPalRed, X : STA $7EC600, X + DEX : DEX : BNE -- + INC $15 ;Refresh Palettes + + SEP #$20 + PLX + + INC.w SprMiscC, X ; Enraging + + LDA #$50 : STA.w SprHealth, X + + %ShowUnconditionalMessage($170) + + %GotoAction(00) + + RTS + + + dlinkPalRed: + dw #$7FFF, #$14A5, #$2108, #$294A, #$1CF5, #$7E4E, #$001D, #$6FF4 +} +;================================================================================================== +; Sprite Draw code +; -------------------------------------------------------------------------------------------------- +; Draw the tiles on screen with the data provided by the sprite maker editor +;================================================================================================== +Sprite_DarkLink_Draw: +{ + JSL Sprite_PrepOamCoord + JSL Sprite_OAM_AllocateDeferToPlayer + + LDA.w SprMiscF, X : BNE .justshadow + + + LDA $0DC0, X : CLC : ADC $0D90, X : TAY;Animation Frame + LDA .start_index, Y : STA $06 + + + PHX + LDX .nbr_of_tiles, Y ;amount of tiles -1 + LDY.b #$00 + .nextTile + + PHX ; Save current Tile Index? + + TXA : CLC : ADC $06 ; Add Animation Index Offset + + PHA ; Keep the value with animation index offset? + + ASL A : TAX + + REP #$20 + + LDA $00 : CLC : ADC .x_offsets, X : STA ($90), Y + AND.w #$0100 : STA $0E + INY + LDA $02 : CLC : ADC .y_offsets, X : STA ($90), Y + CLC : ADC #$0010 : CMP.w #$0100 + SEP #$20 + BCC .on_screen_y + + LDA.b #$F0 : STA ($90), Y ;Put the sprite out of the way + STA $0E + .on_screen_y + + PLX ; Pullback Animation Index Offset (without the *2 not 16bit anymore) + INY + LDA .chr, X : STA ($90), Y + INY + LDA .properties, X : STA ($90), Y + + PHY + + TYA : LSR #2 : TAY + + LDA .sizes, X : ORA $0F : STA ($92), Y ; store size in oam buffer + + PLY : INY + + PLX : DEX : BPL .nextTile + + PLX + + .justshadow + LDA.w SprHeight, X : CMP #$5F : BCS + + LDA.w SprAction, X : CMP #11 : BCS + + JSL Sprite_DrawShadow + + + RTS + + + + + + .Sprite_SwordAttack_Draw + JSL Sprite_PrepOamCoord + JSL Sprite_OAM_AllocateDeferToPlayer + + LDA.w SprMiscF, X : BNE .justshadow + + LDA $0DC0, X : CLC : ADC $0D90, X : TAY;Animation Frame + LDA .start_index2, Y : STA $06 + + + PHX + LDX .nbr_of_tiles2, Y ;amount of tiles -1 + LDY.b #$00 + .nextTile2 + + PHX ; Save current Tile Index? + + TXA : CLC : ADC $06 ; Add Animation Index Offset + + PHA ; Keep the value with animation index offset? + + ASL A : TAX + + REP #$20 + + LDA $00 : CLC : ADC .x_offsets2, X : STA ($90), Y + AND.w #$0100 : STA $0E + INY + LDA $02 : CLC : ADC .y_offsets2, X : STA ($90), Y + CLC : ADC #$0010 : CMP.w #$0100 + SEP #$20 + BCC .on_screen_y2 + + LDA.b #$F0 : STA ($90), Y ;Put the sprite out of the way + STA $0E + .on_screen_y2 + + PLX ; Pullback Animation Index Offset (without the *2 not 16bit anymore) + INY + LDA .chr2, X : STA ($90), Y + INY + LDA .properties2, X : STA ($90), Y + + PHY + + TYA : LSR #2 : TAY + + LDA .sizes2, X : ORA $0F : STA ($92), Y ; store size in oam buffer + + PLY : INY + + PLX : DEX : BPL .nextTile2 + + PLX + + RTS + + + .start_index2 + db $00, $03, $06, $09, $0C, $0F, $11, $14, $17, $1A, $1D, $20, $22, $25, $28, $2B, $2E, $31, $33, $36, $39, $3C, $3F, $42 + .nbr_of_tiles2 + db 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1 + .x_offsets2 + dw 0, 0, -12 + dw 0, -6, 0 + dw 0, 2, 0 + dw 0, 0, 5 + dw 0, 15, 0 + dw 0, 0 + dw 0, 0, 15 + dw 10, 0, 0 + dw 4, 0, 0 + dw -5, -1, 0 + dw -8, -1, 0 + dw 0, 0 + dw 0, 0, -2 + dw 11, 0, -1 + dw 0, 0, 14 + dw 0, 0, 14 + dw 0, -1, 2 + dw 0, -2 + dw -4, 0, 2 + dw -11, 0, 0 + dw -12, 0, 0 + dw 0, -1, -14 + dw 0, 1, -2 + dw 0, 1 + .y_offsets2 + dw 0, -16, 0 + dw 0, 8, -7 + dw 0, 11, -6 + dw 1, -4, 13 + dw 0, 2, -6 + dw 0, -7 + dw -1, -17, 0 + dw -10, 0, -8 + dw -14, 0, -8 + dw -17, 0, -9 + dw -13, 0, -8 + dw 0, -8 + dw -12, 0, -8 + dw -10, 0, -8 + dw 0, -8, -4 + dw 0, -8, 0 + dw 0, -8, 10 + dw 0, -8 + dw -12, 0, -7 + dw -8, 0, -7 + dw -3, 0, -7 + dw 0, -7, 0 + dw 0, -8, 9 + dw 0, -8 + .chr2 + db $2C, $0C, $88 + db $0A, $84, $06 + db $0E, $82, $06 + db $0E, $06, $80 + db $2E, $86, $06 + db $2E, $06 + db $6E, $4E, $88 + db $84, $60, $08 + db $82, $60, $08 + db $80, $62, $08 + db $82, $62, $08 + db $64, $08 + db $80, $46, $00 + db $84, $48, $02 + db $4A, $04, $86 + db $4A, $04, $88 + db $4C, $00, $82 + db $4C, $00 + db $80, $46, $00 + db $84, $48, $02 + db $86, $4A, $04 + db $4A, $04, $88 + db $4C, $00, $82 + db $4C, $00 + .properties2 + db $31, $31, $71 + db $31, $F1, $31 + db $31, $F1, $31 + db $31, $31, $F1 + db $31, $B1, $31 + db $31, $31 + db $31, $31, $31 + db $31, $31, $31 + db $31, $31, $31 + db $31, $31, $31 + db $71, $31, $31 + db $31, $31 + db $31, $31, $31 + db $31, $31, $31 + db $31, $31, $31 + db $31, $31, $31 + db $31, $31, $B1 + db $31, $31 + db $71, $71, $71 + db $71, $71, $71 + db $71, $71, $71 + db $71, $71, $71 + db $71, $71, $F1 + db $71, $71 + .sizes2 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02 + + + ;================================================================================================== + ; Sprite Draw Generated Data + ; -------------------------------------------------------------------------------------------------- + ; This is where the generated Data for the sprite go + ;================================================================================================== + .start_index + db $00, $02, $04, $06, $08, $0A, $0C, $0E, $10, $12, $14, $16, $18, $1A, $1C, $1E, $20, $22, $24, $26, $28, $2A, $2C, $2E, $30, $32, $34, $36, $38, $3A, $3C, $3E, $40, $42, $44, $45, $48, $4B, $4E, $50, $52, $54, $56, $58, $5A, $5C + .nbr_of_tiles + db 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 + .x_offsets + dw 0, 0 + dw 0, 0 + dw 0, -2 + dw 0, 2 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, -2 + dw 0, 0 + dw 0, 0 + dw 0, -1 + dw 0, 2 + dw 0, 1 + dw 0, 1 + dw 0, 1 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw 0, 0 + dw -1, 0 + dw 0 + dw 0, 0, 8 + dw 0, 0, 5 + dw 0, 0, -2 + dw 0, -2 + dw 0, -1 + dw 0, -1 + dw 0, 1 + dw 0, 0 + dw 0, 1 + dw 0, 1 + dw -4, 12 + .y_offsets + dw 0, -6 + dw 0, -6 + dw 0, -8 + dw 0, -8 + dw 0, -6 + dw 0, -6 + dw 0, -7 + dw 0, -6 + dw 0, -6 + dw 0, -6 + dw 0, -7 + dw 0, -6 + dw 0, -6 + dw 0, -6 + dw 0, -7 + dw 0, -6 + dw 0, -6 + dw 0, -6 + dw 0, -7 + dw 0, -6 + dw 0, -8 + dw 0, -8 + dw 0, -9 + dw 0, -8 + dw 0, -8 + dw 0, -8 + dw 0, -9 + dw 0, -8 + dw 0, -16 + dw 0, -8 + dw 0, -7 + dw 0, -16 + dw 0, -8 + dw 0, -9 + dw 0 + dw 0, -7, -12 + dw 0, -7, -13 + dw 0, -4, 10 + dw 0, -8 + dw 0, -8 + dw 0, -8 + dw 0, -9 + dw 0, -8 + dw 0, -8 + dw 0, -8 + dw 0, 0 + .chr + db $42, $06 + db $44, $08 + db $40, $00 + db $40, $00 + db $42, $06 + db $24, $06 + db $26, $06 + db $24, $06 + db $42, $06 + db $24, $06 + db $26, $06 + db $24, $06 + db $44, $08 + db $28, $08 + db $2A, $08 + db $28, $08 + db $44, $08 + db $28, $08 + db $2A, $08 + db $28, $08 + db $40, $00 + db $20, $02 + db $22, $04 + db $20, $02 + db $40, $00 + db $20, $02 + db $22, $04 + db $20, $02 + db $2C, $0C + db $0A, $06 + db $0E, $06 + db $6E, $4E + db $60, $08 + db $62, $08 + db $06 + db $66, $06, $82 + db $66, $06, $80 + db $68, $06, $80 + db $46, $00 + db $48, $02 + db $4A, $04 + db $46, $00 + db $48, $02 + db $4A, $04 + db $A0, $00 + db $A2, $A4 + .properties + db $31, $31 + db $31, $31 + db $31, $31 + db $71, $71 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $71, $31 + db $71, $31 + db $71, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $71, $31 + db $71, $31 + db $71, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $71, $71 + db $71, $71 + db $71, $71 + db $71, $71 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $31, $31 + db $31 + db $31, $31, $31 + db $31, $31, $31 + db $31, $31, $B1 + db $31, $31 + db $31, $31 + db $31, $31 + db $71, $71 + db $71, $71 + db $71, $71 + db $31, $31 + db $31, $31 + .sizes + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 + db $02, $02 +} + + + + + +GanonInit: +{ +LDA #$88 +JSL Sprite_SpawnDynamically + LDA #$05 : STA.w SprSubtype, Y + LDA $00 : STA $0D10, Y + LDA $01 : STA.w $0D30, Y + + LDA $02 : STA.w $0D00, Y + LDA $03 : STA.w $0D20, Y + + LDA.b #$30 : STA.w SprTimerA, Y + LDA #$1E : STA.w $012C +RTL +} + + +Sprite_Ganon_Main: +LDA.w SprAction, X; Load the SprAction +JSL UseImplicitRegIndexedLocalJumpTable; Goto the SprAction we are currently in +dw Wait +dw ShowMessage +dw Fall +dw FellWait +dw FadingAwait + + +Wait: +LDA.w SprTimerA, X : BNE .wait +LDA.b #$30 : STA.w SprTimerA, X +%ShowUnconditionalMessage($46) +%GotoAction(1) +.wait + +RTS + +ShowMessage: +LDA.w SprTimerA, X : BNE .wait +LDA.b #$90 : STA.w SprTimerA, X +%GotoAction(2) +.wait + +RTS + +Fall: +LDA.w SprTimerA, X : BNE .wait +LDA.b #$50 : STA.w SprTimerA, X +LDA #$01 : STA.w SprFrame, X +INC.w SprMiscA, X +%GotoAction(3) +.wait + + +RTS + +FellWait: +LDA.w SprTimerA, X : BNE .wait +LDA.b #$30 : STA.w SprTimerA, X +%GotoAction(4) +.wait + + +RTS + +FadingAwait: +LDA.w SprTimerA, X : BNE .wait +STZ.w SprState, X +.wait + + +RTS + + +Sprite_Ganon_Draw: +LDA.w SprAction, X : CMP #$04 : BNE + +LDA.w SprTimerA, X : AND #$04 : BEQ + +RTS + ++ +JSL Sprite_PrepOamCoord +LDA #$18 +JSL OAM_AllocateFromRegionB + + +LDA $0DC0, X : CLC : ADC $0D90, X : TAY;Animation Frame +LDA .start_index, Y : STA $06 + + +PHX +LDX .nbr_of_tiles, Y ;amount of tiles -1 +LDY.b #$00 +.nextTile + +PHX ; Save current Tile Index? + +TXA : CLC : ADC $06 ; Add Animation Index Offset + +PHA ; Keep the value with animation index offset? + +ASL A : TAX + +REP #$20 + +LDA $00 : CLC : ADC .x_offsets, X : STA ($90), Y +AND.w #$0100 : STA $0E +INY +LDA $02 : CLC : ADC .y_offsets, X : STA ($90), Y +CLC : ADC #$0010 : CMP.w #$0100 +SEP #$20 +BCC .on_screen_y + +LDA.b #$F0 : STA ($90), Y ;Put the sprite out of the way +STA $0E +.on_screen_y + +PLX ; Pullback Animation Index Offset (without the *2 not 16bit anymore) +INY +LDA .chr, X : STA ($90), Y +INY +LDA .properties, X : STA ($90), Y + +PHY + +TYA : LSR #2 : TAY + +LDA .sizes, X : ORA $0F : STA ($92), Y ; store size in oam buffer + +PLY : INY + +PLX : DEX : BPL .nextTile + +PLX + +RTS + + +;================================================================================================== +; Sprite Draw Generated Data +; -------------------------------------------------------------------------------------------------- +; This is where the generated Data for the sprite go +;================================================================================================== +.start_index +db $00, $0C +.nbr_of_tiles +db 11, 11 +.x_offsets +dw 0, 16, 28, 28, 0, 0, 16, 16, 0, 16, -12, -12 +dw 22, 22, -5, -5, -3, 18, 0, 16, 0, 16, 0, 16 +.y_offsets +dw 7, 7, -9, 7, -16, 0, 0, -16, -19, -19, -9, 7 +dw 10, 26, 11, 27, -21, -21, -11, -11, 5, 5, 10, 10 +.chr +db $E0, $E0, $C4, $E4, $C2, $E2, $E2, $C2, $C0, $C0, $C4, $E4 +db $C4, $E4, $C4, $E4, $E6, $E6, $C8, $C8, $E8, $E8, $C6, $C6 +.properties +db $3D, $7D, $7D, $7D, $3B, $3B, $7B, $7B, $3D, $7D, $3D, $3D +db $7D, $7D, $3D, $3D, $3D, $7D, $3B, $7B, $3B, $7B, $3D, $7D +.sizes +db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 +db $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02 diff --git a/Sprites/impa.asm b/Sprites/impa.asm index 333b8a7..c87f611 100644 --- a/Sprites/impa.asm +++ b/Sprites/impa.asm @@ -1,5 +1,6 @@ +pushpc ; Impa Fix org $05EBCF LDA $7EF359 : CMP.b #$04 - \ No newline at end of file +pullpc \ No newline at end of file diff --git a/Sprites/minecart.asm b/Sprites/minecart.asm index a7bd8a4..b05359f 100644 --- a/Sprites/minecart.asm +++ b/Sprites/minecart.asm @@ -2,33 +2,33 @@ ; Sprite Properties ;============================================================================== -!SPRID = $BE ; The sprite ID you are overwriting (HEX) -!NbrTiles = 08 ; Number of tiles used in a frame -!Harmless = 01 ; 00 = Sprite is Harmful, 01 = Sprite is Harmless -!HVelocity = 00 ; Is your sprite going super fast? put 01 if it is -!Health = 00 ; Number of Health the sprite have -!Damage = 00 ; (08 is a whole heart), 04 is half heart -!DeathAnimation = 00 ; 00 = normal death, 01 = no death animation -!ImperviousAll = 00 ; 00 = Can be attack, 01 = attack will clink on it -!SmallShadow = 00 ; 01 = small shadow, 00 = no shadow -!Shadow = 00 ; 00 = don't draw shadow, 01 = draw a shadow -!Palette = 00 ; Unused in this template (can be 0 to 7) -!Hitbox = 00 ; 00 to 31, can be viewed in sprite draw tool -!Persist = 00 ; 01 = your sprite continue to live offscreen -!Statis = 00 ; 00 = is sprite is alive?, (kill all enemies room) -!CollisionLayer = 00 ; 01 = will check both layer for collision -!CanFall = 00 ; 01 sprite can fall in hole, 01 = can't fall -!DeflectArrow = 00 ; 01 = deflect arrows -!WaterSprite = 00 ; 01 = can only walk shallow water -!Blockable = 00 ; 01 = can be blocked by link's shield? -!Prize = 00 ; 00-15 = the prize pack the sprite will drop from -!Sound = 00 ; 01 = Play different sound when taking damage -!Interaction = 00 ; ?? No documentation -!Statue = 00 ; 01 = Sprite is statue -!DeflectProjectiles = 00 ; 01 = Sprite will deflect ALL projectiles -!ImperviousArrow = 00 ; 01 = Impervious to arrows -!ImpervSwordHammer = 00 ; 01 = Impervious to sword and hammer attacks -!Boss = 00 ; 00 = normal sprite, 01 = sprite is a boss +!SPRID = $BE ; The sprite ID you are overwriting (HEX) +!NbrTiles = 08 ; Number of tiles used in a frame +!Harmless = 01 ; 00 = Sprite is Harmful, 01 = Sprite is Harmless +!HVelocity = 00 ; Is your sprite going super fast? put 01 if it is +!Health = 00 ; Number of Health the sprite have +!Damage = 00 ; (08 is a whole heart), 04 is half heart +!DeathAnimation = 00 ; 00 = normal death, 01 = no death animation +!ImperviousAll = 01 ; 00 = Can be attack, 01 = attack will clink on it +!SmallShadow = 00 ; 01 = small shadow, 00 = no shadow +!Shadow = 00 ; 00 = don't draw shadow, 01 = draw a shadow +!Palette = 00 ; Unused in this template (can be 0 to 7) +!Hitbox = 00 ; 00 to 31, can be viewed in sprite draw tool +!Persist = 01 ; 01 = your sprite continue to live offscreen +!Statis = 00 ; 00 = is sprite is alive?, (kill all enemies room) +!CollisionLayer = 00 ; 01 = will check both layer for collision +!CanFall = 00 ; 01 sprite can fall in hole, 01 = can't fall +!DeflectArrow = 00 ; 01 = deflect arrows +!WaterSprite = 00 ; 01 = can only walk shallow water +!Blockable = 00 ; 01 = can be blocked by link's shield? +!Prize = 00 ; 00-15 = the prize pack the sprite will drop from +!Sound = 00 ; 01 = Play different sound when taking damage +!Interaction = 00 ; ?? No documentation +!Statue = 00 ; 01 = Sprite is statue +!DeflectProjectiles = 00 ; 01 = Sprite will deflect ALL projectiles +!ImperviousArrow = 00 ; 01 = Impervious to arrows +!ImpervSwordHammer = 00 ; 01 = Impervious to sword and hammer attacks +!Boss = 00 ; 00 = normal sprite, 01 = sprite is a boss ;============================================================================== @@ -36,7 +36,6 @@ ;============================================================================== -print "Minecart: ", pc Sprite_Minecart_Long: { PHB : PHK : PLB @@ -55,6 +54,16 @@ Sprite_Minecart_Long: ;============================================================================== +; $0DE0[0x10] - (Sprite) ;functions +; udlr +; 0 - up +; 1 - down +; 2 - left +; 3 - right + +!MinecartSpeed = 20 +!MinecartDirection = $012B + Sprite_Minecart_Prep: { PHB : PHK : PLB @@ -76,6 +85,7 @@ Sprite_Minecart_Prep: CMP.b #$03 : BEQ .west .north + LDA #$01 : STA !MinecartDirection %GotoAction(1) ; Minecart_MoveNorth JMP .done .east @@ -95,16 +105,15 @@ Sprite_Minecart_Prep: ;============================================================================== macro HandlePlayerCamera() + LDA $22 : SEC : SBC $3F : STA $31 + LDA $20 : SEC : SBC $3E : STA $30 PHX - JSL $07E6A6 ; Link_HandleMovingAnimation_FullLongEntry - JSL $07F42F ; HandleIndoorCameraAndDoors_Long + JSL $07E6A6 ; Link_HandleMovingAnimation_FullLongEntry + JSL $07F42F ; HandleIndoorCameraAndDoors_Long JSL Player_HaltDashAttack PLX endmacro -!MinecartSpeed = 20 -!MinecartDirection = $012B - Sprite_Minecart_Main: { LDA.w SprAction, X ; Load the SprAction @@ -155,10 +164,12 @@ Sprite_Minecart_Main: LDA $0FDA : SEC : SBC #$0B : STA $20 ; Adjust player pos LDA !MinecartDirection : BNE .opposite_direction + LDA #$01 : STA $0DE0, X %GotoAction(4) ; Minecart_MoveSouth RTS .opposite_direction + LDA #$00 : STA $0DE0, X %GotoAction(2) ; Minecart_MoveNorth .not_on_platform .not_ready @@ -171,17 +182,15 @@ Sprite_Minecart_Main: { %PlayAnimation(2,3,8) LDA.b #-!MinecartSpeed : STA SprYSpeed, X - LDA #$35 : STA $012E + JSL Sprite_MoveVert + + ; LDA SprY, X : SEC : SBC #$04 : STA $20 + ; LDA $0FD8 : CLC : ADC #$02 : STA $22 ; X - JSL Sprite_MoveVert - LDA SprY, X : SEC : SBC #$04 : STA $20 - LDA $0FD8 : CLC : ADC #$02 : STA $22 ; X JSR DragPlayer - %HandlePlayerCamera() - JSR HandleTileDirections - + LDA #$35 : STA $012E RTS } @@ -191,21 +200,17 @@ Sprite_Minecart_Main: Minecart_MoveEast: { %PlayAnimation(0,1,8) - %HandlePlayerCamera() LDA.b #!MinecartSpeed : STA $0D50, X JSL Sprite_MoveHoriz - LDA #$35 : STA $012E ; Make Link move with the minecart - LDA SprX, X : STA $22 + ; LDA SprX, X : STA $22 JSR DragPlayer - %HandlePlayerCamera() - JSR HandleTileDirections - + LDA #$35 : STA $012E RTS } @@ -217,14 +222,15 @@ Sprite_Minecart_Main: %PlayAnimation(2,3,8) LDA.b #!MinecartSpeed : STA SprYSpeed, X + JSL Sprite_MoveVert - JSL Sprite_MoveVert - LDA SprY, X : SEC : SBC #$04 : STA $20 - LDA $0FD8 : CLC : ADC #$02 : STA $22 ; X + ; LDA SprY, X : SEC : SBC #$04 : STA $20 + ; LDA $0FD8 : CLC : ADC #$02 : STA $22 ; X + JSR DragPlayer %HandlePlayerCamera() - JSR HandleTileDirections + LDA #$35 : STA $012E LDA $40 : SEC : SBC.b #$FF : STA $40 LDA $68 : SEC : SBC.b #$FF : STA $68 @@ -240,29 +246,14 @@ Sprite_Minecart_Main: %PlayAnimation(0,1,8) LDA.b #-!MinecartSpeed : STA $0D50, X JSL Sprite_MoveHoriz - LDA #$35 : STA $012E ; Make Link move with the minecart - LDA SprX, X : STA $22 + ; LDA SprX, X : STA $22 JSR DragPlayer - - JSR HandleTileDirections - - ; ; Set Minecart sprite coords to look for tile attributes - ; LDA.w SprY, X : CLC : ADC.b #$04 : STA.b $00 - ; LDA.w SprYH, X : STA.b $01 - - ; LDA.w SprX, X : STA.b $02 - ; LDA.w SprXH, X : STA.b $03 - - ; LDA.b #$00 : JSL Sprite_GetTileAttr - - ; ; Check for bottom left corner tile - ; LDA $0FA5 : CMP.b #$B1 : BNE .continue - - %HandlePlayerCamera() + JSR HandleTileDirections + LDA #$35 : STA $012E RTS } @@ -290,14 +281,13 @@ macro StopCart() endmacro macro SwapSubtype() - LDA SprSubtype, X ; Load the current direction subtype + LDA SprSubtype, X ; Load the current direction subtype ; Assume the new direction is opposite to the current direction. ; This is just an example, adjust the logic as needed. - EOR #$03 ; Toggle the least significant 2 bits (0 <-> 3, 1 <-> 2) - STA SprSubtype, X ; Store the new direction subtype + EOR #$03 ; Toggle the least significant 2 bits (0 <-> 3, 1 <-> 2) + STA SprSubtype, X ; Store the new direction subtype endmacro -print pc HandleTileDirections: { ; Setup Minecart position to look for tile IDs @@ -308,7 +298,7 @@ HandleTileDirections: LDA.b #$00 : JSL Sprite_GetTileAttr ; Load the tile index - LDA $0FA5 + LDA $0FA5 CLC : CMP.b #$01 : BNE .not_out_of_bounds LDA #$40 : STA SprTimerD, X @@ -324,18 +314,18 @@ HandleTileDirections: CLC : CMP.b #$B8 : BEQ .stop_south CLC : CMP.b #$B9 : BEQ .stop_east CLC : CMP.b #$BA : BEQ .stop_west - JMP .check_for_movement ; if none of the above, continue with normal logic + JMP .check_for_movement ; if none of the above, continue with normal logic .stop_north ; Set the new direction to north and flip the cart's orientation LDA.b South : STA SprSubtype, X STZ.w !MinecartDirection - JMP .go_vert + JMP .go_vert .stop_south ; Set the new direction to south and flip the cart's orientation LDA.b North : STA SprSubtype, X - LDA #$01 : STA !MinecartDirection + LDA #$01 : STA !MinecartDirection .go_vert %SetTimerA($40) %StopCart() @@ -345,8 +335,8 @@ HandleTileDirections: .stop_east ; Set the new direction to east and flip the cart's orientation LDA.b West : STA SprSubtype, X - LDA #$01 : STA !MinecartDirection - JMP .go_horiz + LDA #$01 : STA !MinecartDirection + JMP .go_horiz .stop_west ; Set the new direction to west and flip the cart's orientation @@ -372,8 +362,8 @@ HandleTileDirections: ASL A ; Multiply by 4 (shifting left by 2 bits) to offset rows in the lookup table TAY ; Transfer to Y to use as an offset for the rows - LDA $0FA5 ; Load the tile type - SEC : SBC.b #$B3 ; Subtract $B2 to normalize the tile type to 0 to 3 + LDA $0FA5 ; Load the tile type + SEC : SBC.b #$B3 ; Subtract $B2 to normalize the tile type to 0 to 3 CLC ADC.w .DirectionTileLookup, Y ; Add the row and column offsets to index into the lookup table TAY @@ -393,24 +383,23 @@ HandleTileDirections: .DirectionTileLookup { ; TL, BL, TR, BR, Stop - db $02, $00, $04, $00 ; North - db $00, $00, $03, $01 ; East - db $00, $02, $00, $04 ; South - db $03, $01, $00, $00 ; West + db $02, $00, $04, $00 ; North + db $00, $00, $03, $01 ; East + db $00, $02, $00, $04 ; South + db $03, $01, $00, $00 ; West } .check_direction - print pc - LDA SprSubtype, X + LDA SprSubtype, X BNE .not_zero .not_zero - ASL #2 ; Multiply by 4 (shifting left by 2 bits) to offset rows in the lookup table - STA $07 ; Store the action index in $07 + ASL #2 ; Multiply by 4 (shifting left by 2 bits) to offset rows in the lookup table + STA $07 ; Store the action index in $07 - LDA $0FA5 ; Load the tile type - SEC : SBC.b #$B2 ; Subtract $B2 to normalize the tile type to 0 to 3 - CLC : ADC.w $07 ; Add the action index to the tile type offset to get the composite index + LDA $0FA5 ; Load the tile type + SEC : SBC.b #$B2 ; Subtract $B2 to normalize the tile type to 0 to 3 + CLC : ADC.w $07 ; Add the action index to the tile type offset to get the composite index TAY LDA.w .DirectionTileLookup, Y @@ -425,25 +414,29 @@ HandleTileDirections: .move_north LDA #$00 : STA SprSubtype, X + STA $0DE0, X %GotoAction(2) ; Minecart_MoveNorth RTS .move_east LDA #$01 : STA SprSubtype, X + LDA #$03 : STA $0DE0, X %GotoAction(3) ; Minecart_MoveEast RTS .move_south LDA #$02 : STA SprSubtype, X + LDA #$01 : STA $0DE0, X %GotoAction(4) ; Minecart_MoveSouth RTS .move_west LDA #$03 : STA SprSubtype, X + LDA #$02 : STA $0DE0, X %GotoAction(5) ; Minecart_MoveWest .done RTS .tile_ids - ; db $B0 ; - Horiz - ; db $B1 ; | Vert + ; db $B0 ; - Horiz + ; db $B1 ; | Vert ; TL, BL, TR, BR db $B2, $B3, $B4, $B5 ; db $B8 Stop North @@ -451,7 +444,7 @@ HandleTileDirections: ; db $BA Stop East ; db $BB Stop West - ; db $BE ; + any direction + ; db $BE ; + any direction } ;============================================================================== @@ -468,7 +461,7 @@ DragPlayer: .SomariaPlatform_DragLink REP #$20 - LDA $0FD8 : SEC : SBC.w #$0008 : CMP $22 : BEQ .x_done + LDA $0FD8 : SEC : SBC.w #$0002 : CMP $22 : BEQ .x_done BPL .x_too_low DEC $0B7C diff --git a/Sprites/poltergeist.asm b/Sprites/poltergeist.asm index 1dbecbe..e405758 100644 --- a/Sprites/poltergeist.asm +++ b/Sprites/poltergeist.asm @@ -1,7 +1,7 @@ ;============================================================================== ; Sprite Properties ;============================================================================== -!SPRID = $B6; The sprite ID you are overwriting (HEX) +!SPRID = $B6 ; The sprite ID you are overwriting (HEX) !NbrTiles = 4 ; Number of tiles used in a frame !Harmless = 00 ; 00 = Sprite is Harmful, 01 = Sprite is Harmless !HVelocity = 00 ; Is your sprite going super fast? put 01 if it is diff --git a/Sprites/portal_sprite.asm b/Sprites/portal_sprite.asm index c8686a8..325b74f 100644 --- a/Sprites/portal_sprite.asm +++ b/Sprites/portal_sprite.asm @@ -3,7 +3,7 @@ ; Portal Sprite ; ========================================================= -!SPRID = $B6 ; The sprite ID you are overwriting (HEX) +!SPRID = $B8 ; The sprite ID you are overwriting (HEX) !NbrTiles = 01 ; Number of tiles used in a frame !Harmless = 00 ; 00 = Sprite is Harmful, 01 = Sprite is Harmless !HVelocity = 00 ; Is your sprite going super fast? put 01 if it is @@ -60,6 +60,7 @@ Sprite_Portal_Prep: PHB : PHK : PLB ; Persist outside of camera + LDA #$00 : STA $0CAA, X LDA SprHitbox, X : AND.b #$20 : STA SprHitbox, X PLB diff --git a/Sprites/twinrova.asm b/Sprites/twinrova.asm index 258baf0..d342c54 100644 --- a/Sprites/twinrova.asm +++ b/Sprites/twinrova.asm @@ -703,7 +703,6 @@ db $02, $02, $02, $02 db $02, $02, $02, $02 } -print "TWINROVA ============ ", pc ApplyTwinrovaGraphics: { PHX