Implmented New Item GFX System

This commit is contained in:
codemann8
2024-03-01 14:00:10 -06:00
parent 59eb254116
commit a008406fde
17 changed files with 235 additions and 213 deletions

View File

@@ -2,22 +2,20 @@
; Randomize Book of Mudora
;--------------------------------------------------------------------------------
LoadLibraryItemGFX:
LDA.l LibraryItem_Player : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
%GetPossiblyEncryptedItem(LibraryItem, SpriteItemValues)
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteID, X
JML RequestStandingItemVRAMSlot
LDA.l LibraryItem_Player : STA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
%GetPossiblyEncryptedItem(LibraryItem, SpriteItemValues)
STA.w SprSourceItemId, X
JML RequestStandingItemVRAMSlot
;--------------------------------------------------------------------------------
DrawLibraryItemGFX:
PHA
LDA.w SpriteID, X
LDA.w SprItemReceipt, X
JSL DrawPotItem
PLA
RTL
;--------------------------------------------------------------------------------
SetLibraryItem:
LDY.w SpriteID, X
LDY.w SprItemReceipt, X
JSL ItemSet_Library ; contains thing we wrote over
RTL
;--------------------------------------------------------------------------------
@@ -29,17 +27,14 @@ RTL
LoadBonkItemGFX:
LDA.b #$08 : STA.w SpriteOAMProp, X ; thing we wrote over
LoadBonkItemGFX_inner:
JSR LoadBonkItem_Player : STA !MULTIWORLD_SPRITEITEM_PLAYER_ID
JSR LoadBonkItem_Player : STA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
JSR LoadBonkItem
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteItemType, X
STA.w SpriteID, X
STA.w SprSourceItemId, X
JSL RequestStandingItemVRAMSlot
PHA : PHX
LDA.w SpriteID,X : TAX
LDA.w SprItemReceipt,X : TAX
LDA.l SpriteProperties_standing_width,X : BNE +
LDA.b #$00 : STA.l SpriteOAM : STA.l SpriteOAM+8
LDA.b #$00 : STA.l SpriteDynamicOAM : STA.l SpriteDynamicOAM+8
+
PLX : PLA
RTL
@@ -52,7 +47,7 @@ DrawBonkItemGFX:
BRA .done ; don't draw on the init frame
.skipInit
LDA.w SpriteID,X
LDA.w SprItemReceipt,X
JSL DrawPotItem
.done
@@ -60,8 +55,8 @@ DrawBonkItemGFX:
RTL
;--------------------------------------------------------------------------------
GiveBonkItem:
JSR LoadBonkItem_Player : STA !MULTIWORLD_ITEM_PLAYER_ID
JSR LoadBonkItem
LDA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_ITEM_PLAYER_ID
LDA.w SprItemReceipt, X
JSR AbsorbKeyCheck : BCC .notKey
.key
PHY : LDY.b #$24 : JSL AddInventory : PLY ; do inventory processing for a small key

View File

@@ -197,16 +197,19 @@ PostNMIUpdateBGCharHalf:
LDA.w VRAMTileMapIndex : CMP.b #$46 : BNE .return ; checks to see if this is the last VRAM write
LDA.b LinkState : CMP.b #$08 : BCC + : CMP.b #$0A+1 : BCS + ; skip if we're mid-medallion
RTL
+ JSL HeartPieceSetRedraw ; set redraw flag for items
+ JSL DynamicDropGFXClear
JSL HeartPieceSetRedraw ; set redraw flag for items
.return
RTL
; Force redraws of items following map checks
PostOverworldGfxLoad:
INC.b GameSubMode : STZ.b INIDISPQ ; what we wrote over
JSL DynamicDropGFXClear
JSL HeartPieceSetRedraw
RTL
PostUnderworldMap:
JSL DynamicDropGFXClear
JSL HeartPieceSetRedraw
LDA.l $7EC229 ; what we wrote over
RTL

View File

@@ -3,6 +3,7 @@
;--------------------------------------------------------------------------------
SpawnDungeonPrize:
PHX : PHB
PHA : LDA.b #$00 : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID : PLA
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w ItemReceiptID
@@ -12,7 +13,7 @@ SpawnDungeonPrize:
JSL AddAncillaLong
BCS .failed_spawn
LDA.w ItemReceiptID
STA.w AncillaGet,X : STA.w SpriteID,X
STA.w AncillaGet,X : STA.w SprItemReceipt,X
JSR AddDungeonPrizeAncilla
.failed_spawn
PLB : PLX
@@ -61,10 +62,11 @@ RTS
PrepPrizeTile:
PHA : PHX : PHY
LDA.b #$00 : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w AncillaGet, X
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteID,X
STA.w SprItemReceipt,X
JSL TransferItemReceiptToBuffer_using_ReceiptID
PLY : PLX : PLA
RTL

View File

@@ -1,3 +1,6 @@
org $89C4E3
JSL Overworld_LoadSprites_Decision
org $89C50B ; 0x4C50B
{
; .loadData

View File

@@ -6,3 +6,11 @@ LoadOverworldSprites:
; set bank
LDA.b #$09 : STA.b Scrap02 ; default is bank 9
RTL
; return A = $03 for post-aga enemies, $02 for pre-aga enemies, else rain state enemies
Overworld_LoadSprites_Decision:
PHY : SEP #$10
JSL ClearSpriteData_shared
REP #$10 : PLY
LDA.l ProgressIndicator ; what we wrote over
RTL

View File

@@ -24,15 +24,18 @@ OnDungeonEntrance:
STA.l PegColor ; thing we wrote over
JSL MaybeFlagDungeonTotalsEntrance
INC.w UpdateHUDFlag
JSL DynamicDropGFXClear
RTL
;--------------------------------------------------------------------------------
OnDungeonBossExit:
JSL StatTransitionCounter
JSL DynamicDropGFXClear
RTL
;--------------------------------------------------------------------------------
OnPlayerDead:
PHA
JSL SetDeathWorldChecked
JSL DynamicDropGFXClear
JSL SetSilverBowMode
JSL RefreshRainAmmo
PLA
@@ -42,6 +45,7 @@ OnDungeonExit:
PHA : PHP
SEP #$20 ; set 8-bit accumulator
JSL SQEGFix
JSL DynamicDropGFXClear
PLP : PLA
STA.w DungeonID : STZ.w Map16ChangeIndex ; thing we wrote over
@@ -163,6 +167,7 @@ OnFileLoad:
LDA.l CurrentGenericKeys : STA.l CurrentSmallKeys ; copy generic keys to key counter
+
JSL DynamicDropGFXClear
JSL SetSilverBowMode
JSL RefreshRainAmmo
JSL SetEscapeAssist

View File

@@ -3,15 +3,21 @@
;--------------------------------------------------------------------------------
HeartPieceGet:
PHX : PHY
JSL LoadHeartPieceRoomValue
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
TAY
LDA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_ITEM_PLAYER_ID : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDY.w SprItemReceipt, X : BNE +
LDA.w SprSourceItemId, X : BNE ++
JSL LoadHeartPieceRoomValue
STA.w SprSourceItemId, X
++
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SprItemReceipt, X
TAY
+
JSL MaybeMarkDigSpotCollected
.skipLoad
JSL HeartPieceGetPlayer : STA.l !MULTIWORLD_ITEM_PLAYER_ID
CPY.b #$26 : BNE .not_heart ; don't add a 1/4 heart if it's not a heart piece
LDA.l !MULTIWORLD_ITEM_PLAYER_ID : BNE .not_heart
LDA.w SprItemMWPlayer, X : BNE .not_heart
LDA.l HeartPieceQuarter : INC A : AND.b #$03 : STA.l HeartPieceQuarter
.not_heart
JSL Player_HaltDashAttackLong
@@ -25,8 +31,15 @@ RTL
HeartContainerGet:
PHX : PHY
JSL IncrementBossSword
LDY.w SpriteID, X : BNE +
JSL LoadHeartContainerRoomValue : TAY
LDY.w SprItemReceipt, X : BNE +
LDA.w SprSourceItemId, X : BNE ++
JSL LoadHeartContainerRoomValue
STA.w SprSourceItemId, X
++
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SprItemReceipt, X
TAY
+
BRA HeartPieceGet_skipLoad
;--------------------------------------------------------------------------------
@@ -39,7 +52,7 @@ DrawHeartPieceGFX:
LDA.w SprRedrawFlag, X : CMP.b #$02 : BEQ .skipInit
BRA .done ; don't draw on the init frame
.skipInit
LDA.w SpriteID, X ; Retrieve stored item type
LDA.w SprItemReceipt, X ; Retrieve stored item type
.skipLoad
PHA : PHX
TAX
@@ -73,7 +86,7 @@ DrawHeartContainerGFX:
BRA DrawHeartPieceGFX_done ; don't draw on the init frame
.skipInit
LDA.w SpriteID, X ; Retrieve stored item type
LDA.w SprItemReceipt, X ; Retrieve stored item type
BRA DrawHeartPieceGFX_skipLoad
;--------------------------------------------------------------------------------
@@ -108,33 +121,20 @@ RTL
RTL
;--------------------------------------------------------------------------------
HeartPieceSpritePrep:
PHA
LDA.l ServerRequestMode : BEQ + : : +
JSL HeartPieceGetPlayer : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
JSL LoadHeartPieceRoomValue
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteID, X
JSL RequestStandingItemVRAMSlot
.skip
PLA
RTL
JSL HeartPieceGetPlayer : STA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w SprSourceItemId, X : BNE +
JSL LoadHeartPieceRoomValue
STA.w SprSourceItemId, X
+ JML RequestStandingItemVRAMSlot
;--------------------------------------------------------------------------------
HeartContainerSpritePrep:
PHA
JSL HeartPieceGetPlayer : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
JSL LoadHeartContainerRoomValue ; load item type
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteID, X
JSL RequestStandingItemVRAMSlot
PLA
RTL
JSL HeartPieceGetPlayer : STA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w SprSourceItemId, X : BNE +
JSL LoadHeartContainerRoomValue ; load item type
STA.w SprSourceItemId, X
+ JML RequestStandingItemVRAMSlot
;--------------------------------------------------------------------------------
LoadHeartPieceRoomValue:
LDA.b IndoorsFlag : BEQ .outdoors ; check if we're indoors or outdoors
@@ -160,8 +160,6 @@ HPItemReset:
PHA : PHY
LDY.b #$0F
- LDA.w SpriteAITable,Y : BEQ +
LDA.w SprRedrawFlag, Y : CMP.b #$02 : BNE +
; attempt redraw of any sprite using the overflow slot
LDA.b #$01 : STA.w SprRedrawFlag, Y
+ DEY : BPL -
PLY : PLA
@@ -240,7 +238,7 @@ LoadIndoorValue:
+
PHX
LDX.w CurrentSpriteSlot ; If we're on a different screen ID via glitches load the sprite
LDA.w SpriteID,X ; we can see and are interacting with
LDA.w SprItemReceipt,X ; we can see and are interacting with
PLX
.done
AND.w #$00FF ; the loads are words but the values are 1-byte so we need to clear the top half of the accumulator - no guarantee it was 8-bit before
@@ -445,7 +443,7 @@ LoadOutdoorValue:
+
PHX
LDX.w CurrentSpriteSlot ; If we're on a different screen ID via glitches load the sprite
LDA.w SpriteID,X ; we can see and are interacting with.
LDA.w SprItemReceipt,X ; we can see and are interacting with.
PLX
.done
AND.w #$00FF ; the loads are words but the values are 1-byte so we need to clear the top half of the accumulator - no guarantee it was 8-bit before

View File

@@ -561,13 +561,17 @@ RTL
;--------------------------------------------------------------------------------
LoadPowder:
JSL Sprite_SpawnDynamically ; thing we wrote over
LDA.l WitchItem_Player : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
%GetPossiblyEncryptedItem(WitchItem, SpriteItemValues)
JSL AttemptItemSubstitution
.justGFX
LDA.l WitchItem_Player : STA.w SprItemMWPlayer, Y : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w SprSourceItemId, Y : BNE +
%GetPossiblyEncryptedItem(WitchItem, SpriteItemValues)
STA.w SprSourceItemId, Y
+ JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteID, Y
STA.l PowderFlag
LDA.b #$01 : STA.w SprRedrawFlag, Y
PHX : TYX : PLY
JSL RequestStandingItemVRAMSlot_resolved
PHY : TXY : PLX
RTL
;--------------------------------------------------------------------------------
@@ -590,13 +594,11 @@ RTL
DrawPowder:
;LDA.w ItemReceiptPose : BNE .defer ; defer if link is buying a potion
LDA.w SprRedrawFlag, X : BEQ +
LDA.l WitchItem_Player : STA !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w SpriteID, X ; Retrieve stored item type
JML RequestStandingItemVRAMSlot
JML LoadPowder_justGFX
+
; this fights with the shopkeep code, so had to move the powder draw there when potion shop is custom
; LDA.l ShopType : CMP.b #$FF : BNE .defer
LDA.w SpriteID, X ; Retrieve stored item type
LDA.w SprItemReceipt, X ; Retrieve stored item type
JML DrawPotItem
.defer
RTL
@@ -609,15 +611,11 @@ LoadMushroom:
LDA.b #$00 : STA.w SpriteGFXControl, X ; thing we wrote over
.justGFX
PHA
LDA.l MushroomItem_Player : STA !MULTIWORLD_SPRITEITEM_PLAYER_ID
%GetPossiblyEncryptedItem(MushroomItem, SpriteItemValues)
JSL AttemptItemSubstitution
JSR ResolveLootID
STA.w SpriteID,X
JSL RequestStandingItemVRAMSlot
.skip
LDA.l MushroomItem_Player : STA.w SprItemMWPlayer : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w SprSourceItemId, X : BNE +
%GetPossiblyEncryptedItem(MushroomItem, SpriteItemValues)
STA.w SprSourceItemId, X
+ JSL RequestStandingItemVRAMSlot
PLA
RTL
;--------------------------------------------------------------------------------
@@ -627,13 +625,13 @@ RTL
;--------------------------------------------------------------------------------
DrawMushroom:
PHA : PHY
LDA.w SprRedrawFlag, X : BEQ .skipInit ; skip init if already ready
LDA.w SprRedrawFlag, X : BEQ .draw ; skip init if already ready
JSL LoadMushroom_justGFX
LDA.w SprRedrawFlag, X : CMP.b #$02 : BEQ .skipInit
LDA.w SprRedrawFlag, X : CMP.b #$02 : BEQ .draw
BRA .done ; don't draw on the init frame
.skipInit
LDA.w SpriteID, X ; Retrieve stored item type
.draw
LDA.w SprItemReceipt, X ; Retrieve stored item type
JSL DrawPotItem
.done
@@ -645,7 +643,7 @@ RTL
; CollectPowder:
;--------------------------------------------------------------------------------
CollectPowder:
LDY.w SpriteID, X ; Retrieve stored item type
LDY.w SprItemReceipt, X ; Retrieve stored item type
BNE +
; if for any reason the item value is 0 reload it, just in case
%GetPossiblyEncryptedItem(WitchItem, SpriteItemValues) : TAY

View File

@@ -5,6 +5,11 @@
; A = item receipt ID
; X = sprite slot
RequestStandingItemVRAMSlot:
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
.resolved
STA.w SprItemReceipt, X
JSL ResolveBeeTrapLong
PHX : PHY
PHA
LDA.b #$01 : STA.w SprRedrawFlag, X
@@ -13,26 +18,20 @@ RequestStandingItemVRAMSlot:
LDA.b GameSubMode : CMP.b #$21 : BCS ++ ; skip if OW is loading Map16 GFX ; TODO: Figure out how to allow submodule 22, check DMA status instead
LDA.b LinkState : CMP.b #$14 : BEQ ++ ; skip if we're mid-mirror
LDA.b IndoorsFlag : BEQ + ; OW current doesn't occupy any slots that medallion gfx do
CMP.b #$08 : BCC + : CMP.b #$0A+1 : BCS + ; skip if we're mid-medallion
LDA.w GfxChrHalfSlotVerify : CMP.b #$03 : BCC +
++ PLA : JMP .return
+
LDA.w SpriteTypeTable, X : CMP.b #$C0 : BNE + ; if catfish
TYX
+ CMP.b #$52 : BNE + ; if zora
TYX
+
LDA.b 1,S : PHX : JSL GetSpritePalette : PLX : STA.w SpriteOAMProp, X ; setup the palette
PLA
; gfx that are already present, use that instead of a new slot
; gfx that are already present in vanilla, use that instead of a new slot
CMP.b #$34 : BCC + : CMP.b #$36+1 : BCS + ; if rupees, use animated rupee OAM slot
LDA.b IndoorsFlag : BEQ ++
LDA.b #!DynamicDropGFXSlotCount_UW
BRA +++
++ LDA.b #!DynamicDropGFXSlotCount_OW
+++ INC : STA.w SprItemGFX,X
+++ INC : STA.w SprItemGFXSlot,X
JMP .success
+ CMP.b #$A0 : BCC + : CMP.b #$AF+1 : BCS + ; if key, use key OAM slot
LDY.b LinkState : CPY.b #$19 : BCC ++ : CPY.b #$1A+1 : BCS ++ ; if getting tablet item, don't use key slot
@@ -42,87 +41,103 @@ RequestStandingItemVRAMSlot:
LDA.b #!DynamicDropGFXSlotCount_UW
BRA +++
++ LDA.b #!DynamicDropGFXSlotCount_OW
+++ INC #2 : STA.w SprItemGFX,X
+++ INC #2 : STA.w SprItemGFXSlot,X
JMP .success
+ CMP.b #$D6 : BNE + ; if good bee, use bee OAM slot
LDA.b IndoorsFlag : BEQ ++
LDA.b #!DynamicDropGFXSlotCount_UW
BRA +++
++ LDA.b #!DynamicDropGFXSlotCount_OW
+++ INC #3 : STA.w SprItemGFX,X
+++ INC #3 : STA.w SprItemGFXSlot,X
JMP .success
+ CMP.b #$D2 : BNE + ; if fairy, use fairy OAM slot
LDA.b IndoorsFlag : BEQ ++
LDA.b #!DynamicDropGFXSlotCount_UW
BRA +++
++ LDA.b #!DynamicDropGFXSlotCount_OW
+++ INC : STA.w SprItemGFX,X
+++ INC : STA.w SprItemGFXSlot,X
JMP .success
+ CMP.b #$D1 : BNE + ; if apple, use apple OAM slot
LDA.b IndoorsFlag : BEQ ++
LDA.b #!DynamicDropGFXSlotCount_UW
BRA +++
++ LDA.b #!DynamicDropGFXSlotCount_OW
+++ INC #2 : STA.w SprItemGFX,X
+++ INC #2 : STA.w SprItemGFXSlot,X
JMP .success
+
PHA
LDA.w DynamicDropGFXIndex
INC
; check if gfx that are already present from previous requests
LDY.b #$00
- LDA.w DynamicDropGFXSlots, Y : CMP.b 1,S : BEQ +
INY : CPY.b #$0F : !BLT -
STZ.w RandoOverworldTargetEdge ; some free ram OWR also uses
BRA .newSlot
+ TYA : STA.w SprItemGFXSlot,X
PLA : JMP .success
nop #10
.newSlot
PHX
LDX.b IndoorsFlag : BEQ +
CMP.b #!DynamicDropGFXSlotCount_UW : BCC .setIndex
BRA ++
+ CMP.b #!DynamicDropGFXSlotCount_OW : BCC .setIndex
++ LDA.b #$00
LDY.b IndoorsFlag : BEQ +
LDA.b #!DynamicDropGFXSlotCount_UW-1
BRA ++
+ LDA.b #!DynamicDropGFXSlotCount_OW-1
++ STA.w DynamicDropGFXIndex
.next
LDA.w RandoOverworldTargetEdge : BNE +
; on first loop, skip over gfx slots that have some item gfx loaded
LDY.w DynamicDropGFXIndex : LDA.w DynamicDropGFXSlots, Y : BNE .slotUsed
.setIndex
PLX
STA.w DynamicDropGFXIndex
STA.w SprItemGFX,X
PHX
; loop thru other sprites, check if any use the same gfx slot
LDY.b #$0F
+ LDY.b #$0F
- TYA : CMP.b 1,S : BEQ + ; don't check self
LDA.w SpriteAITable,Y : BEQ +
LDA.w SprRedrawFlag, Y : BNE +
LDA.w SprItemGFX,Y : CMP.w DynamicDropGFXIndex : BNE +
LDA.w SpriteTypeTable,Y ; don't need E5 enemy big key drop and E9 powder item
CMP.b #$EB : BEQ ++ ; heart piece
CMP.b #$E4 : BEQ ++ ; enemy drop
CMP.b #$3B : BEQ ++ ; bonk item
CMP.b #$E7 : BEQ ++ ; mushroom
BRA +
++
; slot already in use, use overflow slot
LDA.b #$02 : STA.w SprRedrawFlag, X
LDA.b IndoorsFlag : BEQ ++
LDA.b #!DynamicDropGFXSlotCount_UW
BRA +++
++ LDA.b #!DynamicDropGFXSlotCount_OW
+++ STA.w SprItemGFX,X
PLX : PLA : BRA .return
++ LDA.w SprItemGFXSlot,Y : CMP.w DynamicDropGFXIndex : BNE +
; gfx slot already in use
.slotUsed
DEC.w DynamicDropGFXIndex : BMI .loopAgain : BRA .next
+ DEY : BPL -
PLX
BRA .initRequest
.initRequest
.loopAgain
LDA.w RandoOverworldTargetEdge : BNE .overflow
INC : STA.w RandoOverworldTargetEdge
BRA .newSlot+1
.overflow ; slot already in use, use overflow slot
LDA.b #$02 : STA.w SprRedrawFlag, X
LDA.b IndoorsFlag : BEQ ++
LDA.b #!DynamicDropGFXSlotCount_UW
BRA +++
++ LDA.b #!DynamicDropGFXSlotCount_OW
+++ STA.w SprItemGFXSlot,X
PLX : PLA : BRA .return
.initRequest
LDA.b 1,S
LDY.w DynamicDropGFXIndex : STA.w DynamicDropGFXSlots, Y
TYA : STA.w SprItemGFXSlot, X
PLA
PHX ;: PHY
; unsure about substitution rules here, because they aren't skipped properly for MW yet
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
JSL ResolveBeeTrapLong
PHX
REP #$30
ASL : TAX
LDA.l StandingItemGraphicsOffsets,X : LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.w DynamicDropGFXIndex : AND.w #$000F : ASL : TAX
LDA.b IndoorsFlag : AND.w #$00FF : BEQ +
LDA.l FreeUWGraphics,X : BRA ++
+ LDA.l FreeOWGraphics,X
++ LDX.w ItemStackPtr : STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
ASL : TAX
LDA.l StandingItemGraphicsOffsets,X : LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.w DynamicDropGFXIndex : AND.w #$000F : ASL : TAX
LDA.b IndoorsFlag : AND.w #$00FF : BEQ +
LDA.l FreeUWGraphics,X : BRA ++
+ LDA.l FreeOWGraphics,X
++ LDX.w ItemStackPtr : STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
SEP #$30
PLX
@@ -167,14 +182,13 @@ FreeOWGraphics:
DrawPotItem:
PHA
; TODO: allow drawing if gfx are not using a VRAM slot that changes during medallion
LDA.b $5D : CMP.b #$08 : BCC + : CMP.b #$0A+1 : BCS + ; skip if we're mid-medallion
PLA : SEC : RTL
LDA.b IndoorsFlag : BEQ + ; OW current doesn't occupy any slots that medallion gfx do
LDA.w GfxChrHalfSlotVerify : CMP.b #$03 : BCC +
PLA : SEC : RTL
+
PLA
PHX
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
TAX
LDA.l BeeTrapDisguise : BEQ +
TAX
@@ -208,7 +222,7 @@ DrawPotItem:
+ LDA.w #DynamicOAMTileOW_thin
.transfer
STA.b Scrap08
LDA.w SprItemGFX,X
LDA.w SprItemGFXSlot,X
AND.w #$00FF
ASL : ASL : ASL : ASL
ADC.b Scrap08
@@ -405,6 +419,13 @@ DynamicOAMTileOW_full:
dw 0, 0 : db $E5, $00, $20, $02 ; apple
dd 0, 0
DynamicDropGFXClear:
PHA : PHX
LDX.b #$0E
- STZ.w DynamicDropGFXSlots, X : DEX : BPL -
PLX : PLA
RTL
ConditionalPushBlockTransfer:
LDA.b IndoorsFlag : BNE +
LDA.b #$0F ; don't transfer push block when on the OW

View File

@@ -9,10 +9,6 @@ org $829C25
org $89C2BB
JSL ClearSpriteData
; underworld -> overworld transition
org $8282D1
JSL ClearSpriteData2
org $89C327
JSL LoadSpriteData
@@ -333,19 +329,16 @@ ClearSpriteData:
.shared:
PHX
LDA.b #$00 : LDX.b #$00
LDX.b #$0F
.loop
STA.w SprDropsItem, X : STA.w SprItemReceipt, X : STA.w SprItemIndex, X
STA.w SprItemMWPlayer, X : STA.w SprItemFlags, X
INX : CPX.b #$10 : BCC .loop
STZ.w SprDropsItem, X : STZ.w SprItemIndex, X : STZ.w SprItemFlags, X
STZ.w SprSourceItemId, X : STZ.w SprItemReceipt, X : STZ.w SprItemMWPlayer, X
STZ.w SprRedrawFlag, X
DEX : BPL .loop
JSR SetupEnemyDropIndicator
PLX
RTL
ClearSpriteData2:
LDA.b #$82 : STA.b CGWSELQ
JMP ClearSpriteData_shared
; this routine determines whether enemies still have drops or not
; and sets EnemyDropIndicator appropriately
@@ -405,7 +398,7 @@ LoadSpriteData:
LDA.b #$01 : STA.w SprDropsItem, X
DEY
.common
DEY : LDA.b [$00], Y : STA.w SprItemReceipt, X
DEY : LDA.b [$00], Y : STA.w SprSourceItemId, X
STA.b Scrap0E
LDA.w SprItemMWPlayer, X : BNE + ; skip if multiworld
PHX
@@ -437,7 +430,7 @@ CheckIfDropValid:
;This section sets up the drop
LDA.b #$02 : STA.w SpawnedItemFlag
STX.w SpawnedItemIndex
LDA.w SprItemReceipt, X : STA.w SpawnedItemID
LDA.w SprSourceItemId, X : STA.w SpawnedItemID
LDA.w SprItemMWPlayer, X : STA.w SpawnedItemMWPlayer
LDY.b #$01 ; trigger the small key routines
LDA.w SpawnedItemID : STA.b Scrap00 : CMP.b #$32 : BNE +
@@ -626,22 +619,14 @@ SpriteKeyPrep:
CPX.b #$0A : BNE .continue ; the hera basement key is always sprite 0x0A
LDA.b LinkQuadrantH : ORA.b LinkQuadrantV : AND.b #$03 : CMP.b #$02 : BNE .continue
LDA.b #$00 : STA.w SpawnedItemFlag : STA.w SprItemFlags, X
LDA.b #$24 : STA.w SpriteItemType, X
LDA.b #$24 : STA.w SprSourceItemId, X
BRA +
.continue
LDA.w SpawnedItemIndex : STA.w SprItemIndex, X
LDA.w SpawnedItemMWPlayer : STA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w SpawnedItemFlag : STA.w SprItemFlags, X : BEQ +
LDA.w SpawnedItemID : STA.w SpriteItemType, X
PHA : PHY : PHX
JSL GetSpritePalette : PLX : STA.w SpriteOAMProp, X ; setup the palette
PLY : PLA
CMP #$24 : BNE ++ ;
PHX : JSL GetSpritePalette : PLX : STA.w SpriteOAMProp, X ; setup the palette
LDA.b RoomIndex : CMP.b #$80 : BNE +
LDA.w SpawnedItemFlag : BNE +
LDA.b #$24 ; it's the big key drop?
++ JSL RequestStandingItemVRAMSlot
LDA.w SpawnedItemID : STA.w SprSourceItemId, X
JSL RequestStandingItemVRAMSlot
+ PLA
RTL
@@ -650,11 +635,11 @@ SpriteKeyDrawGFX:
PHA
LDA.l SprItemMWPlayer, X : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.w SprRedrawFlag, X : BEQ +
LDA.w SpriteItemType, X
LDA.w SprSourceItemId, X
JSL RequestStandingItemVRAMSlot
LDA.w SprRedrawFlag, X : CMP.b #$02 : BEQ +
BRA .skipDraw
+ LDA.w SpriteItemType, X
+ LDA.w SprItemReceipt, X
CMP.b #$24 : BNE +
LDA.b RoomIndex : CMP.b #$80 : BNE ++
LDA.w SpawnedItemFlag : BNE ++
@@ -678,7 +663,7 @@ KeyGet:
PHA
LDA.l StandingItemsOn : BNE +
PLA : RTL
+ LDY.w SpriteItemType, X
+ LDY.w SprItemReceipt, X
LDA.w SprItemIndex, X : STA.w SpawnedItemIndex
LDA.w SprItemFlags, X : STA.w SpawnedItemFlag
LDA.b RoomIndex : CMP.b #$87 : BNE + ;check for hera cage
@@ -725,7 +710,7 @@ ShouldKeyBeCountedForDungeon:
BigKeyGet:
LDY.w SpriteItemType, X
LDY.w SprItemReceipt, X
CPY.b #$32 : BNE +
STZ.w ItemReceiptMethod : LDY.b #$32 ; what we wrote over
PHX : JSL Link_ReceiveItem : PLX ; what we wrote over
@@ -737,9 +722,7 @@ LoadProperties_PreserveCertainProps:
CMP.b #$E5 : BEQ +
JML SpritePrep_LoadProperties
+ LDA.w SpriteOAMProp, X : PHA
LDA.w SpriteItemType, X : PHA
JSL SpritePrep_LoadProperties
PLA : STA.w SpriteItemType, X
PLA : STA.w SpriteOAMProp, X
RTL
@@ -852,7 +835,7 @@ pullpc
SetBottleVendorKey:
LDA.w SpriteTypeTable,Y : CMP.b #$E4 : BNE +
; small key from bottle vendor
LDA.b #$AF : STA.w SpriteItemType,Y
LDA.b #$AF : STA.w SprSourceItemId,Y
LDA.b #$01 : STA.w SprRedrawFlag, Y
BRA .shift
+ CMP.b #$DE : BEQ .return

View File

@@ -138,7 +138,7 @@ RTL
ItemSet_Mushroom:
PHA
LDA.l NpcFlags+1 : ORA.b #$10 : STA.l NpcFlags+1
LDY.w SpriteID, X ; Retrieve stored item type
LDY.w SprItemReceipt, X ; Retrieve stored item type
BNE +
; if for any reason the item value is 0 reload it, just in case
%GetPossiblyEncryptedItem(MushroomItem, SpriteItemValues) : TAY
@@ -187,11 +187,11 @@ RTL
LoadZoraKingItemGFX:
LDA.l ZoraItem_Player : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.l $1DE1C3 ; location randomizer writes zora item to
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteID,Y
TYX
JML RequestStandingItemVRAMSlot
STA.w SprSourceItemId, Y
PHX : TYX : PLY
JSL RequestStandingItemVRAMSlot
PHY : TXY : PLX
RTL
;--------------------------------------------------------------------------------
JumpToSplashItemTarget:
LDA.w SpriteMovement, X
@@ -204,14 +204,14 @@ JumpToSplashItemTarget:
LoadCatfishItemGFX:
LDA.l CatfishItem_Player : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.l $1DE185 ; location randomizer writes catfish item to
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
STA.w SpriteID, Y
TYX
JML RequestStandingItemVRAMSlot
STA.w SprSourceItemId, Y
PHX : TYX : PLY
JSL RequestStandingItemVRAMSlot
PHY : TXY : PLX
RTL
;--------------------------------------------------------------------------------
DrawThrownItem:
LDA.w SpriteID,X
LDA.w SprItemReceipt,X
JML DrawPotItem
;--------------------------------------------------------------------------------
MarkThrownItem:

View File

@@ -446,6 +446,7 @@ OWBonkDropSparkle:
LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BEQ .nosparkle
LDA.w $0E90,X : BEQ .nosparkle
LDA.w SprRedrawFlag,X : BNE .nosparkle
LDA.b GameMode : CMP.b #$0E : BEQ .nosparkle
JSL Sprite_SpawnSparkleGarnish
; move sparkle down 1 tile
PHX : TYX : PLY
@@ -594,15 +595,13 @@ OWBonkDrops:
PLX : BEQ + : LDA.b #$00 : STA.w SpriteAITable,Y : BRA .return ; S = FlagBitmask, X (row + 2)
+ PHA
LDA.b #$EB : STA.l MiniGameTime
LDA.b #$EB
JSL Sprite_SpawnDynamically+15 ; +15 to skip finding a new slot, use existing sprite
LDA.b #$01 : STA.w SprRedrawFlag,Y
PLA
JSL AttemptItemSubstitution
STA.w SpriteItemType,Y
STA.w SpriteID,Y
PLA : STA.w SprSourceItemId, Y
PHX : TYX : PLY
JSL RequestStandingItemVRAMSlot
PHY : TXY : PLX
; affects the rate the item moves in the Y/X direction
LDA.b #$00 : STA.w SpriteVelocityY,Y
@@ -667,7 +666,7 @@ OWBonkDropCollected:
RTS
}
; A = SpriteID, Y = Sprite Slot Index, X = free/overwritten
; A = SprItemReceipt, Y = Sprite Slot Index, X = free/overwritten
OWBonkSpritePrep:
{
STA.w SpriteTypeTable,Y

16
ram.asm
View File

@@ -203,7 +203,7 @@ ProgressiveFlag = $7E0224 ; unused
ItemStackPtr = $7E0226 ; Pointer into Item GFX and VRAM target queues. Word length.
; If not zero, pointer should always be left pointing at the
; next available slot in the stack during the frame.
SpriteID = $7E0230 ; 0x10 bytes. Receipt ID for main loop sprite we're handling.
SprSourceItemId = $7E0230 ; 0x10 bytes. Receipt ID without item substitutions.
SpriteMetaData = $7E0240 ; 0x10 bytes. Sprite metadata. Used for prog bow tracking.
AncillaVelocityZ = $7E0294 ; 0x0A bytes
AncillaZCoord = $7E029E ; 0x0A bytes
@@ -325,12 +325,14 @@ SprItemReceipt = $7E0740 ; Array for item id for each sprite 0x16
SprItemIndex = $7E0750 ; Array for item index (see code)
SprItemMWPlayer = $7E0760 ; Player id for each sprite drop 0x16
SprItemFlags = $7E0770 ; Array 0x16 (used for both pots and drops) (combine with SprDropsItem?)
SprItemGFX = $7E0780 ; this will keep track of the DynamicDropGFXIndex for each item
SprItemGFXSlot = $7E0780 ; this will keep track of the DynamicDropGFXIndex for each item
SprRedrawFlag = $7E0790 ; this is a flag indicating the gfx for a sprite should be reloaded and redrawn
;
DynamicDropGFXIndex = $7E07F0 ; this will just count from 0 to 6 to determine which slot we're using
; we're expecting 5 items max per room, and order is irrelevant
; we just need to keep track of where they go
DynamicDropGFXSlots = $7E07F1 ; Assume future use of this up to $0E bytes, these will store
; which item gfx is currently occupying each slot
OAMBuffer = $7E0800 ; Main OAM buffer sent to OAM. $200 bytes.
OAMBuffer2 = $7E0A00 ;
;
@@ -407,7 +409,7 @@ SpriteOAMProperties = $7E0E40 ; h m w o o o o o | h = Harmless | m = m
SpriteHitPoints = $7E0E50 ; Set from $0DB173
SpriteControl = $7E0E60 ; n i o s p p p t | n = Death animation? | i = Immune to attack/collion?
; o = Shadow | p = OAM prop palette | t = OAM prop name table
SpriteItemType = $7E0E80 ; Sprite Item Type. Also used for jump table local. $10 bytes.
SpriteJumpIndex = $7E0E80 ; Sprite Item Type. Also used for jump table local. $10 bytes.
;
SpriteDirectionTable = $7E0EB0 ; Sprite direction. $10 bytes.
;
@@ -428,6 +430,7 @@ CurrentSpriteSlot = $7E0FA0 ; Holds the current sprite/ancilla's index
;
FreezeSprites = $7E0FC1 ; "Seems to freeze sprites"
;
GfxChrHalfSlotVerify = $7E0FC6 ; Mirrors $0AAA, set to >= $03 when VRAM has temp graphics loaded
PrizePackIndexes = $7E0FC7 ; $07 bytes. One for each prize pack.
;
SpriteCoordCacheX = $7E0FD8 ;
@@ -810,6 +813,7 @@ endmacro
%assertRAM(MenuBlink, $7E0207)
%assertRAM(RaceGameFlag, $7E021B)
%assertRAM(MessageJunk, $7E0223)
%assertRAM(SprSourceItemId, $7E0230)
%assertRAM(ItemReceiptID, $7E02D8)
%assertRAM(ItemReceiptPose, $7E02DA)
%assertRAM(BunnyFlag, $7E02E0)
@@ -880,9 +884,10 @@ endmacro
%assertRAM(SprItemIndex, $7E0750)
%assertRAM(SprItemMWPlayer, $7E0760)
%assertRAM(SprItemFlags, $7E0770)
%assertRAM(SprItemGFX, $7E0780)
%assertRAM(SprItemGFXSlot, $7E0780)
%assertRAM(SprRedrawFlag, $7E0790)
%assertRAM(DynamicDropGFXIndex, $7E07F0)
%assertRAM(DynamicDropGFXSlots, $7E07F1)
%assertRAM(OAMBuffer, $7E0800)
%assertRAM(OAMBuffer2, $7E0A00)
%assertRAM(TransparencyFlag, $7E0ABD)
@@ -926,7 +931,7 @@ endmacro
%assertRAM(SpriteOAMProperties, $7E0E40)
%assertRAM(SpriteHitPoints, $7E0E50)
%assertRAM(SpriteControl, $7E0E60)
%assertRAM(SpriteItemType, $7E0E80)
%assertRAM(SpriteJumpIndex, $7E0E80)
%assertRAM(SpriteDirectionTable, $7E0EB0)
%assertRAM(SpriteSpawnStep, $7E0ED0)
%assertRAM(SpriteHalt, $7E0F00)
@@ -938,6 +943,7 @@ endmacro
%assertRAM(SpriteSubPixelZ, $7E0F90)
%assertRAM(CurrentSpriteSlot, $7E0FA0)
%assertRAM(FreezeSprites, $7E0FC1)
%assertRAM(GfxChrHalfSlotVerify, $7E0FC6)
%assertRAM(PrizePackIndexes, $7E0FC7)
%assertRAM(SpriteCoordCacheX, $7E0FD8)
%assertRAM(SpriteCoordCacheY, $7E0FDA)

View File

@@ -245,7 +245,7 @@ ShopkepeerPotion_CallOriginal:
LDA.b #PotionShopkeeperJumpTable>>16 : PHA
LDA.b #PotionShopkeeperJumpTable>>8 : PHA
LDA.b #PotionShopkeeperJumpTable : PHA
LDA.w SpriteItemType, X
LDA.w SpriteJumpIndex, X
JML JumpTableLocal
;--------------------------------------------------------------------------------
Shopkepeer_CallOriginal:
@@ -253,7 +253,7 @@ Shopkepeer_CallOriginal:
LDA.b #ShopkeeperJumpTable>>16 : PHA
LDA.b #ShopkeeperJumpTable>>8 : PHA
LDA.b #ShopkeeperJumpTable : PHA
LDA.w SpriteItemType, X
LDA.w SpriteJumpIndex, X
JML JumpTableLocal
;--------------------------------------------------------------------------------
@@ -274,7 +274,7 @@ Sprite_ShopKeeperPotion:
+
PLB
LDA.w SpriteItemType, X : BNE +
LDA.w SpriteJumpIndex, X : BNE +
PHK : PEA.w .jslrtsreturn-1
PEA.w $85f527 ; an rtl address - 1 in Bank05
JML Sprite_WitchAssistant
@@ -457,7 +457,8 @@ Shopkeeper_BuyItem:
REP #$20 : LDA.l CurrentRupees : !SUB ShopInventory+1, X : STA.l CurrentRupees : SEP #$20 ; Take price away
++
PHX
LDA.b #0 : XBA : TXA : LSR #2 : TAX : LDA.l ShopInventoryPlayer, X : STA.l !MULTIWORLD_ITEM_PLAYER_ID
LDA.b #0 : XBA : TXA : LSR #2 : TAX
LDA.l ShopInventoryPlayer, X : STA.l !MULTIWORLD_ITEM_PLAYER_ID : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
TXA : !ADD ShopSRAMIndex : TAX
LDA.l PurchaseCounts, X : BNE +++ ;Is this the first time buying this slot?
LDA.l EnableShopItemCount, X : STA.l ShopEnableCount ; If so, store the permission to count the item here.

View File

@@ -55,6 +55,7 @@ DungeonExitTransition:
LDA.b #$00 : STA.w UseY1 ; stop item dashing
+
LDA.b #$0F : STA.b GameMode ; stop running through the transition
JSL DynamicDropGFXClear
StatTransitionCounter:
PHA : PHP
LDA.l StatsLocked : BNE +

View File

@@ -29,16 +29,15 @@ SetTabletItemFlag:
RTS
;--------------------------------------------------------------------------------
SpawnTabletItem:
LDA.b #$EB
JSL Sprite_SpawnDynamically
JSL HeartPieceGetPlayer : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
JSL LoadOutdoorValue
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
PHA
LDA.b #$EB : STA.l MiniGameTime
JSL Sprite_SpawnDynamically
PLA
STA.w SpriteID,Y
LDA.b #$01 : STA.w SprRedrawFlag, Y
STA.w SprSourceItemId, Y
PHX : TYX : PLY
JSL RequestStandingItemVRAMSlot
PHY : TXY : PLX
LDA.b LinkPosX : STA.w SpritePosXLow, Y
LDA.b LinkPosX+1 : STA.w SpritePosXHigh, Y

View File

@@ -50,15 +50,15 @@ RTL
PrepDynamicTile:
PHX : PHY : PHB
LDA.l RemoteItems : BEQ .notRemote
LDA.l SpriteID, X : CMP.l !MULTIWORLD_SCOUTREPLY_LOCATION : BNE ++
LDA.l SprItemReceipt, X : CMP.l !MULTIWORLD_SCOUTREPLY_LOCATION : BNE ++
LDA.l !MULTIWORLD_SCOUTREPLY_PLAYER : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.l !MULTIWORLD_SCOUTREPLY_ITEM
STA.l SpriteID, X
STA.l SprItemReceipt, X
BRA .notRemote
++
STA.l !MULTIWORLD_SCOUT_LOCATION
LDA.b #$00 : STA.l !MULTIWORLD_SPRITEITEM_PLAYER_ID
LDA.b #$6B : STA.l SpriteID, X ; make it a power star, I guess
LDA.b #$6B : STA.l SprItemReceipt, X ; make it a power star, I guess
.notRemote
JSR ResolveLootID
-
@@ -95,7 +95,7 @@ RTL
;--------------------------------------------------------------------------------
; LoadDynamicTileOAMTable
; in: SpriteID,X - Loot ID
; in: SprItemReceipt,X - Loot ID
; out: A - Loot ID
;-------------------------------------------------------------------------------- 20/847B
LoadDynamicTileOAMTable:
@@ -104,7 +104,7 @@ LoadDynamicTileOAMTable:
LDA.w #$0000 : STA.l SpriteOAM : STA.l SpriteOAM+2
LDA.w #$0200 : STA.l SpriteOAM+6
LDA.l BeeTrapDisguise : AND.w #$00FF : BNE +
LDA.w SpriteID,X : AND.w #$00FF
LDA.w SprItemReceipt,X : AND.w #$00FF
+ LDY.w #$0024
PHX : ASL : TAX
LDA.l InventoryTable_properties, X : BIT.w #$8000 : BEQ +
@@ -114,7 +114,7 @@ LoadDynamicTileOAMTable:
SEP #$30
LDA.l BeeTrapDisguise : BNE +
LDA.w SpriteID,X
LDA.w SprItemReceipt,X
+ JSL GetSpritePalette_resolved
STA.l SpriteOAM+5 : STA.l SpriteOAM+13
PHX
@@ -219,7 +219,7 @@ PrepDrawRemoteItemSprite:
CMP.l !MULTIWORLD_SCOUTREPLY_LOCATION : BNE ++
LDA.l !MULTIWORLD_SCOUT_LOCATION : BEQ +++
LDA.l !MULTIWORLD_SCOUTREPLY_LOCATION
STA.l SpriteID, X
STA.l SprItemReceipt, X
JSL PrepDynamicTile
LDA #$00
BRA ++