Deleted several unused modules and some commented code Reorganized some routines to clean up modules Moved some memory into mirrored WRAM Refactored NMI hook aux routine Removed old fake flipper fix
835 lines
26 KiB
NASM
835 lines
26 KiB
NASM
;--------------------------------------------------------------------------------
|
|
; 291 - Moldorm Cave
|
|
; 286 - Northeast Dark Swamp Cave
|
|
;--------------------------------------------------------------------------------
|
|
!FREE_TILE_BUFFER = $1180
|
|
; A = Tile ID
|
|
macro UploadOAM(dest)
|
|
PHA : PHP
|
|
|
|
PHA
|
|
REP #$20 ; set 16-bit accumulator
|
|
LDA.w #$0000 : STA.l SpriteOAM
|
|
STA.l SpriteOAM+2
|
|
LDA.w #$0200 : STA.l SpriteOAM+6
|
|
SEP #$20 ; set 8-bit accumulator
|
|
LDA.b <dest> : STA.l SpriteOAM+4
|
|
|
|
LDA.b $01,s
|
|
|
|
JSL.l GetSpritePalette
|
|
STA.l SpriteOAM+5 : STA.l SpriteOAM+13
|
|
PLA
|
|
JSL.l IsNarrowSprite : BCS .narrow
|
|
|
|
BRA .done
|
|
|
|
.narrow
|
|
REP #$20 ; set 16-bit accumulator
|
|
LDA.w #$0000 : STA.l SpriteOAM+7
|
|
STA.l SpriteOAM+14
|
|
LDA.w #$0800 : STA.l SpriteOAM+9
|
|
LDA.w #$3400 : STA.l SpriteOAM+11
|
|
|
|
.done
|
|
PLP : PLA
|
|
endmacro
|
|
;--------------------------------------------------------------------------------
|
|
; $0A : Digit Offset
|
|
; $0C-$0D : Value to Display
|
|
; $0E-$0F : Base Coordinate
|
|
;--------------------------------------------------------------------------------
|
|
macro DrawDigit(value,offset)
|
|
STZ.b Scrap0A ; clear digit buffer
|
|
LDA.b Scrap0C ; load value
|
|
--
|
|
CMP.w <value> : !BLT ++
|
|
!SUB.w <value>
|
|
INC.b Scrap0A
|
|
BRA --
|
|
++
|
|
STA.b Scrap0C ; save value
|
|
CPY.b #$FF : BNE +
|
|
LDY.b <offset>
|
|
LDA.b Scrap0E : !ADD.w .digit_offsets, Y : STA.b Scrap0E
|
|
+
|
|
LDA.b Scrap0E : STA.l BigRAM, X : INX : INX
|
|
LDA.w #56 : STA.l BigRAM, X : INX : INX
|
|
LDY.b Scrap0A : TYA : ASL : TAY : LDA.w .digit_properties, Y : STA.l BigRAM, X : INX : INX
|
|
LDA.w #$0000 : STA.l BigRAM, X : INX : INX
|
|
|
|
LDA.b Scrap0E : !ADD.w #$0008 : STA.b Scrap0E ; move offset 8px right
|
|
endmacro
|
|
;--------------------------------------------------------------------------------
|
|
DrawPrice:
|
|
PHX : PHY : PHP
|
|
LDY.b #$FF
|
|
LDX.b #$00 ; clear bigram pointer
|
|
|
|
LDA.b Scrap0C : CMP.w #1000 : !BLT + : JMP .len4 : +
|
|
CMP.w #100 : !BLT + : JMP .len3 : +
|
|
CMP.w #10 : !BLT + : JMP .len2 : +
|
|
CMP.w #1 : !BLT + : JMP .len1 : +
|
|
|
|
.len4
|
|
%DrawDigit(#1000,#6)
|
|
|
|
.len3
|
|
%DrawDigit(#100,#4)
|
|
|
|
.len2
|
|
%DrawDigit(#10,#2)
|
|
|
|
.len1
|
|
%DrawDigit(#1,#0)
|
|
|
|
SEP #$20 ; set 8-bit accumulator
|
|
TXA : LSR #3 : STA.b Scrap06 ; request 1-4 OAM slots
|
|
ASL #2
|
|
PHA
|
|
LDA.b $22 : CMP.l ShopPriceColumn : !BLT .off
|
|
CMP.l ShopPriceColumn+1 : !BGE .off
|
|
.on
|
|
PLA : JSL.l OAM_AllocateFromRegionB : BRA + ; request 4-16 bytes
|
|
.off
|
|
PLA : JSL.l OAM_AllocateFromRegionA ; request 4-16 bytes
|
|
+
|
|
TXA : LSR #3
|
|
PLP : PLY : PLX
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
.digit_properties
|
|
dw $0230, $0231, $0202, $0203, $0212, $0213, $0222, $0223, $0232, $0233
|
|
;--------------------------------------------------------------------------------
|
|
.digit_offsets
|
|
dw 4, 0, -4, -8
|
|
;--------------------------------------------------------------------------------
|
|
SpritePrep_ShopKeeper:
|
|
PHX : PHY : PHP
|
|
|
|
REP #$30 ; set 16-bit accumulator & index registers
|
|
LDX.w #$0000
|
|
-
|
|
LDA.l ShopTable+1, X : CMP.b RoomIndex : BNE +
|
|
LDA.l ShopTable+5, X : AND.w #$0040 : BNE ++
|
|
LDA.l PreviousOverworldDoor : AND #$00FF : CMP.l ShopTable+3, X : BNE +
|
|
++
|
|
SEP #$20 ; set 8-bit accumulator
|
|
LDA.l ShopTable, X : STA.l ShopId
|
|
LDA.l ShopTable+5, X : STA.l ShopType
|
|
AND.b #$03 : ASL #2 : STA.l ShopCapacity
|
|
LDA.l ShopTable+6, X : STA.l ShopMerchant
|
|
LDA.l ShopTable+7, X : STA.l ShopSRAMIndex
|
|
BRA .success
|
|
+
|
|
LDA.l ShopTable, X : AND.w #$00FF : CMP.w #$00FF : BEQ .fail
|
|
INX #8
|
|
BRA -
|
|
|
|
.fail
|
|
SEP #$20 ; set 8-bit accumulator
|
|
LDA.b #$FF : STA.l ShopType ; $FF = error condition
|
|
JMP .done
|
|
|
|
.success
|
|
SEP #$20 ; set 8-bit accumulator
|
|
|
|
LDX.w #$0000
|
|
LDY.w #$0000
|
|
-
|
|
TYA : CMP.l ShopCapacity : !BLT ++ : JMP .stop : ++
|
|
LDA.l ShopContentsTable+1, X : CMP.b #$FF : BNE ++ : JMP .stop : ++
|
|
|
|
LDA.l ShopContentsTable, X : CMP.l ShopId : BEQ ++ : JMP .next : ++
|
|
LDA.l ShopContentsTable+1, X : PHX : TYX : STA.l ShopInventory, X : PLX
|
|
LDA.l ShopContentsTable+2, X : PHX : TYX : STA.l ShopInventory+1, X : PLX
|
|
LDA.l ShopContentsTable+3, X : PHX : TYX : STA.l ShopInventory+2, X : PLX
|
|
|
|
PHY
|
|
PHX
|
|
LDA.b #$00 : XBA : TYA : LSR #2 : !ADD ShopSRAMIndex : TAX
|
|
LDA.l PurchaseCounts, X : TYX : STA.l ShopInventory+3, X : TAY
|
|
PLX
|
|
|
|
LDA.l ShopContentsTable+4, X : BEQ ++
|
|
TYA : CMP.l ShopContentsTable+4, X : !BLT ++
|
|
PLY
|
|
LDA.l ShopContentsTable+5, X : PHX : TYX : STA.l ShopInventory, X : PLX
|
|
LDA.l ShopContentsTable+6, X : PHX : TYX : STA.l ShopInventory+1, X : PLX
|
|
LDA.l ShopContentsTable+7, X : PHX : TYX : STA.l ShopInventory+2, X : PLX
|
|
BRA +++
|
|
++
|
|
PLY : +++
|
|
|
|
PHX : PHY
|
|
PHX : TYX : LDA.l ShopInventory, X : PLX : TAY
|
|
REP #$20 ; set 16-bit accumulator
|
|
LDA.b 1,s : TAX : LDA.l .tile_offsets, X : TAX
|
|
JSR LoadTile
|
|
PLY : PLX
|
|
INY #4
|
|
|
|
.next
|
|
INX #8
|
|
JMP -
|
|
.stop
|
|
|
|
LDA.b #Shopkeeper_UploadVRAMTilesLong>>16 : STA.w NMIAux+2
|
|
LDA.b #Shopkeeper_UploadVRAMTilesLong>>8 : STA.w NMIAux+1
|
|
LDA.b #Shopkeeper_UploadVRAMTilesLong>>0 : STA.w NMIAux
|
|
|
|
.done
|
|
LDA.l ShopType : BIT.b #$20 : BEQ .notTakeAll ; Take-all
|
|
.takeAll
|
|
|
|
LDA.b #$00 : XBA : LDA.l ShopSRAMIndex : TAX
|
|
LDA.l PurchaseCounts, X
|
|
BRA ++
|
|
.notTakeAll
|
|
LDA.b #$00
|
|
++
|
|
STA.l ShopState
|
|
|
|
; If the item is $FF, make it not show (as if already taken)
|
|
LDA.l ShopInventory : CMP.b #$FF : BNE +
|
|
LDA.l ShopState : ORA.l Shopkeeper_ItemMasks : STA.l ShopState
|
|
+
|
|
LDA.l ShopInventory+4 : CMP.b #$FF : BNE +
|
|
LDA.l ShopState : ORA.l Shopkeeper_ItemMasks+1 : STA.l ShopState
|
|
+
|
|
LDA.l ShopInventory+8 : CMP.b #$FF : BNE +
|
|
LDA.l ShopState : ORA.l Shopkeeper_ItemMasks+2 : STA.l ShopState
|
|
+
|
|
|
|
PLP : PLY : PLX
|
|
|
|
LDA.l ShopType : CMP.b #$FF : BNE +
|
|
PLA : PLA : PLA
|
|
INC.w $0BA0, X
|
|
LDA.w $0E40, X
|
|
JML.l ShopkeeperFinishInit
|
|
+
|
|
RTL
|
|
.tile_offsets
|
|
dw $0000, $0000
|
|
dw $0080, $0000
|
|
dw $0100, $0000
|
|
;--------------------------------------------------------------------------------
|
|
; X - Tile Buffer Offset
|
|
; Y - Item ID
|
|
LoadTile:
|
|
TXA : !ADD.w #!FREE_TILE_BUFFER : STA.l TileUploadOffsetOverride ; load offset from X
|
|
SEP #$30 ; set 8-bit accumulator & index registers
|
|
TYA ; load item ID from Y
|
|
JSL.l GetSpriteID ; convert loot id to sprite id
|
|
JSL.l GetAnimatedSpriteTile_variable
|
|
REP #$10 ; set 16-bit index registers
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
;ShopInventory, X
|
|
;[id][$lo][$hi][purchase_counter]
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_UploadVRAMTilesLong:
|
|
JSR.w Shopkeeper_UploadVRAMTiles
|
|
RTL
|
|
Shopkeeper_UploadVRAMTiles:
|
|
LDA.w DMAP0 : PHA ; preserve DMA parameters
|
|
LDA.w BBAD0 : PHA ; preserve DMA parameters
|
|
LDA.w A1T0L : PHA ; preserve DMA parameters
|
|
LDA.w A1T0H : PHA ; preserve DMA parameters
|
|
LDA.w A1B0 : PHA ; preserve DMA parameters
|
|
LDA.w DAS0L : PHA ; preserve DMA parameters
|
|
LDA.w DAS0H : PHA ; preserve DMA parameters
|
|
;--------------------------------------------------------------------------------
|
|
LDA.b #$01 : STA.w DMAP0 ; set DMA transfer direction A -> B, bus A auto increment, double-byte mode
|
|
LDA.b #$18 : STA.w BBAD0 ; set bus B destination to VRAM register
|
|
LDA.b #$80 : STA.w VMAIN ; set VRAM to increment by 2 on high register write
|
|
|
|
LDA.b #$80 : STA.w A1T0L ; set bus A source address to tile buffer
|
|
LDA.b #$A1 : STA.w A1T0H
|
|
LDA.b #$7E : STA.w A1B0
|
|
|
|
LDA.l ShopType : AND.b #$10 : BNE .special
|
|
JMP .normal
|
|
|
|
.special
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$40 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5A : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$40 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5B : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$60 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5A : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$60 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5B : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$80 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5A : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$80 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5B : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
JMP .end
|
|
|
|
.normal
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$60 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5C : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$60 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5D : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$80 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5C : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$80 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5D : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$A0 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5C : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
|
|
LDA.b #$40 : STA.w DAS0L : STZ.b DAS0H ; set transfer size to 0x40
|
|
LDA.b #$A0 : STA.w VMADDL ; set VRAM register destination address
|
|
LDA.b #$5D : STA.w VMADDH
|
|
LDA.b #$01 : STA.w MDMAEN ; begin DMA transfer
|
|
;--------------------------------------------------------------------------------
|
|
.end
|
|
PLA : STA.w DAS0H ; restore DMA parameters
|
|
PLA : STA.w DAS0L ; restore DMA parameters
|
|
PLA : STA.w A1B0 ; restore DMA parameters
|
|
PLA : STA.w A1T0H ; restore DMA parameters
|
|
PLA : STA.w A1T0L ; restore DMA parameters
|
|
PLA : STA.w BBAD0 ; restore DMA parameters
|
|
PLA : STA.w DMAP0 ; restore DMA parameters
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
Shopkepeer_CallOriginal:
|
|
PLA : PLA : PLA
|
|
LDA.b #ShopkeeperJumpTable>>16 : PHA
|
|
LDA.b #ShopkeeperJumpTable>>8 : PHA
|
|
LDA.b #ShopkeeperJumpTable : PHA
|
|
LDA.w $0E80, X
|
|
JML.l UseImplicitRegIndexedLocalJumpTable
|
|
;--------------------------------------------------------------------------------
|
|
Sprite_ShopKeeper:
|
|
|
|
LDA.l ShopType : CMP.b #$FF : BNE + : JMP.w Shopkepeer_CallOriginal : +
|
|
|
|
PHB : PHK : PLB
|
|
JSL.l Sprite_PlayerCantPassThrough
|
|
|
|
; Draw Shopkeeper
|
|
JSR.w Shopkeeper_DrawMerchant
|
|
|
|
LDA.l ShopType : BIT.b #$80 : BEQ .normal ; Take-any
|
|
BIT.b #$20 : BNE .normal ; Not A Take-All
|
|
PHX
|
|
LDA.l ShopSRAMIndex : TAX
|
|
LDA.l PurchaseCounts, X : BEQ ++ : PLX : BRA .done : ++
|
|
PLX
|
|
.normal
|
|
|
|
; Draw Items
|
|
JSR.w Shopkeeper_DrawItems
|
|
|
|
; Set Up Hitboxes
|
|
JSR.w Shopkeeper_SetupHitboxes
|
|
|
|
; $22
|
|
; 0x48 - Left
|
|
; 0x60 - Midpoint 1
|
|
; 0x78 - Center
|
|
; 0x90 - Midpoint 2
|
|
; 0xA8 - Right
|
|
.done
|
|
PLB
|
|
RTL
|
|
;--------------------------------------------------------------------------------
|
|
macro DrawMerchant(head,body,speed)
|
|
PHX : LDX.b #$00
|
|
LDA.b $1A : AND.b <speed> : BEQ +
|
|
-
|
|
LDA.w .oam_shopkeeper_f1, X : STA.l BigRAM, X : INX
|
|
CPX.b #$10 : !BLT -
|
|
+
|
|
-
|
|
LDA.w .oam_shopkeeper_f2, X : STA.l BigRAM, X : INX
|
|
CPX.b #$10 : !BLT -
|
|
++
|
|
PLX
|
|
|
|
LDA.l ShopMerchant : LSR #4 : AND.b #$0E : ORA.l BigRAM+5 : STA.l BigRAM+5
|
|
LDA.l ShopMerchant : LSR #4 : AND.b #$0E : ORA.l BigRAM+13 : STA.l BigRAM+13
|
|
|
|
PHB
|
|
LDA.b #$02 : STA.b Scrap06 ; request 2 OAM slots
|
|
LDA.b #$08 : JSL.l OAM_AllocateFromRegionA ; request 8 bytes
|
|
STZ.b Scrap07
|
|
|
|
LDA.b #BigRAM : STA.b Scrap08
|
|
LDA.b #BigRAM>>8 : STA.b Scrap09
|
|
LDA.b #$7E : PHA : PLB ; set data bank to $7E
|
|
JSL.l Sprite_DrawMultiple_quantity_preset
|
|
LDA.b $90 : !ADD.b #$04*2 : STA.b $90 ; increment oam pointer
|
|
LDA.b $92 : INC #2 : STA.b $92
|
|
PLB
|
|
RTS
|
|
.oam_shopkeeper_f1
|
|
dw 0, -8 : db <head>, $00, $00, $02
|
|
dw 0, 0 : db <body>, $00, $00, $02
|
|
.oam_shopkeeper_f2
|
|
dw 0, -8 : db <head>, $00, $00, $02
|
|
dw 0, 0 : db <body>, $40, $00, $02
|
|
endmacro
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawMerchant:
|
|
LDA.l ShopMerchant : AND.b #$07
|
|
BEQ Shopkeeper_DrawMerchant_Type0
|
|
CMP.b #$01 : BNE + : JMP Shopkeeper_DrawMerchant_Type1 : +
|
|
CMP.b #$02 : BNE + : JMP Shopkeeper_DrawMerchant_Type2 : +
|
|
CMP.b #$03 : BNE + : JMP Shopkeeper_DrawMerchant_Type3 : +
|
|
CMP.b #$04 : BNE + : RTS : +
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawMerchant_Type0:
|
|
%DrawMerchant(#$00, #$10, #$10)
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawMerchant_Type1:
|
|
LDA.b #$01 : STA.b Scrap06 ; request 1 OAM slot
|
|
LDA.b #$04 : JSL.l OAM_AllocateFromRegionA ; request 4 bytes
|
|
STZ.b Scrap07
|
|
LDA.b $1A : AND #$08 : BEQ +
|
|
LDA.b #.oam_shopkeeper_f1 : STA.b Scrap08
|
|
LDA.b #.oam_shopkeeper_f1>>8 : STA.b Scrap09
|
|
BRA ++
|
|
+
|
|
LDA.b #.oam_shopkeeper_f2 : STA.b Scrap08
|
|
LDA.b #.oam_shopkeeper_f2>>8 : STA.b Scrap09
|
|
++
|
|
JSL.l Sprite_DrawMultiple_quantity_preset
|
|
LDA.b $90 : !ADD.b #$04 : STA.b $90 ; increment oam pointer
|
|
LDA.b $92 : INC : STA.b $92
|
|
RTS
|
|
.oam_shopkeeper_f1
|
|
dw 0, 0 : db $46, $0A, $00, $02
|
|
.oam_shopkeeper_f2
|
|
dw 0, 0 : db $46, $4A, $00, $02
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawMerchant_Type2:
|
|
%DrawMerchant(#$84, #$10, #$40)
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawMerchant_Type3:
|
|
%DrawMerchant(#$8E, #$10, #$40)
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_SetupHitboxes:
|
|
PHX : PHY : PHP
|
|
LDY.b #$00
|
|
-
|
|
PHY
|
|
TYA : LSR #2 : TAY
|
|
LDA.l ShopState : AND.w Shopkeeper_ItemMasks, Y : BEQ +
|
|
PLY : BRA .no_interaction
|
|
+
|
|
PLY
|
|
LDA.w $00EE : CMP.w $0F20, X : BNE .no_interaction
|
|
|
|
JSR.w Setup_LinksHitbox
|
|
JSR.w Setup_ShopItemCollisionHitbox
|
|
JSL.l Utility_CheckIfHitBoxesOverlapLong
|
|
BCC .no_contact
|
|
JSR.w Sprite_HaltSpecialPlayerMovementCopied
|
|
.no_contact
|
|
|
|
JSR.w Setup_ShopItemInteractionHitbox
|
|
JSL.l Utility_CheckIfHitBoxesOverlapLong : BCC .no_interaction
|
|
LDA.b $F6 : AND.b #$80 : BEQ .no_interaction ; check for A-press
|
|
LDA.b $10 : CMP.b #$0C : !BGE .no_interaction ; don't interact in other modes besides game action
|
|
JSR.w Shopkeeper_BuyItem
|
|
.no_interaction
|
|
INY #4
|
|
TYA : CMP.l ShopCapacity : !BLT -
|
|
;CPY.b #$0C : !BLT -
|
|
|
|
PLP : PLY : PLX
|
|
RTS
|
|
|
|
Shopkeeper_BuyItem:
|
|
PHX : PHY
|
|
TYX
|
|
|
|
LDA.l ShopInventory, X
|
|
CMP.b #$0E : BEQ .refill ; Bee Refill
|
|
CMP.b #$2E : BEQ .refill ; Red Potion Refill
|
|
CMP.b #$2F : BEQ .refill ; Green Potion Refill
|
|
CMP.b #$30 : BEQ .refill ; Blue Potion Refill
|
|
BRA +
|
|
.refill
|
|
JSL.l Sprite_GetEmptyBottleIndex : BMI .full_bottles
|
|
+
|
|
|
|
LDA.l ShopType : AND.b #$80 : BNE .buy ; don't charge if this is a take-any
|
|
REP #$20 : LDA.l CurrentRupees : CMP.l ShopInventory+1, X : SEP #$20 : !BGE .buy
|
|
|
|
.cant_afford
|
|
LDA.b #$7A
|
|
LDY.b #$01
|
|
JSL.l Sprite_ShowMessageUnconditional
|
|
LDA.b #$3C : STA.w $012E ; error sound
|
|
JMP .done
|
|
.full_bottles
|
|
LDA.b #$6B
|
|
LDY.b #$01
|
|
JSL.l Sprite_ShowMessageUnconditional
|
|
LDA.b #$3C : STA.w $012E ; error sound
|
|
JMP .done
|
|
.buy
|
|
LDA.l ShopType : AND.b #$80 : BNE ++ ; don't charge if this is a take-any
|
|
REP #$20 : LDA.l CurrentRupees : !SUB ShopInventory+1, X : STA.l CurrentRupees : SEP #$20 ; Take price away
|
|
++
|
|
LDA.l ShopInventory, X : TAY : JSL.l Link_ReceiveItem
|
|
LDA.l ShopInventory+3, X : INC : STA.l ShopInventory+3, X
|
|
|
|
TXA : LSR #2 : TAX
|
|
LDA.l ShopType : BIT.b #$80 : BNE +
|
|
LDA.l ShopState : ORA.w Shopkeeper_ItemMasks, X : STA.l ShopState
|
|
PHX
|
|
TXA : !ADD ShopSRAMIndex : TAX
|
|
LDA.l PurchaseCounts, X : INC : BEQ +++ : STA.l PurchaseCounts, X : +++
|
|
PLX
|
|
BRA ++
|
|
+ ; Take-any
|
|
BIT.b #$20 : BNE .takeAll
|
|
.takeAny
|
|
LDA.l ShopState : ORA.b #$07 : STA.l ShopState
|
|
PHX : LDA.l ShopSRAMIndex : TAX : LDA.b #$01 : STA.l PurchaseCounts, X : PLX
|
|
BRA ++
|
|
.takeAll
|
|
LDA.l ShopState : ORA.w Shopkeeper_ItemMasks, X : STA.l ShopState
|
|
PHX : LDA.l ShopSRAMIndex : TAX : LDA.l ShopState : STA.l PurchaseCounts, X : PLX
|
|
++
|
|
.done
|
|
PLY : PLX
|
|
RTS
|
|
Shopkeeper_ItemMasks:
|
|
db #$01, #$02, #$04
|
|
;--------------------
|
|
Setup_ShopItemCollisionHitbox:
|
|
;The complications with XBA are to handle the fact that nintendo likes to store
|
|
;high and low bytes of 16 bit postion values seperately :-(
|
|
|
|
REP #$20 ; set 16-bit accumulator
|
|
LDA.b Scrap00 : PHA
|
|
SEP #$20 ; set 8-bit accumulator
|
|
|
|
; load shopkeeper X (16 bit)
|
|
LDA.w $0D30, X : XBA : LDA.w $0D10, X
|
|
|
|
REP #$20 ; set 16-bit accumulator
|
|
PHA : PHY
|
|
LDA.l ShopType : AND.w #$0003 : DEC : ASL : TAY
|
|
LDA.w Shopkeeper_DrawNextItem_item_offsets_idx, Y : STA.b Scrap00 ; get table from the table table
|
|
PLY : PLA
|
|
|
|
!ADD ($00), Y
|
|
!ADD.w #$0002 ; a small negative margin
|
|
; TODO: add 4 for a narrow item
|
|
SEP #$20 ; set 8-bit accumulator
|
|
|
|
; store hitbox X
|
|
STA.b Scrap04 : XBA : STA.b Scrap0A
|
|
|
|
;load shopkeeper Y (16 bit)
|
|
LDA.w $0D20, X : XBA : LDA.w $0D00, X
|
|
|
|
REP #$20 ; set 16-bit accumulator
|
|
PHY : INY #2
|
|
!ADD ($00), Y
|
|
PLY
|
|
PHA : LDA.l ShopType : AND.w #$0080 : BEQ + ; lower by 4 for Take-any
|
|
PLA : !ADD.w #$0004
|
|
BRA ++
|
|
+ : PLA : ++
|
|
SEP #$20 ; set 8-bit accumulator
|
|
|
|
; store hitbox Y Low: $05, High $0B
|
|
STA.b Scrap05 : XBA : STA.b Scrap0B
|
|
|
|
LDA.b #12 : STA.b Scrap06 ; Hitbox width, always 12 for existing (wide) shop items
|
|
; TODO: for narrow sprite store make width 4 (i.e. 8 pixels smaller)
|
|
|
|
LDA.b #14 : STA.b Scrap07 ; Hitbox height, always 14
|
|
|
|
REP #$20 ; set 16-bit accumulator
|
|
PLA : STA.b Scrap00
|
|
SEP #$20 ; set 8-bit acc
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
; Adjusts the already set up collision hitbox to be a suitable interaction hitbox
|
|
Setup_ShopItemInteractionHitbox:
|
|
PHP
|
|
SEP #$20 ; set 8-bit accumulator
|
|
|
|
; collision hitbox has left margin of -2, we want margin of 8 so we subtract 10
|
|
LDA.b Scrap04 : !SUB.b #$0A : STA.b Scrap04
|
|
LDA.b Scrap0A : SBC.b #$00 : STA.b Scrap0A ; Apply borrow
|
|
|
|
; collision hitbox has 0 top margin, we want a margin of 8 so we subtract 8
|
|
LDA.b Scrap05 : !SUB.b #$08 : STA.b Scrap05
|
|
LDA.b Scrap0B : SBC.b #$00 : STA.b Scrap0B ; Apply borrow
|
|
|
|
; We want a width of 32 for wide or 24 for narrow, so we add 20
|
|
LDA.b Scrap06 : !ADD.b #20 : STA.b Scrap06 ; Hitbox width
|
|
|
|
LDA.b #40 : STA.b Scrap07 ; Hitbox height, always 40
|
|
PLP
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
; Following is a copy of procedure $3770A (Bank06.asm Line 6273)
|
|
; because there is no long version available
|
|
Setup_LinksHitbox:
|
|
LDA.b #$08 : STA.b Scrap02
|
|
STA.b Scrap03
|
|
|
|
LDA.b $22 : !ADD.b #$04 : STA.b Scrap00
|
|
LDA.b $23 : ADC.b #$00 : STA.b Scrap08
|
|
|
|
LDA.b $20 : ADC.b #$08 : STA.b Scrap01
|
|
LDA.b $21 : ADC.b #$00 : STA.b Scrap09
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
; The following is a copy of procedure Sprite_HaltSpecialPlayerMovement (Bank1E.asm line 255)
|
|
; because there is no long version available
|
|
Sprite_HaltSpecialPlayerMovementCopied:
|
|
PHX
|
|
JSL Sprite_NullifyHookshotDrag
|
|
STZ $5E ; Set Link's speed to zero...
|
|
JSL Player_HaltDashAttackLong
|
|
PLX
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawItems:
|
|
PHB : PHK : PLB
|
|
PHX : PHY
|
|
TXA : STA.l ShopScratch;
|
|
|
|
LDX.b #$00
|
|
LDY.b #$00
|
|
LDA.l ShopType : AND.b #$03
|
|
CMP.b #$03 : BNE +
|
|
JSR.w Shopkeeper_DrawNextItem : BRA ++
|
|
+ CMP.b #$02 : BNE + : ++
|
|
JSR.w Shopkeeper_DrawNextItem : BRA ++
|
|
+ CMP.b #$01 : BNE + : ++
|
|
JSR.w Shopkeeper_DrawNextItem
|
|
+
|
|
PLY : PLX
|
|
PLB
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawNextItem:
|
|
LDA.l ShopState : AND.w Shopkeeper_ItemMasks, Y : BEQ + : JMP .next : +
|
|
|
|
PHY
|
|
|
|
LDA.l ShopType : AND.b #$03 : DEC : ASL : TAY
|
|
REP #$20 ; set 16-bit accumulator
|
|
LDA.w .item_offsets_idx, Y : STA.b Scrap00 ; get table from the table table
|
|
LDA.b 1,s : ASL #2 : TAY ; set Y to the item index
|
|
LDA.b ($00), Y : STA.l SpriteOAM ; load X-coordinate
|
|
INY #2
|
|
LDA.l ShopType : AND.w #$0080 : BNE +
|
|
LDA.b ($00), Y : STA.l SpriteOAM+2 : BRA ++ ; load Y-coordinate
|
|
+
|
|
LDA.b ($00), Y : !ADD.w #$0004 : STA.l SpriteOAM+2 ; load Y-coordinate
|
|
++
|
|
SEP #$20 ; set 8-bit accumulator
|
|
PLY
|
|
|
|
LDA.l ShopInventory, X ; get item id
|
|
CMP.b #$2E : BNE + : BRA .potion
|
|
+ CMP.b #$2F : BNE + : BRA .potion
|
|
+ CMP.b #$30 : BEQ .potion
|
|
.normal
|
|
LDA.w .tile_indices, Y : BRA + ; get item gfx index
|
|
.potion
|
|
LDA.b #$C0 ; potion is #$C0 because it's already there in VRAM
|
|
+
|
|
XBA
|
|
|
|
LDA.l ShopType : AND.b #$10 : BEQ +
|
|
XBA : !SUB #$22 : XBA ; alt vram
|
|
+
|
|
XBA
|
|
|
|
STA.l SpriteOAM+4
|
|
|
|
LDA.l ShopInventory, X ; get item palette
|
|
JSL.l GetSpritePalette : STA.l SpriteOAM+5
|
|
|
|
LDA.b #$00 : STA.l SpriteOAM+6
|
|
|
|
LDA.l ShopInventory, X ; get item palette
|
|
JSL.l IsNarrowSprite : BCS .narrow
|
|
.full
|
|
LDA.b #$02
|
|
STA.l SpriteOAM+7
|
|
LDA.b #$01
|
|
BRA ++
|
|
.narrow
|
|
LDA.b #$00
|
|
STA.l SpriteOAM+7
|
|
JSR.w PrepNarrowLower
|
|
LDA.b #$02
|
|
++
|
|
PHX : PHA : LDA.l ShopScratch : TAX : PLA : JSR.w RequestItemOAM : PLX
|
|
|
|
LDA.l ShopType : AND.b #$80 : BNE +
|
|
JSR.w Shopkeeper_DrawNextPrice
|
|
+
|
|
|
|
.next
|
|
INY
|
|
INX #4
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
.item_offsets_idx
|
|
dw #.item_offsets_1
|
|
dw #.item_offsets_2
|
|
dw #.item_offsets_3
|
|
.item_offsets_1
|
|
dw 8, 40
|
|
.item_offsets_2
|
|
dw -16, 40
|
|
dw 32, 40
|
|
.item_offsets_3
|
|
dw -40, 40
|
|
dw 8, 40
|
|
dw 56, 40
|
|
.tile_indices
|
|
db $C6, $C8, $CA
|
|
;--------------------------------------------------------------------------------
|
|
Shopkeeper_DrawNextPrice:
|
|
PHB : PHK : PLB
|
|
PHX : PHY : PHP
|
|
|
|
REP #$20 ; set 16-bit accumulator
|
|
PHY
|
|
LDA.l ShopType : AND.w #$0003 : DEC : ASL : TAY
|
|
LDA.w Shopkeeper_DrawNextItem_item_offsets_idx, Y : STA.b Scrap00 ; get table from the table table
|
|
LDA.w .price_columns_idx, Y : STA.b Scrap02 ; get table from the table table
|
|
PLY : PHY
|
|
TYA : ASL #2 : TAY
|
|
LDA.b ($00), Y : STA.b Scrap0E ; set coordinate
|
|
TYA : LSR : TAY
|
|
LDA.b ($02), Y : STA.l ShopPriceColumn
|
|
INY : LDA.b ($02), Y : STA.l ShopPriceColumn+1
|
|
PLY
|
|
LDA.l ShopInventory+1, X : STA.b Scrap0C ; set value
|
|
|
|
BEQ .free
|
|
JSR.w DrawPrice
|
|
SEP #$20 : STA.b Scrap06 : STZ.b Scrap07 ; set 8-bit accumulator & store result
|
|
PHA
|
|
LDA.b #BigRAM : STA.b Scrap08
|
|
LDA.b #BigRAM>>8 : STA.b Scrap09
|
|
LDA.b #$7E : PHA : PLB ; set data bank to $7E
|
|
|
|
PHX : PHA : LDA.l ShopScratch : TAX : PLA : JSL.l Sprite_DrawMultiple_quantity_preset : PLX
|
|
|
|
LDA.b 1,s
|
|
ASL #2 : !ADD $90 : STA.b $90 ; increment oam pointer
|
|
PLA
|
|
!ADD $92 : STA.b $92
|
|
.free
|
|
PLP : PLY : PLX
|
|
PLB
|
|
RTS
|
|
.price_columns_idx
|
|
dw #.price_columns_1
|
|
dw #.price_columns_2
|
|
dw #.price_columns_3
|
|
.price_columns_1
|
|
db #$00, #$FF
|
|
.price_columns_2
|
|
db #$00, #$80, #$80, $FF
|
|
.price_columns_3
|
|
db #$00, #$60, #$60, #$90, #$90, $FF
|
|
;--------------------------------------------------------------------------------
|
|
RequestItemOAM:
|
|
PHX : PHY : PHA
|
|
STA.b Scrap06 ; request A OAM slots
|
|
LDA.b $20 : CMP.b #$62 : !BGE .below
|
|
.above
|
|
LDA.b 1,s : ASL #2 : JSL.l OAM_AllocateFromRegionA ; request 4A bytes
|
|
BRA +
|
|
.below
|
|
LDA.b 1,s : ASL #2 : JSL.l OAM_AllocateFromRegionB ; request 4A bytes
|
|
+
|
|
LDA.b 1,s : STA.b Scrap06 ; request 3 OAM slots
|
|
STZ.b Scrap07
|
|
LDA.b #SpriteOAM : STA.b Scrap08
|
|
LDA.b #SpriteOAM>>8 : STA.b Scrap09
|
|
LDA.b #$7E : PHB : PHA : PLB
|
|
JSL Sprite_DrawMultiple_quantity_preset
|
|
PLB
|
|
LDA.b 1,s : ASL #2 : !ADD $90 : STA.b $90 ; increment oam pointer
|
|
LDA.b $92 : !ADD 1,s : STA.b $92
|
|
PLA : PLY : PLX
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
PrepNarrowLower:
|
|
PHX
|
|
LDX.b #$00
|
|
REP #$20 ; set 16-bit accumulator
|
|
LDA.l SpriteOAM, X : !ADD.w #$0004 : STA.l SpriteOAM, X : STA.l SpriteOAM+8, X
|
|
LDA.l SpriteOAM+2, X : !ADD.w #$0008 : STA.l SpriteOAM+10, X
|
|
LDA.l SpriteOAM+4, X : !ADD.w #$0010 : STA.l SpriteOAM+12, X
|
|
LDA.l SpriteOAM+6, X : STA.l SpriteOAM+14, X
|
|
SEP #$20 ; set 8-bit accumulator
|
|
PLX
|
|
RTS
|
|
;--------------------------------------------------------------------------------
|
|
;.oam_items
|
|
;dw -40, 40 : db $C0, $08, $00, $02
|
|
;dw 8, 40 : db $C2, $04, $00, $02
|
|
;dw 56, 40 : db $C4, $02, $00, $02
|
|
;--------------------------------------------------------------------------------
|
|
;.oam_prices
|
|
;dw -48, 56 : db $30, $02, $00, $00
|
|
;dw -40, 56 : db $31, $02, $00, $00
|
|
;dw -32, 56 : db $02, $02, $00, $00
|
|
;dw -24, 56 : db $03, $02, $00, $00
|
|
;
|
|
;dw 0, 56 : db $12, $02, $00, $00
|
|
;dw 8, 56 : db $13, $02, $00, $00
|
|
;dw 16, 56 : db $22, $02, $00, $00
|
|
;dw 24, 56 : db $23, $02, $00, $00
|
|
;
|
|
;dw 48, 56 : db $32, $02, $00, $00
|
|
;dw 56, 56 : db $33, $02, $00, $00
|
|
;dw 64, 56 : db $30, $02, $00, $00
|
|
;dw 72, 56 : db $31, $02, $00, $00
|
|
;--------------------------------------------------------------------------------
|