Update Sprites and Items

- Add the Portal Rod item (WIP)
- Add Twinrova Boss Sprite
- Update the Minecart Sprite
- Fix the HUD magic meter draw
- Fix some Zora Mask bugs (WIP)
- General housekeeping
This commit is contained in:
scawful
2023-09-13 23:01:16 -04:00
parent 00c700c31d
commit 9e0ee96943
27 changed files with 2562 additions and 457 deletions

19
Items/all_items.asm Normal file
View File

@@ -0,0 +1,19 @@
; Inherits Free Space from Bank07
incsrc "Items/bottle_net.asm"
print "End of Items/bottle_net.asm ", pc
incsrc "Items/ocarina.asm"
print "End of Items/ocarina.asm ", pc
incsrc "Items/ice_rod.asm"
print "End of Items/ice_rod.asm ", pc
; Starts Expanded Bank 0x2B
incsrc "Items/jump_feather.asm"
incsrc "Items/book_of_secrets.asm"
incsrc "Items/portal_rod.asm"
incsrc "Items/sword_collect.asm"
print "End of Items/sword_collect.asm ", pc

View File

@@ -26,10 +26,9 @@ org $068365
JSL LinkItem_SecretsBook ; overwrite it (originally JSL $099F91) JSL LinkItem_SecretsBook ; overwrite it (originally JSL $099F91)
; ============================================================================= ; =============================================================================
; go to expanded space to write our routine
; (keep EveryFrame.asm in mind for the right adresses) pullpc
; org $3CA600
org $2B8000
LinkItem_SecretsBook: LinkItem_SecretsBook:
{ {
LDA $1B ; load data that tells us whether we are in a building or not LDA $1B ; load data that tells us whether we are in a building or not
@@ -57,6 +56,8 @@ LinkItem_SecretsBook:
JSL $099F91 ; at least execute original code JSL $099F91 ; at least execute original code
RTL RTL
} }
print "End of Items/book_of_secrets.asm ", pc
pushpc pushpc

View File

@@ -7,8 +7,6 @@
LinkItem_IceRod: LinkItem_IceRod:
{ {
lorom
org $088a5d ; jsl to main code org $088a5d ; jsl to main code
jsl $0efba0 jsl $0efba0

View File

@@ -1,7 +1,7 @@
; ============================================================================= ; =============================================================================
; Zarby Feather ; Zarby Feather
org $07AFF8 org $07AFF8 ; LinkItem_BugCatchingNet
{ {
BIT $3A : BVS .return ;if Y or B are already pressed BIT $3A : BVS .return ;if Y or B are already pressed
@@ -17,7 +17,7 @@ org $07AFF8
; ============================================================================= ; =============================================================================
org $2A8000 org $2B8000
NewBookCode: NewBookCode:
{ {
JSL $07983A ; Reset swim state JSL $07983A ; Reset swim state
@@ -25,20 +25,27 @@ NewBookCode:
LDA #$02 : STA $5D ; state recoil LDA #$02 : STA $5D ; state recoil
LDA #$01 : STA $4D ; state recoil 2 LDA #$01 : STA $4D ; state recoil 2
LDA #$20 ; Change this to change the length of the jump ; Length of the jump
LDA #$20
STA $46 STA $46
LDA #$24 ; Change this to change the height of the jump ; Height of the jump
LDA #$24
STA $29 : STA $02C7 ; Set vertical resistance
STA $29
STA $02C7
; Set Links direction to right(?)
LDA #$08 : STA $0340 : STA $67 LDA #$08 : STA $0340 : STA $67
; Reset Link movement offsets
STZ $31 STZ $31
STZ $30 STZ $30
LDA $F4 : AND #$08 : BEQ .noUp LDA $F4 : AND #$08 : BEQ .noUp
LDA #-8 ; Change that -8 if you want higher speed moving up LDA #-8 ; Change that -8 if you want higher speed moving up
STA $27 STA $27 ; Vertical recoil
.noUp .noUp
LDA $F4 : AND #$04 : BEQ .noDown LDA $F4 : AND #$04 : BEQ .noDown
LDA #8 ; Change that -8 if you want higher speed moving down LDA #8 ; Change that -8 if you want higher speed moving down
@@ -46,7 +53,7 @@ NewBookCode:
.noDown .noDown
LDA $F4 : AND #$02 : BEQ .noLeft LDA $F4 : AND #$02 : BEQ .noLeft
LDA #-8 ; Change that -8 if you want higher speed moving left LDA #-8 ; Change that -8 if you want higher speed moving left
STA $28 STA $28 ; Horizontal recoil
.noLeft .noLeft
LDA $F4 : AND #$01 : BEQ .noRight LDA $F4 : AND #$01 : BEQ .noRight
LDA #8 ; Change that 8 if you want higher speed moving right LDA #8 ; Change that 8 if you want higher speed moving right
@@ -55,3 +62,6 @@ NewBookCode:
.cantuseit .cantuseit
RTL RTL
} }
print "End of Items/jump_feather.asm ", pc
pushpc

581
Items/portal_rod.asm Normal file
View File

@@ -0,0 +1,581 @@
org $07A471 ; Mudora
JSR LinkItem_PortalRod
RTS
warnpc $07A493
; *$3A50F-$3A568
org $07A50F
RodAnimationTimer:
db $03, $03, $05
LinkItem_PortalRod:
{
BIT $3A : BVS .y_button_held
LDA $6C : BNE .return
JSR Link_CheckNewY_ButtonPress : BCC .return
LDX.b #$00
JSR LinkItem_EvaluateMagicCost : BCC .insufficient_mp
LDA.b #$30 : JSR $802F ; Sfx3
JSL LinkItem_FirePortal
.y_button_held
JSR $AE65 ; HaltLinkWhenUsingItems
; What's the point of this?
; LDA $67 : AND.b #$F0 : STA $67
DEC $3D : BPL .return
LDA $0300 : INC A : STA $0300 : TAX
LDA RodAnimationTimer, X : STA $3D
CPX.b #$03 : BNE .return
STZ $5E
STZ $0300
STZ $3D
LDA $0301 : AND.b #$FE : STA $0301
.insufficient_mp
LDA $3A : AND.b #$BF : STA $3A
.return
RTS
}
warnpc $07A568
pullpc
macro SpawnPortal(x_offset, y_offset)
REP #$20
LDA $22 : CLC : ADC.w #<x_offset>
SEP #$20
STA $0D10, Y ; SprX
XBA : STA $0D30, Y ; SprXH
REP #$20
LDA $20 : CLC : ADC.w #<y_offset>
SEP #$20
STA $0D00, Y ; SprY
XBA : STA $0D20, Y ; SprYH
endmacro
LinkItem_FirePortal:
{
LDA.b #$B6
JSL Sprite_SpawnDynamically : BPL .continue
RTS
.continue
PHX
LDA $7E0FA6 : BEQ .spawn_blue
STZ.w $0FA6
JMP .check_direction
.spawn_blue
LDA #$01 : STA $7E0FA6
.check_direction
LDA $2F : CMP.b #$00 : BEQ .facing_up
LDA $2F : CMP.b #$02 : BEQ .facing_down
LDA $2F : CMP.b #$04 : BEQ .facing_left
LDA $2F : CMP.b #$06 : BEQ .facing_right
; Portal Spawn Location
.facing_up
%SpawnPortal($0000, -0020)
JMP .finish
.facing_down
%SpawnPortal($0000, $001F)
JMP .finish
.facing_left
%SpawnPortal(-0020, $0000)
JMP .finish
.facing_right
%SpawnPortal(0020, $0000)
JMP .finish
.finish
TYX
STZ $0D60, X
STZ $0D70, X
PLX
.return
; Delay the spin attack for some amount of time?
LDA RodAnimationTimer : STA $3D
STZ $2E
STZ $0300
STZ $0301
LDA.b #$01 : TSB $0301
RTL
}
pushpc
org $02FF6E
Overworld_OperateCameraScroll_Long:
{
PHB : PHK : PLB
JSR $BB90
PLB
RTL
}
Overworld_ScrollMap_Long:
{
PHB : PHK : PLB
JSR $F273
PLB
RTL
}
pullpc
ScrollToPortal:
{
REP #$20
STZ $00
STZ $02
LDA $22 : CMP $7EC186 : BEQ .set_x : BCC .x_low
DEC $02
DEC A : CMP $7EC186 : BEQ .set_x
DEC $02
DEC A
BRA .set_x
.x_low
INC $02
INC A : CMP $7EC186 : BEQ .set_x
INC $02
INC A
.set_x
STA $22
LDA $20 : CMP $7EC184 : BEQ .set_y : BCC .y_low
DEC $00
DEC A : CMP $7EC184 : BEQ .set_y
DEC $00
DEC A
BRA .set_y
.y_low
INC $00
INC A : CMP $7EC184 : BEQ .set_y
INC $00
INC A
.set_y
STA $20
CMP $7EC184 : BNE .delay_advance
LDA $22 : CMP $7EC186 : BNE .delay_advance
INC $B0
STZ $46
.delay_advance
SEP #$20
LDA $00 : STA $30
LDA $02 : STA $31
JSL Overworld_OperateCameraScroll_Long ; $13B90 IN ROM
LDA $0416 : BEQ .exit
JSL Overworld_ScrollMap_Long ; $17273 IN ROM
.exit
RTL
}
Ancilla_MoveXYWithPortal:
{
; Increments X_reg by 0x0A so that X coordinates will be handled next
TXA : CLC : ADC.b #$0A : TAX
; MoveVertical
LDA $0C22, X : ASL #4 : CLC : ADC $0C36, X : STA $0C36, X
LDY.b #$00
; upper 4 bits are pixels per frame. lower 4 bits are 1/16ths of a pixel per frame.
; store the carry result of adding to $0C36, X
; check if the y pixel change per frame is negative
LDA $0C22, X : PHP : LSR #4 : PLP : BPL .moving_down
; sign extend from 4-bits to 8-bits
ORA.b #$F0
DEY
.moving_down
; modifies the y coordinates of the special object
ADC $0BFA, X : STA $0BFA, X
TYA : ADC $0C0E, X : STA $0C0E, X
LDX.w $0FA0
RTL
}
; #_088087: db $50 ; 0x18 - ETHER SPELL
; #_088088: db $00 ; 0x19 - BOMBOS SPELL
; LDA.b #$18 ; Ether Spell
; LDY.b #$01
; JSL Ancilla_PortalShot
print "End of Items/portal_rod.asm ", pc
pushpc
; org $0997DE
; AddSilverArrowSparkle:
; org $088D68
; Ancilla_CheckSpriteCollision:
; org $088981
; Ancilla_CheckTileCollision:
; org $088027
; Ancilla_DoSfx2:
; org $08A121
; Ancilla_Arrow:
; {
; .y_offsets
; dw -4, 2, 0, 0
; .x_offsets
; dw 0, 0, -4, 4
; LDA.b $11 : BEQ .normal_submode
; BRL .draw
; .normal_submode
; DEC.w $0C5E, X : LDA.w $0C5E, X : BMI .timer_elapsed
; CMP.b #$04 : BCC .begin_moving
; ; The object doesn't even start being drawn until this timer counts
; ; down.
; BRL .do_nothing
; .timer_elapsed
; LDA.b #$FF : STA.w $0C5E, X
; .begin_moving
; ; JSL Ancilla_MoveXYWithPortal
; JSR $908B
; JSR $9080
; LDA.l $7EF340 : AND.b #$04 : BEQ .dont_spawn_sparkle
; LDA.b $1A : AND.b #$01 : BNE .dont_spawn_sparkle
; PHX
; JSL AddSilverArrowSparkle
; PLX
; .dont_spawn_sparkle
; LDA.b #$FF : STA $03A9, X
; JSR Ancilla_CheckSpriteCollision : BCS .sprite_collision
; JSR Ancilla_CheckTileCollision : BCS .tile_collision
; BRL .draw
; .tile_collision
; TYA : STA $03C5, X
; LDA $0C72, X : AND.b #$03 : ASL A : TAY
; LDA.w .y_offsets+0, Y : CLC : ADC.w $0BFA, X : STA.w $0BFA, X
; LDA.w .y_offsets+1, Y : ADC.w $0C0E, X : STA.w $0C0E, X
; LDA.w .x_offsets+0, Y : CLC : ADC.w $0C04, X : STA.w $0C04, X
; LDA.w .x_offsets+1, Y : ADC.w $0C18, X : STA.w $0C18, X
; STZ.w $0B88
; BRA .transmute_to_halted_arrow
; .sprite_collision
; LDA $0C04, X : SEC : SBC $0D10, Y : STA $0C2C, X
; LDA $0BFA, X : SEC : SBC $0D00, Y : CLC : ADC $0F70, Y : STA $0C22, X
; TYA : STA $03A9, X
; LDA $0E20, Y : CMP.b #$65 : BNE .not_archery_game_sprite
; LDA $0D90, Y : CMP.b #$01 : BNE .not_archery_target_mop
; LDA.b #$2D : STA $012F
; ; Set a delay for the archery game proprietor and set a timer for the
; ; target that was hit (indicating it was hit)
; LDA.b #$80 : STA $0E10, Y : STA $0F10
; ; \tcrf In conjunction with the ArcheryGameGuy sprite code, this is
; ; another lead the suggested that there were 9 game prize values
; ; instead of just the normal 5.
; LDA $0B88 : CMP.b #$09 : BCS .prize_index_maxed_out
; INC $0B88
; .prize_index_maxed_out
; LDA $0B88 : STA $0DA0, Y
; LDA $0ED0, Y : INC A : STA $0ED0, Y
; BRA .transmute_to_halted_arrow
; .not_archery_target_mop
; LDA.b #$04 : STA $0EE0, Y
; .not_archery_game_sprite
; STZ $0B88
; .transmute_to_halted_arrow
; LDA $0E20, Y : CMP.b #$1B : BEQ .hit_enemy_arrow_no_sfx
; LDA.b #$08 : JSR Ancilla_DoSfx2
; .hit_enemy_arrow_no_sfx
; STZ $0C5E, X
; LDA.b #$0A : STA $0C4A, X
; LDA.b #$01 : STA $03B1, X
; LDA $03C5, X : BEQ .draw
; REP #$20
; LDA $E0 : SEC : SBC $E2 : CLC : ADC $0C04, X : STA $00
; LDA $E6 : SEC : SBC $E8 : CLC : ADC $0BFA, X : STA $02
; SEP #$20
; LDA $00 : STA $0C04, X
; LDA $02 : STA $0BFA, X
; BRA .draw
; .do_nothing
; RTS
; .draw
; BRL $09236E ; Arrow_Draw
; }
; warnpc $08A24E
; ; Portal Rod logic based on Fire Rod
; Ancilla_PortalShot:
; {
; LDA $0C54, X : BEQ .traveling_shot
; JMP Ancilla_ConsumingFire
; .traveling_shot
; LDA $11 : BNE .just_draw
; STZ $0385, X
; JSR Ancilla_MoveHoriz
; JSR Ancilla_MoveVert
; JSR Ancilla_CheckSpriteCollision : BCS .collided
; LDA $0C72, X : ORA.b #$08 : STA $0C72, X
; JSR Ancilla_CheckTileCollision
; PHP
; LDA $03E4, X : STA $0385, X
; PLP : BCS .collided
; LDA $0C72, X : ORA.b #$0C : STA $0C72, X
; LDA $028A, X : STA $74
; JSR Ancilla_CheckTileCollision
; PHP
; LDA $74 : STA $028A, X
; PLP : BCC .no_collision
; .collided
; INC $0C54, X
; ; Check if it's blue or orange portal
; LDA $0C68, X
; CMP.b #$1F
; BEQ .blue_portal
; JMP .orange_portal
; .blue_portal
; LDA.b #$20 : STA $0C68, X
; LDA.b #$08 : STA $0C90, X
; LDA.b #$2B : JSR Ancilla_DoSfx2 ; Different sound effect for blue portal
; JMP .portal_created
; .orange_portal
; LDA.b #$21 : STA $0C68, X
; LDA.b #$08 : STA $0C90, X
; LDA.b #$2C : JSR Ancilla_DoSfx2 ; Different sound effect for orange portal
; .portal_created
; ; CLC : ADC portal creation logic here if necessary
; .no_collision
; INC $0C5E, X
; LDA $0C72, X : AND.b #$F3 : STA $0C72, X
; LDA $0385, X : STA $0333
; AND.b #$F0 : CMP.b #$C0 : BNE .just_draw
; LDA $03E4, X : STA $0333
; AND.b #$F0 : CMP.b #$C0 : BNE .just_draw
; .just_draw
; JSR PortalShot_Draw
; RTS
; }
; ; *$4077C-$407CA LOCAL
; PortalShot_Draw:
; {
; JSR Ancilla_BoundsCheck
; LDA $0280, X : BEQ .default_priority
; LDA.b #$30 : TSB $04
; .default_priority
; LDA $0C5E, X : AND.b #$0C : STA $02
; PHX
; LDX.b #$02
; LDY.b #$00
; .next_oam_entry
; STX $03
; TXA : ORA $02 : TAX
; LDA $00 : CLC : ADC .x_offsets, X : STA ($90), Y
; LDA $01 : CLC : ADC .y_offsets, X : INY : STA ($90), Y
; LDX $03
; LDA .chr, X : INY : STA ($90), Y
; LDA $04 : ORA.b #$02 : INY : STA ($90), Y
; PHY
; TYA : LSR #2 : TAY
; LDA.b #$00 : STA ($92), Y
; PLY : INY
; DEX : BPL .next_oam_entry
; PLX
; RTS
; .x_offsets
; db 7, 0, 8, 0, 8, 4, 0, 0
; db 2, 8, 0, 0, 1, 4, 9, 0
; .y_offsets
; db 1, 4, 9, 0, 7, 0, 8, 0
; db 8, 4, 0, 0, 2, 8, 0, 0
; .chr
; db $8D, $9D, $9C
; }

View File

@@ -106,4 +106,6 @@ LinkItem_Ether:
.return .return
CLC CLC
RTS RTS
} }
warnpc $07A4F6

View File

@@ -7,9 +7,23 @@ incbin gfx/deku_link.bin
; ============================================================================= ; =============================================================================
org $07B0AB
LinkItem_EvaluateMagicCost:
org $07A64B ; formerly Quake org $07A64B ; formerly Quake
LinkItem_DekuMask: LinkItem_DekuMask:
{ {
JSR Link_CheckNewY_ButtonPress : BCC .continue
LDX.b #$01
JSR LinkItem_EvaluateMagicCost : BCC .return
LDA.b #$0A : STA $5D
RTS
.continue
; Check for R button held ; Check for R button held
%CheckNewR_ButtonPress() : BEQ .return %CheckNewR_ButtonPress() : BEQ .return
@@ -26,6 +40,7 @@ LinkItem_DekuMask:
LDA #$35 : STA $BC ; put the mask on LDA #$35 : STA $BC ; put the mask on
LDA #$01 : STA $02B2 ; set the deku mask flag LDA #$01 : STA $02B2 ; set the deku mask flag
STA $02F5 ; Somaria platform flag, no dash.
BRA .return BRA .return
@@ -33,6 +48,7 @@ LinkItem_DekuMask:
STZ $5D STZ $5D
; Restore the shield ; Restore the shield
LDA $0AAF : STA.l $7EF35A LDA $0AAF : STA.l $7EF35A
STZ $02F5
%ResetToLinkGraphics() %ResetToLinkGraphics()
@@ -40,6 +56,19 @@ LinkItem_DekuMask:
RTS RTS
} }
; =========================================================
org $07E370
LinkHop_FindArbitraryLandingSpot:
org $07A6D6
LinkState_UsingQuake:
{
}
warnpc $07A779
org $318000 org $318000
; org $07A013 ; org $07A013
; JSL LinkItem_SlingshotPrepare ; JSL LinkItem_SlingshotPrepare

View File

@@ -17,32 +17,44 @@ UpdateGbcPalette:
GameboyLinkPalette: GameboyLinkPalette:
{ {
dw #$0000, #$7FFF, #$237E, #$B711, #$369E, #$14A5, #$01FF, #$1078, #$46FF dw #$0000, #$7FFF, #$237E, #$B711, #$369E, #$14A5, #$01FF, #$1078, #$46FF
dw #$22A2, #$3B68, #$0A4A, #$12EF, #$2A5C, #$1571, #$7A18, #$7FFF dw #$22A2, #$3B68, #$0A4A, #$12EF, #$2A5C, #$1571, #$7A18, #$7FFF
dw #$237E, #$B711, #$369E, #$14A5, #$01FF, #$1078, #$46FF, #$7E03 dw #$237E, #$B711, #$369E, #$14A5, #$01FF, #$1078, #$46FF, #$7E03
dw #$7691, #$2678, #$435C, #$1199, #$7A18, #$7FFF, #$237E, #$B711 dw #$7691, #$2678, #$435C, #$1199, #$7A18, #$7FFF, #$237E, #$B711
dw #$369E, #$14A5, #$01FF, #$1078, #$46FF, #$147F, #$457E, #$6DF3 dw #$369E, #$14A5, #$01FF, #$1078, #$46FF, #$147F, #$457E, #$6DF3
dw #$7EB9, #$2A5C, #$2227, #$7A18, #$7FFF, #$237E, #$B711, #$369E dw #$7EB9, #$2A5C, #$2227, #$7A18, #$7FFF, #$237E, #$B711, #$369E
dw #$14A5, #$01FF, #$1078, #$46FF, #$05FF, #$3B68, #$0A4A, #$12EF dw #$14A5, #$01FF, #$1078, #$46FF, #$05FF, #$3B68, #$0A4A, #$12EF
dw #$567E, #$1872, #$7A18, #$5276, #$0352 dw #$567E, #$1872, #$7A18, #$5276, #$0352
} }
org $07A9B1
LinkMode_MagicMirror:
{
JSL LinkState_GameboyForm
}
pullpc
LinkState_GameboyForm: LinkState_GameboyForm:
{ {
CLC SEP #$30
LDA $0FFF : BEQ .return ; not in dark world LDA $02B2 : CMP.b #$06 : BEQ .already_gbc
LDA $7EF357 : BEQ .return ; doesnt have the pearl
; %PlayerTransform() LDA $0FFF : BEQ .return ; not in dark world
%PlayerTransform()
JSL UpdateGbcPalette JSL UpdateGbcPalette
LDA #$3B : STA $BC ; change link's sprite LDA #$3B : STA $BC ; change link's sprite
LDA #$06 : STA $02B2 LDA #$06 : STA $02B2
BRA .return BRA .return
.return .already_gbc
LDA $BC : CMP.b #$06 : BNE .not_gbc %PlayerTransform()
LDA #$10 : STA $BC LDA #$10 : STA $BC
STZ $02B2
.not_gbc .not_gbc
CLC .return
JSL $07F1E6
RTL RTL
} }
pushpc

View File

@@ -53,6 +53,7 @@ LinkItem_ShovelAndFlute:
JMP LinkItem_WolfMask JMP LinkItem_WolfMask
} }
; warnpc $07A31F
; ============================================================================= ; =============================================================================

View File

@@ -26,7 +26,7 @@ UpdateZoraPalette:
REP #$30 ; change 16 bit mode REP #$30 ; change 16 bit mode
LDX #$001E LDX #$001E
.loop .loop
LDA.l zora_palette, X : STA $7EC6E0, X LDA.l zora_palette, X : STA $7EC6E0, X
DEX : DEX : BPL .loop DEX : DEX : BPL .loop
@@ -51,9 +51,13 @@ org $0998FC
; ============================================================================= ; =============================================================================
; Replaces Bombos medallion
org $07A569 org $07A569
LinkItem_ZoraMask: LinkItem_ZoraMask:
{ {
; No removing the mask whilst diving.
LDA $0AAB : BNE .return
; Check for R button held ; Check for R button held
%CheckNewR_ButtonPress() : BEQ .return %CheckNewR_ButtonPress() : BEQ .return
@@ -75,26 +79,17 @@ LinkItem_ZoraMask:
CLC CLC
RTS RTS
} }
print pc, " ==> LinkItem_ZoraMask ", pc
warnpc $07A5CE
; ============================================================================= ; =============================================================================
; End of LinkState_Swimming ; End of LinkState_Swimming
org $079781 org $079781
JSR LinkState_UsingZoraMask JSR LinkState_UsingZoraMask
RTS RTS
; End of LinkState_Default
org $0782D2
JSR LinkState_UsingZoraMask_dungeon_resurface
JSR $E8F0
CLC
RTS
; C2C3
org $07C307
JSR LinkState_UsingZoraMask_dungeon_stairs
RTS
; ============================================================================= ; =============================================================================
pullpc ; Bank07 Free Space from Deku Mask pullpc ; Bank07 Free Space from Deku Mask
@@ -109,10 +104,9 @@ LinkState_UsingZoraMask:
.normal .normal
; Return to normal state ; Return to normal state
STZ $55 STZ $55
STZ $5E ; Reset speed to normal
STZ $037B STZ $037B
STZ $0351 STZ $0351
LDA #$00 : STA $5E ; Reset speed to normal
STA $037B
JMP .return JMP .return
.swimming .swimming
@@ -189,7 +183,7 @@ LinkState_UsingZoraMask:
LDA #$08 LDA #$08
STA $5E ; Set the player speed STA $5E ; Set the player speed
STZ $0345 STZ $0345 ; Reset deep water flag
LDA #$01 LDA #$01
STA $0AAB ; Set the player underwater flag STA $0AAB ; Set the player underwater flag
@@ -200,6 +194,19 @@ LinkState_UsingZoraMask:
} }
} }
pushpc
; End of LinkState_Default
org $0782D2
JSR LinkState_UsingZoraMask_dungeon_resurface
JSR $E8F0
CLC
RTS
warnpc $078364
pullpc
.dungeon_resurface .dungeon_resurface
{ {
LDA $1B : BEQ .return_default ; We are in overworld actually LDA $1B : BEQ .return_default ; We are in overworld actually
@@ -214,7 +221,7 @@ LinkState_UsingZoraMask:
; Check if the ground level is safe ; Check if the ground level is safe
; Otherwise, eject the player back to the surface ; Otherwise, eject the player back to the surface
LDA $0114 : BNE .remove_dive : CLC LDA $0114 : BNE .remove_dive : CLC
CMP.b #$09 : BEQ .remove_dive ; CMP.b #$09 : BEQ .remove_dive
; Check the Y button and clear state if activated ; Check the Y button and clear state if activated
JSR Link_CheckNewY_ButtonPress : BCC .return_default JSR Link_CheckNewY_ButtonPress : BCC .return_default
@@ -244,6 +251,14 @@ LinkState_UsingZoraMask:
RTS RTS
} }
pushpc
; C2C3
org $07C307
JSR LinkState_UsingZoraMask_dungeon_stairs
RTS
pullpc
.dungeon_stairs .dungeon_stairs
{ {
@@ -257,19 +272,21 @@ LinkState_UsingZoraMask:
} }
print "==> LinkState_UsingZoraMask ", pc print "==> LinkState_UsingZoraMask ", pc
; =============================================================================
; TODO: Make this so it does not cancel if $0202 is still the same mask ; TODO: Make this so it does not cancel if $0202 is still the same mask
; corresponding to the form the player is in. ; corresponding to the form the player is in.
; Also, prevent this from canceling minish form. ; Also, prevent this from canceling minish form.
LinkState_ResetMaskAnimated: LinkState_ResetMaskAnimated:
{ {
LDA $02B2 : BEQ .no_mask LDA $02B2 : BEQ .no_mask
CMP #$05 : BEQ .no_mask CMP.b #$05 : BEQ .no_mask
CMP #$01 : BNE .transform CMP.b #$06 : BEQ .gbc_form
CMP.b #$02 : BEQ .no_mask
CMP #$01 : BNE .transform
; Restore the sword, shield, and bow override ; Restore the sword, shield, and bow override
LDA $0AA5 : STA.l $7EF359
LDA $0AAF : STA.l $7EF35A LDA $0AAF : STA.l $7EF35A
LDA #$00 : STA $7E03FC
.transform .transform
LDY.b #$04 : LDA.b #$23 LDY.b #$04 : LDA.b #$23
@@ -280,6 +297,7 @@ LinkState_ResetMaskAnimated:
JSL Palette_ArmorAndGloves JSL Palette_ArmorAndGloves
LDA #$10 : STA $BC LDA #$10 : STA $BC
.no_mask .no_mask
.gbc_form
RTL RTL
} }

View File

@@ -49,10 +49,7 @@ org $2E8000
HUD_Update: HUD_Update:
{ {
; JSL LinkState_GameboyForm
JSR HUD_UpdateItemBox JSR HUD_UpdateItemBox
.ignoreItemBox ; ALTERNATE ENTRY POINT .ignoreItemBox ; ALTERNATE ENTRY POINT
SEP #$30 SEP #$30
@@ -122,11 +119,10 @@ HUD_Update:
LDA $7EF36E : AND.w #$00FF : CLC : ADC #$0007 : AND.w #$FFF8 : TAX LDA $7EF36E : AND.w #$00FF : CLC : ADC #$0007 : AND.w #$FFF8 : TAX
; these four writes draw the magic power bar based on how much MP you have ; these four writes draw the magic power bar based on how much MP you have
LDA.l (MagicTilemap)+0, X : STA $7EC76A LDA.l (MagicTilemap)+0, X : STA $7EC76C
LDA.l (MagicTilemap)+2, X : STA $7EC76C LDA.l (MagicTilemap)+2, X : STA $7EC76E
LDA.l (MagicTilemap)+4, X : STA $7EC76E LDA.l (MagicTilemap)+4, X : STA $7EC770
LDA.l (MagicTilemap)+6, X : STA $7EC770 LDA.l (MagicTilemap)+6, X : STA $7EC772
LDA.l (MagicTilemap)+8, X : STA $7EC772
; Load how many rupees the player has ; Load how many rupees the player has
LDA $7EF362 LDA $7EF362
@@ -206,52 +202,31 @@ HUD_Update:
; ============================================================================= ; =============================================================================
Full = $3C5F Full = $3C5F
MostlyFull = $3C4D MostlyFull = $3C4D
KindaFull = $3C4E KindaFull = $3C4E
HalfEmpty = $3C4F HalfEmpty = $3C4F
AlmostEmpty = $3C5E AlmostEmpty = $3C5E
Empty = $3C4C Empty = $3C4C
New_MagicTilemap:
dw Empty, Empty, Empty, Empty, Empty
dw Empty, Empty, Empty, Empty, AlmostEmpty
dw Empty, Empty, Empty, Empty, HalfEmpty
dw Empty, Empty, Empty, Empty, KindaFull
dw Empty, Empty, Empty, Empty, MostlyFull
dw Empty, Empty, Empty, HalfEmpty, Full
MagicTilemap: MagicTilemap:
dw $3C4C, $3C4C, $3C4C, $3C4C, $3C4C dw Empty, Empty, Empty, Empty
dw $3C4C, $3C4C, $3C4C, $3C4C, $3C5F dw Empty, Empty, Empty, AlmostEmpty
dw $3C4C, $3C4C, $3C4C, $3C4C, $3C4C dw Empty, Empty, Empty, HalfEmpty
dw $3C4C, $3C4C, $3C4C, $3C4C, $3C4D dw Empty, Empty, Empty, KindaFull
dw $3C4C, $3C4C, $3C4C, $3C4C, $3C4E dw Empty, Empty, Empty, MostlyFull
dw $3C4C, $3C4C, $3C4C, $3C5F, $3C5F dw Empty, Empty, AlmostEmpty, Full
dw $3C4C, $3C4C, $3C4C, $3C4C, $3C5F dw Empty, Empty, HalfEmpty, Full
dw $3C4C, $3C4C, $3C4C, $3C4D, $3C5F dw Empty, Empty, KindaFull, Full
dw $3C4C, $3C4C, $3C4C, $3C4E, $3C5F dw Empty, Empty, MostlyFull, Full
dw $3C4D, $3C5F, $3C5F, $3C5F, $3C5F dw Empty, AlmostEmpty, Full, Full
dw $3C4E, $3C5F, $3C5F, $3C5F, $3C5F dw Empty, HalfEmpty, Full, Full
dw $3C4F, $3C5F, $3C5F, $3C5F, $3C5F dw Empty, KindaFull, Full, Full
dw $3C5E, $3C5F, $3C5F, $3C5F, $3C5F dw Empty, MostlyFull, Full, Full
dw $3C5F, $3C5F, $3C5F, $3C5F, $3C5F dw AlmostEmpty, Full, Full, Full
; value 0x80 aka 128 dw HalfEmpty, Full, Full, Full
dw KindaFull, Full, Full, Full
HUD_DrawMagicMeter: dw MostlyFull, Full, Full, Full
{
; check player magic (ranges from 0 to 0x7F)
; X = ((MP & 0xFF)) + 7) & 0xFFF8)
LDA $7EF36E : AND.w #$00FF : CLC : ADC #$0007 : AND.w #$FFF8 : TAX
.draw_magic_meter
LDA.l (MagicTilemap)+0, X : STA $7EC76A
LDA.l (MagicTilemap)+2, X : STA $7EC76C
LDA.l (MagicTilemap)+4, X : STA $7EC76E
LDA.l (MagicTilemap)+6, X : STA $7EC770
LDA.l (MagicTilemap)+8, X : STA $7EC772
}
; ============================================================================ ; ============================================================================
; *$6FAFD-$6FB90 LOCAL ; *$6FAFD-$6FB90 LOCAL
@@ -477,12 +452,11 @@ org $0DF6B1
; Mirror ; Mirror
org $0DF7C9 org $0DF7C9
dw $20F5, $20F5, $20F5, $20F5 ; No mirror dw $2C62, $2C63, $2C72, $2C73 ; Mirror
dw $2C62, $2C63, $2C72, $2C73 ; Mirror dw $2C62, $2C63, $2C72, $2C73 ; Mirror
; Byrna ; Byrna
org $0DF7A9 org $0DF7A9
dw $20F5, $20F5, $20F5, $20F5 ; No Byrna
dw $2CDC, $2CDD, $2CEC, $2CED ; Cane of Byrna dw $2CDC, $2CDD, $2CEC, $2CED ; Cane of Byrna
org $0DF731 org $0DF731
@@ -517,58 +491,59 @@ org $0DF811
; ============================================================================= ; =============================================================================
; $6FE77-$6FFC0 ; $6FE77-$6FFC0
org $0DFE77 org $0DFE77
HUD_Tilemap: HUD_Tilemap:
{ incbin tilemaps/hud.tilemap
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; {
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
; dw $207F, $207F, $207F, $207F
; magic bar top part ; ; magic bar top part
dw $200B, $200C, $200C, $200C, $200C, $200C ; dw $200B, $200C, $200C, $200C, $200C, $200C
; item frame top part ; ; item frame top part
dw $206C, $206D, $206E, $206F ; dw $206C, $206D, $206E, $206F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F ; dw $207F
; rupee icon key icon ; ; rupee icon key icon
dw $3CA8, $FCA8, $207F, $2071, $207F ; dw $3CA8, $FCA8, $207F, $2071, $207F
; magic bar ; ; magic bar
dw $201B, $344B ; dw $201B, $344B
dw $344B, $344B, $344B, $344B ; dw $344B, $344B, $344B, $344B
; item frame left part ; ; item frame left part
dw $20DE, $207F, $207F, $20DF ; dw $20DE, $207F, $207F, $20DF
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F
; magic bar bottom part ; ; magic bar bottom part
dw $A00B, $A00C ; dw $A00B, $A00C
dw $A00C, $A00C, $A00C, $A00C ; dw $A00C, $A00C, $A00C, $A00C
; item frame right part ; ; item frame right part
dw $20EE, $207F, $207F, $20EF ; dw $20EE, $207F, $207F, $20EF
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F
; item frame bottom part ; ; item frame bottom part
dw $207C, $207D, $207E, $201D ; dw $207C, $207D, $207E, $201D
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F ; dw $207F, $207F, $207F, $207F, $207F, $207F, $207F, $207F
dw $207F ; dw $207F
} ; }
; ============================================================================== ; ==============================================================================
@@ -661,4 +636,4 @@ FloorIndicator:
SEP #$30 SEP #$30
RTL RTL
} }

View File

@@ -5,61 +5,61 @@
Menu_ItemIndex: Menu_ItemIndex:
db $00 db $00
; Bow, Boomerang, Hookshot, Bombs, Powder, Bottle 1 ; Bow, Boomerang, Hookshot, Bombs, Powder, Bottle 1
db $03, $02, $0E, $01, $0A, $0B db $03, $02, $0E, $01, $0A, $0B
; Hammer, Lamp, Fire Rod, Ice Rod, Mirror, Bottle 2 ; Hammer, Lamp, Fire Rod, Ice Rod, Mirror, Bottle 2
db $04, $09, $05, $06, $14, $0B db $04, $09, $05, $06, $14, $0B
; Ocarina, Book, Somaria, Byrna, Feather, Bottle3 ; Ocarina, Book, Somaria, Byrna, Feather, Bottle3
db $08, $0C, $12, $0D, $07, $0B db $08, $0C, $12, $0D, $07, $0B
; Deku, Zora, Wolf, Bunny Hood, Stone Mask, Bottle4 ; Deku, Zora, Wolf, Bunny Hood, Stone Mask, Bottle4
db $11, $0F, $08, $10, $13, $0B db $11, $0F, $08, $10, $13, $0B
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; Decides which graphics is drawn ; Decides which graphics is drawn
Menu_AddressIndex: Menu_AddressIndex:
db $7EF340 ; bow db $7EF340 ; Bow
db $7EF341 ; boom db $7EF341 ; Boomerang
db $7EF342 ; hookshot db $7EF342 ; Hookshot
db $7EF343 ; bombs db $7EF343 ; Bombs
db $7EF344 ; powder db $7EF344 ; Powder
db $7EF35C ; bottle1 db $7EF35C ; Bottle 1
db $7EF34B ; hammer db $7EF34B ; Hammer
db $7EF34A ; lamp db $7EF34A ; Lamp
db $7EF345 ; firerod db $7EF345 ; Fire Rod
db $7EF346 ; icerod db $7EF346 ; Ice Rod
db $7EF353 ; mirror db $7EF353 ; Magic Mirror
db $7EF35D ; bottle2 db $7EF35D ; Bottle 2
db $7EF34C ; shovel 7EF34F db $7EF34C ; shovel 7EF34F
db $7EF34E ; book db $7EF34E ; Book
db $7EF350 ; somaria db $7EF350 ; Cane of Somaria
db $7EF351 ; byrna db $7EF351 ; Cane of Byrna
db $7EF34D ; feather db $7EF34D ; Roc's Feather
db $7EF35E ; bottle3 db $7EF35E ; Bottle 3
db $7EF348 ; deku mask db $7EF349 ; Deku Mask
db $7EF347 ; Zora Mask db $7EF347 ; Zora Mask
db $7EF349 ; Bunny Hood db $7EF358 ; Wolf Mask
db $7EF34C ; ocarina db $7EF348 ; Bunny Hood
db $7EF352 ; stone mask db $7EF352 ; Stone Mask
db $7EF35F ; bottle4 db $7EF35F ; Bottle #4
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
Menu_ItemCursorPositions: Menu_ItemCursorPositions:
dw menu_offset(6,2) ; bow dw menu_offset(6,2) ; bow
dw menu_offset(6,5) ; boom dw menu_offset(6,5) ; boom
dw menu_offset(6,8) ; hookshot dw menu_offset(6,8) ; hookshot
dw menu_offset(6,12) ; bombs dw menu_offset(6,12) ; bombs
dw menu_offset(6,15) ; deku mask dw menu_offset(6,15) ; deku mask
dw menu_offset(6,18) ; bottle1 dw menu_offset(6,18) ; bottle1
dw menu_offset(9,2) ; hammer dw menu_offset(9,2) ; hammer
dw menu_offset(9,5) ; lamp dw menu_offset(9,5) ; lamp
dw menu_offset(9,8) ; firerod dw menu_offset(9,8) ; firerod
dw menu_offset(9,12) ; icerod dw menu_offset(9,12) ; icerod
dw menu_offset(9,15) ; goron dw menu_offset(9,15) ; goron
dw menu_offset(9,18) ; bottle2 dw menu_offset(9,18) ; bottle2
dw menu_offset(12,2) ; shovel dw menu_offset(12,2) ; shovel
dw menu_offset(12,5) ; feather dw menu_offset(12,5) ; feather
@@ -80,14 +80,14 @@ Menu_ItemCursorPositions:
Menu_FindNextItem: Menu_FindNextItem:
{ {
LDY.w $0202 : INY LDY.w $0202 : INY
CPY.b #$19 : BCC .no_reset CPY.b #$19 : BCC .no_reset
LDY.b #$01 LDY.b #$01
.no_reset .no_reset
STY.w $0202 STY.w $0202
LDX.w Menu_AddressIndex-1, Y LDX.w Menu_AddressIndex-1, Y
LDA.l $7EF300, X LDA.l $7EF300, X
BEQ Menu_FindNextItem BEQ Menu_FindNextItem
RTS RTS
} }
@@ -95,13 +95,13 @@ Menu_FindNextItem:
Menu_FindPrevItem: Menu_FindPrevItem:
{ {
LDY.w $0202 : DEY : BNE .no_reset LDY.w $0202 : DEY : BNE .no_reset
LDY.b #$18 LDY.b #$18
.no_reset .no_reset
STY.w $0202 STY.w $0202
LDX.w Menu_AddressIndex-1, Y LDX.w Menu_AddressIndex-1, Y
LDA.l $7EF300, X LDA.l $7EF300, X
BEQ Menu_FindPrevItem BEQ Menu_FindPrevItem
RTS RTS
} }
@@ -109,14 +109,14 @@ Menu_FindPrevItem:
Menu_FindNextDownItem: Menu_FindNextDownItem:
{ {
LDA.w $0202 : CLC : ADC.b #$06 LDA.w $0202 : CLC : ADC.b #$06
CMP.b #$19 : BCC .no_reset CMP.b #$19 : BCC .no_reset
SBC.b #$18 SBC.b #$18
.no_reset .no_reset
TAY : STY.w $0202 TAY : STY.w $0202
LDX.w Menu_AddressIndex-1, Y LDX.w Menu_AddressIndex-1, Y
LDA.l $7EF300, X LDA.l $7EF300, X
BEQ Menu_FindNextItem BEQ Menu_FindNextItem
RTS RTS
} }
@@ -124,14 +124,14 @@ Menu_FindNextDownItem:
Menu_FindNextUpItem: Menu_FindNextUpItem:
{ {
LDA.w $0202 : SEC : SBC.b #$06 LDA.w $0202 : SEC : SBC.b #$06
BPL .no_reset : BNE .no_reset BPL .no_reset : BNE .no_reset
CLC : ADC.b #$18 CLC : ADC.b #$18
.no_reset .no_reset
TAY : STY.w $0202 TAY : STY.w $0202
LDX.w Menu_AddressIndex-1, Y LDX.w Menu_AddressIndex-1, Y
LDA.l $7EF300, X LDA.l $7EF300, X
BEQ Menu_FindNextItem BEQ Menu_FindNextItem
RTS RTS
} }
@@ -140,20 +140,20 @@ Menu_FindNextUpItem:
Menu_DeleteCursor: Menu_DeleteCursor:
{ {
REP #$30 REP #$30
LDX.w Menu_ItemCursorPositions-2, Y LDX.w Menu_ItemCursorPositions-2, Y
LDA.w #$20F5 LDA.w #$20F5
STA.w $1108, X STA.w $1108, X
STA.w $1148, X STA.w $1148, X
STA.w $114E, X STA.w $114E, X
STA.w $110E, X STA.w $110E, X
STA.w $11C8, X STA.w $11C8, X
STA.w $1188, X STA.w $1188, X
STA.w $118E, X STA.w $118E, X
STA.w $11CE, X STA.w $11CE, X
SEP #$30 SEP #$30
STZ $0207 STZ $0207
RTS RTS
} }
@@ -161,24 +161,157 @@ Menu_DeleteCursor:
Menu_InitItemScreen: Menu_InitItemScreen:
{ {
SEP #$30 SEP #$30
LDY.w $0202 : BNE .all_good LDY.w $0202 : BNE .all_good
.loop .loop
INY : CPY.b #$25 : BCS .bad INY : CPY.b #$25 : BCS .bad
LDX.w Menu_AddressIndex-1, Y LDX.w Menu_AddressIndex-1, Y
LDA.l $7EF300, X LDA.l $7EF300, X
BEQ .loop BEQ .loop
STY.w $0202 STY.w $0202
BRA .all_good BRA .all_good
.bad .bad
STZ.w $0202 STZ.w $0202
.all_good .all_good
STZ $0207 STZ $0207
LDA.b #$04 LDA.b #$04
STA.w $0200 STA.w $0200
RTS RTS
} }
; -----------------------------------------------------------------------------
Menu_AddressLong:
dl $7EF340 ; Bow
dl $7EF341 ; Boomerang
dl $7EF342 ; Hookshot
dl $7EF343 ; Bombs
dl $7EF344 ; Powder
dl $7EF35C ; Bottle 1
dl $7EF34B ; Hammer
dl $7EF34A ; Lamp
dl $7EF345 ; Fire Rod
dl $7EF346 ; Ice Rod
dl $7EF353 ; Magic Mirror
dl $7EF35D ; Bottle 2
dl $7EF34C ; shovel 7EF34F
dl $7EF34E ; Book
dl $7EF350 ; Cane of Somaria
dl $7EF351 ; Cane of Byrna
dl $7EF34D ; Roc's Feather
dl $7EF35E ; Bottle 3
dl $7EF349 ; Deku Mask
dl $7EF347 ; Zora Mask
dl $7EF358 ; Wolf Mask
dl $7EF348 ; Bunny Hood
dl $7EF352 ; Stone Mask
dl $7EF35F ; Bottle #4
GotoNextItem_Override:
{
; Load our currently equipped item, and move to the next one
; If we reach our limit (21), set it back to the bow and arrow slot.
LDA $0202 : INC A : CMP.b #$18 : BCC .dontReset
LDA.b #$01
.dontReset
; Otherwise try to equip the item in the next slot
STA $0202
RTS
}
DoWeHaveThisItem_Override:
{
LDY $0202
LDX.w Menu_AddressIndex-1, Y
LDA.l $7EF300, X
BNE .have_this_item
CLC
RTL
.have_this_item
SEC
RTL
}
TryEquipNextItem_Override:
{
.keep_looking
JSL GotoNextItem_Override
JSL DoWeHaveThisItem_Override : BCC .keep_looking
RTL
}
SearchForEquippedItem_Override:
{
SEP #$30
STY.w $0202
LDX.w Menu_AddressIndex-1, Y
LDA.l $7EF300, X
CMP.b #$00 : BNE .equippableItemAvailable
; In this case we have no equippable items
STZ $0202
STZ $0203
STZ $0204
.weHaveThatItem
RTL
.equippableItemAvailable
; Is there an item currently equipped (in the HUD slot)?
LDA $0202
BNE .alreadyEquipped
; If not, set the equipped item to the Bow and Arrow (even if we don't actually have it)
LDA.b #$01
STA $0202
.alreadyEquipped
; Checks to see if we actually have that item
; We're done if we have that item
JSR DoWeHaveThisItem_Override
BCS .weHaveThatItem
JMP TryEquipNextItem_Override
}
; -----------------------------------------------------------------------------
pushpc
org $0DDEB0
DoWeHaveThisItem:
{
JSL DoWeHaveThisItem_Override
RTS
}
org $0DDEE2
TryEquipNextItem:
JSL TryEquipNextItem_Override
RTS
org $0DE399
SearchForEquippedItem:
{
JSL SearchForEquippedItem_Override
RTS
}
warnpc $0DE3C7
pullpc

BIN
Menu/tilemaps/hud.tilemap Normal file

Binary file not shown.

View File

@@ -19,29 +19,31 @@
; 25 - N/A ; 25 - N/A
; 26 - N/A ; 26 - N/A
; 27 - N/A ; 27 - N/A
; 28 - Spike Subtype ; 28 - ZS Reserved
; 29 - New Sprite Jump Table ; 29 - ZSprite Jump Table
; 2A - Jump Feather ; 2A - Custom Sprites: Farore, Kydrog, Maku Tree, Mask Salesman
; 2B - Book of Secrets ; Deku Scrub, Anti Kirby, Village Dog, Minecart
; 2C - N/A ; Impa, Bug Net Kid
; 2B - Custom Items: Feather, Book, Sword Collect
; 2C - Dungeon Objects, Spike Subtype
; 2D - Menu ; 2D - Menu
; 2E - HUD ; 2E - HUD
; 2F - House Tag ; 2F - House Tag
; 30 - Custom Sprites and New Functions ; 30 -
; 31 - Deku Link Code ; 31 - Deku Link Code
; 32 - None ; 32 - Entrance Music Fix
; 33 - None ; 33 - Together Warp Tag
; 34 - Zora Link Code ; 34 - N/A
; 35 - Deku Link GFX ; 35 - Deku Link GFX
; 36 - Zora Link GFX ; 36 - Zora Link GFX
; 37 - Bunny Link GFX ; 37 - Bunny Link GFX
; 38 - Wolf Link GFX ; 38 - Wolf Link GFX
; 39 - Minish Link GFX ; 39 - Minish Link GFX
; 3A - StartupMasks, Palette_ArmorAndGloves, CgramAuxToMain ; 3A - StartupMasks, Palette_ArmorAndGloves, CgramAuxToMain
; 3B - N/A ; 3B - GBC Link GFX
; 3C - N/A ; 3C - N/A
; 3D - N/A ; 3D - N/A
; 3F - Boat GFX ; 3F - Load Custom GFX, Boat GFX
; ;
; Used Free RAM: ; Used Free RAM:
; $B6 - Cutscene State ; $B6 - Cutscene State
@@ -70,6 +72,12 @@ namespace Oracle
incsrc "Overworld/master_sword.asm" incsrc "Overworld/master_sword.asm"
print "End of master_sword.asm ", pc print "End of master_sword.asm ", pc
incsrc "Overworld/custom_gfx.asm"
print "End of custom_gfx.asm ", pc
incsrc "Overworld/maku_tree.asm"
print "End of Overworld/maku_tree.asm ", pc
print "" print ""
; --------------------------------------------------------- ; ---------------------------------------------------------
@@ -109,9 +117,6 @@ namespace Oracle
; --------------------------------------------------------- ; ---------------------------------------------------------
; Music ; Music
; incsrc "Music/stone_tower_temple.asm"
; print "End of stone_tower_temple.asm ", pc
incsrc "Music/frozen_hyrule.asm" incsrc "Music/frozen_hyrule.asm"
print "End of Music/frozen_hyrule.asm ", pc print "End of Music/frozen_hyrule.asm ", pc
@@ -123,9 +128,6 @@ namespace Oracle
incsrc "Music/entrance_music_fix.asm" incsrc "Music/entrance_music_fix.asm"
; incsrc "Music/boss_theme.asm"
; print "End of Music/boss_theme.asm ", pc
print "" print ""
; --------------------------------------------------------- ; ---------------------------------------------------------
@@ -145,20 +147,6 @@ namespace Oracle
print "" print ""
; ---------------------------------------------------------
; Graphics
print " -- Graphics -- "
print ""
incsrc "Graphics/boat_gfx.asm"
print "End of Graphics/boat_gfx.asm ", pc
incsrc "Events/maku_tree.asm"
print "End of Events/maku_tree.asm ", pc
print ""
; --------------------------------------------------------- ; ---------------------------------------------------------
; Sprites ; Sprites
@@ -166,7 +154,7 @@ namespace Oracle
print " -- Sprites -- " print " -- Sprites -- "
print "" print ""
incsrc "Sprites/sprites.asm" incsrc "Sprites/all_sprites.asm"
print "" print ""
@@ -186,24 +174,7 @@ namespace Oracle
print " -- Items -- " print " -- Items -- "
print "" print ""
incsrc "Items/bottle_net.asm" incsrc "Items/all_items.asm"
print "End of Items/bottle_net.asm ", pc
incsrc "Items/ocarina.asm"
print "End of Items/ocarina.asm ", pc
incsrc "Items/jump_feather.asm"
print "End of Items/jump_feather.asm ", pc
incsrc "Items/ice_rod.asm"
print "End of Items/ice_rod.asm ", pc
incsrc "Items/book_of_secrets.asm"
print "End of Items/book_of_secrets.asm ", pc
incsrc "Items/sword_collect.asm"
print "End of Items/sword_collect.asm ", pc
print "" print ""

View File

@@ -48,7 +48,7 @@ ApplyGraphics1:
RTS RTS
BoatBitmap: BoatBitmap:
incbin boat.bin incbin gfx/boat.bin
} }
; ============================================================================== ; ==============================================================================

View File

@@ -6,10 +6,10 @@ org $0EDE29
dw $01EF, $01E4, $00AD, $00B9 dw $01EF, $01E4, $00AD, $00B9
; Lost woods, Hyrule Castle Bridge, Entrance to Zora falls, and in Zora Falls... ; Lost woods, Hyrule Castle Bridge, Entrance to Zora falls, and in Zora Falls...
dw $002A, $0000, $000F, $0081 dw $002A, $002D, $000F, $0081
; Direction Link will face when he enters the special area ; Direction Link will face when he enters the special area
dw $0008, $0008, $0008, $0008 dw $0008, $0002, $0008, $0008
; Exit value for the special area. In Hyrule Magic these are those White markers. ; Exit value for the special area. In Hyrule Magic these are those White markers.
dw $0180, $0181, $0182, $0189 dw $0180, $0181, $0182, $0189

View File

@@ -189,7 +189,11 @@ Sprite_VillageDog_Main:
Dog_WagTailLeft: Dog_WagTailLeft:
{ {
%PlayAnimation(0,1, 8) %PlayAnimation(0,1, 8)
LDA $02B2 : CMP.b #$05 : BNE .not_minish
%ShowSolicitedMessage($18) : JMP .continue
.not_minish
%ShowSolicitedMessage($1B) %ShowSolicitedMessage($1B)
.continue
LDA.w SprTimerD, X : BNE + LDA.w SprTimerD, X : BNE +
%GotoAction(0) %GotoAction(0)
+ +
@@ -200,7 +204,11 @@ Sprite_VillageDog_Main:
Dog_WagTailRight: Dog_WagTailRight:
{ {
%PlayAnimation(11,12,8) %PlayAnimation(11,12,8)
LDA $02B2 : CMP.b #$05 : BNE .not_minish
%ShowSolicitedMessage($18) : JMP .continue
.not_minish
%ShowSolicitedMessage($1B) %ShowSolicitedMessage($1B)
.continue
LDA.w SprTimerD, X : BNE + LDA.w SprTimerD, X : BNE +
%GotoAction(0) %GotoAction(0)
+ +

View File

@@ -57,6 +57,8 @@ SprXRound = $0D70
SprCachedX = $0FD8 ; This doesn't need to be indexed with X it contains the 16bit position of the sprite SprCachedX = $0FD8 ; This doesn't need to be indexed with X it contains the 16bit position of the sprite
SprCachedY = $0FDA ; This doesn't need to be indexed with X it contains the 16bit position of the sprite SprCachedY = $0FDA ; This doesn't need to be indexed with X it contains the 16bit position of the sprite
DungeonMainCheck = $021B ;0x01
SpriteRanCheck = $8E ;0x01
org $09AE64 org $09AE64

View File

@@ -3,39 +3,38 @@
;================================================================= ;=================================================================
Sprite_CheckActive: Sprite_CheckActive:
{ {
; Deactivates the sprite in certain situations ; 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
LDA $0DD0, X : CMP.b #$09 : BNE .inactive .inactive
CLC
LDA $0FC1 : BNE .inactive RTL
LDA $11 : BNE .inactive .active
SEC
LDA $0CAA, X : BMI .active RTL
LDA $0F00, X : BEQ .active
.inactive
CLC
RTL
.active
SEC
RTL
} }
; make the sprite move X axis ; make the sprite move X axis
;=================================================================================================== ;==========================================================
Sprite_MoveHoriz: Sprite_MoveHoriz:
LDA.w $0D50,X : BEQ .no_velocity LDA.w $0D50, X : BEQ .no_velocity
ASL : ASL : ASL : ASL ASL : ASL : ASL : ASL
CLC : ADC.w $0D70,X : STA.w $0D70,X CLC : ADC.w $0D70,X : STA.w $0D70,X
LDY.b #$00 LDY.b #$00
LDA.w $0D50,X LDA.w $0D50, X
PHP : LSR : LSR : LSR : LSR : PLP PHP : LSR : LSR : LSR : LSR : PLP
BPL ++ BPL ++
ORA.b #$F0 ORA.b #$F0
DEY DEY
@@ -59,14 +58,14 @@ Sprite_Move:
; make the sprite move Y axis ; make the sprite move Y axis
;=================================================================================================== ;===================================================================================================
Sprite_MoveVert: Sprite_MoveVert:
LDA.w $0D40,X : BEQ .no_velocity LDA.w $0D40, X : BEQ .no_velocity
ASL : ASL : ASL : ASL ASL : ASL : ASL : ASL
CLC : ADC.w $0D60,X : STA.w $0D60,X CLC : ADC.w $0D60,X : STA.w $0D60,X
LDY.b #$00 LDY.b #$00
LDA.w $0D40,X LDA.w $0D40, X
PHP : LSR : LSR : LSR : LSR : PLP PHP : LSR : LSR : LSR : LSR : PLP
BPL ++ BPL ++
ORA.b #$F0 ORA.b #$F0
DEY DEY
@@ -82,12 +81,12 @@ Sprite_MoveVert:
;=================================================================================================== ;===================================================================================================
Sprite_MoveZ: Sprite_MoveZ:
Sprite_MoveAltitude: Sprite_MoveAltitude:
LDA.w $0F80,X : ASL : ASL : ASL : ASL LDA.w $0F80, X : ASL : ASL : ASL : ASL
CLC : ADC.w $0F90,X : STA.w $0F90,X CLC : ADC.w $0F90,X : STA.w $0F90,X
LDA.w $0F80,X : PHP LDA.w $0F80, X : PHP
LSR : LSR : LSR : LSR LSR : LSR : LSR : LSR
PLP : BPL .positive PLP : BPL .positive
ORA.b #$F0 ORA.b #$F0
@@ -107,11 +106,11 @@ Sprite_BounceTowardPlayer:
DEC.w $0F80,X : DEC.w $0F80,X DEC.w $0F80,X : DEC.w $0F80,X
LDA.w $0F70,X : BPL .aloft LDA.w $0F70, X : BPL .aloft
STZ.w $0F70,X STZ.w $0F70, X
LDA.b $08 : STA.w $0F80,X ; set height from 08 LDA.b $08 : STA.w $0F80, X ; set height from 08
;LDA.b $09 ;LDA.b $09
LDA.b #$20 LDA.b #$20
@@ -121,7 +120,7 @@ Sprite_BounceTowardPlayer:
LDA.b #$21 : JSL Sound_SetSfx2PanLong LDA.b #$21 : JSL Sound_SetSfx2PanLong
.aloft .aloft
LDA.w $0F70,X : BEQ .dontmove LDA.w $0F70, X : BEQ .dontmove
JSL Sprite_Move JSL Sprite_Move
@@ -129,41 +128,124 @@ Sprite_BounceTowardPlayer:
RTL RTL
Sprite_BounceFromTileCollision: Sprite_BounceFromTileCollision:
JSL Sprite_CheckTileCollision : AND.b #$03 : BEQ ++ JSL Sprite_CheckTileCollision : AND.b #$03 : BEQ ++
LDA.w $0D50,X : EOR.b #$FF : INC : STA.w $0D50,X LDA.w $0D50,X : EOR.b #$FF : INC : STA.w $0D50,X
INC.w $0ED0,X INC.w $0ED0, X
++ LDA.w $0E70,X : AND.b #$0C : BEQ ++ ++ LDA.w $0E70, X : AND.b #$0C : BEQ ++
LDA.w $0D40,X : EOR.b #$FF : INC : STA.w $0D40,X LDA.w $0D40,X : EOR.b #$FF : INC : STA.w $0D40,X
INC.w $0ED0,X INC.w $0ED0, X
++ RTL ++ RTL
; ============================================================================== ; ==============================================================================
Intro_Dungeon_Main:
{
;test to see if we are at a place where a guardian is present
LDA $0E20 : CMP.b #$92 : BNE .notGuardian
LDA $0E30 : BEQ .notGuardian
LDA $1C : AND.b #$FE : STA $1C ;turn off BG2 (Body)
;free ram used to check if the sprite ran this frame, if 0, it didn't run
LDA.b SpriteRanCheck : BEQ .didNotRun
LDA $1C : ORA.b #$01 : STA $1C ;turn on BG2 (Body)
.didNotRun
STZ.b SpriteRanCheck
.notGuardian
REP #$21 : LDA.w DungeonMainCheck : BNE .intro ;<- load that free ram you are using if it's not zero then we're doing intro thing
LDA $E2 : RTL ;return to normal intro
.intro
PLA ;Pop 2byte from stack
;skip all the BGs codes
SEP #$20
PLA ;Pop 1 byte from the stack
JSL $07F0AC ; $3F0AC IN ROM. Handle the sprites of pushed blocks.
JSL $068328 ;Sprite_Main
JSL $0DA18E ;PlayerOam_Main
JSL $0DDB75 ;HUD.RefillLogicLong
JML $0AFD0C ;FloorIndicator ; $57D0C IN ROM. Handles HUD floor indicator
}
;uses $00 as the Y coordinate and $02 as the X
MoveCamera:
{
REP #$20
;move the camera up or down until a point is reached
LDA $E8 : CMP $00 : BEQ .dontMoveY ;if equals that point, dont move y
BCS .CameraBelowPointY
;CameraAbovePoint
ADC.w #$0001 : STA $E8 : STA $E6 : STA $0122 : STA $0124 ;move the camera down by 1
BRA .dontMoveY
.CameraBelowPointY
SEC : SBC.w #$0001 : STA $E8 : STA $E6 : STA $0122 : STA $0124 ;move the camera up by 1
.dontMoveY
;move the camera right or left until a point is reached
LDA $E2 : CMP.w $02 : BEQ .dontMoveX ;if equals that point, dont move x
BCS .CameraBelowPointX ;left
;CameraAbovePoint ;right
ADC.w #$0001 : STA $E2 : STA $E0 : STA $011E : STA $0120 ;move the camera right by 1
BRA .dontMoveX
.CameraBelowPointX
SEC : SBC.w #$0001 : STA $E2 : STA $E0 : STA $011E : STA $0120 ;move the camera left by 1
.dontMoveX
;if link is outside of a certain range of the camera, make him dissapear so he doesnt appear on the other side
LDA $20 : SEC : SBC $E8 : CMP.w #$00E0 : BCS .MakeLinkInvisible
LDA $22 : SEC : SBC $E2 : CMP.w #$00E0 : BCS .MakeLinkInvisible
SEP #$20
LDA.b #$00 : STA $4B ;make link visible
RTS
.MakeLinkInvisible
SEP #$20
LDA.b #$0C : STA $4B ;make link invisible
RTS
}
MovieEffectTimer = $7EF500 ;0x01 MovieEffectTimer = $7EF500 ;0x01
;these need to be the same as the next set ;these need to be the same as the next set
;used to do the HDMA ;used to do the HDMA
MovieEffectArray = $F900 ;0x0F MovieEffectArray = $F900 ;0x0F
MovieEffectBank = $7E MovieEffectBank = $7E
;used to set the actual values ;used to set the actual values
MovieEffect0 = $7EF900 ;0x01 MovieEffect0 = $7EF900 ;0x01
MovieEffect1 = $7EF901 ;0x01 MovieEffect1 = $7EF901 ;0x01
MovieEffect2 = $7EF902 ;0x01 MovieEffect2 = $7EF902 ;0x01
MovieEffect3 = $7EF903 ;0x01 MovieEffect3 = $7EF903 ;0x01
MovieEffect4 = $7EF904 ;0x01 MovieEffect4 = $7EF904 ;0x01
MovieEffect5 = $7EF905 ;0x01 MovieEffect5 = $7EF905 ;0x01
MovieEffect6 = $7EF906 ;0x01 MovieEffect6 = $7EF906 ;0x01
MovieEffect7 = $7EF907 ;0x01 MovieEffect7 = $7EF907 ;0x01
MovieEffect8 = $7EF908 ;0x01 MovieEffect8 = $7EF908 ;0x01
MovieEffect9 = $7EF909 ;0x01 MovieEffect9 = $7EF909 ;0x01
MovieEffectA = $7EF90A ;0x01 MovieEffectA = $7EF90A ;0x01
MovieEffectB = $7EF90B ;0x01 MovieEffectB = $7EF90B ;0x01
MovieEffectC = $7EF90C ;0x01 MovieEffectC = $7EF90C ;0x01
MovieEffectD = $7EF90D ;0x01 MovieEffectD = $7EF90D ;0x01
MovieEffectE = $7EF90E ;0x01 MovieEffectE = $7EF90E ;0x01
SetupMovieEffect: SetupMovieEffect:
{ {
@@ -212,9 +294,9 @@ MovieEffect:
LDX #$00 : STX $4351 ;Set register to 00 ($21 00) LDX #$00 : STX $4351 ;Set register to 00 ($21 00)
LDA.w #MovieEffectArray : STA $4352 ;set address of the hdma table LDA.w #MovieEffectArray : STA $4352 ;set address of the hdma table
LDX.b #MovieEffectBank : STX $4354 ;set the bank of HDMA table LDX.b #MovieEffectBank : STX $4354 ;set the bank of HDMA table
SEP #$20 SEP #$20
LDA.b #$20 : STA $9B ;Do the HDMA instead of $420C LDA.b #$20 : STA $9B ;Do the HDMA instead of $420C
; LDA $9B : ORA #$20 : STA $9B ; LDA $9B : ORA #$20 : STA $9B
@@ -227,5 +309,5 @@ MovieEffect:
db $50, $0F ;for $A0 line set screen brightness to 15 full db $50, $0F ;for $A0 line set screen brightness to 15 full
db $50, $0F ;for $A0 line set screen brightness to 15 full db $50, $0F ;for $A0 line set screen brightness to 15 full
db $3F, $00 ;for $20 line set screen brightness to 0 db $3F, $00 ;for $20 line set screen brightness to 0
db $00 ;end the HDMA db $00 ;end the HDMA
} }

View File

@@ -25,7 +25,7 @@ incsrc ZSpriteLib/sprite_new_table.asm
;============================================================================== ;==============================================================================
org $308000 org $2A8000
incsrc ZSpriteLib/sprite_new_functions.asm incsrc ZSpriteLib/sprite_new_functions.asm
incsrc "Sprites/farore.asm" incsrc "Sprites/farore.asm"
@@ -52,5 +52,18 @@ print "End of anti_kirby.asm ", pc
incsrc "Sprites/VillageDog/village_dog.asm" incsrc "Sprites/VillageDog/village_dog.asm"
print "End of village_dog.asm ", pc print "End of village_dog.asm ", pc
incsrc "Sprites/Minecart/minecart.asm" incsrc "Sprites/minecart.asm"
print "End of minecart.asm ", pc print "End of minecart.asm ", pc
incsrc "Sprites/twinrova.asm"
incsrc "Sprites/portal_sprite.asm"
incsrc "Sprites/impa.asm"
print "End of impa.asm ", pc
incsrc "Sprites/bug_net_kid.asm"
warnpc $2B8000

56
Sprites/bug_net_kid.asm Normal file
View File

@@ -0,0 +1,56 @@
org $07F4D0
Sprite_CheckIfPlayerPreoccupied:
org $06F154
Sprite_CheckDamageToPlayer_same_layer:
org $06B962
BugNetKid_Resting:
{
JSL Sprite_CheckIfPlayerPreoccupied : BCS .dont_awaken
JSR Sprite_CheckDamageToPlayer_same_layer : BCC .dont_awaken
LDA $7EF34C
CMP.b #$01 : BCC .no_ocarina
INC $0D80, X
INC $02E4
.dont_awaken
RTS
.no_ocarina
; "... Do you have a bottle to keep a bug in? ... I see. You don't..."
LDA.b #$04
LDY.b #$01
JSL Sprite_ShowSolicitedMessageIfPlayerFacing
RTS
}
org $06B9C6
BugNetKid_GrantBugNet:
{
; Give Link the Boots
LDY.b #$4B
STZ $02E9
PHX
JSL Link_ReceiveItem
PLX
INC $0D80, X
STZ $02E4
RTS
}

5
Sprites/impa.asm Normal file
View File

@@ -0,0 +1,5 @@
; Impa Fix
org $05EBCF
LDA $7EF359 : CMP.b #$04

View File

@@ -29,8 +29,6 @@
!ImpervSwordHammer = 00 ; 01 = Impervious to sword and hammer attacks !ImpervSwordHammer = 00 ; 01 = Impervious to sword and hammer attacks
!Boss = 00 ; 00 = normal sprite, 01 = sprite is a boss !Boss = 00 ; 00 = normal sprite, 01 = sprite is a boss
!HVelocity = $06
;============================================================================== ;==============================================================================
%Set_Sprite_Properties(Sprite_Minecart_Prep, Sprite_Minecart_Long) %Set_Sprite_Properties(Sprite_Minecart_Prep, Sprite_Minecart_Long)
@@ -59,21 +57,27 @@ Sprite_Minecart_Prep:
{ {
PHB : PHK : PLB PHB : PHK : PLB
; Adjust the Y position so it aligns with the tracks.
LDA $0D00, X : SEC : SBC.b #$04 : STA $0D00, X
PLB PLB
RTL RTL
} }
;============================================================================== ;==============================================================================
!MinecartSpeed = 10
print "Minecart: ", pc
Sprite_Minecart_Main: Sprite_Minecart_Main:
{ {
LDA.w SprAction, X ; Load the SprAction LDA.w SprAction, X ; Load the SprAction
JSL UseImplicitRegIndexedLocalJumpTable ; Goto the SprAction we are currently in JSL UseImplicitRegIndexedLocalJumpTable ; Goto the SprAction we are currently in
dw Minecart_Adjust dw Minecart_Adjust
dw Minecart_Waiting dw Minecart_Waiting
dw Minecart_Moving dw Minecart_MoveHorizontal
dw Minecart_Moving2 dw Minecart_MoveVertical
Minecart_Adjust: Minecart_Adjust:
{ {
@@ -86,7 +90,6 @@ Sprite_Minecart_Main:
LDA #$00 : STA $0CD2, X LDA #$00 : STA $0CD2, X
LDA #$00 : STA $0B6B, X ;Set interactive hitbox? LDA #$00 : STA $0B6B, X ;Set interactive hitbox?
LDA #$40 : STA $0E00, X LDA #$40 : STA $0E00, X
LDA #$FF : STA $021B
INC $0D80, X INC $0D80, X
@@ -99,151 +102,173 @@ Sprite_Minecart_Main:
JSR CheckIfPlayerIsOn : BCC .not_on_platform JSR CheckIfPlayerIsOn : BCC .not_on_platform
;Cancel Falling ;Cancel Falling
JSL Player_HaltDashAttack JSL Player_HaltDashAttack
LDA #$00 : STA $5D : STA $5B : STA $57 : STA $5E LDA #$02 : STA $02F5
STA $59 LDA $0FDA : SEC : SBC #$0B : STA $20
; LDA #$01 : STA DungeonMainCheck
%GotoAction(2)
RTS
.not_on_platform .not_on_platform
LDA $0E00, X : BNE + ;wait before moving LDA $0E00, X : BNE + ;wait before moving
LDA #$10 : STA $0E00, X ;Wait before checking first tile on ground! LDA #$10 : STA $0E00, X ;Wait before checking first tile on ground!
INC $0D80, X INC $0D80, X
LDA.b #$01 : STA $041A LDA.b #$01 : STA $041A
+ +
RTS RTS
} }
Minecart_Moving: ;Check for pixel X+24, Y+16 if tileid = 0D41 print pc
Minecart_MoveHorizontal:
{ {
JSL Sprite_Move %PlayAnimation(0,1,8)
LDA $5D : CMP #$02 : BNE + LDA.b #-!MinecartSpeed : STA $0D50, X
RTS JSL Sprite_MoveHoriz
+
LDA $021B : CMP #$FF : BEQ .NoPlatformSetted ;if == FF then go check if we're on this platform
CPX $021B : BNE .DoNotCheckThisPlatform ;Is the platform the one we're currently standing on?
LDA #$FF : STA $021B
.NoPlatformSetted
JSR CheckIfPlayerIsOn : BCC .NotOnPlatform
STX $021B ;We are on that platform so put that in
; Make Link move with the minecart
LDA SprX, X : STA $22
LDY $039D ;Load Hookshot slot JSR DragPlayer
LDA $0C4A, Y : CMP #$1F : BNE .noHookshot
LDA #$13 : STA $5D ;we're in hookshot mode then!! ; Set Minecart sprite coords to look for tile attributes
.noHookshot LDA.w $0D00, X : STA.b $00
LDA.w $0D20, X : STA.b $01
LDA $5D : CMP #$13 : BNE .dontstopPlatform ;Hookshotting!! stop the platform
;Prevent platform from moving LDA.w $0D10, X : STA.b $02
STZ $0D50, X : STZ $0D40, X LDA.w $0D30, X : STA.b $03
REP #$20
STZ $0B7E : STZ $0B7C LDA.b #$00 : JSL $06E87B
SEP #$20
;Prevent timers from going down as well ; Check for Top Right Corner Tile
INC $0E10, X LDA $0FA5 : CMP.b #$B1 : BNE .continue
INC $0E00, X %StartOnFrame(2)
LDA #$00 : STA $0D50, X ; Reset X Speed
INC $0D80, X
RTS RTS
.dontstopPlatform .continue
PHX
JSL $07E6A6 ; Link_HandleMovingAnimation_FullLongEntry
JSL $07F42F ; HandleIndoorCameraAndDoors_Long
JSL Player_HaltDashAttack JSL Player_HaltDashAttack
;Cancel Falling PLX
STZ $5D : STZ $5B : STZ $57 : STZ $5E : STZ $59
LDA $0E10, X : BNE .Waiting
JSR CheckPlayerDirection
.DoNotCheckThisPlatform
.NotOnPlatform
LDA $5B : CMP #$02 : BEQ .Check5D ;IF $5B == 2 then we're falling!
BRA .skip5D
.Check5D
LDA $5D : CMP #$01 : BEQ .Falling ;Branch if we're falling!
.skip5D
LDA $0E10, X : BNE .Waiting
STZ $0D50, X : STZ $0D40, X ;Not Needed probably
LDY $0DB0, X ;Load Directtion
LDA SpeedTableX, Y : STA $0D50, X
LDA SpeedTableY, Y : STA $0D40, X
JSR Sprite_Move
JSR GetTileIDAtPosition
+
.Waiting
RTS
.Falling
;Keep Timer incremented
INC $0E10, X
INC $0E00, X
RTS RTS
} }
Minecart_Moving2: ;Check for pixel X+24, Y+16 if tileid = 0D41 ;04 Minecart_MoveVertical:
{ {
LDY $0DB0, X ;Load Directtion %PlayAnimation(2,3,8)
LDA SpeedTableX, Y : STA $0D50, X LDA.b #-!MinecartSpeed : STA $0D40, X
LDA SpeedTableY, Y : STA $0D40, X
JSR Sprite_Move JSL Sprite_MoveVert
JSR GetTileIDAtPosition LDA SprY, X : SEC : SBC #$04 : STA $20
LDA $0FD8 : CLC : ADC #$02 : STA $22 ; X
REP #$20 JSR DragPlayer
LDA $0FD8 : CLC : ADC #$0010 : STA $00
LDA $0FDA : CLC : ADC #$0008 : STA $02
SEP #$20
DEX
LDA $00 : STA $0D10, X ;X low
LDA $01 : STA $0D30, X ;X High
LDA $02 : STA $0D00, X ;Y low
LDA $03 : STA $0D20, X ;Y high
INX LDA.w $0D00, X : STA.b $00
RTS LDA.w $0D20, X : STA.b $01
LDA.w $0D10, X : STA.b $02
LDA.w $0D30, X : STA.b $03
LDA.b #$00 : JSL $06E87B
LDA $0FA5 : CMP.b #$B4 : BNE .continue
LDA $0FDA : SEC : SBC #$0B : STA $20
%GotoAction(2)
RTS
.continue
PHX
JSL $07E6A6 ; Link_HandleMovingAnimation_FullLongEntry
JSL $07F42F ; HandleIndoorCameraAndDoors_Long
JSL Player_HaltDashAttack
PLX
RTS
} }
} }
;Up, Right, Down, Left DragPlayer:
SpeedTableX:
db 00, 16, 00, -16
SpeedTableY:
db -16, 00, 16, 00
SpeedTableWordX:
dw 00, 01, 00, -01
SpeedTableWordY:
dw -01, 00, 01, 00
CheckPlayerDirection:
{ {
REP #$20 LDY.w $0DE0, X
STZ $0B7E : STZ $0B7C ; Not needed propbably LDA.w DragPlayer_drag_x_low, Y : CLC : ADC.w $0B7C : STA $0B7C
LDA.w DragPlayer_drag_x_high, Y : ADC.w $0B7D : STA $0B7D
LDA $0DB0, X : AND #$00FF : ASL : TAY ;Load Direction*2 LDA.w DragPlayer_drag_y_low, Y : CLC : ADC.w $0B7E : STA $0B7E
LDA SpeedTableWordX, Y : STA $0B7C LDA.w DragPlayer_drag_y_high, Y : ADC.w $0B7F : STA $0B7F
LDA SpeedTableWordY, Y : STA $0B7E
SEP #$20 .SomariaPlatform_DragLink
REP #$20
LDA $0FD8 : SEC : SBC.w #$0008 : CMP $22 : BEQ .x_done
BPL .x_too_low
DEC $0B7C
BRA .x_done
.x_too_low
INC $0B7C
.x_done
; Changing the modifier adjusts links position in the cart
LDA $0FDA : SEC : SBC.w #$0008 : CMP $20 : BEQ .y_done
BPL .y_too_low
DEC $0B7E
BRA .y_done
.y_too_low
INC $0B7E
.y_done
SEP #$30
RTS RTS
; .drag_x_high
; db 0, 0, -1, 0, -1
; .drag_x_low
; db 0, 0, -1, 1, -1, 1, 1
; .drag_y_low
; db -1, 1, 0, 0, -1, 1, -1, 1
; .drag_y_high
; db -1, 0, 0, 0, -1, 0, -1, 0
.drag_x_high
db 0, 0, -1, 0
.drag_x_low
db 0, 0, -1, 1
.drag_y_low
db -1, 1, 0, 0
.drag_y_high
db -1, 0, 0, 0
} }
CheckIfPlayerIsOn: CheckIfPlayerIsOn:
{ {
REP #$20 REP #$20
LDA $22 : CLC : ADC #$0009 : CMP $0FD8 : BCC .OutsideLeft LDA $22 : CLC : ADC #$0009 : CMP $0FD8 : BCC .OutsideLeft
LDA $22 : SEC : SBC #$002C : CMP $0FD8 : BCS .OutsideRight LDA $22 : SEC : SBC #$0009 : CMP $0FD8 : BCS .OutsideRight
LDA $20 : CLC : ADC #$0012 : CMP $0FDA : BCC .OutsideUp LDA $20 : CLC : ADC #$0012 : CMP $0FDA : BCC .OutsideUp
LDA $20 : SEC : SBC #$0016 : CMP $0FDA : BCS .OutsideDown LDA $20 : SEC : SBC #$0012 : CMP $0FDA : BCS .OutsideDown
SEP #$21 SEP #$21
RTS ;Return with carry setted RTS ;Return with carry setted

431
Sprites/portal_sprite.asm Normal file
View File

@@ -0,0 +1,431 @@
; =========================================================
; Portal Sprite
; =========================================================
!SPRID = $B6 ; 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
!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 Portal (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
%Set_Sprite_Properties(Sprite_Portal_Prep, Sprite_Portal_Long)
; =========================================================
; Long Sprite Code
; =========================================================
Sprite_Portal_Long:
{
PHB : PHK : PLB
JSR Sprite_Portal_Draw ; Call the draw code
JSL Sprite_CheckActive ; Check if game is not paused
BCC .SpriteIsNotActive ; Skip Main code is sprite is innactive
JSR Sprite_Portal_Main ; Call the main sprite code
.SpriteIsNotActive
PLB ; Get back the databank we stored previously
RTL ; Go back to original code
}
; =========================================================
; Sprite Initialization code
; =========================================================
Sprite_Portal_Prep:
{
PHB : PHK : PLB
; Persist outside of camera
LDA SprHitbox, X : AND.b #$20 : STA SprHitbox, X
PLB
RTL
}
; =========================================================
; FREE RAM: 0x08
BluePortal_X = $7E06F8
BluePortal_Y = $7E06F9
OrangePortal_X = $7E06FA
OrangePortal_Y = $7E06FB
BlueActive = $7E06FC
OrangeActive = $7E06FD
; OrangePortal_Y_Low = $7E06FE
; OrangePortal_Y_High = $7E06FF
OrangeSpriteIndex = $7E0633
BlueSpriteIndex = $7E0632
; =========================================================
; Main Sprite Code
; =========================================================
Sprite_Portal_Main:
{
LDA.w SprAction, X
JSL UseImplicitRegIndexedLocalJumpTable
dw StateHandler
dw BluePortal
dw OrangePortal
dw BluePortal_WarpDungeon
dw OrangePortal_WarpDungeon
dw BluePortal_WarpOverworld
dw OrangePortal_WarpOverworld
StateHandler:
{
JSR CheckForDismissPortal
LDA $7E0FA6 : BNE .BluePortal
LDA #$01 : STA $0307
TXA : STA OrangeSpriteIndex
LDA $0D00, X : STA OrangePortal_X
LDA $0D10, X : STA OrangePortal_Y
%GotoAction(2)
RTS
.BluePortal
LDA #$02 : STA $0307
TXA : STA BlueSpriteIndex
LDA $0D00, X : STA BluePortal_X
LDA $0D10, X : STA BluePortal_Y
%GotoAction(1)
RTS
}
BluePortal:
{
%StartOnFrame(0)
%PlayAnimation(0,1,8)
LDA $11 : CMP.b #$2A : BNE .not_warped_yet
STZ $11
.not_warped_yet
CLC
LDA SprTimerD, X : BNE .NoOverlap
JSR Link_SetupHitBox
JSL $0683EA ; Sprite_SetupHitbox_long
JSL CheckIfHitBoxesOverlap : BCC .NoOverlap
CLC
LDA $1B : BEQ .outdoors
%GotoAction(3) ; BluePortal_WarpDungeon
.NoOverlap
RTS
.outdoors
%GotoAction(5) ; BluePortal_WarpOverworld
RTS
}
OrangePortal:
{
%StartOnFrame(2)
%PlayAnimation(2,3,8)
LDA $11 : CMP.b #$2A : BNE .not_warped_yet
STZ $11
.not_warped_yet
CLC
LDA SprTimerD, X : BNE .NoOverlap
JSR Link_SetupHitBox
JSL $0683EA ; Sprite_SetupHitbox_long
JSL CheckIfHitBoxesOverlap : BCC .NoOverlap
CLC
; JSL $01FF28 ; Player_CacheStatePriorToHandler
LDA $1B : BEQ .outdoors
%GotoAction(4) ; OrangePortal_WarpDungeon
.NoOverlap
RTS
.outdoors
%GotoAction(6) ; OrangePortal_WarpOverworld
RTS
}
BluePortal_WarpDungeon:
{
LDA $7EC184 : STA $20
LDA $7EC186 : STA $22
LDA $7EC188 : STA $0600
LDA $7EC18A : STA $0604
LDA $7EC18C : STA $0608
LDA $7EC18E : STA $060C
; LDA $7EC190 : STA $0610
; LDA $7EC192 : STA $0612
; LDA $7EC194 : STA $0614
; LDA $7EC196 : STA $0616
PHX
LDA OrangeSpriteIndex : TAX
LDA #$40 : STA SprTimerD, X
LDA $0D00, X : STA $7EC184
STA BluePortal_Y
LDA $0D10, X : STA $7EC186
STA BluePortal_X
PLX
LDA #$14 : STA $11
%GotoAction(1) ; Return to BluePortal
RTS
}
OrangePortal_WarpDungeon:
{
LDA $7EC184 : STA $20
LDA $7EC186 : STA $22
; Camera Scroll Boundaries
LDA $7EC188 : STA $0600 ; Small Room North
LDA $7EC18A : STA $0604 ; Small Room South
LDA $7EC18C : STA $0608 ; Small Room West
LDA $7EC18E : STA $060C ; Small Room South
; LDA $7EC190 : STA $0610
; LDA $7EC192 : STA $0612
; LDA $7EC194 : STA $0614
; LDA $7EC196 : STA $0616
PHX
LDA BlueSpriteIndex : TAX
LDA #$40 : STA SprTimerD, X
LDA $0D00, X : STA $7EC184
STA OrangePortal_Y
LDA $0D10, X : STA $7EC186
STA OrangePortal_X
PLX
LDA #$14 : STA $11
%GotoAction(2) ; Return to OrangePortal
RTS
}
BluePortal_WarpOverworld:
{
LDA OrangePortal_X : STA $20
LDA OrangePortal_Y : STA $22
LDA $7EC190 : STA $0610
LDA $7EC192 : STA $0612
LDA $7EC194 : STA $0614
LDA $7EC196 : STA $0616
JSL $07E9D3 ; ApplyLinksMovementToCamera
PHX ; Infinite loop prevention protocol
LDA OrangeSpriteIndex : TAX
LDA #$40 : STA SprTimerD, X
PLX
LDA #$01 : STA $5D
;LDA #$2A : STA $11
%GotoAction(1) ; Return to BluePortal
RTS
}
OrangePortal_WarpOverworld:
{
LDA BluePortal_X : STA $20
LDA BluePortal_Y : STA $22
LDA $7EC190 : STA $0610
LDA $7EC192 : STA $0612
LDA $7EC194 : STA $0614
LDA $7EC196 : STA $0616
JSL $07E9D3 ; ApplyLinksMovementToCamera
PHX
LDA BlueSpriteIndex : TAX
LDA #$40 : STA SprTimerD, X
PLX
LDA #$01 : STA $5D
;LDA #$2A : STA $11
%GotoAction(2) ; Return to BluePortal
RTS
}
}
CheckForDismissPortal:
{
LDA $06FE : CMP.b #$02 : BCC .return
LDA $7E0FA6 : BEQ .DespawnOrange ; Check what portal is spawning next
PHX
LDA BlueSpriteIndex : TAX
STZ.w $0DD0, X
PLX
JMP .return
.DespawnOrange
PHX
LDA OrangeSpriteIndex : TAX
STZ.w $0DD0, X
PLX
.return
INC $06FE ; This ticker needs to be reset when transitioning rooms and maps.
RTS
}
;==========================================================
Sprite_Portal_Draw:
{
JSL Sprite_PrepOamCoord
JSL Sprite_OAM_AllocateDeferToPlayer
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
; Draw Data
.start_index
db $00, $01, $02, $03
.nbr_of_tiles
db 0, 0, 0, 0
.x_offsets
dw 0
dw 0
dw 0
dw 0
.y_offsets
dw 0
dw 0
dw 0
dw 0
.chr
db $EE
db $EE
db $EE
db $EE
.properties
db $34
db $74
db $32
db $72
.sizes
db $02
db $02
db $02
db $02
}
; *$37705-$3772E LOCAL
Link_SetupHitBox:
{
; *$3770A ALTERNATE ENTRY POINT
LDA.b #$08 : STA $02
STA $03
LDA $22 : CLC : ADC.b #$04 : STA $00
LDA $23 : ADC.b #$00 : STA $08
LDA $20 : ADC.b #$08 : STA $01
LDA $21 : ADC.b #$00 : STA $09
RTS
}

733
Sprites/twinrova.asm Normal file
View File

@@ -0,0 +1,733 @@
; =========================================================
; Twinrova Boss Sprite
; =========================================================
!SPRID = $CE ; The sprite ID you are overwriting (HEX)
!NbrTiles = 06 ; 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 = 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 = 01 ; 00 = don't draw shadow, 01 = draw a shadow
!Palette = 00 ; Unused in this Twinrova (can be 0 to 7)
!Hitbox = 03 ; 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 = 01 ; 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 = 01 ; 00 = normal sprite, 01 = sprite is a boss
%Set_Sprite_Properties(Sprite_Twinrova_Prep, Sprite_Twinrova_Long)
; =========================================================
Sprite_Twinrova_Long:
{
PHB : PHK : PLB
JSR Sprite_Twinrova_Draw ; Call the draw code
JSL Sprite_DrawShadow
JSL Sprite_CheckActive ; Check if game is not paused
BCC .SpriteIsNotActive ; Skip Main code is sprite is innactive
JSR Sprite_Twinrova_CheckIfDead ; Check if sprite is dead
JSR Sprite_Twinrova_Main ; Call the main sprite code
.SpriteIsNotActive
PLB ; Get back the databank we stored previously
RTL ; Go back to original code
}
; =========================================================
Sprite_Twinrova_CheckIfDead:
{
LDA $0D80, X : CMP.b #$0A : BEQ .not_dead
; If health is negative, set back to zero
LDA $0E50, X : CMP.b #$44 : BCC .healthNotNegative
LDA.b #$00 : STA $0E50, X
.healthNotNegative
LDA $0E50, X : BNE .not_dead
PHX
LDA.b #$04 : STA $0DD0, X ; Kill sprite boss style
LDA.b #$0A : STA $0D80, X ; Go to Twinrova_Dead stage
PLX
.not_dead
RTS
}
; =========================================================
Sprite_Twinrova_Prep:
{
PHB : PHK : PLB
STZ $0D80, X
LDA.b #$40 : STA $0E50, X ; Health
LDA.b #$04 : STA $0CD2, X ; Bump damage type (4 hearts, green tunic)
%SetSpriteSpeedX(15)
%SetSpriteSpeedX(15)
LDA #$10 : STA $08
LDA #$10 : STA $09
LDA #$00 : STA $7EF3CC
PLB
RTL
}
!AnimSpeed = 8
macro Twinrova_Front()
%PlayAnimation(0,1,!AnimSpeed)
endmacro
macro Twinrova_Back()
%PlayAnimation(2,3,!AnimSpeed)
endmacro
macro Twinrova_Ready()
%PlayAnimation(4,6,!AnimSpeed)
endmacro
macro Twinrova_Attack()
%PlayAnimation(7,7,!AnimSpeed)
endmacro
macro Show_Koume()
%PlayAnimation(8,8,!AnimSpeed)
endmacro
macro Show_Kotake()
%PlayAnimation(9,9,!AnimSpeed)
endmacro
macro Twinrova_Hurt()
%PlayAnimation(10,11,!AnimSpeed)
endmacro
; =========================================================
; Phase 0: Blind Maiden turns into Twinrova.
;
; Phase 1: Twinrova is one entity, moving around the room
; and shooting fire and ice attacks at Link.
; Similar to the Trinexx attacks.
;
; Phase 2: Twinrova alternates between Koume (fire) and
; Kotake (ice) forms. Koume changes the arena
; to a fire arena. Similar to Ganon fight changes.
Sprite_Twinrova_Main:
{
LDA.w SprAction, X
JSL UseImplicitRegIndexedLocalJumpTable
dw Twinrova_Init ; 0x00
dw Twinrova_MoveState ; 0x01
dw Twinrova_MoveForwards ; 0x02
dw Twinrova_MoveBackwards ; 0x03
dw Twinrova_PrepareAttack ; 0x04
dw Twinrova_FireAttack ; 0x05
dw Twinrova_IceAttack ; 0x06
dw Twinrova_Hurt ; 0x07
dw Twinrova_KoumeMode ; 0x08
dw Twinrova_KotakeMode ; 0x09
dw Twinrova_Dead ; 0x0A
Twinrova_Init:
{
; %Twinrova_Front()
JSR ApplyTwinrovaGraphics
%GotoAction(01)
RTS
}
Twinrova_MoveState:
{
LDA $0E50, X : CMP.b #$20 : BCS .phase_1
; -------------------------------------------
; Phase 2
LDA SprTimerE, X : BNE .kotake
LDA #$70 : STA SprTimerD, X
%GotoAction(8) ; Koume Mode
RTS
.kotake
LDA #$70 : STA SprTimerD, X
%GotoAction(9) ; Kotake Mode
RTS
; ---------------------------------------------
.phase_1
LDA $0DA0 : BEQ .not_flashing
LDA.b #$20 : STA.w SprTimerD, X
%GotoAction(7) ; Goto Twinrova_Hurt
RTS
.not_flashing
JSL GetRandomInt : AND.b #$3F : BNE +
LDA.b #$20 : STA.w SprTimerD, X
STZ $AC
%GotoAction(4) ; Prepare Attack
RTS
+
JSL GetRandomInt : AND.b #$3F : BNE ++
LDA.b #$20 : STA.w SprTimerD, X
LDA #$01 : STA $AC
%GotoAction(4) ; Prepare Attack
RTS
++
JSL Sprite_IsBelowPlayer ; Check if sprite is below player
TYA : BNE .MoveBackwards ; If 1,
%GotoAction(2)
RTS
.MoveBackwards
%GotoAction(3)
RTS
}
Twinrova_MoveForwards:
{
%Twinrova_Front()
PHX
JSL Sprite_CheckDamageFromPlayerLong
%DoDamageToPlayerSameLayerOnContact()
PLX
JSL Sprite_DamageFlash_Long
JSL Sprite_BounceTowardPlayer
%GotoAction(1)
RTS
}
Twinrova_MoveBackwards:
{
%Twinrova_Back()
PHX
JSL Sprite_CheckDamageFromPlayerLong
%DoDamageToPlayerSameLayerOnContact()
PLX
JSL Sprite_DamageFlash_Long
JSL Sprite_BounceTowardPlayer
%GotoAction(1)
RTS
}
Twinrova_PrepareAttack:
{
%StartOnFrame(7)
%Twinrova_Attack()
PHX
JSL Sprite_CheckDamageFromPlayerLong
%DoDamageToPlayerSameLayerOnContact()
PLX
LDA $0CAA : AND.b #$03 : STA $0CAA
LDA SprTimerD, X : BNE +
LDA $0CAA : ORA.b #$03 : STA $0CAA
LDA.b #$40 : STA.w SprTimerD, X
LDA $AC : BEQ .fire
%GotoAction(6) ; Ice Attack
RTS
.fire
%GotoAction(5)
+
RTS
}
; 0x05
Twinrova_FireAttack:
{
%StartOnFrame(4)
%Twinrova_Ready()
JSR Sprite_Twinrova_FireAttack
LDA.w SprTimerD, X : BNE +
%GotoAction(1)
+
RTS
}
; 0x06
Twinrova_IceAttack:
{
%StartOnFrame(4)
%Twinrova_Ready()
JSR Sprite_Twinrova_IceAttack
LDA.w SprTimerD, X : BNE +
%GotoAction(1)
+
RTS
}
Twinrova_Hurt:
{
%StartOnFrame(10)
%Twinrova_Hurt()
PHX
JSL Sprite_CheckDamageFromPlayerLong
%DoDamageToPlayerSameLayerOnContact()
PLX
JSL Sprite_DamageFlash_Long
LDA.w SprTimerD, X : BNE +
%GotoAction(1)
+
RTS
}
Twinrova_KoumeMode:
{
%StartOnFrame(8)
%Show_Koume()
PHX
JSL Sprite_CheckDamageFromPlayerLong
%DoDamageToPlayerSameLayerOnContact()
PLX
JSL Sprite_DamageFlash_Long
JSL Sprite_BounceTowardPlayer
LDA SprTimerD, X : BNE +
%GotoAction(1)
+
RTS
}
Twinrova_KotakeMode:
{
%StartOnFrame(9)
%Show_Kotake()
PHX
JSL Sprite_CheckDamageFromPlayerLong
%DoDamageToPlayerSameLayerOnContact()
PLX
JSL Sprite_DamageFlash_Long
JSL Sprite_BounceTowardPlayer
LDA SprTimerD, X : BNE +
%GotoAction(1)
+
RTS
}
Twinrova_Dead:
{
%StartOnFrame(10)
%Twinrova_Hurt()
RTS
}
}
; =========================================================
Untitled_Garnish:
{
LDA $1A : AND.b #$03 : BNE .no_shake
JSL Sprite_IsToRightOfPlayer
LDA $0D50, X : CMP .x_speed_targets, Y : BEQ .no_shake
CLC : ADC.w $8000, Y : STA $0D50, X
.no_shake:
JSL Sprite_CheckTileCollision : BEQ .exit
JSL Sprite_BounceTowardPlayer
.exit
RTS
.x_speed_targets
db 8, -16
}
Sprite_Twinrova_FireAttack:
{
JSL Sprite_CheckTileCollision : BNE .no_collision
JSL Sprite_Move
.no_collision
JSR Sprite_Twinrova_FireAttack_AddFireGarnish
JMP Untitled_Garnish
.AddFireGarnish
INC $0E80, X : LDA $0E80, X : AND.b #$07 : BNE .return
LDA.b #$2A : JSL Sound_SetSfx2PanLong
LDA.b #$1D
; *$EBDE8 ALTERNATE ENTRY POINT
PHX : TXY
TAX : STA $00
.next_slot
LDA $7FF800, X : BEQ .free_slot
DEX : BPL .next_slot
DEC $0FF8 : BPL .use_search_index
LDA $00 : STA $0FF8
.use_search_index
LDX $0FF8
.free_slot
LDA.b #$10 : STA $7FF800, X : STA $0FB4
TYA : STA $7FF92C, X
LDA $0D10, Y : STA $7FF83C, X
LDA $0D30, Y : STA $7FF878, X
LDA $0D00, Y : CLC : ADC.b #$10 : STA $7FF81E, X
LDA $0D20, Y : ADC.b #$00 : STA $7FF85A, X
LDA.b #$7F : STA $7FF90E, X
STX $00
PLX
.return
RTS
}
AddIceGarnishV2:
{
INC $0E80, X : LDA $0E80, X : AND.b #$07 : BNE .return
LDA.b #$14 : JSL Sound_SetSfx3PanLong
LDA.b #$1D
; *$EBDE8 ALTERNATE ENTRY POINT
PHX : TXY
TAX : STA $00
.next_slot
LDA $7FF800, X : BEQ .free_slot
DEX : BPL .next_slot
DEC $0FF8 : BPL .use_search_index
LDA.b #$00 : STA $0FF8
.use_search_index
LDX $0FF8
.free_slot
LDA.b #$0C : STA $7FF800, X : STA $0FB4
TYA : STA $7FF92C, X
LDA $0D10, Y : STA $7FF83C, X
LDA $0D30, Y : STA $7FF878, X
LDA $0D00, Y : CLC : ADC.b #$10 : STA $7FF81E, X
LDA $0D20, Y : ADC.b #$00 : STA $7FF85A, X
LDA.b #$7F : STA $7FF90E, X
STX $00
PLX
.return
RTS
}
Sprite_Twinrova_IceAttack:
{
JSL Sprite_Move
JSR AddIceGarnishV2
JSR Untitled_Garnish
.return
RTS
}
; =========================================================
; Overwrite vanilla Trinexx ice garnish
; Plays like a simple ice cloud animation now.
pushpc
org $09B5DE
Garnish_PrepOamCoord:
org $09B70C
Garnish_SetOamPropsAndLargeSize:
org $09B459
Garnish_CheckPlayerCollision:
org $09B5D6
Garnish_SetOamPropsAndSmallSize:
org $09B33F
TrinexxIce_Pool:
{
.chr
db $2E
db $2E
db $2C
db $2C
.properties
db $35
db $35
db $35
db $35
}
org $09B34F
Garnish_TrinexxIce:
{
; special animation 0x0C
LDA $7FF90E, X : LSR #2 : AND.b #$03 : TAY
LDA TrinexxIce_Pool_properties, Y : STA $04
JSR Garnish_PrepOamCoord
LDA $00 : STA ($90), Y
LDA $02 : INY : STA ($90), Y
LDA $7FF90E, X : LSR #5 : PHX : TAX
LDA TrinexxIce_Pool_chr, X : INY : STA ($90), Y
LDA.b #$35 : ORA $04 : PLX
JMP Garnish_SetOamPropsAndLargeSize
}
warnpc $09B3B8
; Ice Garnish
org $0DB266+$CD
db $04
pullpc
; =========================================================
Sprite_Twinrova_Draw:
{
JSL Sprite_PrepOamCoord
JSL Sprite_OAM_AllocateDeferToPlayer
LDA $0DC0, X : CLC : ADC $0D90, X : TAY;Animation Frame
LDA .start_index, Y : STA $06
; Store Palette thing
LDA $0DA0, X : STA $08
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
; Set palette flash modifier
LDA .properties, X : ORA $08 : STA ($90), Y
PHY
TYA : LSR #2 : TAY
SEP #$20 ;set A back to 8bit but not X and Y
LDA .sizes, X : ORA $0F : STA ($92), Y ; store size in oam buffer
PLY : INY
PLX : DEX : BPL .nextTile
SEP #$30
PLX
RTS
; =========================================================
.start_index
db $00, $04, $08, $0C, $10, $14, $18, $1C, $22, $26, $2A, $2E
.nbr_of_tiles
db 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3
.x_offsets
dw -8, 8, 8, -8
dw -8, 8, -8, 8
dw -8, 8, -8, 8
dw -8, 8, -8, 8
dw -8, 8, -8, 8
dw -8, 8, -8, 8
dw -8, 8, -8, 8
dw -16, 0, 16, -16, 0, 16
dw -8, 8, -8, 8
dw -8, 8, -8, 8
dw -8, 8, -8, 8
dw -8, 8, -8, 8
.y_offsets
dw -8, -8, 8, 8
dw -7, -7, 9, 9
dw -8, -8, 8, 8
dw -8, -8, 8, 8
dw -8, -8, 8, 8
dw -7, -7, 9, 9
dw -6, -6, 10, 10
dw -8, -8, -8, 8, 8, 8
dw -8, -8, 8, 8
dw -8, -8, 8, 8
dw -8, -8, 8, 8
dw -7, -7, 9, 9
.chr
db $00, $02, $22, $24
db $04, $06, $24, $26
db $08, $0A, $28, $2A
db $0C, $0E, $28, $2A
db $44, $46, $64, $66
db $48, $4A, $68, $6A
db $4C, $4E, $6C, $6E
db $88, $8A, $8C, $A8, $AA, $AC
db $80, $82, $A0, $A2
db $84, $86, $A4, $A6
db $40, $42, $60, $62
db $40, $42, $60, $62
.properties
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
db $39, $39, $39, $39
.sizes
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02, $02, $00
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02
db $02, $02, $02, $02
}
print "TWINROVA ============ ", pc
ApplyTwinrovaGraphics:
{
PHX
REP #$20 ; A = 16, XY = 8
LDX #$80 : STX $2100 ;turn the screen off (required)
LDX #$80 : STX $2115 ; Set the video port register every time we write it increase by 1
LDA #$5000 : STA $2116 ; Destination of the DMA $5800 in vram <- this need to be divided by 2
LDA #$1801 : STA $4300 ; DMA Transfer Mode and destination register
; "001 => 2 registers write once (2 bytes: p, p+1)"
LDA.w #TwinrovaGraphics : STA $4302 ; Source address where you want gfx from ROM
LDX.b #TwinrovaGraphics>>16 : STX $4304
LDA #$2000 : STA $4305 ; size of the transfer 4 sheets of $800 each
LDX #$01 : STX $420B ; Do the DMA
LDX #$0F : STX $2100 ;turn the screen back on
SEP #$30
PLX
RTS
TwinrovaGraphics:
incbin twinrova.bin
}

View File

@@ -17,9 +17,9 @@ lorom
!MagicPowder = $7EF344 !MagicPowder = $7EF344
!FireRod = $7EF345 !FireRod = $7EF345
!IceRod = $7EF346 !IceRod = $7EF346
!BunnyMask = $7EF347 !BunnyMask = $7EF348
!DekuMask = $7EF348 !DekuMask = $7EF349
!ZoraMask = $7EF349 !ZoraMask = $7EF347
!Lamp = $7EF34A !Lamp = $7EF34A
!MagicHammer = $7EF34B !MagicHammer = $7EF34B
!Flute = $7EF34C !Flute = $7EF34C
@@ -63,7 +63,7 @@ org $3CA62A ; Expanded space for our routine
; Load items ; Load items
; 0 - nothing. 1 - bow w/ no arrows. 2 - bow w/ arrows. 3 - silver arrows ; 0 - nothing. 1 - bow w/ no arrows. 2 - bow w/ arrows. 3 - silver arrows
LDA #$03 : STA !Bow LDA #$02 : STA !Bow
; 0 - nothing. 1 - blue boomerang. 2 - red boomerang ; 0 - nothing. 1 - blue boomerang. 2 - red boomerang
LDA #$02 : STA !Boomerang LDA #$02 : STA !Boomerang
@@ -115,7 +115,7 @@ org $3CA62A ; Expanded space for our routine
LDA #$01 : STA !Shield LDA #$01 : STA !Shield
; 0 - nothing. 1 - Green Mail. 2 - Blue Mail. 3 - Red Mail ; 0 - nothing. 1 - Green Mail. 2 - Blue Mail. 3 - Red Mail
LDA #$00 : STA !Mail LDA #$01 : STA !Mail
; 0-No bottle. ; 0-No bottle.
; 1-Mushroom (no use). 2-Empty bottle. ; 1-Mushroom (no use). 2-Empty bottle.