diff --git a/Sprites/sprite_jump_table.asm b/Sprites/sprite_jump_table.asm new file mode 100644 index 0000000..2bd11ae --- /dev/null +++ b/Sprites/sprite_jump_table.asm @@ -0,0 +1,77 @@ +pushpc +org $06FFF8 ; New Jumptable for sprites +NewMainSprFunction: +JSL SpriteActiveExp_MainLong +RTS + +org $068EB9 +NewSprPrepFunction: +JSL Sprite_PrepExp_Long +RTS +pullpc + + + +SpriteActiveExp_MainLong: +{ +PHB : PHK : PLB + +JSL NewSprTable + +PLB + +RTL +} + +NewSprTable: +LDA $0E20, X ; Load Sprite ID +REP #$30 +AND.w #$00FF +STA $06 +ASL A ; *2 +CLC : ADC $06 ; *3 +TAY + +LDA NewSprRoutinesLong, Y ; Load sprite Address +STA $06 +SEP #$30 +LDA NewSprRoutinesLong+2, Y +STA $08 +JMP [$0006] + +;do a JML and sprite will RTL back to previous code + +Sprite_PrepExp_Long: +{ +PHB : PHK : PLB + +JSL NewSprPrepTable + +PLB + +RTL +} + +NewSprPrepTable: +LDA $0E20, X ; Load Sprite ID +REP #$30 +AND.w #$00FF +STA $06 +ASL A ; *2 +CLC : ADC $06 ; *3 +TAY + +LDA NewSprPrepRoutinesLong, Y ; Load sprite Address +STA $06 +SEP #$30 +LDA NewSprPrepRoutinesLong+2, Y +STA $08 +JMP [$0006] + +NewSprRoutinesLong: +fillbyte $00 +fill $2FD + +NewSprPrepRoutinesLong: +fillbyte $00 +fill $2FD diff --git a/Sprites/sprite_macros.asm b/Sprites/sprite_macros.asm new file mode 100644 index 0000000..37335de --- /dev/null +++ b/Sprites/sprite_macros.asm @@ -0,0 +1,198 @@ +; Write Sprite Properties in the rom MACRO +macro Set_Sprite_Properties(SprPrep, SprMain) + +pushpc ; Save writing Position for the sprite +org $0DB080+!SPRID ; Oam Harmless ($0E40) +db ((!Harmless<<7)|(!HVelocity<<6)|!NbrTiles) + +org $0DB173+!SPRID ; Sprite HP ($0E50) +db !Health + +org $0DB266+!SPRID ; Sprite Damage ($0CD2) +db !Damage + +org $0DB359+!SPRID ; Sprite Data ($0E60 / $0F50) +db ((!DeathAnimation<<7)|(!ImperviousAll<<6)|(!SmallShadow<<5)|(!Shadow<<4)|(!Palette<<1)) + +org $0DB44C+!SPRID ; Sprite Hitbox ($0F60) +db ((!CollisionLayer<<7)|(!Statis<<6)|(!Persist<<5)|(!Hitbox)) + +org $0DB53F+!SPRID ; Sprite Fall ($0B6B) +db ((!DeflectArrow<<3)|(!Boss<<1)|!CanFall) + +org $0DB632+!SPRID ; Sprite Prize ($0BE0) +db ((!Interaction<<7)|(!WaterSprite<<6)|(!Blockable<<5)|(!Sound<<4)|!Prize) + +org $0DB725+!SPRID ; Sprite ($0CAA) +db ($40|(!Statue<<5)|(!DeflectProjectiles<<4)|(!ImpervSwordHammer<<2)|(!ImperviousArrow<<1)) + +org $069283+(!SPRID*2) ; Vanilla Sprite Main Pointer +dw NewMainSprFunction + +org $06865B+(!SPRID*2) ; Vanilla Sprite Prep Pointer +dw NewSprPrepFunction + +org NewSprRoutinesLong+(!SPRID*3) ; New Long Sprite Pointer +dl + +org NewSprPrepRoutinesLong+(!SPRID*3) ; New Long Sprite Pointer +dl +pullpc ; Get back the writing position for the sprite + +endmacro + +; Go to the action specified ID can be Hex or Decimal +macro GotoAction(action) + LDA.b # : STA.w SprAction, X +endmacro + + +; Increase the sprite frame every (frames_wait) frames +; reset to (frame_start) when reaching (frame_end) +; This is using SprTimerB +macro PlayAnimation(frame_start, frame_end, frame_wait) + LDA.w SprTimerB, X : BNE + + LDA.w SprFrame, X : INC : STA.w SprFrame, X : CMP.b #+1 : BCC .noframereset + LDA.b # : STA.w SprFrame, X + .noframereset + LDA.b # : STA.w SprTimerB, X + + +endmacro + + +; Show message if the player is facing toward sprite and pressing A +; Return Carry Set if message is displayed +; can use BCC .label <> .label to see if message have been displayed +macro ShowSolicitedMessage(message_id) + LDY.b #()>>8 + LDA.b # + JSL Sprite_ShowSolicitedMessageIfPlayerFacing +endmacro + +; Show message no matter what (should not be used without code condition) +macro ShowUnconditionalMessage(message_id) + LDY.b #()>>8 + LDA.b # + JSL Sprite_ShowMessageUnconditional +endmacro + +; Make the sprite move towards the player at a speed of (speed) +macro MoveTowardPlayer(speed) + LDA.b # + JSL Sprite_ApplySpeedTowardsPlayer + JSL Sprite_MoveLong +endmacro + +; Prevent the player from passing through sprite hitbox +macro PlayerCantPassThrough() + JSL Sprite_PlayerCantPassThrough +endmacro + +; Do damage to player on contact if sprite is on same layer as player +macro DoDamageToPlayerSameLayerOnContact() + JSL Sprite_CheckDamageToPlayerSameLayer +endmacro + +; Set harmless flag, 0 = harmful, 1 = harmless +macro SetHarmless(value) + LDA.w SprNbrOAM, X + AND #$7F + if != 0 + ORA.b #()<<7 + endif + STA.w SprNbrOAM, X +endmacro + +; Set Room Flag (Chest 6) +; Do not use if you have more than 5 chests or a small key under a pot +; in that room unless you want it to be already opened/taken +macro SetRoomFlag(value) + if != 0 + LDA $0403 : ORA #$20 : STA $0403 + else + LDA $0403 : AND #$DF : STA $0403 + endif +endmacro + +; Will prevent the player from moving or opening his menu +macro PreventPlayerMovement() +LDA #$01 : STA $02E4 +endmacro + +; Will allow the player to move or open his menu +macro AllowPlayerMovement() +STZ.w $02E4 +endmacro + +; Enter 16bit mode +macro Set16bitmode() +REP #$30 +endmacro + +; Enter 8bit mode +macro Set8bitmode() +SEP #$30 +endmacro + +; This is a 16 bit will load A with current rupee count +; to use with instructions CMP and BCC/BCS +macro GetPlayerRupees() +LDA $7EF360 +endmacro + +; Set the velocity Y of the sprite at (speed) value +; this require the use of the function JSL Sprite_MoveLong +macro SetSpriteSpeedY(speed) +LDA.b # : STA.w SprYSpeed, x +endmacro + +; Set the velocity X of the sprite at (speed) value +; this require the use of the function JSL Sprite_MoveLong +macro SetSpriteSpeedX(speed) +LDA.b # : STA.w SprXSpeed, x +endmacro + +; Will play a sound SFX 1 See Zelda_3_RAM.log for more informations +macro PlaySFX1(sfxid) +LDA.b # : STA $012E +endmacro + +; Will play a sound SFX 2 See Zelda_3_RAM.log for more informations +macro PlaySFX2(sfxid) +LDA.b # : STA $012F +endmacro + +; Will play a music See Zelda_3_RAM.log for more informations +macro PlayMusic(musicid) +LDA.b # : STA $012C +endmacro + +; Will set the timer A to wait (length) amount of frames +macro SetTimerA(length) +LDA.b # : STA.w SprTimerA, X +endmacro + +; Will set the timer B to wait (length) amount of frames +macro SetTimerB(length) +LDA.b # : STA.w SprTimerB, X +endmacro + +; Will set the timer C to wait (length) amount of frames +macro SetTimerC(length) +LDA.b # : STA.w SprTimerC, X +endmacro + +; Will set the timer D to wait (length) amount of frames +macro SetTimerD(length) +LDA.b # : STA.w SprTimerD, X +endmacro + +; Will set the timer E to wait (length) amount of frames +macro SetTimerE(length) +LDA.b # : STA.w SprTimerE, X +endmacro + +; Will set the timer F to wait (length) amount of frames +macro SetTimerF(length) +LDA.b # : STA.w SprTimerF, X +endmacro \ No newline at end of file diff --git a/Sprites/sprite_new_functions.asm b/Sprites/sprite_new_functions.asm new file mode 100644 index 0000000..765ed0e --- /dev/null +++ b/Sprites/sprite_new_functions.asm @@ -0,0 +1,139 @@ +;================================================================= +;Long function, return Carry Set if Active +;================================================================= +Sprite_CheckActive: +{ + ; Deactivates the sprite in certain situations + + LDA $0DD0, X : CMP.b #$09 : BNE .inactive + + LDA $0FC1 : BNE .inactive + + LDA $11 : BNE .inactive + + LDA $0CAA, X : BMI .active + + LDA $0F00, X : BEQ .active + + .inactive + CLC + RTL + + .active + SEC + RTL +} + + +; make the sprite move X axis +;=================================================================================================== +Sprite_MoveHoriz: + LDA.w $0D50,X : BEQ .no_velocity + ASL : ASL : ASL : ASL + CLC : ADC.w $0D70,X : STA.w $0D70,X + + LDY.b #$00 + LDA.w $0D50,X + PHP : LSR : LSR : LSR : LSR : PLP + BPL ++ + + ORA.b #$F0 + DEY + +++ ADC.w $0D10,X : STA.w $0D10,X + TYA : ADC.w $0D30,X : STA.w $0D30,X + +.no_velocity + RTL + +;=================================================================================================== +; make the sprite move both directions (also height) +;=================================================================================================== +Sprite_MoveXyz: + JSL Sprite_MoveAltitude +Sprite_Move: + JSL Sprite_MoveHoriz + ; no RTL, just continue into Sprite_MoveVert + +;=================================================================================================== +; make the sprite move Y axis +;=================================================================================================== +Sprite_MoveVert: + LDA.w $0D40,X : BEQ .no_velocity + ASL : ASL : ASL : ASL + CLC : ADC.w $0D60,X : STA.w $0D60,X + + LDY.b #$00 + LDA.w $0D40,X + PHP : LSR : LSR : LSR : LSR : PLP + BPL ++ + + ORA.b #$F0 + DEY + +++ ADC.w $0D00,X : STA.w $0D00,X + TYA : ADC.w $0D20,X : STA.w $0D20,X + +.no_velocity + RTL + +;=================================================================================================== +; make the sprite move Z axis (height) +;=================================================================================================== +Sprite_MoveZ: +Sprite_MoveAltitude: + LDA.w $0F80,X : ASL : ASL : ASL : ASL + CLC : ADC.w $0F90,X : STA.w $0F90,X + + LDA.w $0F80,X : PHP + LSR : LSR : LSR : LSR + PLP : BPL .positive + + ORA.b #$F0 + +.positive + ADC.w $0F70,X : STA.w $0F70,X + + RTL + + +;=================================================================================================== +; make the sprite bounce toward player (like vitreous) +; Movement, Collision are handled by this function (height:20 = vitreous) +; $09 = speed, $08 = max height +;=================================================================================================== +Sprite_Bouncetowardplayer: + JSL Sprite_MoveAltitude + + DEC.w $0F80,X : DEC.w $0F80,X + + LDA.w $0F70,X : BPL .aloft + + STZ.w $0F70,X + + LDA.b $08 : STA.w $0F80,X ; set height from 08 + + LDA.b $09 + + JSL Sprite_ApplySpeedTowardsPlayer + + LDA.b #$21 : JSL Sound_SetSfx2PanLong + +.aloft + LDA.w $0F70,X : BEQ .dontmove + + JSL Sprite_Move + +.dontmove + RTL + +Sprite_BounceFromTileCollision: + JSL Sprite_CheckTileCollision : AND.b #$03 : BEQ ++ + LDA.w $0D50,X : EOR.b #$FF : INC : STA.w $0D50,X + INC.w $0ED0,X + +++ LDA.w $0E70,X : AND.b #$0C : BEQ ++ + LDA.w $0D40,X : EOR.b #$FF : INC : STA.w $0D40,X + INC.w $0ED0,X + +++ RTL \ No newline at end of file