Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
279 changes: 208 additions & 71 deletions shopkeeper.asm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ macro UploadOAM(dest)
.done
PLP : PLA
endmacro

BigRAMStore:
STA !BIGRAM, X : INX : INX : RTS
;--------------------------------------------------------------------------------
; $0A : Digit Offset
; $0C-$0D : Value to Display
Expand All @@ -55,11 +58,11 @@ macro DrawDigit(value,offset)
LDY.b <offset>
LDA $0E : !ADD.w .digit_offsets, Y : STA $0E
+
LDA $0E : STA !BIGRAM, X : INX : INX
LDA.w #56 : STA !BIGRAM, X : INX : INX
LDA $0E : JSR BigRAMStore
LDA.w #56 : JSR BigRAMStore
LDA $A0 : CMP.l #$109 : BNE + : LDA.w #$FFCA : STA !BIGRAM-2, X : +
LDY $0A : TYA : ASL : TAY : LDA.w .digit_properties, Y : STA !BIGRAM, X : INX : INX
LDA.w #$0000 : STA !BIGRAM, X : INX : INX
LDY $0A : TYA : ASL : TAY : LDA.w .digit_properties, Y : JSR BigRAMStore
LDA.w #$0000 : JSR BigRAMStore

LDA $0E : !ADD.w #$0008 : STA $0E ; move offset 8px right
endmacro
Expand All @@ -75,6 +78,82 @@ DrawPrice:
LDY.b #$FF
LDX #$00 ; clear bigram pointer

REP #$20

; set up shop shuffle star
; i set it all up before then backtrack (dex #8) because i hate 16-bit 8-bit accumulator logic mixups
LDA $0E : !ADD.w #$10 : JSR BigRAMStore ; change this to a set distance from center
LDA.w #36 : JSR BigRAMStore
LDA $A0 : CMP.l #$109 : BNE + : LDA.w #$FFAA : STA !BIGRAM-2, X : +
LDA.w #$0391 : JSR BigRAMStore ; Yellow Star
LDA.w #$0000 : JSR BigRAMStore : STX $06

SEP #$20 ; set 8-bit accumulator
LDX $07 : LDA.l !SHOP_INVENTORY+3, X : CMP.b #$40 : !BGE +++ ; do not render on base items
; LDA.b $07 : LSR #2 : TAX : LDA.l !SHOP_INVENTORY_PLAYER, X : BEQ ++ ; use a different icon if multiworld
; LDX $06 : LDA.b #$09 : STA !BIGRAM-3, X : LDA.b #$92 : STA !BIGRAM-4, X : BRA ++++ : ++
LDX $06 : BRA ++++
+++ : LDX $06 : DEX #8
++++
REP #$20

LDA $0D : AND.w #$80 : BNE ++
BRL .normal_price
++
; AT price location $0C-0D
; 0D item type (if highest bit is set 0x80, use 0x7F to determine type of price)
; 0C special price value 1-255
; Rupees = (normal price type)
; Hearts = 0
; Magic = 1
; Bomb = 2
; Arrows = 3
; HeartContainer = 4
; BombUpgrade = 5
; ArrowUpgrade = 6
; Keys = 7
; Potion = 8
; Item = 9
LDA $0E : !SUB.W #$04 : JSR BigRAMStore
LDA.w #56 : JSR BigRAMStore
LDA $A0 : CMP.l #$109 : BNE + : LDA.w #$FFCA : STA !BIGRAM-2, X : + ; potion shop check
LDA $0D : AND #$000F : ASL : PHX : TAX : PHX : LSR : TAX;; Store OAM X, ICON array X (with A), LSR then get Adjust, then PLX
LDA $0C : AND.w #$FF
LDY .adjust_value, X : BEQ + ; Adjust "value" to less arbitrary number, (a 255 value of magic reduced to 32 pips) but should probably just use graphcis
- : LSR : DEY : BNE -
+ : STA $0C : PLX
LDA.w .icon_graphics, X : PLX : JSR BigRAMStore
; Compare current Icon_Graphics (didn't feel like reloading price) to determine further icon adjusting
; We should be able to just write new graphics and patch them in instead, but I don't know how to do that with SNES
CMP.w #$0563 : BNE +
LDA.w #54
JSR LongPriceIcon
LDA.w #$0573 : JSR BigRAMStore
+
CMP.w #$0D63 : BNE +
LDA.w #54
JSR LongPriceIcon
LDA.w #$0D73 : JSR BigRAMStore
+
CMP.w #$056B : BNE +
LDA.w #53
JSR LongPriceIcon
LDA.w #$057B : JSR BigRAMStore
+
CMP.w #$0272 : BNE +
PHX
LDA $0C : ASL : TAX : LDA .icon_graphics_bottle, X
PLX : STA !BIGRAM-2, X
LDA.w #$0000 : JSR BigRAMStore
LDA $0E : !ADD.w #$8 : STA $0E ; move offset 8px right
BRL .len0
+
.icon_done
LDA.w #$0000 : JSR BigRAMStore
LDA $0E : !ADD.w #$8 : STA $0E ; move offset 8px right
BRL .len2

.normal_price
LDA $0C : CMP.w #1000 : !BLT + : BRL .len4 : +
CMP.w #100 : !BLT + : BRL .len3 : +
CMP.w #10 : !BLT + : BRL .len2 : +
Expand All @@ -90,25 +169,13 @@ DrawPrice:
%DrawDigit(#10,#2)

.len1
.len0
%DrawDigit(#1,#0)

.len0
.okay

; set up shop shuffle star
; i set it all up before then backtrack (dex #8) because i hate 16-bit 8-bit accumulator logic mixups
LDA $0E : STA !BIGRAM, X : INX : INX ; change this to a set distance from center
LDA.w #36 : STA !BIGRAM, X : INX : INX
LDA $A0 : CMP.l #$109 : BNE + : LDA.w #$FFAA : STA !BIGRAM-2, X : +
LDA.w #$0391 : STA !BIGRAM, X : INX : INX ; Yellow Star
LDA.w #$0000 : STA !BIGRAM, X : INX : INX : STX $06
SEP #$20

SEP #$20 ; set 8-bit accumulator
LDX $07 : LDA.l !SHOP_INVENTORY+3, X : CMP.b #$40 : !BGE +++ ; do not render on base items
; LDA.b $07 : LSR #2 : TAX : LDA.l !SHOP_INVENTORY_PLAYER, X : BEQ ++ ; use a different icon if multiworld
; LDX $06 : LDA.b #$09 : STA !BIGRAM-3, X : LDA.b #$92 : STA !BIGRAM-4, X : BRA ++++ : ++
LDX $06 : BRA ++++
+++ : LDX $06 : DEX #8
++++
TXA : LSR #3 : STA $06 ; request 1-4 OAM slots
ASL #2
PHA
Expand All @@ -122,6 +189,36 @@ DrawPrice:
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
;--------------------------------------------------------------------------------
.icon_graphics
dw $0329, $0960, $8570, $0563, $0d29, $8d70, $0d63, $056b, $0272, $0991
;-------------------------------------------------------------------
.icon_graphics_bottle
dw $0372, $0972, $0572, $0b72, $0d72, $0d72
;--------------------------------------------------------------------------------
.adjust_value:
db $03, $03, $00, $00, $03, $00, $00, $00, $00, $00, $00, $00
;------
ResourceOffset: ; where is our special price (8-bit) in memory relative to memaddress (i forgot the address)
db $6D, $6E, $43, $77, $6C, $70, $71, $6F, $00

LongPriceIcon:
; A == Y offset
; Y == secondary Y offset (potentially)
STA !BIGRAM-4, X ; TODO: use subtraction for potion shop offset
LDA $A0 : CMP.l #$109 : BNE + : LDA.w #$FFC8 : STA !BIGRAM-4, X : +
LDA.w #$0000 : JSR BigRAMStore
LDA $0E : !SUB.W #$04 : JSR BigRAMStore ; arrow Y POSITION
LDA.w #58 : JSR BigRAMStore
LDA $A0 : CMP.l #$109 : BNE + : LDA.w #$FFC8 : STA !BIGRAM-2, X : +
RTS

;--------------------------------------------------------------------------------
!TILE_UPLOAD_OFFSET_OVERRIDE = "$7F5042"
!FREE_TILE_BUFFER = "#$1180"
Expand All @@ -142,12 +239,6 @@ RTS
;--------------------------------------------------------------------------------
!NMI_AUX = "$7F5044"
;--------------------------------------------------------------------------------
.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

Expand Down Expand Up @@ -178,55 +269,16 @@ SpritePrep_ShopKeeper:

.success
SEP #$20 ; set 8-bit accumulator

LDX.w #$0000
LDY.w #$0000
-
TYA : CMP !SHOP_CAPACITY : !BLT ++ : BRL .stop : ++
LDA.l ShopContentsTable+1, X : CMP.b #$FF : BNE ++ : BRL .stop : ++

LDA.l ShopContentsTable, X : CMP !SHOP_ID : BEQ ++ : BRL .next : ++
LDA.l ShopContentsTable+1, X : PHX : TYX : STA.l !SHOP_INVENTORY, X : PLX
LDA.l ShopContentsTable+2, X : PHX : TYX : STA.l !SHOP_INVENTORY+1, X : PLX
LDA.l ShopContentsTable+3, X : PHX : TYX : STA.l !SHOP_INVENTORY+2, X : PLX
LDA.l ShopContentsTable+8, X : PHX : PHA
LDA #0 : XBA : TYA : LSR #2 : TAX ; This will convert the value back to the slot number (in 8-bit accumulator mode)
PLA : STA.l !SHOP_INVENTORY_PLAYER, X : LDA #0 : STA.l !SHOP_INVENTORY_DISGUISE, X : PLX

PHY
PHX
LDA.b #$00 : XBA : TYA : LSR #2 : !ADD !SHOP_SRAM_INDEX : TAX
LDA !SHOP_PURCHASE_COUNTS, X : TYX : STA.l !SHOP_INVENTORY+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 !SHOP_INVENTORY, X : PLX
LDA.l ShopContentsTable+6, X : PHX : TYX : STA.l !SHOP_INVENTORY+1, X : PLX
LDA.l ShopContentsTable+7, X : PHX : TYX : STA.l !SHOP_INVENTORY+2, X : PLX
LDA #$40 : PHX : TYX : STA.l !SHOP_INVENTORY+3, X : PLX
PHX : LDA #0 : XBA : TYA : LSR #2 : TAX ; This will convert the value back to the slot number (in 8-bit accumulator mode)
LDA #0 : STA.l !SHOP_INVENTORY_PLAYER, X : PLX
BRA +++
+ : PLY : LDA #$40 : PHX : TYX : STA.l !SHOP_INVENTORY+3, X : PLX : BRA +++
++ : PLY : +++


PHX : PHY
PHX : TYX : LDA.l !SHOP_INVENTORY, X : PLX
CMP #$5A : BEQ ++
CMP #$B0 : BNE + : ++
PHX : LDA #0 : XBA : TYA : LSR #2 : TAX ; This will convert the value back to the slot number (in 8-bit accumulator mode)
JSL GetRandomInt : AND #$3F : STA !BEE_TRAP_DISGUISE
BNE ++ : LDA #$49 : ++ : CMP #$26 : BNE ++ : LDA #$6A : ++ ; if 0 (fighter's sword + shield), set to just sword, if filled container (bugged palette), switch to triforce piece
STA.l !SHOP_INVENTORY_DISGUISE, X : PLX
+ : TAY
REP #$20 ; set 16-bit accumulator
LDA 1,s : TAX : LDA.l .tile_offsets, X : TAX
JSR LoadTile
PLY : PLX
INY #4 ; width of shop inventory item
JSR SetupShopItem
INY #4 ; width of shop inventory item

.next
INX #9 ; width of shop contents table
Expand All @@ -236,9 +288,9 @@ SpritePrep_ShopKeeper:
LDA #$01 : STA !NMI_AUX+2 : STA !NMI_AUX

.done

LDA.l !SHOP_TYPE : BIT.b #$20 : BEQ .notTakeAll ; Take-all
.takeAll

LDA.b #$00 : XBA : LDA !SHOP_SRAM_INDEX : TAX
LDA.l !SHOP_PURCHASE_COUNTS, X
BRA ++
Expand Down Expand Up @@ -267,6 +319,48 @@ SpritePrep_ShopKeeper:
JML.l ShopkeeperFinishInit
+
RTL
SetupShopItem:
LDA.l ShopContentsTable+1, X : PHX : TYX : STA.l !SHOP_INVENTORY, X : PLX
LDA.l ShopContentsTable+2, X : PHX : TYX : STA.l !SHOP_INVENTORY+1, X : PLX
LDA.l ShopContentsTable+3, X : PHX : TYX : STA.l !SHOP_INVENTORY+2, X : PLX
LDA.l ShopContentsTable+8, X : PHX : PHA
LDA #0 : XBA : TYA : LSR #2 : TAX ; This will convert the value back to the slot number (in 8-bit accumulator mode)
PLA : STA.l !SHOP_INVENTORY_PLAYER, X : LDA #0 : STA.l !SHOP_INVENTORY_DISGUISE, X : PLX

PHY
PHX
LDA.b #$00 : XBA : TYA : LSR #2 : !ADD !SHOP_SRAM_INDEX : TAX
LDA !SHOP_PURCHASE_COUNTS, X : TYX : STA.l !SHOP_INVENTORY+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 !SHOP_INVENTORY, X : PLX
LDA.l ShopContentsTable+6, X : PHX : TYX : STA.l !SHOP_INVENTORY+1, X : PLX
LDA.l ShopContentsTable+7, X : PHX : TYX : STA.l !SHOP_INVENTORY+2, X : PLX
LDA #$40 : PHX : TYX : STA.l !SHOP_INVENTORY+3, X : PLX
PHX : LDA #0 : XBA : TYA : LSR #2 : TAX ; This will convert the value back to the slot number (in 8-bit accumulator mode)
LDA #0 : STA.l !SHOP_INVENTORY_PLAYER, X : PLX
BRA +++
+ : PLY : LDA #$40 : PHX : TYX : STA.l !SHOP_INVENTORY+3, X : PLX : BRA +++
++ : PLY
+++

PHX : PHY
PHX : TYX : LDA.l !SHOP_INVENTORY, X : PLX
CMP #$5A : BEQ ++
CMP #$B0 : BNE + : ++
PHX : LDA #0 : XBA : TYA : LSR #2 : TAX ; This will convert the value back to the slot number (in 8-bit accumulator mode)
JSL GetRandomInt : AND #$3F : STA !BEE_TRAP_DISGUISE
BNE ++ : LDA #$49 : ++ : CMP #$26 : BNE ++ : LDA #$6A : ++ ; if 0 (fighter's sword + shield), set to just sword, if filled container (bugged palette), switch to triforce piece
STA.l !SHOP_INVENTORY_DISGUISE, X : PLX
+ : TAY
REP #$20 ; set 16-bit accumulator
LDA 1,s : TAX : LDA.l .tile_offsets, X : TAX
JSR LoadTile
PLY : PLX
RTS
.tile_offsets
dw $0000, $0000
dw $0080, $0000
Expand Down Expand Up @@ -557,6 +651,14 @@ Shopkeeper_SetupHitboxes:

PLP : PLY : PLX
RTS

GetFunnyBottleFunction:
; A = contents - 3 (red, green, blue, fairy, bee, goldbee)
PHX : PHA
LDA $7EF34F : BEQ .noBottle : TAX : DEX : PLA : !ADD #$3 : PHA
CMP $7EF35C, X : BNE .noBottle
.hasBottle : PLA : INX : TXA : PLX : RTS
.noBottle : PLA : PLX : LDA #$0 : RTS
!LOCK_STATS = "$7EF443"
!ITEM_TOTAL = "$7EF423"
;--------------------
Expand All @@ -573,11 +675,41 @@ Shopkeeper_BuyItem:
CMP.b #$B2 : BEQ .refill ; Good Bee Refill
BRA +
.refill
JSL.l Sprite_GetEmptyBottleIndex : BMI .full_bottles
LDA #$1 : STA !SHOP_KEEP_REFILL ; If this is on, don't toggle bit to remove from shop
JSL.l Sprite_GetEmptyBottleIndex : BPL + : BRL .full_bottles
+

LDA !SHOP_TYPE : AND.b #$80 : BNE .buy ; don't charge if this is a take-any
LDA !SHOP_TYPE : AND.b #$80 : BEQ + : BRL .buy : + ; don't charge if this is a take-any

.custom_price
LDA !SHOP_INVENTORY+2, X : AND.b #$80 : BEQ .price_is_rupees ; i honestly can't think of a better way to do this block because i haven't done asm in like 8 months
LDA !SHOP_INVENTORY+2, X : AND.b #$7F : CMP.b #$09 : BNE + ; 09 specifically is item
LDA !SHOP_INVENTORY+1, X : CMP.b $0303 : BNE .gotItem
BRL .cant_afford
.gotItem ; hand it over?? not logic friendly
BRL .buy_real
+
CMP.b #$08 : BNE + ; 08 specifically is potion
LDA !SHOP_INVENTORY+1, X : JSR GetFunnyBottleFunction : CMP #$0 : BNE .gotBottle
BRL .cant_afford
.gotBottle
PHX : LDA $7EF34F : TAX : DEX : LDA #$02 : STA $7EF35C, X : PLX : BRL .buy_real
+
LDA !SHOP_INVENTORY+2, X : AND.b #$07 ; if bit 80, it's custom, if numbers 0-7, custom resource
; store shop index, get resource offset (X), load val, pop shop index, cmp val to shop_price...
PHX : TAX : LDA ResourceOffset, X : TAX : TAY : LDA $7EF300, X ; fumble around with our resource value and price, sub value then put back into RAM
PLX : CMP !SHOP_INVENTORY+1,X : BCC + ; if resource is less than value, skip
; subtract and store, store (x), store val back to address
; if X is heart containers, set ordinary hearts
!SUB !SHOP_INVENTORY+1,X : PHX : TYX : STA $7EF300, X
CPX #$6C : BNE .notHeartContainers
CMP $7EF36D : !BGE .notHeartContainers : STA $7EF36D
.notHeartContainers
PLX : BRL .buy_real
+
BRL .cant_afford
.price_is_rupees

REP #$20 : LDA $7EF360 : CMP.l !SHOP_INVENTORY+1, X : SEP #$20 : !BGE .buy

.cant_afford
Expand All @@ -602,6 +734,7 @@ Shopkeeper_BuyItem:
LDA #0 : XBA : TXA : LSR #2 : TAX : LDA.l !SHOP_INVENTORY_PLAYER, X : STA !MULTIWORLD_ITEM_PLAYER_ID
LDA.l !SHOP_TYPE : BIT.b #$80 : BNE + ;Is the shop location a take-any cave
TXA : !ADD !SHOP_SRAM_INDEX : TAX : BRA ++ ;If so, explicitly load first SRAM Slot.

+ LDA.l !SHOP_SRAM_INDEX : TAX

++ LDA.l !SHOP_PURCHASE_COUNTS, X : BNE +++ ;Is this the first time buying this slot?
Expand All @@ -611,7 +744,7 @@ Shopkeeper_BuyItem:
LDA.l !SHOP_INVENTORY, X : TAY : JSL.l Link_ReceiveItem
LDA.l !SHOP_INVENTORY+3, X : INC : STA.l !SHOP_INVENTORY+3, X
LDA.b #0 : STA.l !SHOP_ENABLE_COUNT

TXA : LSR #2 : TAX
LDA !SHOP_TYPE : BIT.b #$80 : BNE +
LDA !SHOP_KEEP_REFILL : BNE +++
Expand Down Expand Up @@ -657,11 +790,15 @@ Shopkeeper_BuyItem:
LDA.l !SHOP_SRAM_INDEX : TAX : LDA.l !SHOP_STATE : STA.l !SHOP_PURCHASE_COUNTS, X
PLX
++
; JSL SpritePrep_ShopKeeper ;; reloads entire shop again
; JSL.l ReloadShopkeep
.done
LDA #$0 : STA !SHOP_KEEP_REFILL
PLY : PLX
RTS
ReloadShopkeep:
PHX : PHY : PHP
REP #$30 ; set 16-bit accumulator & index registers
JMP SpritePrep_ShopKeeper_success
Shopkeeper_ItemMasks:
db #$01, #$02, #$04, #$08
;--------------------
Expand Down