102 Commits

Author SHA1 Message Date
codemann8
781431f633 Fixes issue not able to screen transition if bumped by enemy in water 2026-01-19 15:21:03 -06:00
codemann8
e02f98e6c5 Fixed L/R map swap while in special world 2026-01-17 13:58:18 -06:00
codemann8
7898e2149f Fixed issue with Old Man follower infinite pit fall 2026-01-17 00:51:26 -06:00
codemann8
3c41d7ff39 Change key total display based on seen by player 2026-01-16 15:30:06 -06:00
codemann8
ab0f37b7ba Merge branch 'OWMain' of https://github.com/codemann8/z3randomizer into OWMain 2026-01-16 14:30:04 -06:00
codemann8
343d61a976 Fixing key totals marking MapCountDisplay flag 2026-01-16 14:30:01 -06:00
codemann8
804e72395b Fixing key totals marking MapCountDisplay flag 2026-01-16 14:19:48 -06:00
codemann8
e8e6120a9e Some added labeling 2026-01-13 23:51:42 -06:00
codemann8
b0dfcdcae6 Fixed screen drawing issue on Pyramid screen 2026-01-13 15:29:04 -06:00
codemann8
920212d1b8 Removed sprite pointer label since value can shift via generator 2026-01-13 11:26:28 -06:00
codemann8
b7e123a7cf Removed hardcoded sprite data 2026-01-13 11:25:41 -06:00
codemann8
ce7f35ac7b Fixed screen drawing issue on HC screen 2026-01-13 11:24:37 -06:00
codemann8
a090f95659 Hold L/R during Grid OW map check to see opposite world 2026-01-12 22:35:07 -06:00
Catobat
9cbc202b62 Move dynamically positioned sprites on overworld map to match custom layout 2026-01-11 21:45:42 +01:00
Catobat
2ee7be56fc Overworld map fog 2026-01-11 21:45:42 +01:00
Catobat
fe5c936c7c Draw arbitrary layouts on the overworld map 2026-01-11 21:45:42 +01:00
Catobat
afa0f95072 Overworld edges are disabled if the destination is set to 0xFF 2026-01-11 21:45:42 +01:00
codemann8
ead6a30aa5 Fixed boss icons not showing on dungeon map check 2026-01-11 01:59:44 -06:00
codemann8
d532ac2f4a Fixed bonk drops duplicate counting and potentially writing bad values 2026-01-11 00:38:24 -06:00
codemann8
71ebc09270 Fix bonk drops updating HUD on collection 2026-01-11 00:06:52 -06:00
codemann8
0fef82981a Fixed bonk drops double counting and potentially writing bad values 2026-01-11 00:06:19 -06:00
codemann8
7d45a5cf66 Merge branch 'OWMain' of https://github.com/codemann8/z3randomizer into OWMain 2026-01-08 19:47:22 -06:00
codemann8
5af2fdc51e Fix psuedoboots ability to open Kings Tomb 2026-01-08 19:47:06 -06:00
codemann8
bff1da4330 Fix psuedoboots ability to open Kings Tomb 2026-01-08 16:16:33 -06:00
codemann8
0dba4601fc Fix issue with zoomed-in map check displaying icons from off-screen 2026-01-05 23:57:19 -06:00
codemann8
e30e5107c6 Implement more accurate map check coordinates 2026-01-05 22:38:53 -06:00
codemann8
a97f8fbb48 Merged in DR v1.5.2 2025-12-09 16:44:50 -06:00
aerinon
ac7f50fc62 fix: revert to old way 2025-12-09 14:43:47 -07:00
codemann8
dd9ea4d38e Merge branch 'DRUnstable' into OWMain 2025-12-09 09:23:48 -06:00
codemann8
5b7a4c11ed Fixed issue with bonk drops not showing sparkles in DW 2025-12-08 20:40:39 -06:00
aerinon
4437194cfe fix: key counts again 2025-12-08 16:37:51 -07:00
codemann8
0d827eadd2 Merge branch 'DRUnstable' into OWMain 2025-12-04 19:12:35 -06:00
aerinon
fca7f214bc fix: key counts for pot keys and normal absorbed keys 2025-12-04 15:37:02 -07:00
codemann8
a277fb12ac Completed Rain State fixes for Bonk Drops 2025-12-04 12:39:19 -06:00
codemann8
1242198bea Merged in DR v1.5.0 2025-12-03 10:53:43 -06:00
codemann8
96333b22a2 Fixed cucco storm to actually work on first trigger 2025-12-03 10:11:47 -06:00
codemann8
4f4f483647 Completed Rain State fixes for Bonk Drops 2025-12-03 10:10:14 -06:00
codemann8
dfe49a11c4 Merged in DR v1.5.0 2025-12-03 10:09:50 -06:00
codemann8
581e45a63c Merge branch 'DRUnstable' into OWMain 2025-12-03 09:37:31 -06:00
aerinon
b583cc58ff fix: not sure what I was thinking - fix branches and width 2025-12-02 11:09:37 -07:00
KrisDavie
761365927f Prevent prizes dropping in dungeons where they shouldn't (including cave state) and fix rain state items/tablets. 2025-12-02 08:28:08 -07:00
aerinon
68c511d6be fix: skip map check based on "compass" mode 2025-12-02 08:26:33 -07:00
codemann8
94efc26bf3 Merge branch 'limited' into OWMain 2025-12-02 08:57:32 -06:00
codemann8
029f687470 Merge branch 'limited' of https://github.com/codemann8/z3randomizer into limited 2025-12-02 08:57:16 -06:00
codemann8
4dd7bac4d6 Fixed cucco storm to actually work on first trigger 2025-12-02 08:56:53 -06:00
codemann8
1368e15872 Merge branch 'limited' into OWMain 2025-12-01 23:45:56 -06:00
codemann8
2fa0bfc4ef Fixed cucco storm to actually work on first trigger 2025-12-01 23:45:31 -06:00
codemann8
2418c1b322 Fix for post-mirror follower sprite gfx 2025-11-22 06:52:45 -06:00
codemann8
00fb9e6c5d Adding compress/decompress script for use with gfx 2025-11-21 09:20:59 -06:00
aerinon
5936b08497 fix: skip map check only when maps aren't shuffled 2025-11-20 10:04:53 -07:00
aerinon
70a23191ba fix: bunch of fixes for key counting system 2025-11-19 16:29:40 -07:00
codemann8
d21daccf4c changed TF item to use its own gfx id 2025-11-19 08:56:12 -06:00
codemann8
7b93b4b4eb Added new gfx for 10/11 keys rather than A/B keys 2025-11-18 23:54:10 -06:00
aerinon
fee689e583 feat: hud shows all keys, instead of chest keys. Dropped Map requirement for key info. 2025-11-18 15:19:28 -07:00
aerinon
08ecc9b673 feat: pot lose coloring upon collection
fix: normal lamp cone
2025-11-18 10:43:16 -07:00
codemann8
d451b531e7 Added default VRAM values for OWR edge data 2025-11-18 06:09:33 -06:00
aerinon
7f7ffeb5fb feat: lamp cone bitmask settings 2025-11-14 14:37:15 -07:00
aerinon
b27d7c996b feat: enemy "spies" during enemy drop 2025-11-14 09:06:07 -07:00
codemann8
57b8b04f0b Merged in DR v1.4.11 2025-11-13 19:21:33 -06:00
codemann8
7334dd02db Fix to allow VRAM corruption in Blind fight 2025-11-12 10:04:21 +01:00
codemann8
0fdec905d6 Fix to allow VRAM corruption in Blind fight 2025-11-12 02:29:01 -06:00
codemann8
f91e2eb1a2 Re-fixed purple chest follower dupe 2025-11-08 11:12:09 -06:00
codemann8
5a802eda70 Fixed issue with GT Cutscene freezing 2025-11-08 10:29:41 -06:00
codemann8
4d3c2bd7dc Added custom gfx for Ped and Murahdahla 2025-11-03 10:59:08 -06:00
codemann8
fa72adb53d Restore Kodongo AI when in vanilla rooms 2025-10-31 10:37:09 -06:00
codemann8
b24e440597 Fix issue with music silence in DR when straight stairs lead to pre-Aga room 2025-10-31 10:36:23 -06:00
aerinon
44b014fc65 fix: fix for pot drops at sprite limit 2025-10-31 10:29:29 -06:00
codemann8
78fa8b7dd9 Fixed Bosses goal condition check 2025-10-31 01:00:56 -05:00
codemann8
db62d4c660 Fixed issue with Locksmith despawning after purple chest turn-in when a follower is stored 2025-10-29 15:01:47 -05:00
codemann8
2ffcb1c3bd Implemented Custom Goal Framework 2025-10-29 00:08:16 -05:00
codemann8
a9ef09e2d0 Fixed Ganon silvers hint for free-standing items 2025-10-18 02:26:42 -05:00
codemann8
dfc182a2d5 New fix for pot drops when at sprite limit 2025-10-14 11:35:07 -05:00
codemann8
a8b1fc989e Fixed pogdor (frogdor at PoD entrance) with Kiki following while exiting at PoD 2025-09-21 13:40:51 -05:00
codemann8
c3616f2d65 Fixed issue with Duck overwriting GT cutscene gfx 2025-09-21 13:38:02 -05:00
codemann8
912df0be14 Re-fixed old man spawn on pyramid issue 2025-09-07 10:47:23 -05:00
codemann8
2ed9de827b Some follower fixes to support Zelda in TT Prison 2025-09-07 10:47:23 -05:00
codemann8
060554a5fb Implemented ability to change GT cutscene gfx 2025-08-25 15:20:36 -05:00
codemann8
e236543180 New gfx for chicken item 2025-08-19 10:17:04 -05:00
codemann8
ea4f39e116 Corrected some music fade-outs during mosaic transitions 2025-08-19 10:16:16 -05:00
codemann8
8ac480947d Fix for music so it doesn't change when going into special OW screens 2025-08-19 10:12:05 -05:00
codemann8
11ff5825ae Fix music change after dig game ends 2025-08-19 10:10:51 -05:00
codemann8
34fa1cd98e Fix issue with music silence in DR when straight stairs lead to pre-Aga room 2025-08-19 10:10:08 -05:00
codemann8
4c5adfbee2 Fix issue with LH/BS half volume issue when exiting to Kakariko 2025-08-19 10:08:36 -05:00
codemann8
6566aa6d48 Restore Kodongo AI when in vanilla rooms 2025-07-13 00:27:22 -05:00
codemann8
7164c3159d Fix crash when Old Man exits out of his House entrance 2025-07-11 04:54:28 -05:00
codemann8
d75d912c7d Added some compass icons to DR pause menu 2025-07-10 22:59:51 -05:00
codemann8
953c115719 Fix HUD to show prize, key count, and compass count if seen by player 2025-07-07 15:03:14 -05:00
codemann8
1995d8747c Fixed issue with Quake scaring Kiki 2025-06-13 23:39:32 -05:00
codemann8
d8341c650d Fixed issue with Kiki running away at maze if Link spawns from Sanc 2025-06-12 10:28:38 -05:00
codemann8
021ba9d8a6 Actual fix for issue with no music in LH after S+Q from Kakariko 2025-06-12 01:50:21 -05:00
codemann8
4088698af9 Undo MSU Kak Music Fix 2025-06-12 00:54:23 -05:00
codemann8
d19e22cc7d Fix issue with Boots not showing in menu until S+Q 2025-06-10 02:47:08 -05:00
codemann8
e266d351cd Fix issue with despawning follower sprite after purple chest item get 2025-06-08 14:34:16 -05:00
codemann8
baec6954a3 Reset MSU Resume on S+Q 2025-06-05 20:52:13 -05:00
codemann8
faadd1d7f1 Fixing boss behavior in Swamp Palace Arrghus' room 2025-06-05 19:50:49 -05:00
codemann8
936ff5a882 Locksmith follower now behaves closer to vanilla 2025-05-16 22:20:48 -05:00
codemann8
86efa74185 Various bug fixes for Follower Shuffle post-launch
- Fix issue with infinite purple chest item get
- Fix issue with Kiki running away on iframe ledge hops
- Fix issue with bad follower gfx on screens with followers
- Fix issue with Zelda appearing in conditional follower locations
2025-05-04 09:24:33 -05:00
codemann8
7b4470ddae Merge branch 'DRUnstable' into OWMain 2025-04-30 06:58:20 -05:00
codemann8
2d84f7431e Minor consistency 2025-04-30 06:48:54 -05:00
codemann8
ed7fb312d5 Fixed some incorrect bunny music behavior 2025-04-30 06:26:33 -05:00
codemann8
aabb649578 Initial Follower Shuffle Implementation 2025-04-30 06:18:08 -05:00
aerinon
e86cccad52 fix: fix conveyor bug, unless Helmasaur is present 2025-04-28 14:15:31 -06:00
66 changed files with 3098 additions and 1362 deletions

View File

@@ -73,6 +73,8 @@ function hexto555(h) = ((((h&$FF)/8)<<10)|(((h>>8&$FF)/8)<<5)|(((h>>16&$FF)/8)<<
!FLAG_OW_MIXED = $04
!FLAG_OW_CROSSED = $02
!FLAG_OW_BONKDROP = $02
!FLAG_OW_CUSTOM_MAP = $02
!FLAG_OW_ADJUST_DYNAMIC_MAP_SPRITE_POSITION = $04
incsrc hooks.asm
incsrc spriteswap.asm
@@ -118,6 +120,7 @@ incsrc doorframefixes.asm
incsrc music.asm
incsrc roomloading.asm
incsrc icepalacegraphics.asm
incsrc follower.asm
warnpc $A18000
org $9C8000 ; text tables for translation
@@ -181,9 +184,6 @@ incsrc dungeonmap.asm
incsrc hextodec.asm
incsrc multiworld.asm
incsrc textrenderer.asm
incsrc crystalswitchbook.asm
incsrc mimicdash.asm
incsrc souls.asm
warnpc $A58000
org $A28000
@@ -193,7 +193,6 @@ fillbyte $00 : fill 32
incbin "data/customitems.4bpp"
PreloadedGraphicsROM:
incbin "data/preloadedgfx.4bpp"
incbin "data/bossicons.souls.4bpp"
warnpc $A2B000
org $A2B000
incsrc itemdatatables.asm ; Statically mapped

View File

@@ -16,7 +16,7 @@ DrawLibraryItemGFX:
RTL
;--------------------------------------------------------------------------------
SetLibraryItem:
LDY.w SprItemReceipt, X
LDY.w SprSourceItemId, X
JSL ItemSet_Library ; contains thing we wrote over
RTL
;--------------------------------------------------------------------------------
@@ -52,7 +52,7 @@ RTL
;--------------------------------------------------------------------------------
GiveBonkItem:
LDA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_ITEM_PLAYER_ID
LDA.w SprItemReceipt, X
LDA.w SprSourceItemId, X
JSR AbsorbKeyCheck : BCC .notKey
PHY : LDY.b #$24 : JSL AddInventory : PLY ; do inventory processing for a small key
LDA.l CurrentSmallKeys : INC A : STA.l CurrentSmallKeys

View File

@@ -28,16 +28,19 @@ AddBonkTremors:
JSL AddDashTremor : JSL Player_ApplyRumbleToSprites ; things we wrote over
RTL
;--------------------------------------------------------------------------------
BonkBreakableWall:
PHX : PHP
SEP #$30 ; set 8-bit accumulator and index registers
ValidDashCheck:
PHP
SEP #$20
LDA.l BootsModifier : CMP.b #$01 : BEQ +
LDA.l BootsEquipment : BNE + ; Check for Boots
PLP : PLX : LDA.w #$0000 : RTL
+
PLP : PLX
LDA.w LinkDashing : AND.w #$00FF ; things we wrote over
RTL
LDA.l BootsEquipment : BEQ .exit
+ LDA.w LinkDashing
.exit
BEQ +
PLP : REP #$02
RTL
+
PLP : SEP #$02
RTL
;--------------------------------------------------------------------------------
BonkRockPile:
LDA.l BootsModifier : CMP.b #$01 : BEQ +
@@ -48,10 +51,7 @@ BonkRockPile:
RTL
;--------------------------------------------------------------------------------
GravestoneHook:
LDA.l BootsModifier : CMP.b #$01 : BEQ +
LDA.l BootsEquipment : BEQ .done ; Check for Boots
+
LDA.w LinkDashing : BEQ .done ; things we wrote over
JSL ValidDashCheck : BEQ .done ; things we wrote over
JML moveGravestone
.done
JML GravestoneHook_continue

View File

@@ -1,12 +1,5 @@
;================================================================================
;--------------------------------------------------------------------------------
AssignKiki:
LDA.b #$00 : STA.l FollowerDropped ; defuse bomb
LDA.b #$0A : STA.l FollowerIndicator ; assign kiki as follower
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; Name: AllowSQ
; Returns: Accumulator = 0 if S&Q is disallowed, 1 if allowed
@@ -187,6 +180,25 @@ LDA.b IndoorsFlag : BNE +
+
RTL
PostFixMirrorGfxPrep:
LDA.b #$01 : STA.w OWTransitionFlag
JML HandleFollowersAfterMirroring ; what we wrote over
; warning, this is called on frames after PostFixMirrorGfxPrep but for
; several frames after, so we use OWTransitionFlag to run something once
PostFixMirrorGfx:
STA.w SubModuleInterface ; what we wrote over
LDA.w OWTransitionFlag : CMP.b #$01 : BNE .done
LDA.b #$08 : STA.w OWTransitionFlag
JML FollowerGfxRedraw
.done
RTL
PostFixOAMGfx:
JSL FollowerGfxRedraw
REP #$30 : LDA.w #$2000 ; what we wrote over
RTL
;--------------------------------------------------------------------------------
; Fix losing VRAM gfx when using quake
PostNMIUpdateBGCharHalf:
@@ -226,6 +238,18 @@ FixJingleGlitch:
.exit
RTL
;--------------------------------------------------------------------------------
FixSwimBump:
LDA.b LinkIncapacitatedTimer : BEQ .normal
LDA.b LinkJumping : BNE .normal
INC.b LinkJumping
BRA .not_diving
.normal
LDA.b LinkJumping : BNE .continue ; what we wrote over
.not_diving
PLA : PLA : PEA.w $87964E ; skip ahead, not diving
.continue
RTL
;--------------------------------------------------------------------------------
; Fix spawning with more hearts than capacity when less than 3 heart containers
pushpc
org $09F4AC ; <- module_death.asm:331
@@ -259,7 +283,7 @@ ParadoxCaveGfxFix:
LDA.b #$01 : STA.w DMAENABLE
.skipLine
RTL
JML FollowerGfxRedraw
.skipMostOfLine
; Set line length to 192 bytes (the first 6 8x8 tiles in the line)
@@ -267,65 +291,9 @@ ParadoxCaveGfxFix:
BRA .uploadLine
;--------------------------------------------------------------------------------
SetItemRiseTimer:
LDA.w ItemReceiptMethod : CMP.b #$01 : BNE .not_from_chest
LDA.b #$38 : STA.w AncillaTimer, X
RTL
.not_from_chest
LDA.l MultiworldJunkItemTimer : BEQ .default
LDA.l !MULTIWORLD_ITEM_PLAYER_ID : BNE .multiworld
LDA.l !MULTIWORLD_RECEIVING_ITEM : BNE .multiworld
BRA .default
.multiworld
LDA.l !MULTIWORLD_ITEM_ID
JSL.l ItemIsJunk
BEQ .default
.junk
LDA.l MultiworldJunkItemTimer : STA.w AncillaTimer, X
RTL
.default
TYA : STA.w AncillaTimer, X ; What we wrote over
RTL
;--------------------------------------------------------------------------------
ItemIsJunk:
PHX
LDX.b #JunkItems_end-JunkItems-1
-
CMP.l JunkItems, X : BEQ .junk
DEX : BPL -
PLX
LDA.b #$00
RTL
.junk
PLX
LDA.b #$01
RTL
LDA.w ItemReceiptMethod : CMP.b #$01 : BNE .not_from_chest
LDA.b #$38 : STA.w AncillaTimer, X
RTL
.not_from_chest
TYA : STA.w AncillaTimer, X ; What we wrote over
RTL
JunkItems:
db $27 ; Bomb
db $28 ; 3 bombs
db $31 ; 10 bombs
db $34 ; 1 rupee
db $35 ; 5 rupees
db $36 ; 20 rupees
db $40 ; 100 rupees
db $41 ; 50 rupees
db $42 ; Heart
db $43 ; Arrow
db $44 ; 10 arrows
db $45 ; Small magic
db $46 ; 300 rupees
db $47 ; 20 rupees green
db $59 ; Rupoor
db $D1 ; Apples
db $D2 ; Fairy
db $D3 ; Chicken
db $D4 ; Big Magic
db $D5 ; 5 Arrows
db $D6 ; Good Bee
.end
;--------------------------------------------------------------------------------

View File

@@ -1,52 +0,0 @@
pushpc
org $87A46E
JSL CheckBookTriggerSwitch
BCS +
skip 15
+
org $8296A8
JSL FinishPegChange
pullpc
FinishPegChange:
LDA.b #$20
TRB.w $037A
STZ.b $B0
STZ.b $11
RTL
CheckBookTriggerSwitch:
LDA.l CrystalSwitchBook
BEQ +
LDA.b $10
CMP.b #$07
BNE +
LDA.l $7EC172
EOR.b #$01
STA.l $7EC172
LDA.b #$16
STA.b $11
LDA.b #$20
TSB.w $037A
LDA.b #$25
JSL $8DBB8A
SEC
BRA .done
+ CLC
.done
; what we wrote over
LDA.b $3A
AND.b #$BF
STA.b $3A
RTL

View File

@@ -3,6 +3,7 @@
!INERT = $00
!INIT = $08
!ALIVE = $09
!OAMPROPS = $09
!CUCCO_ENRAGED = $23
CuccoStorm:
@@ -12,6 +13,7 @@ CuccoStorm:
LDA.b GameMode : CMP.b #$09 : BNE + ; only if outdoors
LDA.l LoopFrames : AND.b #$7F : BNE + ; check every 128 frames
.activate
-
;==== Find a Cucco
@@ -40,7 +42,11 @@ CuccoStorm:
PLY
CPY.b #$FF : BEQ + ; fail if no slots found
LDA.b #!CUCCO : STA.w SpriteTypeTable, Y
LDA.b #!INIT : STA.w SpriteAITable, Y
LDA.b #!ALIVE : STA.w SpriteAITable, Y
PHX
TYX : JSL ResetSpriteProperties
PLX
LDA.b #!OAMPROPS : STA.w SpriteOAMProp, Y
LDA.b LinkPosY : STA.w SpritePosYLow, Y
LDA.b LinkPosY+1 : STA.w SpritePosYHigh, Y
LDA.b LinkPosX : STA.w SpritePosXLow, Y

View File

@@ -15,27 +15,3 @@ dw $0000, $7E4E, $6F44, $1CF5, $7399, $1CE7, $02F9, $0233
dw $7FFF, $7FFF, $0000, $5907, $6E0E, $0000, $7FBB, $7672
.off_black
dw $0000, $14A5, $14A5, $14A5, $14A5, $14A5, $14A5, $14A5
.armos
dw hexto555($000000), hexto555($F8F8F8), hexto555($D86060), hexto555($5070C8), hexto555($B090F8), hexto555($282828), hexto555($F0A068), hexto555($B06028)
.lanmolas
dw hexto555($787040), hexto555($585030), hexto555($484018), hexto555($50C090), hexto555($408858), hexto555($305830), hexto555($D8A800), hexto555($E06018)
.moldorm
dw hexto555($F8D018), hexto555($C8B818), hexto555($A89818), hexto555($806818), hexto555($503818), hexto555($903818), hexto555($D85800), hexto555($F8A828)
.agahnim
dw hexto555($000000), hexto555($F8F8F8), hexto555($C04080), hexto555($B08828), hexto555($E8C070), hexto555($282828), hexto555($90D038), hexto555($688020)
.helmasaur
dw hexto555($A00028), hexto555($D03828), hexto555($E88820), hexto555($4848B0), hexto555($7870E8), hexto555($A8A8F8), hexto555($F8F8F8), hexto555($181818)
.arrghus
dw hexto555($000000), hexto555($F8F8F8), hexto555($903018), hexto555($D85800), hexto555($F8A828), hexto555($282828), hexto555($E88068), hexto555($B04038)
.mothula
dw hexto555($000000), hexto555($F8F8F8), hexto555($4848B0), hexto555($7870E8), hexto555($A8A8F8), hexto555($282828), hexto555($F8A840), hexto555($D85820)
.blind
dw hexto555($88D0F8), hexto555($7890F8), hexto555($903018), hexto555($D85800), hexto555($F8A828), hexto555($282828), hexto555($E88068), hexto555($B04038)
.kholdstare
dw hexto555($7098C0), hexto555($58B0E8), hexto555($D0F8F8), hexto555($4828C8), hexto555($4828F0), hexto555($8070F8), hexto555($F8C8F8), hexto555($E088B0)
.vitreous
dw hexto555($000000), hexto555($F8F8F8), hexto555($50C090), hexto555($408858), hexto555($305830), hexto555($282828), hexto555($D8A800), hexto555($E06018)
.trinexx
dw hexto555($A00028), hexto555($A8A8F8), hexto555($7870E8), hexto555($4848B0), hexto555($505060), hexto555($788890), hexto555($78C0A8), hexto555($707068)
.ganon
dw hexto555($385088), hexto555($5088A8), hexto555($88C8A0), hexto555($B090F8), hexto555($C0A028), hexto555($886008), hexto555($B83010), hexto555($E86040)

View File

@@ -2,7 +2,6 @@
; Dark World Spawn Location Fix & Master Sword Grove Fix
;--------------------------------------------------------------------------------
DarkWorldSaveFix:
LDA.b #$70 : PHA : PLB ; thing we wrote over - data bank change
JSL MasterSwordFollowerClear
JML StatSaveCounter
;--------------------------------------------------------------------------------
@@ -12,6 +11,7 @@ DoWorldFix:
+
LDA.l Bugfix_MirrorlessSQToLW : BEQ .skip_mirror_check
LDA.l FollowerIndicator : CMP.b #$04 : BNE + ; if old man following, skip mirror/aga check
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ +
LDA.l OldManRetrievalWorld
BRA .noMirror
+ LDA.l MirrorEquipment : AND.b #$02 : BEQ .noMirror ; check if we have the mirror
@@ -60,6 +60,7 @@ RTL
DoWorldFix_Inverted:
LDA.l Bugfix_MirrorlessSQToLW : BEQ .skip_mirror_check
LDA.l FollowerIndicator : CMP.b #$04 : BNE + ; if old man following, skip mirror/aga check
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ +
LDA.l OldManRetrievalWorld
BRA .setWorld
+ LDA.l MirrorEquipment : AND.b #$02 : BEQ .noMirror ; check if we have the mirror
@@ -115,12 +116,13 @@ FakeWorldFix:
RTL
;--------------------------------------------------------------------------------
GetCurrentWorldForLoad:
LDA FollowerIndicator : CMP #$04 : BNE .default
LDA InvertedMode : BEQ +
LDA #$40
+ RTL
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .default
LDA.l FollowerIndicator : CMP.b #$04 : BNE .default
LDA.l InvertedMode : BEQ +
LDA.b #$40
+ RTL
.default
LDA CurrentWorld
LDA.l CurrentWorld
RTL
;--------------------------------------------------------------------------------
MasterSwordFollowerClear:
@@ -131,7 +133,9 @@ MasterSwordFollowerClear:
RTL
;--------------------------------------------------------------------------------
FixAgahnimFollowers:
LDA.b #$00 : STA.l FollowerIndicator ; clear follower
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ +
LDA.b #$00 : STA.l FollowerIndicator ; clear follower
+
JML PrepDungeonExit ; thing we wrote over
;--------------------------------------------------------------------------------

Binary file not shown.

View File

@@ -202,6 +202,8 @@ DecompressAllItemGraphics:
LDX.b #$5C+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$5B+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$5A+$73 : JSR AddGfxSheetToBigBuffer
JSR AddCherryPickGfxToBigBuffer
LDX.b #$01 : STX.w $06FA
LDX.b #$06+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$07+$73 : JSR AddGfxSheetToBigBuffer
@@ -497,6 +499,11 @@ macro DoPlanesA(offset)
XBA
ORA.b Decomp3BPPScratch
PHY
LDY.w $06FA : BEQ +
AND.w #$00FF ; idk why this line works but some sheets we pull in aren't correct without it
+
PLY
STA.w BigDecompressionBuffer+$10+<offset>+<offset>,X
endmacro
@@ -520,7 +527,11 @@ macro DoIndirectPlanesA(offset)
XBA
ORA.b Decomp3BPPScratch
AND.w #$00FF ; idk why this line works but the 2 sheets we pull in aren't correct without it
PHY
LDY.w $06FA : BEQ +
AND.w #$00FF ; idk why this line works but some sheets we pull in aren't correct without it
+
PLY
STA.l BigDecompressionBuffer+$10+<offset>+<offset>,X
endmacro
@@ -612,4 +623,57 @@ Unrolled3BPPConvert:
;===================================================================================================
macro CherryPickGfx(source,dest,length)
LDX.w #BigDecompressionBuffer+<source>
LDY.w #BigDecompressionBuffer+<dest>
LDA.w #<length>-1
MVN BigDecompressionBuffer>>16,BigDecompressionBuffer>>16
LDX.w #BigDecompressionBuffer+<source>+$200
LDY.w #BigDecompressionBuffer+<dest>+$200
LDA.w #<length>-1
MVN BigDecompressionBuffer>>16,BigDecompressionBuffer>>16
endmacro
;===================================================================================================
AddCherryPickGfxToBigBuffer:
; this is mostly to load and rearrange follower gfx to save on space
; assumes DecompBufferOffset left off at $A000 (#BigDecompressionBuffer+$2000)
; adjustments will be needed if anything prior to this changes
LDX.b #$01 : STX.w $06FA
LDX.b #$35+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$55+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2400,$2140,$40) ; move old man head
%CherryPickGfx($2D40,$20C0,$40) ; move zelda body
LDA.b DecompBufferOffset : SEC : SBC.w #$0C00 : STA.b DecompBufferOffset
SEP #$30
LDX.b #$11+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$15+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2940,$2180,$80) ; move locksmith head/body
%CherryPickGfx($2D00,$0440,$40) ; move frog
%CherryPickGfx($31C0,$0500,$40) ; move purple chest
LDA.b DecompBufferOffset : SEC : SBC.w #$1000 : STA.b DecompBufferOffset
SEP #$30
LDX.b #$59+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$58+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2880,$0480,$40) ; move kiki head
%CherryPickGfx($2900,$04C0,$40) ; move kiki body
%CherryPickGfx($30C0,$0540,$40) ; move big bomb
%CherryPickGfx($2C40,$0180,$40) ; move duck
LDA.b DecompBufferOffset : SEC : SBC.w #$1000 : STA.b DecompBufferOffset
SEP #$30
LDX.b #$4D+$73 : JSR AddGfxSheetToBigBuffer
LDX.b #$50+$73 : JSR AddGfxSheetToBigBuffer
REP #$30
%CherryPickGfx($2880,$0580,$40) ; move smith
%CherryPickGfx($3140,$0140,$40) ; move chicken
LDA.b DecompBufferOffset : SEC : SBC.w #$1000 : STA.b DecompBufferOffset
SEP #$30
STZ.w $06FA
RTS

View File

@@ -265,7 +265,7 @@ RTL
RTL
;--------------------------------------------------------------------------------
DialogGanon1:
JSL CheckGanonVulnerability
LDA.b #$01 : JSL CheckConditionPass
REP #$20
LDA.w #$018C
BCC +
@@ -284,7 +284,7 @@ RTL
; s = silver arrow bow
; p = 2nd progressive bow
DialogGanon2:
JSL CheckGanonVulnerability
LDA.b #$01 : JSL CheckConditionPass
REP #$20
BCS +
@@ -372,8 +372,8 @@ RTL
;---------------------------------------------------------------------------------------------------
AgahnimAsksAboutPed:
LDA.l GanonVulnerableMode
CMP.b #$06 : BNE .vanilla
; seems light_speed option to change some aga text is unused for now
BRA .vanilla
LDA.l OverworldEventDataWRAM+$80 ; check ped flag
AND.b #$40

View File

@@ -13,6 +13,7 @@ PHP
SetDefaultWorld:
PHP : SEP #$20
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .default
LDA.l FollowerIndicator : CMP.b #$04 : BNE .default
LDA.l OldManRetrievalWorld : BRA +
.default

View File

@@ -55,7 +55,7 @@ DRHUD_EnemyDropIndicator:
REP #$30
LDA.w EnemyDropIndicator : STA.w HUDMultiIndicator
SEP #$20
LDA.w DungeonID : CMP.b #$1B : BCS DRHUD_Finished
LDA.w DungeonID : CMP.b #$1B : BCC + : JMP DRHUD_Finished : +
SEP #$10 : TAX : REP #$10
DRHUD_DrawCurrentDungeonIndicator: ; mX
@@ -69,11 +69,17 @@ DRHUD_DrawCurrentDungeonIndicator: ; mX
STY.w HUDCurrentDungeonWorld
DRHUD_DrawKeyCounter:
LDA.l DRFlags : AND.b #$04 : BEQ DRHUD_Finished
REP #$20
LDA.w MapField : AND.l DungeonMask, X : BEQ DRHUD_Finished
TXA : LSR : TAX
LDA.l GenericKeys : AND.w #$00FF : BNE .total_only
LDA.l DRFlags : AND.b #$04 : BEQ DRHUD_Finished
LDA.l CompassMode : BIT.b #$03 : BEQ DRHUD_Finished
REP #$20
BIT.w #$0002 : BNE .skip_map_check
LDA.w MapField : AND.l DungeonMask, X : BEQ DRHUD_Finished
.skip_map_check
TXA : LSR : BNE .dungeon_id
INC
.dungeon_id
TAX
LDA.l GenericKeys : LSR : BCS .total_only
LDA.w DungeonCollectedKeys, X : JSR ConvertToDisplay : STA.w HUDKeysObtained
LDA.w #!SlashTile : STA.w HUDKeysSlash
.total_only
@@ -152,16 +158,17 @@ DrHudDungeonItemsAdditions:
jsr ConvertToDisplay2 : sta.w $1644, y
+ iny #2 : lda.w #$24f5 : sta.w $1644, y
phx : ldx.b Scrap00
lda.l MapField : and.l DungeonMask, x : beq + ; must have map
plx : sep #$30 : lda.l ChestKeys, x : sta.b Scrap02
lda.l GenericKeys : bne +++
lda.b Scrap02 : !SUB.l DungeonCollectedKeys, x : sta.b Scrap02
+++ lda.b Scrap02
rep #$30
jsr ConvertToDisplay2 : sta.w $1644, y ; small key totals
bra .skipStack
+ plx
.skipStack iny #2
LDA.l MapField : ORA.l MapCountDisplay : AND.l DungeonMask, x : BEQ .key_info_done ; must have map
plx : sep #$30 : lda.l ChestKeys, x : sta.b Scrap02
lda.l GenericKeys : bne +++
lda.b Scrap02 : !SUB.l DungeonCollectedKeys, x : sta.b Scrap02
+++ lda.b Scrap02
rep #$30
jsr ConvertToDisplay2 : sta.w $1644, y ; small key totals
bra .skipStack
.key_info_done
plx
.skipStack iny #2
cpx.w #$000d : beq +
lda.w #$24f5 : sta.w $1644, y
+
@@ -169,23 +176,26 @@ DrHudDungeonItemsAdditions:
+ inx #2 : cpx.w #$001b : bcs ++ : JMP -
++
lda.l HudFlag : and.w #$0020 : bne + : JMP ++ : +
; map symbols (do I want these) ; note compass symbol is 2c20
lda.w #$2821 : sta.w $1606 : sta.w $1610 : sta.w $161a : sta.w $1624
; map symbols
lda.w #$2821 : sta.w $1606 : sta.w $1610 : sta.w $161a
; compass symbols
lda.w #$2c20 : sta.w $160a : sta.w $1614 : sta.w $161e : sta.w $16e4
; blank out a couple thing from old hud
lda.w #$24f5 : sta.w $16e4 : sta.w $1724
sta.w $160a : sta.w $1614 : sta.w $161e ; blank out sm key indicators
lda.w #$24f5 : sta.w $1624 : sta.w $1724
ldx.w #$0002
- lda.w #$0000 ; start of hud area
!ADD.l RowOffsets, x : !ADD.l ColumnOffsets, x : tay
lda.l DungeonReminderTable, x : sta.w $1644, y
iny #2
lda.w #$24f5 : sta.w $1644, y ; blank out map spot
lda.l MapField : and.l DungeonMask, x : beq + ; must have map
lda.l MapField : ora.l MapCountDisplay : ora.l MapOverlay
and.l DungeonMask, x : beq + ; must have map
JSR MapIndicatorShort : STA.w $1644, Y
+ iny #2
cpx.w #$001a : bne +
tya : !ADD.w #$003c : tay
+ lda.l CompassField : and.l DungeonMask, x : beq + ; must have compass
+ lda.l CompassField : ora.l CompassCountDisplay
and.l DungeonMask, x : beq + ; must have compass
phx ; total chest counts
LDA.l CompassTotalsWRAM, x : !SUB.l DungeonLocationsChecked, x
SEP #$30 : JSR HudHexToDec2DigitCopy : REP #$30
@@ -241,18 +251,36 @@ BkStatus:
ConvertToDisplay:
and.w #$00ff : cmp.w #$000a : !BLT +
!ADD.w #$2553 : rts
!ADD.w #$2519 : rts
+ !ADD.w #$2490 : rts
ConvertToDisplay2:
and.w #$00ff : beq ++
cmp.w #$000a : !BLT +
!ADD.w #$2553 : rts ; 2580 with 258A as "A" for non transparent digits
!ADD.w #$2517 : rts ; 2580 with 258A as "A" for non transparent digits
+ !ADD.w #$2816 : rts
++ lda.w #$2827 : rts ; 0/O for 0 or placeholder digit ;2483
CountAbsorbedKeys:
JML IncrementSmallKeysNoPrimary
JML IncrementSmallKeysNoPrimary
; This function apporach doesn't currently work
CountAbsorbedKeysViaCountAllKey:
PHA : PHX
LDA.l StandingItemsOn : BEQ .count_it
; LDA.w SpawnedItemKeyCounted : BNE .done ; this was added because pot keys were being double counted when they weren't shuffled
CPY.b #$24 : BEQ .count_it ; small key for this dungeon
LDA.w DungeonID : LSR : TAX
TYA : CMP.l KeyTable, X : BNE .done
.count_it
STY.b Scrap02 : LDY.b #$24 ; for non-24 items (w/o standing_items a small key is just $C), fake it
LDX.b #$84 ; pretend this isn't a smallkey, but an absorbed object (small heart)
REP #$10 : JSL CountAllKey : SEP #$10
LDY.b Scrap02
.done
; STZ.w SpawnedItemKeyCounted ; reset to zero for next time
PLX : PLA
JML IncrementSmallKeysNoPrimary
;================================================================================
; 8-bit registers

View File

@@ -11,6 +11,7 @@ rtl
OnFileLoadOverride:
jsl OnFileLoad ; what I wrote over
jsl StartingFollower
+ lda.l DRFlags : and.b #$02 : beq + ; Mirror Scroll
lda.l MirrorEquipment : bne +
lda.b #$01 : sta.l MirrorEquipment
@@ -52,8 +53,9 @@ GuruguruFix:
BlindAtticFix:
lda.l DRMode : beq +
lda.b #$01 : rtl
+ lda.l FollowerIndicator : cmp.b #$06
- lda.b #$01 : rtl
+ lda.l FollowerTravelAllowed : cmp.b #$02 : beq -
lda.l FollowerIndicator : cmp.b #$06
rtl
SuctionOverworldFix:
@@ -119,12 +121,6 @@ BlindsAtticHint:
SEP #$20 : RTL ; skip the dialog box if the hole is already open
+ SEP #$20 : JML Main_ShowTextMessage
BlindZeldaDespawnFix:
CMP.b #06 : BEQ +
LDA.w SpritePosYLow,X : BEQ + ; don't despawn follower if maiden isn't "present"
PLA : PLA : PEA.w SpritePrep_BlindMaiden_despawn_follower-1 : RTL
+ PLA : PLA : PEA.w SpritePrep_BlindMaiden_kill_the_girl-1 : RTL
BigKeyDoorCheck:
CPY.w #$001E : BNE + ; skip if it isn't a BK door
LDA.l DRFlags : AND.w #$0400 : BNE + ; skip if the flag is set - bk doors can be double-sided

View File

@@ -3,6 +3,16 @@
;--------------------------------------------------------------------------------
SpawnDungeonPrize:
PHX : PHB
PHA
; Don't spawn prize in Cave state, Hyrule Castle, Escape, Castle Tower, or Ganon's Tower
LDA.w DungeonID : BMI .skip_prize_drop ; Cave state
CMP.b #$00 : BEQ .skip_prize_drop ; Escape
CMP.b #$02 : BEQ .skip_prize_drop ; Hyrule Castle
CMP.b #$1A : BEQ .skip_prize_drop ; Ganon's Tower
CMP.b #$08 : BEQ .skip_prize_drop ; Agahnim's Tower (Castle Tower)
PLA
STA.w ItemReceiptID
TAX
LDA.b $06,S : STA.b ScrapBuffer72 ; Store current RoomTag index
@@ -18,6 +28,10 @@ SpawnDungeonPrize:
PLB : PLX
RTL
.skip_prize_drop:
PLA : PLB : PLX
RTL
AddDungeonPrizeAncilla:
LDY.w ItemReceiptID
STZ.w AncillaVelocityY,X
@@ -453,6 +467,7 @@ RTL
MaybeSkipCrystalCutsceneFollowerReset:
PHA
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .skip
; skip if prizes are shuffled outside of normal boss drops
LDA.l InventoryTable_properties+($37*2) : AND.b #$01 : BEQ .continue
.skip

View File

@@ -17,10 +17,14 @@ DoDungeonMapBossIcon:
ASL
TAX
; get sprite pointer table
LDA.l $89C298 : STA.b Scrap00
LDA.w #$0089 : STA.b Scrap02
TXY
; get sprite pointer for room
LDA.l UWSpritesPointers,X
LDA.b [Scrap00], Y
STA.b Scrap00 ; pointer in $00
LDA.w #$0028 : STA.b Scrap02 ; set the bank to 28 for now
LDA.w #UWSpritesData>>16 : STA.b Scrap02 ; set the bank to 28 for now
LDY.w #$0001 ; to skip the "sort"
; get first byte to make sure it isn't an empty room

View File

@@ -39,32 +39,30 @@ RTL
Elder_Code:
{
REP #$20
LDA.l GoalItemRequirement : BEQ .despawn
LDA.l GanonVulnerableMode : AND.w #$00FF : CMP.w #$0005 : BEQ .despawn
LDA.l TurnInGoalItems : AND.w #$00FF : BNE +
TXY : LDX.b #$06
REP #$30
LDA.l GoalConditionTable, X
TAX : LDA.l $B00000, X
SEP #$30
TYX
CMP.b #$00 : BEQ .despawn ; no goal, despawn
LDA.l TurnInGoalItems : BNE +
.despawn
SEP #$20
STZ.w SpriteAITable, X ; despawn self
RTS
+
SEP #$20
LDA.b GameSubMode
BNE .done
LDA.b #$96
LDY.b #$01
JSL Sprite_ShowSolicitedMessageIfPlayerFacing_PreserveMessage : BCC .dont_show
REP #$20
LDA.l GoalCounter
CMP.l GoalItemRequirement : !BLT +
SEP #$20
LDA.b #$03 : JSL CheckConditionPass : BCC +
JSL ActivateTriforceCutscene
+
.dont_show
.done
SEP #$20
LDA.b FrameCounter : LSR #5 : AND.b #$01 : STA.w SpriteGFXControl, X
RTS
}
@@ -144,19 +142,35 @@ MasterSword_CheckIfPulled:
MasterSword_ConditionalActivateCutscene:
LDA.w SpriteMovement,X : BNE .specialCutscene
PHX
REP #$30
LDA.w SprRedrawFlag, X : BNE .doNormalPed
INC.w SprRedrawFlag, X
LDA.l PedPullGfx : BEQ .doNormalPed
LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.w #$BCE0>>1 : STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
.doNormalPed
SEP #$30
PLX
JML Sprite_CheckDamageToPlayerSameLayerLong ; what we wrote over
.specialCutscene
LDA.b #$02 : STA.w ItemReceiptPose ; Link's 2-hands-up pose
STA.b LinkLayer ; draw Link on top
; draw Triforce piece in VRAM
LDA.w SprRedrawFlag, X : BNE .skipTransfer
INC.w SprRedrawFlag, X
PHX
REP #$30
LDX.w #$006A<<1
LDA.l StandingItemGraphicsOffsets,X : LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.l MurahdahlaGfx : BNE .submitRequest
LDX.w #$006A<<1 : LDA.l StandingItemGraphicsOffsets,X
.submitRequest
LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.w #$9CE0>>1 : STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
SEP #$30
PLX
.skipTransfer
PLA : PLA : PLA : JML MasterSword_InPedestal_DoCutscene ; do cutscene
MasterSword_ConditionalGrabPose:
@@ -173,10 +187,20 @@ RTL
MasterSword_SpawnPendantProp_ChangePalette:
STA.w SpriteVelocityY,Y : PLX ; what we wrote over
LDA.w SpriteMovement,X : BNE .specialCutscene
LDA.l PedPullGfx : BNE .customPedGfx
LDA.l PedPullGfx+1 : BNE .customPedGfx
BRA .done
.customPedGfx
LDA.l PedPullPalette : ASL : INC : BRA .setPalette
.specialCutscene
LDA.b #$08 : STA.w SpriteOAMProp,Y ; change palette
LDA.b #$02 : STA.w SpriteLayer,Y ; change layer
LDA.l MurahdahlaGfx : BNE .customGfx
LDA.l MurahdahlaGfx+1 : BNE .customGfx
LDA.b #$08 : BRA .setPalette
.customGfx
LDA.l MurahdahlaPalette : ASL
.setPalette
STA.w SpriteOAMProp,Y ; change palette
.done
JML MasterSword_SpawnPendantProp_ChangePalette_return

View File

@@ -23,12 +23,13 @@ boss_move:
+
CMP.b #41 : BNE + ; Is it Skull Woods Boss Room
; TODO: Add moving floor sprite
JSL Sprite_ResetAll ; reset sprites twice in that room for some reasons (fix bug with kholdstare)
JSL Dungeon_ResetSprites ; Restore the dungeon_resetsprites
LDA.b #$07 : STA.w $0B00 ;Spawn the moving floor sprite
STZ.w $0B28
INC.w OverlordXLow
LDA.w $0E20 : CMP.b #$92 : BNE ++ ; Is it Helmasuar King?
LDA.b #$07 : STA.w $0B00 ;Spawn the bugged moving floor sprite
STZ.w $0B28
INC.w OverlordXLow
++
BRL .move_to_bottom_right
+
@@ -287,3 +288,16 @@ new_trinexx_code:
RTL
;--------------------------------------------------------------------------------
;================================================================================
; Check if water tile in Swamp boss room, skip interaction
;--------------------------------------------------------------------------------
swamp_boss_tile_interaction:
LDA.l Sprite_ReducedTileInteractionTable, X : BEQ .return
CPX.b #$09 : BNE .return ; return if non-water tile
LDX.b IndoorsFlag : BEQ .return ; return if overworld
LDX.b RoomIndex : CPX.b #$06 : BNE .return ; return if not swamp boss room
LDA.b #$00
.return
RTL
;--------------------------------------------------------------------------------

View File

@@ -15,3 +15,12 @@ incsrc hooks/damage_hooks.asm
incsrc hooks/overworld_sprite_hooks.asm
incsrc hooks/underworld_sprite_hooks.asm
org $85B8BA
JSL GeldmanDrawOverride
org $9EAAAC
JSL StalfosKnightDrawOverride
org $9EB209
JSL BlobDrawOverride

View File

@@ -39,3 +39,10 @@ JSL new_kholdstare_code ; Write new gfx in the vram
org $1DAD67 ; sprite_trinexx.asm (62) : LDA.b #$03 : STA $0DC0, X
JSL new_trinexx_code : NOP
;--------------------------------------------------------------------------------
;================================================================================
; Swamp Boss Room Water Fix
;--------------------------------------------------------------------------------
org $06E81A
JSL swamp_boss_tile_interaction
;--------------------------------------------------------------------------------

View File

@@ -2,7 +2,11 @@
; New bush mob randomization
;--------------------------------------------------------------------------------
org $868279
NOP #$0A
BRA +
MaybeSkipTerrainDebris:
JSL MaybeSkipTerrainDebris_long : RTS ; sticking this here, no other free space in bank 06
NOP #3
+
JSL sprite_bush_spawn
NOP ; we keep the branch
;--------------------------------------------------------------------------------

View File

@@ -18,10 +18,3 @@ org $9DD88E
;0EDBB2 0EDBB3
; LDX.b #$01
;}
org $85B8BA ; geldman
JSL Sprite_MaybeForceDrawShadow
org $9EAAAC ; stalfos knight
JSL Sprite_MaybeForceDrawShadow
org $9EB209 ; blob
JSL Sprite_MaybeForceDrawShadow

View File

@@ -2,8 +2,7 @@ pushpc
org $9EC147
JSL NewKodongoCollision
JMP .continue : NOP #2
.continue
BRA + : NOP #3 : +
org $9EC152
Kodongo_SetDirection:
@@ -12,8 +11,18 @@ pullpc
NewKodongoCollision:
LDA.w SpriteMoveDirection, X : INC A : AND.b #$03 : STA.w SpriteMoveDirection, X
JSL Kodongo_InVanillaRoom : BEQ .continue
;If they collide more than 4 times just set direction
LDA.w SpriteAuxTable, X : INC A : STA.w SpriteAuxTable, X : CMP.b #$04 : BCC .continue
PLA : PLA : PEA.w Kodongo_SetDirection-1
.continue
RTL
RTL
Kodongo_InVanillaRoom:
LDA.b RoomIndex+1 : BNE .return
LDA.b RoomIndex : CMP.b #$19 : BEQ .return
CMP.b #$27 : BEQ .return
CMP.b #$77 : BEQ .return
.return
RTL
nop #10

View File

@@ -52,8 +52,5 @@ incsrc falling_death.asm
incsrc shell_gfx.asm
warnpc $B6FFFF ;if we hit this we need to split stuff by bank
org $8684BD
Sprite_Get16BitCoords_long:
org $9EC6FA ;F46FA
SpritePrep_Eyegore:

View File

@@ -26,7 +26,7 @@ SpritePrep_Eyegore_become_mimic:
;JSL resetSprite_Mimic : NOP
org $86ED9E ; Sprite_ApplyCalculatedDamage, skip high sprite id early exit
; JSL IsItReallyAMimic : NOP ; now hooked into from souls.asm
JSL IsItReallyAMimic : NOP
org $86EDA6 ; Sprite_ApplyCalculatedDamage .not_absorbable
JSL notItemSprite_Mimic
@@ -108,4 +108,4 @@ notItemSprite_Mimic:
.continue
; restore code
REP #$20 : ASL #2
RTL
RTL

View File

@@ -8,4 +8,40 @@ GetSpriteSlot16Bit:
LDA.b Scrap03 : AND.w #$00FF
ASL A
TAY
RTL
RTL
GeldmanDrawOverride:
PLA : PLA : PLA ; fix the call stack
LDA.l DRFlags+1 : AND.b #$08 : BEQ .vanilla
LDA.b #$01
STA.w $0DC0,X
JML Sprite_4C_Geldman_do_indeed_draw
.vanilla
JSL Sprite_PrepOAMCoordLong
JML Sprite_4C_Geldman_continue
StalfosKnightDrawOverride:
LDA.l DRFlags+1 : AND.b #$08 : BEQ .vanilla
JSL Sprite_PrepOAMCoordLong
LDA.b #$12
JML Sprite_DrawShadowLong
.vanilla
JSL Sprite_PrepOAMCoordLong
RTL
BlobDrawOverride:
PLA : PLA : PLA ; fix the call stack
LDA.l DRFlags+1 : AND.b #$08 : BEQ .vanilla
LDA.b #$05
STA.w $0DC0,X
JML SpriteDraw_Blob_head_popping_out
.vanilla
JSL Sprite_PrepOAMCoordLong
JML SpriteDraw_Blob_bad_gfx

View File

@@ -25,15 +25,3 @@ NewFireBarDamage:
RTL
.NotSameLayer
RTL
;--------------------------------------------------------------------------------
Sprite_MaybeForceDrawShadow:
JSL Sprite_PrepOAMCoordLong
LDA.l DRFlags+1 : AND.b #$08 : BEQ .return
LDA.b GameMode : CMP.b #$07 : BNE .return
JSL Sprite_DrawShadowLong
; LDA.w SpriteTypeTable,X : CMP.b #$91 : BNE .return ; stalfos knight
; ; move shadow down by 8 pixels
; + LDA.w SpriteOAMProperties,X : AND.b #$1F : ASL #2 : TAY : INY ; get OAM offset
; LDA.b (OAMPtr),Y : CLC : ADC.b #$08 : STA.b (OAMPtr),Y
.return
RTL

View File

@@ -63,8 +63,8 @@ RTS
RTS
;--------------------------------------------------------------------------------
SmithDoorCheck:
LDA.l SmithTravelsFreely : AND.w #$00FF : BEQ .orig
;If SmithTravelsFreely is set Frog/Smith can enter multi-entrance overworld doors
LDA.l FollowerTravelAllowed : AND.w #$00FF : BEQ .orig
;If FollowerTravelAllowed is set Frog/Smith can enter multi-entrance overworld doors
JML Overworld_Entrance_BRANCH_RHO
.orig ; The rest is equivlent to what we overwrote

View File

@@ -61,13 +61,22 @@ OnDungeonExit:
PLP : PLA
RTL
;--------------------------------------------------------------------------------
OnSave:
LDA.b #$70 : PHA : PLB ; thing we wrote over - data bank change
JSL DarkWorldSaveFix
JML MSUResumeReset
;--------------------------------------------------------------------------------
OnQuit:
JSL SQEGFix
JSL MSUResumeReset
LDA.b #$00 : STA.l AltTextFlag ; bandaid patch bug with mirroring away from text
LDA.b #$10 : STA.b MAINDESQ ; thing we wrote over
RTL
;--------------------------------------------------------------------------------
OnDeathNoSave:
JSL MSUResumeReset
LDA.b #$05 : STA.b $10 ; what we wrote over
RTL
;--------------------------------------------------------------------------------
OnUncleItemGet:
PHA
@@ -98,8 +107,8 @@ RTL
;--------------------------------------------------------------------------------
OnAga1Defeated:
STA.l ProgressIndicator ; vanilla game state stuff we overwrote
LDA.l GanonVulnerableMode
CMP.b #$06 : BNE +
; seems light_speed option to auto triforce room is unused for now
BRA +
.light_speed
REP #$20
LDA.w #$0019 : STA.b GameMode
@@ -135,7 +144,7 @@ OnFileCreation:
; Resolve instant post-aga if standard
SEP #$20
LDA.l InitProgressIndicator : BIT #$80 : BEQ +
LDA.l InitProgressIndicator : BIT.b #$80 : BEQ +
LDA.b #$00 : STA.l ProgressIndicatorSRAM ; set post-aga after zelda rescue
LDA.b #$00 : STA.l OverworldEventDataSRAM+$02 ; keep rain state vanilla
+

951
follower.asm Normal file
View File

@@ -0,0 +1,951 @@
pushpc
; follower hooks
org $81EBB6
JSL MaybeSetZeldaCheckpoint
org $899FA1
db $FF, $FF, $FF ; disable timed follower messages
org $89A647
JSL MaybeSkipFollowerTrigger : NOP
org $89F544
JSL MaybeDeleteFollowersOnDeath
org $85EBCF
JSL SpritePrep_ZeldaFollower : NOP #2
org $85EC9E
JSL SpriteDraw_ZeldaMaiden
org $85ECD9
JSL Zelda_WaitingInCell
org $85ED46
JSL Zelda_BecomeFollower : NOP #2
org $9EE902
JSL SpritePrep_OldManFollower : NOP #2 : db $F0 ; BEQ
org $9DFF18
JSL SpriteDraw_OldManFollower
org $9EE9BC
JSL OldMan_WaitForCollision
org $9EE9CC
JSL OldMan_BecomeFollower : NOP #2
org $86899C
JSL SpritePrep_BlindMaiden : NOP #2
org $8689A7
JSL BlindZeldaDespawnFix : NOP #2
org $9EE8B0
JSL SpriteDraw_ZeldaMaiden
org $9EE8CD
JSL Follower_CheckCollision
org $9EE8D7
JSL BlindMaiden_BecomeFollower : NOP
org $868A7E
JSL SpritePrep_SmithyFrog : BRA + : NOP #8 : +
org $86B2AA
JSL Follower_CheckMessageCollision
org $86B2B4
JSL Frog_BecomeFollower : NOP #2
org $86B341
JSL SpriteDraw_FrogFollower
org $868A53
JSL SpritePrep_PurpleChest : NOP #2
org $9EE0D7
JSL SpriteDraw_PurpleChest
org $9EE0E7
JSL Follower_CheckMessageCollision
org $9EE0ED
JSL PurpleChest_FollowCheck
org $9EE0F7
JSL PurpleChest_BecomeFollower : NOP
org $868A0A
JSL SpritePrep_SuperBomb
org $868A4A
SuperBomb_BecomeFollower_exit:
org $9EE16E
BRA + : NOP #6 : + ; fix bomb shop dialog for dwarfless big bomb
org $9EE1E8
JSL SuperBomb_FollowCheck
org $9EE1F1
JSL SuperBomb_BecomeFollower : NOP #2
org $9EE2C0
JSL SpriteDraw_SuperBomb
org $868D51
JSL SpritePrep_Kiki : NOP #2
org $9EE3E6
JSL Kiki_OfferToFollow
org $9EE495
JSL Kiki_FollowCheck : BRA + : NOP #12 : +
org $9EE4AF
JSL Kiki_BecomeFollower : NOP #2
org $9EE4F7
JSL Kiki_FixTeleportOnExit
org $89A1B2
JSL Kiki_DontScareTheMonke : NOP #3
org $868D63
JSL SpritePrep_Locksmith : NOP #2 : db $90 ; BCC
org $868D7E
db $80 ; BRA
org $86BCD9
JML Locksmith_Chillin_PostMessage
org $86BD09
JSL Locksmith_BecomeFollower : NOP #2
org $86BD7A ; allow follower pickup after purple chest item
LDA.b #$00 : STA.w SpriteActivity, X
JSL Locksmith_RespondToAnswer_PostItem
org $86BDB4
JSL SpriteDraw_LocksmithFollower
pullpc
MaybeSkipFollowerTrigger:
LDA.b GameMode : AND.w #$00FF : CMP.w #$0010 : BNE .normal
.no_trigger
INC : RTL
.normal
LDA.w $02F2 : AND.b Scrap06 ; what we wrote over
RTL
MaybeDeleteFollowersOnDeath:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
; s+q = favor keeping current follower
; death = favor replacing with unfulfilled starting followers
; during escape = always favor keeping zelda
LDA.b GameMode : CMP.b #$17 : BEQ .keep
LDA.w DungeonID : NOP #2 : BPL .keep
LDA.l InitFollowerIndicator : BEQ .keep
JSL DetermineFollowerSpawn_check_resolved : BCS .keep
LDA.l ProgressIndicator : CMP.b #$02 : BCS .delete
LDA.l FollowerIndicator : CMP.b #$01 : BEQ .keep
.delete
PLA : PLA : PEA.w $89F558-1
RTL
.keep
PLA : PLA : PEA.w $89F55E-1
RTL
.vanilla
LDA.l FollowerIndicator ; what we wrote over
RTL
StartingFollower:
LDA.l InitFollowerIndicator : BEQ .return
PHA
REP #$20
; possible spawn points
LDA.b RoomIndex : CMP.w #$0104 : BEQ + ; links house
CMP.w #$0012 : BEQ + ; sanc
CMP.w #$00E4 : BEQ + ; old man
CMP.w #$0112 : BEQ + ; dark sanc
CMP.w #$011C : BEQ + ; bomb shop
SEP #$20 : PLA : RTL
+
SEP #$20
LDA.l FollowerIndicator : BEQ +
LDA.l FollowerDropped : CMP.b #$80 : PLA : BCC .return : PHA
+ LDA.l ProgressIndicator : CMP.b #$02 : PLA : BCC .escape_check
PHA
JSL DetermineFollowerSpawn_check_resolved
PLA
BCC .issue_follower
BRA .return
.escape_check
CMP.b #$01 : BNE .return
PHA : LDA.l ProgressFlags : AND.b #$04 : CMP.b #$04 : PLA : BCS .return
.issue_follower
STA.l FollowerIndicator
LDA.b #$00 : STA.l FollowerDropped
.return
RTL
MaybeSetZeldaCheckpoint:
AND.w #$7FFF : TAX ; what we wrote over
SEP #$20
LDA.l ProgressFlags : AND.b #$04 : BNE .return ; zelda rescued
LDA.l StartingEntrance : CMP.b #$02 : BEQ .return ; cell checkpoint set
CMP.b #$04 : BEQ .return ; throne room checkpoint set
LDA.l FollowerIndicator : CMP.b #$01 : BNE .return ; zelda following
LDA.b RoomIndex : CMP.b #$80 : BNE + ;zelda cell
LDA.l Follower_Zelda : CMP.b #$01 : BNE .return
BRA .set_checkpoint
+ CMP.b #$45 : BNE .return ; maiden cell
CPX.w #$0964 : BNE .return ; top big lock
LDA.l Follower_Maiden : CMP.b #$01 : BNE .return
.set_checkpoint
LDA.b #$02 : STA.l StartingEntrance
PHX
SEP #$10
JSL SaveDeathCount
JSL Dungeon_SaveRoomQuadrantData
REP #$10
PLX
.return
REP #$30
RTL
FollowerGfxRedraw:
PHP : SEP #$30
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .return
PHY
LDY.b #$0F
.next
LDA.w SpriteAITable,Y : BEQ ++
LDA.w SpriteTypeTable,Y : CMP.b #$76 : BEQ + ; zelda
CMP.b #$AD : BEQ + ; old man
CMP.b #$B7 : BEQ + ; maiden
CMP.b #$1A : BEQ + ; frog
CMP.b #$39 : BEQ + ; locksmith
CMP.b #$B6 : BEQ + ; kiki
CMP.b #$B4 : BEQ + ; purple chest
CMP.b #$B5 : BNE ++ ; big bomb
LDA.w SpriteJumpIndex,Y : CMP.b #$02 : BEQ +
BRA ++
+ LDA.b #$01 : STA.w SprRedrawFlag,Y
++ DEY : BPL .next
PLY
.return
PLP
RTL
; A = 2 byte VRAM position in OAM2 for head/body
; Scrap06/07/08 = address to OAM group
; Returns with carry flag set if draw occurred
TransferAndDrawFollowerGfx:
PHA
LDA.w SpriteTimerE, X : AND.w #$0008 : BNE .skip_draw ; skip drawing every other frame
LDA.b 1,S
JSR TransferFollowerSpriteGfx ; returns with SEP #$20
LDA.w SpriteTypeTable, X : CMP.b #$39 : BNE +
; locksmith location flicker if quest completed but purple chest remains
LDA.w SpriteAux, X : BNE .continue
JSL DetermineFollowerSpawn : BCS .flicker
+ BRA .continue
.flicker
LDA.w SpriteTimerE, X : NOP #2 : BNE .continue
LDA.b #$0C : STA.w SpriteTimerE, X
.continue
PLA : XBA : PLA : XBA
JSL SpriteDraw_Follower
SEC
RTL
.skip_draw
PLA
SEP #$20
CLC
RTL
; A = 2 byte VRAM position in OAM2 for head/body
TransferFollowerSpriteGfx_skip_transfer:
PLA : PLA
RTS
TransferFollowerSpriteGfx:
PHA : SEP #$20
LDA.w SprRedrawFlag, X : BEQ .skip_transfer
.redraw
STZ.w SprRedrawFlag, X
JSL DetermineFollower
CMP.b #$01 : BNE +
PLA : XBA : LDA.b #$83 ; zelda body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$82 ; zelda head
JMP QueueFollowerSpriteGfx
+ CMP.b #$04 : BNE +
PLA : XBA : LDA.b #$84 ; old man body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$85 ; old man head
JMP QueueFollowerSpriteGfx
+ CMP.b #$06 : BNE +
PLA : XBA : LDA.b #$81 ; maiden body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$80 ; maiden head
JMP QueueFollowerSpriteGfx
+ CMP.b #$07 : BNE +
PLA : XBA : PLA : LDA.b #$11 ; frog
JMP QueueFollowerSpriteGfx
+ CMP.b #$08 : BNE +
PLA : XBA : PLA : LDA.b #$16 ; smith
JMP QueueFollowerSpriteGfx
+ CMP.b #$09 : BNE +
PLA : XBA : LDA.b #$87 ; locksmith body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$86 ; locksmith head
JMP QueueFollowerSpriteGfx
+ CMP.b #$0A : BNE +
PLA : XBA : LDA.b #$13 ; kiki body
JSR QueueFollowerSpriteGfx
PLA : XBA : LDA.b #$12 ; kiki head
JMP QueueFollowerSpriteGfx
+ CMP.b #$0C : BNE +
PLA : XBA : PLA : LDA.b #$14 ; purple chest
JMP QueueFollowerSpriteGfx
+ PLA : XBA : PLA : LDA.b #$15 ; super bomb
JMP QueueFollowerSpriteGfx
; A = 2 bytes, dest/src
QueueFollowerSpriteGfx:
PHX : REP #$20
PHA
AND.w #$00FF : CMP.w #$00FF : BEQ +
ASL #6 : EOR.w #$8000 : BRA .write_src
+ LDA.w #$0020 ; blank tile
.write_src
LDX.w ItemStackPtr : STA.l ItemGFXStack,X
PLA : XBA
AND.w #$00FF : ASL #4 : EOR.w #$5000
STA.l ItemTargetStack,X
TXA : INC #2 : STA.w ItemStackPtr
SEP #$20 : PLX
RTS
; A = 2 byte VRAM position in OAM2 for head/body
; Scrap06/07/08 = address to OAM group
; Scrap09/0A = address to palette data
SpriteDraw_Follower:
PHB : LDY.b #$7E : PHY : PLB
REP #$20
PHA
LDY.b #$0E
- LDA.b [Scrap06], Y : STA.w SpriteDynamicOAM, Y
DEY #2 : BPL -
LDA.b Scrap09 : STA.b Scrap06
PLA
SEP #$20
STA.w SpriteDynamicOAM+$0C : XBA : STA.w SpriteDynamicOAM+$04
JSL DetermineFollower : PHA
PHX
TAX : DEX
LDA.b Scrap06 : ORA.b Scrap07 : BEQ +
TXY
LDA.b [Scrap06], Y
BRA .set_palette
+
LDA.l .palette_data, X
.set_palette
STA.w SpriteDynamicOAM+$05 : STA.w SpriteDynamicOAM+$0D
PLX
REP #$20
LDA.w #$0002 : STA.b Scrap06
LDA.w #SpriteDynamicOAM : STA.b Scrap08
SEP #$20
PLA : CMP.b #$07 : BCC + : CMP.b #$09 : BEQ + : CMP.b #$0A : BEQ +
; only draw body
PHA
LDA.b #$01 : STA.b Scrap06
LDA.b #SpriteDynamicOAM+8 : STA.b Scrap08
PLA
+
; follower specific adjustments
CMP.b #$04 : BNE +
LDA.w SpriteDynamicOAM+$0A : SEC : SBC.b #8 : STA.w SpriteDynamicOAM+$02 ; old man coords
+
CMP.b #$0A : BNE +
LDA.w SpriteDynamicOAM+$0A : SEC : SBC.b #6 : STA.w SpriteDynamicOAM+$02 ; kiki coords
LDA.w SpriteTypeTable, X : CMP.b #$1A : BEQ ++ : CMP.b #$B4 : BCS ++ : BRA .draw
++ LDA.w SpriteDynamicOAM+$05 : ORA.b #$40
STA.w SpriteDynamicOAM+$05 : STA.w SpriteDynamicOAM+$0D ; kiki horiz flip
+
.draw
JSL Sprite_DrawMultiple_player_deferred
PLB
RTL
.palette_data
; 01 04 06 07 08 09 0A 0C 0D
db $00, $00, $00, $00, $00, $06, $00, $00, $06, $00, $00, $00, $00
DetermineFollower:
LDA.w SpriteAux, X : BEQ .skip_stored : RTL ; stored follower
.skip_stored
+ LDA.w $0E20,X : CMP.b #$1A : BNE +
LDA.l Follower_Frog : BRA .finalize
+ CMP.b #$39 : BNE +
LDA.l Follower_Locksmith : BRA .finalize
+ CMP.b #$AD : BNE +
LDA.l Follower_OldMan : BRA .finalize
+ CMP.b #$B6 : BNE +
LDA.l Follower_Kiki : BRA .finalize
+ CMP.b #$B7 : BNE +
LDA.l Follower_Maiden : BRA .finalize
+ CMP.b #$76 : BNE +
LDA.l Follower_Zelda : BRA .finalize
+ CMP.b #$B4 : BNE +
LDA.l Follower_PurpleChest : BRA .finalize
+ LDA.l Follower_SuperBomb
.finalize
PHA
CMP.b #$07 : BNE +
LDA.l CurrentWorld : BNE +
PLA : LDA.b #$08 : RTL
+
PLA
RTL
SetAndLoadFollower:
LDA.l FollowerIndicator
.skip_current
PHA
LDA.b #$00 : STA.l FollowerDropped
JSL DetermineFollower : STA.l FollowerIndicator
CMP.b #$01 : BNE +
JSL DetermineFollower_skip_stored : CMP.b #$01 : BNE +
LDA.b #$02 : STA.l StartingEntrance
JSL SaveDeathCount
PHX
JSL Dungeon_SaveRoomQuadrantData
PLX
+ CMP.b #$09 : BNE +
LDA.b #$40 : STA.w $02CD : STZ.w $02CE ; locksmith timed message
+
PHX
JSL Tagalong_LoadGfx
PLX
PLA : BNE +
JSL Follower_Initialize
JML Sprite_BecomeFollower
+
RTL
StoreAndLoadFollower:
LDA.l FollowerDropped : BNE .no_storage
LDA.l FollowerIndicator : BEQ .no_storage
PHA
JSL SetAndLoadFollower_skip_current
PLA : STA.w SpriteAux, X
LDA.b #$13 : JSL Sound_SetSfx3PanLong
LDA.b #$01 : STA.w SprRedrawFlag, X
STZ.w SpriteActivity, X
LDA.b #$90 : STA.w SpriteTimerE, X
SEC : RTL
.no_storage
JSL SetAndLoadFollower_skip_current
CLC : RTL
; return SEC if destination resolved
DetermineFollowerSpawn_locksmith_check:
; locksmith location needs to spawn if purple chest reward not acquired
LDA.l FollowerIndicator : CMP.b #$0C : BEQ .always_spawn
JSL DetermineFollower_skip_stored : CMP.l FollowerIndicator : BEQ .matched_following
LDA.l NpcFlagsVanilla : AND.b #$10 : BEQ .always_spawn
BRA DetermineFollowerSpawn
.always_spawn
CLC : RTL
.matched_following
SEC : RTL
DetermineFollowerSpawn_include_stored:
JSL DetermineFollower
BRA DetermineFollowerSpawn_byof
DetermineFollowerSpawn:
JSL DetermineFollower_skip_stored
.byof
CMP.l FollowerIndicator : BEQ .matched_following
.skip_match_check
PHA
; despawn if pre-requisite not met
LDA.w SpriteTypeTable, X : CMP.b #$B4 : BNE +
LDA.l NpcFlagsVanilla : AND.b #$20 : EOR.b #$20 : CMP.b #$20
BRA .prereq_check
+ CMP.b #$B5 : BNE +
LDA.l CrystalsField : AND.b #$05 : CMP.b #$05
LDA.b #$FF : ADC.b #$00 : ROR ; flip carry flag
.prereq_check
PLA : BCC .check_resolved
RTL
+
PLA
.check_resolved
CMP.b #$01 : BNE +
LDA.l ProgressFlags : AND.b #$04 : CMP.b #$04 : RTL
+ CMP.b #$04 : BNE +
JML ItemCheck_OldMan
+ CMP.b #$06 : BNE +
LDA.l RoomDataWRAM[$AC].high : AND.b #$08 : CMP.b #$08 : BCS ++
LDA.l EnemizerFlags_close_blind_door : CMP.b #$01
++
RTL
+ CMP.b #$09 : BCS + ; if frog or smith
LDA.l NpcFlagsVanilla : AND.b #$20 : CMP.b #$20 : RTL
+ CMP.b #$0A : BNE +
LDA.l OverworldEventDataWRAM+$5E : AND.b #$20 : CMP.b #$20 : RTL
+ CMP.b #$0C : BNE +
LDA.l NpcFlagsVanilla : AND.b #$10 : CMP.b #$10 : RTL
+
.always_spawn
CLC : RTL ; big bomb and locksmith have no completion condition in code
.matched_following
SEC : RTL
Follower_CheckMessageCollision:
PHA
LDA.w SpriteTimerE, X : BNE .skip_collision_check
PLA
JML Sprite_ShowMessageFromPlayerContact ; what we wrote over
.skip_collision_check
PLA
CLC : RTL
Follower_CheckTileCollision:
LDA.w SpriteTimerE, X : BNE .skip_collision_check
JML Sprite_CheckTileCollisionLong ; what we wrote over
.skip_collision_check
RTL
Follower_CheckCollision:
LDA.w SpriteTimerE, X : BNE .skip_collision_check
JML Sprite_CheckDamageToPlayerSameLayerLong ; what we wrote over
.skip_collision_check
CLC : RTL
SpritePrep_ZeldaFollower:
LDA.b RoomIndex : CMP.b #$12 : BEQ .no_follower_shuffle_sanc
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
JSL DetermineFollowerSpawn : BCC + : RTL : +
LDA.b #$01 : STA.w SprRedrawFlag, X
PLA : PLA : PEA.w $EC4B-1 ; return to spawn
RTL
.no_follower_shuffle
LDA.l FollowerIndicator : CMP.b #$01
RTL
.no_follower_shuffle_sanc
LDA.l FollowerIndicator : CMP.b #$02
RTL
Zelda_WaitingInCell:
JSL Follower_CheckCollision ; what we wrote over, kinda
BCC .return
PHP
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE +
INC.w SpriteActivity, X
PLP
PLA : PLA : PEA.w $ECF9-1 : RTL ; skip sprite movement
+
PLP
.return
RTL
Zelda_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $ED68-1 : RTL ; jump to avoid sprite despawn
+
PEA.w $ED60-1 ; jump to despawn
RTL
.vanilla
LDA.b #$02 : STA.l StartingEntrance ; what we wrote over
RTL
SpritePrep_BlindMaiden:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$01 : RTL
+
LDA.b #$01 : STA.w SprRedrawFlag, X
INC.w SpriteAncillaInteract, X
STZ.w FollowerNoDraw
PLA : PLA : PEA.w $89C8-1 ; return to spawn
RTL
.vanilla
LDA.l RoomDataWRAM[$AC].high : AND.b #$08 ; what we wrote over
RTL
; Prevent followers from causing blind/maiden to despawn:
; Door rando: let zelda despawn the maiden.
BlindZeldaDespawnFix:
LDA.l FollowerIndicator ; what we wrote over
CMP.b #06 : BEQ +
LDA.w SpritePosYLow,X : BEQ +
LDA.b #$00 : RTL ; don't despawn follower if maiden isn't "present"
+
LDA.b #$01 : RTL
SpriteDraw_ZeldaMaiden:
LDA.b RoomIndex : CMP.b #$12 : BEQ .vanilla
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
LDA.w SpriteTypeTable, X : CMP.b #$76 : BNE +
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
LDA.l Follower_Zelda_vram
BRA .transfer
+
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #.palette_data_maiden : STA.b Scrap09
LDA.l Follower_Maiden_vram
.transfer
JML TransferAndDrawFollowerGfx
.skip_draw
RTL
.vanilla:
JML SpriteDraw_Maiden
.oam_group:
dw 1, -7 : db $20, $00, $00, $02
dw 1, 3 : db $22, $00, $00, $02
.palette_data_maiden
; 01 04 06 07 08 09 0A 0C 0D
db $02, $00, $00, $02, $00, $04, $02, $02, $04, $02, $00, $02, $02
BlindMaiden_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCS .return
STZ.w SpriteAITable, X
.return
PEA.w $E8EA-1 ; jump ahead on return
RTL
.vanilla
STZ.w SpriteAITable, X : LDA.b #$06 ; what we wrote over
RTL
SpritePrep_OldManFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
PLA : PLA
JSL DetermineFollowerSpawn : BCC +
PEA.w $E928-1 ; return to despawn
RTL
+
LDA.b #$01 : STA.w SprRedrawFlag, X
PEA.w $E927-1 ; return to spawn
RTL
.no_follower_shuffle
LDA.l FollowerIndicator : CMP.b #$04
RTL
SpriteDraw_OldManFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.w SpriteJumpIndex, X : CMP.b #$01 : BEQ .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
PLA : PEA.w $FF45-1 ; skip vanilla draw
LDA.l Follower_OldMan_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$02 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group
dw 0, 0 : db $AC, $00, $00, $02
dw 0, 8 : db $AE, $00, $00, $02
OldMan_WaitForCollision:
PHA
LDA.w LinkIFrames : BEQ +
PLA : CLC
RTL
+
PLA
JML Follower_CheckMessageCollision
OldMan_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BCC .set_follower_and_despawn
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $E9DF-1 : RTL ; jump to avoid sprite despawn
+
PEA.w $E9DC-1 ; jump to despawn
RTL
.set_follower_and_despawn
JSL SetAndLoadFollower
PLA : PLA : PEA.w $E9D6-1
SpritePrep_SmithyFrog:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
JSL DetermineFollowerSpawn : BCC +
LDA.b #$01 ; return to despawn
RTL
+
LDA.b #$01 : STA.w SprRedrawFlag, X
DEC ; return to spawn
RTL
.no_follower_shuffle
LDA.l FollowerIndicator : BNE + ; what we wrote over
LDA.l NpcFlagsVanilla : AND.b #$20 ; what we wrote over
+ RTL
SpriteDraw_FrogFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
PLA : PEA.w $DCD6-1
LDA.l Follower_Frog_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$01 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group:
dw 1, -8 : db $FF, $00, $00, $02
dw 1, 0 : db $C8, $00, $00, $02
Frog_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BCC .set_follower_and_despawn
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $B2C7-1 : RTL ; jump to avoid sprite despawn
+
PEA.w $B2C4-1 ; jump to despawn
RTL
.set_follower_and_despawn
JSL SetAndLoadFollower
PLA : PLA : PEA.w $B2C4-1 ; jump to despawn
RTL
SpritePrep_PurpleChest:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$00 ; return to despawn
RTL
+
PLA : PLA : PEA.w $8A69-1 ; return to spawn
LDA.b #$01 : STA.w SprRedrawFlag, X
RTL
.vanilla
LDA.l FollowerIndicator : CMP.b #$0C
RTL
SpriteDraw_PurpleChest:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #0000 : STA.b Scrap09
LDA.l Follower_PurpleChest_vram
JML TransferAndDrawFollowerGfx
.vanilla
JML Sprite_PrepAndDrawSingleLargeLong ; what we wrote over
.oam_group:
dw 0, -8 : db $C8, $00, $00, $02
dw 0, 0 : db $EE, $00, $00, $02
PurpleChest_FollowCheck:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #$00
RTL
.vanilla
LDA.l FollowerIndicator ; what we wrote over
RTL
PurpleChest_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCS .return
STZ.w SpriteAITable, X
.return
PEA.w $E10A-1 ; jump ahead on return
RTL
.vanilla
STZ.w SpriteAITable, X : LDA.b #$0C ; what we wrote over
RTL
SpritePrep_SuperBomb:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$00 ; despawn on exit
RTL
+
LDA.b #$05
RTL
.vanilla
LDA.l CrystalsField ; what we wrote over
RTL
SpriteDraw_SuperBomb:
LDA.w SpriteJumpIndex, X : CMP.b #$02 : BNE .vanilla
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #.palette_data : STA.b Scrap09
PLA : PEA.w $E2E2-1 ; skip vanilla draw
LDA.l Follower_SuperBomb_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$01 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group:
dw 0, -8 : db $AE, $08, $00, $02
dw 0, 0 : db $4E, $08, $00, $02
.palette_data
; 01 04 06 07 08 09 0A 0C 0D
db $08, $00, $00, $08, $00, $06, $08, $08, $06, $08, $00, $08, $08
SuperBomb_FollowCheck:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.w SpriteTimerE, X : BNE .skip_follow
LDA.w SpriteAux, X : BEQ .vanilla
PLA : PLA : PEA.w $E1F1-1 ; jump to skip cost, no double charge
RTL
.skip_follow
PLA : PLA : PEA.w $E20C-1 ; jump to exit
RTL
.vanilla
LDA.b #$64 : LDY.b #$00 ; what we wrote over
RTL
SuperBomb_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
PLA : PLA
JSL StoreAndLoadFollower : BCC +
PEA.w $E20C-1 : RTL ; jump to exit
+
PEA.w $E201-1 ; jump to despawn
RTL
.vanilla
LDA.b #$0D : STA.l FollowerIndicator ; what we wrote over
RTL
pushpc
org $868A14
NOP #3 ; fix bomb shop spawn for dwarfless big bomb
LDA.b #$B5 : JSL Sprite_SpawnDynamically
BMI SuperBomb_BecomeFollower_exit
LDA.b #$01 : STA.w SprRedrawFlag, Y ; force redraw for super bomb gfx
pullpc
SpritePrep_Kiki:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn : BCC +
LDA.b #$20 : RTL ; despawn on exit
+
LDA.b #$00
RTL
.vanilla
LDX.b OverworldIndex : LDA.l OverworldEventDataWRAM,X ; what we wrote over
RTL
Kiki_OfferToFollow:
PHA
LDA.w SpriteTimerE, X : BNE .skip_collision_check
PLA
JML Sprite_ShowMessageUnconditional ; what we wrote over
.skip_collision_check
PLA
CLC : RTL
Kiki_FollowCheck:
JSL DetermineFollowerSpawn_include_stored : BCS .skip_follow
LDA.w SpriteTimerE, X
RTL
.skip_follow
LDA.b #$20
RTL
Kiki_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_follower_shuffle
PLA : PLA : PEA.w $E4C2-1 ; jump to exit
STZ.w FollowerNoDraw
JML StoreAndLoadFollower
.no_follower_shuffle
LDA.b #$00 : STA.l FollowerDropped ; defuse bomb
LDA.b #$0A : STA.l FollowerIndicator
RTL
Kiki_FixTeleportOnExit:
REP #$30
LDA.b LinkPosX : STA.w LinkPosXCache
LDA.b LinkPosY : STA.w LinkPosYCache
SEP #$30
LDA.b #$19 : LDY.b #$01 ; what we wrote over
RTL
; on return it checks BEQ and if non-zero, kiki get spook
Kiki_DontScareTheMonke:
LDA.b LinkJumping : BEQ .return
CMP.b #$02 : BEQ .no_spook ; needed for quake usage
LDA.w NoDamage : BNE .no_spook
LDA.w LinkThud : BNE .no_spook
.spook
LDA.b #$01 : RTL
.no_spook
LDA.b #$00
.return
RTL
SpritePrep_Locksmith:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
JSL DetermineFollowerSpawn_locksmith_check : BCS +
LDA.b #$01 : STA.w SprRedrawFlag, X
+
LDA.l FollowerIndicator
RTL
.vanilla
LDA.l FollowerIndicator : CMP.b #$09 ; what we wrote over
BEQ +
CLC : RTL
+
SEC : RTL
SpriteDraw_LocksmithFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
LDA.b #.oam_group>>16 : STA.b Scrap08
REP #$20
LDA.w #.oam_group : STA.b Scrap06
LDA.w #.palette_data : STA.b Scrap09
PLA : PEA.w $DCD6-1 ; skip draw on exit
LDA.l Follower_Locksmith_vram
JML TransferAndDrawFollowerGfx
.vanilla
LDA.b #$02 : STA.b Scrap06 ; what we wrote over
RTL
.oam_group:
dw 0, -8 : db $EA, $00, $00, $02
dw 0, 0 : db $EC, $00, $00, $02
.palette_data
; 01 04 06 07 08 09 0A 0C 0D
db $00, $00, $00, $0E, $00, $00, $0E, $0E, $00, $0E, $00, $0E, $0E
Locksmith_Chillin_PostMessage:
LDA.w SpriteAux, X : BEQ +
; when a follower is stored, merely walk near them
LDA.w SpritePosXLow, X : PHA
JSL Follower_CheckCollision : BCC .return
BRA .continue
+
LDA.w SpritePosXLow, X : PHA
SEC : SBC.b #$10 : STA.w SpritePosXLow, X
LDA.b #$01 : STA.w SpriteVelocityX, X
JSL Sprite_Get16BitCoords_long
JSL Follower_CheckTileCollision : BNE .return
.continue
INC.w SpriteActivity, X ; award follower
LDA.l FollowerIndicator : CMP.b #$0C : BEQ .purple_chest_prize
LDA.l FollowerTravelAllowed : CMP.b #$02 : BEQ .return
LDA.l FollowerIndicator : CMP.b #$00 : BEQ .return
LDA.b #$05 : STA.w SpriteActivity, X ; forever do nothing
BRA .return
.purple_chest_prize
INC.w SpriteActivity, X ; prep for purple chest prize
.return
PLA : STA.w SpritePosXLow, X
JML $86BD08 ; jump back to immediately RTS
Locksmith_BecomeFollower:
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .vanilla
STZ.w FollowerNoDraw
PLA : PLA
JSL StoreAndLoadFollower : BCS +
LDA.l FollowerIndicator : CMP.b #$0C : BEQ +
PEA.w $BD24-1 : RTL ; jump to despawn
+
PEA.w $BD27-1 ; jump to exit
RTL
.vanilla
LDA.b #$09 : STA.l FollowerIndicator
RTL
Locksmith_RespondToAnswer_PostItem:
STA.l FollowerIndicator ; what we wrote over
LDA.l FollowerTravelAllowed : CMP.b #$02 : BNE .no_despawn
LDA.w SpriteAux, X : CMP.b #$0C : BEQ .despawn
CMP.b #$00 : BNE .no_despawn
LDA.l Follower_Locksmith : CMP.b #$0C : BEQ .despawn
JSL DetermineFollowerSpawn_include_stored : BCC .no_despawn
.despawn
STZ.w SpriteAITable, X
.no_despawn
RTL

View File

@@ -48,7 +48,7 @@ JML NMIHookReturn
;--------------------------------------------------------------------------------
PostNMIHookAction:
LDA.w NMIAux : BEQ +
PHK : PEA .return-1 ; push stack for RTL return
PHK : PEA.w .return-1 ; push stack for RTL return
JMP.w [NMIAux]
.return
STZ.w NMIAux ; zero bank byte of NMI hook pointer

View File

@@ -1,6 +1,6 @@
GoalItemGanonCheck:
LDA.w SpriteTypeTable, X : CMP.b #$D6 : BNE .success ; skip if not ganon
JSL CheckGanonVulnerability
LDA.b #$01 : JSL CheckConditionPass
BCS .success
.fail
@@ -11,104 +11,193 @@ RTL
LDA.b OAMOffsetY : CMP.b #$80 ; thing we wrote over
RTL
;--------------------------------------------------------------------------------
;Carry clear = ganon invincible
;Carry set = ganon vulnerable
CheckGanonVulnerability:
PHX
LDA.l GanonVulnerableMode
ASL
TAX
; Input A = Type of condition check
; Carry clear = failed check
; Carry set = successful check
CheckConditionPass:
PHX : PHY
PHB
LDY.b #GoalConditionTable>>16 : PHY : PLB : STY.b Scrap02
REP #$20
ASL : TAY
LDA.w GoalConditionTable, Y : STA.b Scrap00
PHK : PLB
SEP #$20
LDY.b #$00
- LDA.b [Scrap00], Y : CMP.b #$FF : BEQ .exit
INY : ROL : TAX
JSR (.conditions, X) : BCC .exit : BRA -
; Carry
; 0 - invulnerable
; 1 - vulnerable
JSR (.goals, X)
.exit
PLB : PLY : PLX
RTL
PLX
RTL
.goals
dw .vulnerable
dw .invulnerable
dw .all_dungeons
dw .crystals_and_aga
; Y = index after condition code
; Carry = Set if using default target value
.conditions
dw .always_fail
dw .pendants
dw .crystals
dw .pendant_bosses
dw .crystal_bosses
dw .bosses
dw .agahnim_defeated
dw .agahnim2_defeated
dw .goal_item
dw .light_speed
dw .crystals_and_bosses
dw .bosses_only
dw .all_dungeons_no_agahnim
dw .all_items
dw .completionist
dw .collection_rate
dw .custom_goal
dw .bingo
dw .success
dw .success
dw .success
dw .success
; 00 = always vulnerable
.vulnerable
.agahnim2_defeated
LDA.l RoomDataWRAM[$0D].high : AND.b #$08 : BEQ .fail
.bingo ; not implemented yet
.success
SEC
RTS
; 01 = always invulnerable
.invulnerable
SEC : RTS
.always_fail
.fail
CLC
RTS
; 02 = All dungeons
.all_dungeons
LDA.l ProgressIndicator : CMP.b #$03 : BCC .fail ; require post-aga world state
; 09 = All dungeons except agahnim
.all_dungeons_no_agahnim
LDA.l PendantsField : AND.b #$07 : CMP.b #$07 : BNE .fail ; require all pendants
LDA.l CrystalsField : AND.b #$7F : CMP.b #$7F : BNE .fail ; require all crystals
LDA.l RoomDataWRAM[$0D].high : AND.b #$08 : BEQ .fail ; require aga2 defeated (pyramid hole open)
BRA .success
; 03 = crystals and aga 2
.crystals_and_aga
LDA.l RoomDataWRAM[$0D].high : AND.b #$08 : BEQ .fail ; check aga2 first then bleed in
; 04 = crystals only
CLC : RTS
.pendants
PHP
LDA.l PendantCounter : PLP : BCC +
CMP.b #$03 : RTS
.crystals
JSL CheckEnoughCrystalsForGanon
RTS
; 05 = require goal item
PHP
LDA.l CrystalCounter : PLP : BCC +
CMP.b #$07 : RTS
.pendant_bosses
PHP
LDA.b #$02
JSR CheckForBossesDefeated : PLP : BCC +
CMP.b #$03 : RTS
.crystal_bosses
PHP
LDA.b #$01
JSR CheckForBossesDefeated : PLP : BCC +
CMP.b #$07 : RTS
.bosses
PHP
LDA.b #$00
JSR CheckForBossesDefeated : PLP : BCC +
CMP.b #$10 : RTS
+ CMP.b [Scrap00], Y : INY : RTS
.agahnim_defeated
LDA.l ProgressIndicator : CMP.b #$03 : RTS
.goal_item
REP #$20
LDA.l GoalCounter : CMP.l GoalItemRequirement
SEP #$20
REP #$20
LDA.l GoalCounter : BCC +
CMP.l GoalItemRequirement : BRA ++
.collection_rate
REP #$20
LDA.l TotalItemCounter : BCC +
CMP.l TotalItemCount : BRA ++
+ CMP.b [Scrap00], Y : INY : INY : ++
SEP #$20
RTS
.custom_goal
LDA.b [Scrap00], Y : INY ; options
PHA : AND.b #$07 : ASL : TAX : PLA
;JMP CheckConditionPassCustom
; flows into next function, do not insert code after without uncommenting above
; 06 = light speed
.light_speed
BRA .fail
; --------------------------------------------------------------------------------
; Input A = Options value, see GoalConditionTable for format
; Input X = Condition check type index
; Input Y = Index after Options byte
CheckConditionPassCustom:
PHX : PHA : BIT.b #$08 : PHP
REP #$30
LDA.b [Scrap00], Y : INY : INY ; address
PLP : REP #$30 : BEQ .byte
.word
TAX
SEP #$20
PLA
AND.b #$10
REP #$20
BNE +
LDA.l $7E0000, X : BRA ++
+
LDA.l $7F0000, X : ++
SEP #$10
PLX
REP #$10
JSR (.comparisons, X)
INY
SEP #$30
RTS
.byte
TAX
SEP #$20
PLA
AND.b #$10 : BNE +
LDA.l $7E0000, X : BRA ++
+
LDA.l $7F0000, X : ++
SEP #$10
PLX
JMP (.comparisons, X)
; 07 = Crystals and bosses
.crystals_and_bosses
JSL CheckEnoughCrystalsForGanon ; check crystals first then bleed in to next
BCC .fail
; 08 = Crystal bosses but no crystals
.bosses_only
JMP CheckForCrystalBossesDefeated
; 09 = 100% item collection rate
.all_items
REP #$20
LDA.l TotalItemCounter : CMP.l TotalItemCount
SEP #$20
RTS
; 0A = 100% item collection rate and all dungeons
.completionist
REP #$20
LDA.l TotalItemCounter : CMP.l TotalItemCount
SEP #$20
BCC .fail
BRA .all_dungeons
.comparisons
dw .minimum
dw .exact
dw .bitfield_nonzero
dw .bitfield_match
dw .count_bits
dw .fail
dw .fail
dw .fail
.pass
INY : SEC : RTS
.count_bits
JSL CountBits
.minimum
CMP.b [Scrap00], Y : INY
RTS
.bitfield_match
AND.b [Scrap00], Y
.exact
CMP.b [Scrap00], Y : BEQ .pass
INY : CLC : RTS
.bitfield_nonzero
AND.b [Scrap00], Y : BNE .pass
.fail
INY : CLC : RTS
;--------------------------------------------------------------------------------
GTCutscene_TransferGfx:
PHA
REP #$20
STZ.w DuckPose
LDA.l GanonsTowerOpenGfx : BEQ .original_crystal
PHX
LDX.w ItemStackPtr : STA.l ItemGFXStack,X
LDA.w #$81C0>>1 : STA.l ItemTargetStack,X
INX #2 : STX.w ItemStackPtr
PLX
SEP #$20
PLA
RTL
.original_crystal
SEP #$20
PLA
JML TransferItemReceiptToBuffer_using_GraphicsID
;--------------------------------------------------------------------------------
AncillaDraw_GTCutsceneCrystal_OAMPrep:
LDA.l GanonsTowerOpenGfx : ORA.l GanonsTowerOpenGfx+1 : BEQ .vanilla
LDA.b #$0E : STA.b (OAMPtr),Y
INY
LDA.l GanonsTowerOpenPalette : AND.b #$67 : ASL : ORA.b #$30
STA.b (OAMPtr),Y
RTL
.vanilla
LDA.b #$24 : STA.b (OAMPtr),Y
INY
LDA.b #$3C : STA.b (OAMPtr),Y
RTL
;--------------------------------------------------------------------------------
GTCutscene_CrystalMasks:
db %00000000 ; 0 crystals
@@ -171,48 +260,94 @@ GTCutscene_ActivateSparkle_SelectCrystal:
PLY
RTL
;--------------------------------------------------------------------------------
; prioritizes: number of gfx used > sum of targets > number of goals
; Scrap00 stores number of goals
; Y sums all goal target values
GTCutscene_NumberOfCrystals:
PHX : PHY : PHP
REP #$20
LDA.l GanonsTowerOpenAddress : CMP.w #CrystalCounter : BEQ +
LDA.w #$0001 : BRA .done
+ LDA.l GanonsTowerOpenTarget
.done
LDA.l GanonsTowerOpenGfx+2 : BEQ .not_multiple_gfx
LDX.b #$04
- LDA.l GanonsTowerOpenGfx, X : BEQ +
INX : INX : CPX.b #$0E : BCC -
+
TXA : LSR
JMP .done
.not_multiple_gfx
LDX.b #$00 : LDA.l GoalConditionTable, X
TXY : STY.b Scrap00
REP #$10
SEP #$20
TAX
.next
LDA.l $B00000, X : CMP.b #$FF : BNE + : JMP .use_y : +
INC.b Scrap00
ROL : PHP : CMP.b #$10 : BCS .not_8bit_compare
CMP.b #$0C : BEQ .agas_goal
CMP.b #$0E : BEQ .agas_goal
; uses 8-bit targets
PLP : BCC .use_8bit_target
CMP.b #$04 : BEQ .crystal_goal ; crystal goal
CMP.b #$08 : BEQ .crystal_goal ; crystal bosses goal
CMP.b #$02 : BEQ .pendant_goal ; pendant goal
CMP.b #$06 : BEQ .pendant_goal ; pendant bosses goal
BRA .bosses_goal
.crystal_goal
LDA.b #$07 : INX : BRA .add_to_y
.pendant_goal
LDA.b #$03 : INX : BRA .add_to_y
.bosses_goal
INY : INX : BRA .next ; just increment Y by 1 since default of 10 is already more than max 7
.agas_goal
PLP : INX : BRA .next
.use_8bit_target
INX : LDA.l $B00000, X : INX
.add_to_y
PHY : CLC : ADC.b 1,S : PLY : TAY : BRA .next
.not_8bit_compare
CMP.b #$14 : BEQ .custom_goal : BCS .unknown
; triforce hunt/collection rate - uses 16-bit targets
PLP : INX : BCC +
LDA.l $B00000, X : INX : INX : BRA .add_to_y
+ INY : BRA .next
.custom_goal
PLP
INX : LDA.l $B00000, X : BIT.b #$08 : PHP
INX : INX : INX : AND.b #$03 : BEQ .use_custom_target
; comparison method doesn't use a quantity, increment Y by 1
INY : INX : PLP : BEQ +
INX
+
BRA .next
.use_custom_target
PLP : BEQ ..8bit
; 16-bit target
REP #$20
LDA.l $B00000, X : CMP.w #$0008 : SEP #$20 : INX : BRA +
..8bit
LDA.l $B00000, X : CMP.b #$08 : + : BCC +
; target exceeds 7, just increment Y by 1
INY : INX : JMP .next
+
INX : BRA .add_to_y
.unknown ; unknown condition, exit with safe value
PLP : INY
.use_y
TYA : BEQ + : CMP.b #$08 : BCC .done
+ LDA.b Scrap00 : BEQ .use_one : CMP.b #$08 : BCC .done
.use_one
LDA.b #$01
.done
PLP : PLY : PLX
RTS
;--------------------------------------------------------------------------------
CheckEnoughCrystalsForGanon:
REP #$20
LDA.l CrystalCounter
CMP.l GanonVulnerableTarget
SEP #$20
RTL
;--------------------------------------------------------------------------------
CheckTowerOpen:
LDA.l GanonsTowerOpenMode : ASL : TAX
JSR (.tower_open_modes,X)
RTL
.tower_open_modes
dw .vanilla
dw .arbitrary_cmp
.vanilla
LDA.l CrystalsField
AND.b #$7F : CMP.b #$7F
RTS
.arbitrary_cmp
REP #$30
LDA.l GanonsTowerOpenAddress : TAX
LDA.l $7E0000,X
CMP.l GanonsTowerOpenTarget
SEP #$30
RTS
LDA.b #$00 : JML CheckConditionPass
;---------------------------------------------------------------------------------------------------
CheckAgaForPed:
REP #$20
LDA.l GanonVulnerableMode
CMP.w #$0006 : BNE .vanilla
; seems light_speed option to force blue balls is unused for now
BRA .vanilla
.light_speed
SEP #$20
@@ -233,73 +368,61 @@ CheckAgaForPed:
RTL
;---------------------------------------------------------------------------------------------------
CheckForCrystalBossesDefeated:
CheckForBossesDefeated:
PHB : PHX : PHY
LDA.b #CrystalPendantFlags_2>>16
STA.b Scrap04 ; 0 = check all, 1 = check crystals, 2 = check pendants
LDA.b #CrystalPendantFlags_3>>16
PHA : PLB
REP #$30
STZ.b Scrap03 ; count of number of bosses killed
STZ.b Scrap05
; count of number of bosses killed
STZ.b Scrap00
REP #$30
LDY.w #10
.next_check
LDA.w CrystalPendantFlags_2+2,Y
BIT.w #$0040
BEQ ++
LDA.w CrystalPendantFlags_3+2,Y : AND.w #$00FF : BEQ .skip
CMP.w #$0008 ; C set = pendant, C clear = crystal
LDA.b Scrap04 : BEQ .proceed
PHP : ROR : BCC +
PLP : BCS .skip : BRA .proceed
+ PLP : BCC .skip
TYA
ASL
TAX
.proceed
TYA : ASL : TAX
LDA.l DrawHUDDungeonItems_boss_room_ids-4,X
TAX
LDA.l DungeonMapBossRooms+4,X
ASL : TAX
LDA.l RoomDataWRAM.l,X
AND.w #$0800
BEQ ++
AND.w #$0800 : BEQ .skip
INC.b Scrap03
INC.b Scrap00
++ DEY
BPL .next_check
.skip
DEY : BPL .next_check
SEP #$30
PLY : PLX : PLB
LDA.b Scrap00 : CMP.l GanonVulnerableTarget
LDA.b Scrap03
RTS
;---------------------------------------------------------------------------------------------------
CheckPedestalPull:
; Out: c - Successful ped pull if set, do nothing if unset.
PHX
LDA.l PedCheckMode : ASL : TAX
JSR (.pedestal_modes,X)
PLX
LDA.b #$02 : JSL CheckConditionPass : BCS .return
PHX : PHP
LDA.b GameMode : CMP.b #$0E : BEQ +
REP #$30
LDX.w #$0004 : LDA.l GoalConditionTable, X : TAX
LDA.l $B00000, X : CMP.w #$FF81 : BEQ +
SEP #$30
LDA.b #$97 : LDY.b #$01
JSL Sprite_ShowMessageUnconditional
+
PLP : PLX
.return
RTL
.pedestal_modes
dw .vanilla
dw .arbitrary_cmp
.vanilla
LDA.l PendantsField
AND.b #$07 : CMP.b #$07 : BNE ..nopull
SEC
RTS
..nopull
CLC
RTS
.arbitrary_cmp
REP #$30
LDA.l PedPullAddress : TAX
LDA.l $7E0000,X
CMP.l PedPullTarget
SEP #$30
RTS

View File

@@ -4,19 +4,10 @@
HeartPieceGet:
PHX : PHY
LDA.w SprItemMWPlayer, X : 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
+
LDY.w SprSourceItemId, X
JSL MaybeMarkDigSpotCollected
.skipLoad
LDA.w SprItemMWPlayer, X : STA.l !MULTIWORLD_ITEM_PLAYER_ID
LDA.w SprItemMWPlayer, X : 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
CMP.b #$00 : BNE .not_heart
LDA.l HeartPieceQuarter : INC A : AND.b #$03 : STA.l HeartPieceQuarter
@@ -32,16 +23,7 @@ RTL
HeartContainerGet:
PHX : PHY
JSL IncrementBossSword
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
+
LDY.w SprSourceItemId, X
BRA HeartPieceGet_skipLoad
;--------------------------------------------------------------------------------
DrawHeartPieceGFX:
@@ -260,6 +242,12 @@ LoadOutdoorValue:
PHP
REP #$20 ; set 16-bit accumulator
LDA.b OverworldIndex
; Rain state fix: In rain state DW, use LW screen ID for item lookup
BIT.w #$0040 : BEQ +
LDA.l ProgressIndicator : AND.w #$00FF : CMP.w #$0002
LDA.b OverworldIndex : BCS ++ : AND.w #$00BF
++
+
CMP.w #$00 : BNE +
LDA.l OWBonkPrizeTable[$00].loot
JMP .done

125
hooks.asm
View File

@@ -120,7 +120,7 @@ JSL AddBonkTremors : NOP #4
; Bonk Breakable Walls
;--------------------------------------------------------------------------------
org $81CF8E ; CF8E <- Bank01.asm : 11641 (LDA $0372 : AND.w #$00FF)
JSL BonkBreakableWall : NOP #2
JSL ValidDashCheck : NOP #2
;--------------------------------------------------------------------------------
;================================================================================
@@ -139,6 +139,11 @@ GravestoneHook_continue:
org $87C106
moveGravestone:
;--------------------------------------------------------------------------------
org $899A30
JSL ValidDashCheck : NOP #2
org $899A3A
JSL ValidDashCheck : NOP #2
;--------------------------------------------------------------------------------
;================================================================================
; Jump Down Ledge
@@ -407,6 +412,16 @@ STA.l StalfosBombDamage
org $8AB76E ; <- 5376E - Bank0A.asm : 30 (JSL OverworldMap_InitGfx)
JSL OnLoadDuckMap
;================================================================================
; Fix Clobbered Gfx
;--------------------------------------------------------------------------------
org $80DB92
JSL PostFixMirrorGfxPrep
org $80D911
JML PostFixMirrorGfx
org $80E259
JSL PostFixOAMGfx : NOP
;================================================================================
; Infinite Bombs / Arrows / Magic
;--------------------------------------------------------------------------------
@@ -530,6 +545,8 @@ JML GTCutscene_ConditionalAnimateCrystals
org $88CE93
GTCutscene_DrawSingleCrystal:
JML GTCutscene_ConditionalDrawSingleCrystal
org $88CED1
JSL AncillaDraw_GTCutsceneCrystal_OAMPrep : BRA + : NOP #3 : +
;--------------------------------------------------------------------------------
org $88CF19 ; <- 44F19 - ancilla_break_tower_seal.asm : 336 (TXA : AND.b #$07 : TAX)
JSL GTCutscene_ActivateSparkle_SelectCrystal
@@ -555,12 +572,6 @@ JSL AgahnimAsksAboutPed
org $9ED6E8
JSL CheckAgaForPed : NOP
;================================================================================
; Zelda Sprite Fixes
;--------------------------------------------------------------------------------
org $85EBCF ; <- 2EBCF - sprite_zelda.asm : 23 (LDA $7EF359 : CMP.b #$02 : BCS .hasMasterSword)
JSL SpawnZelda : NOP #2
;================================================================================
; Alternate Goal
;--------------------------------------------------------------------------------
@@ -688,12 +699,6 @@ db $06, $1F, $40, $12, $01, $3F, $14, $01, $3F, $13, $1F, $42, $1A, $1F, $4B, $1
org $85DFB1 ; <- 2DFB1 - Bank05.asm : 2499
JSL SkipDrawEOR
;================================================================================
; Kiki Big Bomb Fix
;--------------------------------------------------------------------------------
org $9EE4AF ; <- f64af sprite_kiki.asm : 285 (LDA.b #$0A : STA $7EF3CC)
JSL AssignKiki : NOP #2
;================================================================================
; Wallmaster camera fix
;--------------------------------------------------------------------------------
@@ -845,11 +850,6 @@ org $81E97E
dw $0116 : db $08
dw $0116 : db $25
;--------------------------------------------------------------------------------
org $9EE16E ; <- F616E - sprite_bomb_shop_entity.asm : 73
NOP #8 ; fix bomb shop dialog for dwarfless big bomb
org $868A14 ; <- 30A14 - sprite_prep.asm : 716
NOP #8 ; fix bomb shop spawn for dwarfless big bomb
;--------------------------------------------------------------------------------
org $86B489 ; <- 33489 - sprite_smithy_bros.asm : 473 (LDA $7EF359 : CMP.b #$03 : BCS .tempered_sword_or_better)
JML GetSmithSword : NOP #4
Smithy_DoesntHaveSword:
@@ -1819,7 +1819,9 @@ Sprite_ShowMessageUnconditional_Rest:
;--------------------------------------------------------------------------------
;-- Music restarting at zelda fix
org $85ED10 ; <- 2ED10 - sprite_zelda.asm : 233 - (LDA.b #$19 : STA $012C)
NOP #5
BRA + : NOP #3 : +
org $85ED63
BRA + : NOP #3 : +
;--------------------------------------------------------------------------------
org $9ECE47 ; <- F4E47 - sprite_crystal_maiden.asm : 220
JML MaidenCrystalScript
@@ -1881,11 +1883,14 @@ JSL CalculateSignIndex
; Dark World Spawn Location Fix & Follower Fixes
;--------------------------------------------------------------------------------
org $80894A ; <- 94A
PHB : JSL DarkWorldSaveFix
PHB : JSL OnSave
;--------------------------------------------------------------------------------
org $828046 ; <- 10046 - Bank02.asm : 217 (JSL EnableForceBlank) (Start of Module_LoadFile)
JSL OnFileLoad
;--------------------------------------------------------------------------------
org $89F5DF
JSL OnDeathNoSave
;--------------------------------------------------------------------------------
org $8280A2
JSL GetCurrentWorldForLoad
;--------------------------------------------------------------------------------
@@ -2102,6 +2107,11 @@ JSL FlipperScrollWarp
;--------------------------------------------------------------------------------
;org $878F51 ; <- 38F51 - Bank07.asm:2444 (JSR $AE54 ; $3AE54 IN ROM)
;JSL OnEnterWater : NOP
;--------------------------------------------------------------------------------
; Fixes getting bumped while swimming, unable to screen transition
org $879632
LinkState_Swimming:
JSL FixSwimBump
;================================================================================
; Floodgate Softlock Fix
;--------------------------------------------------------------------------------
@@ -2182,9 +2192,6 @@ JSL LampCheck
;--------------------------------------------------------------------------------
org $81F503 ; <- F503 - Bank01.asm:14994 (LDA.b #$01 : STA $1D)
JSL SetOverlayIfLamp
;--------------------------------------------------------------------------------
org $81B610 ; <- loading whether room is dark
JSL DarkRoomCheck
;================================================================================
;================================================================================
@@ -2241,8 +2248,6 @@ org $82A9B0 ; (BCS $A9B7)
NOP #2
org $82C1C8 ; (BCS $C1CC)
NOP #2
org $82ADA0 ; (LDA.b #$F1 : STA $012C)
JSL Overworld_MosaicDarkWorldChecks : NOP
;--------------------------------------------------------------------------------
org $85CC58 ; <- Bank05.asm:1307 (LDA $040A : CMP.b #$18)
JSL PsychoSolder_MusicCheck : NOP #1
@@ -2268,8 +2273,9 @@ JSL Overworld_DetermineMusic
BRA + : NOP #42 : +
;--------------------------------------------------------------------------------
org $82B0C4
LDA.b OverworldIndex : CMP.b #$80 : BCS +
JSL Overworld_DetermineAndSetMusic
BRA + : NOP #16 : +
BRA + : NOP #10 : +
;--------------------------------------------------------------------------------
org $82B1C1
JSL Overworld_DetermineAmbientSFX
@@ -2287,8 +2293,18 @@ BRA + : NOP #12 : +
org $88C442
JSL Overworld_DetermineAndSetMusic : NOP
;--------------------------------------------------------------------------------
org $9BD1CD
JSL Overworld_DetermineAndSetMusic : NOP
;--------------------------------------------------------------------------------
org $9DFD27
JSL Overworld_DetermineAndSetMusic : NOP
;--------------------------------------------------------------------------------
org $829253
JSL FixHalfVolumeOnSpawnExitToOverworld : NOP
;--------------------------------------------------------------------------------
org $8292D9
BRA + : NOP #4 : +
JSL FixPreAgaMusicFadeOut : db $B0 ; BCS
;================================================================================
;================================================================================
@@ -2347,24 +2363,6 @@ org $82A451 ; <- 12451 - Bank02.asm:6283 (LDA $F6 : AND.b #$40 : BEQ .xButtonNot
JSL QuickSwap
;================================================================================
;================================================================================
; Tagalong Fixes
;--------------------------------------------------------------------------------
org $8689AB ; <- 309AB - sprite_prep.asm: 647 (LDA $7EF3CC : CMP.b #$06 : BEQ .killSprite)
; Note: In JP 1.0 we have: (CMP.b #$00 : BNE .killSprite) appling US bugfix
; Prevent followers from causing blind/maiden to despawn:
; Door rando: let zelda despawn the maiden.
JSL BlindZeldaDespawnFix
org $8689AF
SpritePrep_BlindMaiden_despawn_follower: ; this is the normal execution path
org $8689C9
SpritePrep_BlindMaiden_kill_the_girl: ; not the follower
;--------------------------------------------------------------------------------
; Fix old man purple chest issues using the same method as above
org $9EE906 ; <- F6906 - sprite_old_mountain_man.asm : 31 (LDA $7EF3CC : CMP.b #$00 : BNE .already_have_tagalong)
CMP.b #$04 : db $F0 ; BEQ
;--------------------------------------------------------------------------------
;Control which doors frog/smith can enter
org $9BBCF0 ; <- DBCF0 - Bank1B.asm: 248 (LDA $04B8 : BNE BRANCH_MU)
@@ -2676,7 +2674,7 @@ org $898AEE : JSL TransferItemReceiptToBuffer_using_GraphicsID
org $898C85 : JSL TransferItemReceiptToBuffer_using_GraphicsID
; gt cutscene
org $899BBE : JSL TransferItemReceiptToBuffer_using_GraphicsID
org $899BBE : JSL GTCutscene_TransferGfx
;===================================================================================================
; gratuitous NOPs removed for speed
@@ -2739,39 +2737,4 @@ NOP #2 ; this fixes Link's direction after mirroring and falling after entering
; Enable new room header table
;--------------------------------------------------------------------------------
org $81B5E6
LDA.b #$30
;===================================================================================================
;--------------------------------------------------------------------------------
; Mimic dash changes
;--------------------------------------------------------------------------------
org $9EC7BE
JSL MimicDirection
;===================================================================================================
;--------------------------------------------------------------------------------
; Boss souls changes
;--------------------------------------------------------------------------------
org $8DB866
JSL CheckBossSoul : BRA + : NOP #2 : +
org $86ED9E
JSL CheckInvincibleFlag : NOP
org $85DFFE
JSL SoulPaletteSet : BRA + : NOP #5 : +
org $85DFB7
JSL SoulPaletteApply : NOP #2
org $9E8086
JSL HelmasaurPaletteFix : BRA + : NOP #2 : +
org $9E838C
JSL HelmasaurHammerFix : NOP
org $9DD884
JSL MoldormPaletteFix_b : NOP
org $9DDB2E
JSL MoldormPaletteFix_d : NOP
LDA.b #$30

View File

@@ -123,8 +123,8 @@ InitNpcFlagsVanilla: skip 1 ; PC 0x1833C9
InitCurrentWorld: skip 1 ; PC 0x1833CA
skip 1 ; PC 0x1833CB
InitFollowerIndicator: skip 1 ; PC 0x1833CC
InitFollowerXCoord: skip 2 ; PC 0x1833CD
InitFollowerYCoord: skip 2 ; PC 0x1833CF
InitFollowerYCoord: skip 2 ; PC 0x1833CD
InitFollowerXCoord: skip 2 ; PC 0x1833CF
InitDroppedFollowerIndoors: skip 1 ; PC 0x1833D1
InitDroppedFollowerLayer: skip 1 ; PC 0x1833D2
InitFollowerDropped: skip 1 ; PC 0x1833D3

View File

@@ -646,7 +646,7 @@ RTL
; CollectPowder:
;--------------------------------------------------------------------------------
CollectPowder:
LDY.w SprItemReceipt, X ; Retrieve stored item type
LDY.w SprSourceItemId, X ; Retrieve stored item type
BNE +
; if for any reason the item value is 0 reload it, just in case
%GetPossiblyEncryptedItem(WitchItem, SpriteItemValues) : TAY
@@ -806,19 +806,10 @@ RTL
; A = item id being collected
ItemGetAlternateSFX:
PEA.w $C567 ; SNES to RTS to in bank 08
LDA.w AncillaGet, X : CMP.b #$4A : BNE +
LDA.w AncillaGet,X : CMP.b #$4A : BNE +
; collecting pre-activated flute
LDA.b #$13 : JML Ancilla_SFX2_Near
+ ; not pre-activated flute
LDA.l !MULTIWORLD_RECEIVING_ITEM : BEQ .normal
LDA.l MultiworldJunkItemTimer : BEQ .normal
LDA.w AncillaGet, X
JSL.l ItemIsJunk : BEQ .normal
.multijunk
LDA.b #$3B : JML Ancilla_SFX3_Near ; what we wrote over
.normal
+ ; normal itemget sfx
LDA.b #$0F : JML Ancilla_SFX3_Near ; what we wrote over
; A = item id being collected
@@ -827,16 +818,6 @@ CPY.b #$4A : BNE +
JSL Sound_SetSfxPanWithPlayerCoords : ORA.b #$13 : STA.w SFX2
RTL
+ ; normal itemget sfx
LDA.l !MULTIWORLD_RECEIVING_ITEM : BEQ .normal
LDA.l MultiworldJunkItemTimer : BEQ .normal
TYA
JSL.l ItemIsJunk : BEQ .normal
.multijunk
JSL Sound_SetSfxPanWithPlayerCoords : ORA.b #$3B : STA.w SFX3
RTL
.normal
JSL Sound_SetSfxPanWithPlayerCoords : ORA.b #$0F : STA.w SFX3 ; what we wrote over
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------

View File

@@ -243,7 +243,7 @@ endmacro
%ReceiptProps($67, -4, 0, $FF, $F36A, $FF, skip, skip) ; 67 -
%ReceiptProps($68, -4, 0, $FF, $F36A, $FF, skip, skip) ; 68 -
%ReceiptProps($69, -4, 0, $FF, $F36A, $FF, skip, skip) ; 69 -
%ReceiptProps($6A, -4, 0, $49, $F36A, $FF, triforce, skip) ; 6A - Triforce
%ReceiptProps($6A, -4, 0, $4A, $F36A, $FF, triforce, skip) ; 6A - Triforce
%ReceiptProps($6B, -4, 0, $50, $F36A, $FF, goal_item, skip) ; 6B - Power star
%ReceiptProps($6C, -4, 0, $49, $F36A, $FF, goal_item, skip) ; 6C - Triforce Piece
%ReceiptProps($6D, -4, 0, $FF, $F36A, $FF, request_F0, skip) ; 6D - Server request item
@@ -377,16 +377,16 @@ endmacro
%ReceiptProps($ED, -4, 0, $49, $F36A, $FF, skip, skip) ; ED -
%ReceiptProps($EE, -4, 0, $49, $F36A, $FF, skip, skip) ; EE -
%ReceiptProps($EF, -4, 0, $49, $F36A, $FF, skip, skip) ; EF -
%ReceiptProps($F0, -4, 0, $51, $F36A, $FF, skip, skip) ; F0 - Armos Soul
%ReceiptProps($F1, -4, 0, $52, $F36A, $FF, skip, skip) ; F1 - Lanmolas Soul
%ReceiptProps($F2, -4, 0, $53, $F36A, $FF, skip, skip) ; F2 - Moldorm Soul
%ReceiptProps($F3, -4, 0, $54, $F36A, $FF, skip, skip) ; F3 - Helmasaur Soul
%ReceiptProps($F4, -4, 0, $55, $F36A, $FF, skip, skip) ; F4 - Arrghus Soul
%ReceiptProps($F5, -4, 0, $56, $F36A, $FF, skip, skip) ; F5 - Mothula Soul
%ReceiptProps($F6, -4, 0, $57, $F36A, $FF, skip, skip) ; F6 - Blind Soul
%ReceiptProps($F7, -4, 0, $58, $F36A, $FF, skip, skip) ; F7 - Kholdstare Soul
%ReceiptProps($F8, -4, 0, $59, $F36A, $FF, skip, skip) ; F8 - Vitreous Soul
%ReceiptProps($F9, -4, 0, $5A, $F36A, $FF, skip, skip) ; F9 - Trinexx Soul
%ReceiptProps($F0, -4, 0, $49, $F36A, $FF, skip, skip) ; F0 -
%ReceiptProps($F1, -4, 0, $49, $F36A, $FF, skip, skip) ; F1 -
%ReceiptProps($F2, -4, 0, $49, $F36A, $FF, skip, skip) ; F2 -
%ReceiptProps($F3, -4, 0, $49, $F36A, $FF, skip, skip) ; F3 -
%ReceiptProps($F4, -4, 0, $49, $F36A, $FF, skip, skip) ; F4 -
%ReceiptProps($F5, -4, 0, $49, $F36A, $FF, skip, skip) ; F5 -
%ReceiptProps($F6, -4, 0, $49, $F36A, $FF, skip, skip) ; F6 -
%ReceiptProps($F7, -4, 0, $49, $F36A, $FF, skip, skip) ; F7 -
%ReceiptProps($F8, -4, 0, $49, $F36A, $FF, skip, skip) ; F8 -
%ReceiptProps($F9, -4, 0, $49, $F36A, $FF, skip, skip) ; F9 -
%ReceiptProps($FA, -4, 0, $49, $F36A, $FF, skip, skip) ; FA -
%ReceiptProps($FB, -4, 0, $49, $F36A, $FF, skip, skip) ; FB -
%ReceiptProps($FC, -4, 0, $49, $F36A, $FF, skip, skip) ; FC -
@@ -656,16 +656,16 @@ endmacro
%SpriteProps($ED, 2, 2, $04, $04, $0000) ; ED -
%SpriteProps($EE, 2, 2, $04, $04, $0000) ; EE -
%SpriteProps($EF, 2, 2, $04, $04, $0000) ; EF -
%SpriteProps($F0, 2, 2, $83, $83, PalettesCustom_armos) ; F0 - Armos Soul
%SpriteProps($F1, 2, 2, $83, $83, PalettesCustom_lanmolas) ; F1 - Lanmolas Soul
%SpriteProps($F2, 2, 2, $83, $83, PalettesCustom_moldorm) ; F2 - Moldorm Soul
%SpriteProps($F3, 2, 2, $83, $83, PalettesCustom_helmasaur) ; F3 - Helmasuar Soul
%SpriteProps($F4, 2, 2, $83, $83, PalettesCustom_arrghus) ; F4 - Arrghus Soul
%SpriteProps($F5, 2, 2, $83, $83, PalettesCustom_mothula) ; F5 - Mothula Soul
%SpriteProps($F6, 2, 2, $83, $83, PalettesCustom_blind) ; F6 - Blind Soul
%SpriteProps($F7, 2, 2, $83, $83, PalettesCustom_kholdstare) ; F7 - Kholdstare Soul
%SpriteProps($F8, 2, 2, $83, $83, PalettesCustom_vitreous) ; F8 - Vitreous Soul
%SpriteProps($F9, 2, 2, $83, $83, PalettesCustom_trinexx) ; F9 - Trinexx Soul
%SpriteProps($F0, 2, 2, $04, $04, $0000) ; F0 -
%SpriteProps($F1, 2, 2, $04, $04, $0000) ; F1 -
%SpriteProps($F2, 2, 2, $04, $04, $0000) ; F2 -
%SpriteProps($F3, 2, 2, $04, $04, $0000) ; F3 -
%SpriteProps($F4, 2, 2, $04, $04, $0000) ; F4 -
%SpriteProps($F5, 2, 2, $04, $04, $0000) ; F5 -
%SpriteProps($F6, 2, 2, $04, $04, $0000) ; F6 -
%SpriteProps($F7, 2, 2, $04, $04, $0000) ; F7 -
%SpriteProps($F8, 2, 2, $04, $04, $0000) ; F8 -
%SpriteProps($F9, 2, 2, $04, $04, $0000) ; F9 -
%SpriteProps($FA, 2, 2, $04, $04, $0000) ; FA -
%SpriteProps($FB, 2, 2, $04, $04, $0000) ; FB -
%SpriteProps($FC, 2, 2, $04, $04, $0000) ; FC -
@@ -932,16 +932,16 @@ endmacro
%InventoryItem($ED, $0001, $0000, $0000) ; ED -
%InventoryItem($EE, $0001, $0000, $0000) ; EE -
%InventoryItem($EF, $0001, $0000, $0000) ; EF -
%InventoryItem($F0, $0081, $0000, $0000) ; F0 - Armos Soul
%InventoryItem($F1, $0081, $0000, $0000) ; F1 - Lanmolas Soul
%InventoryItem($F2, $0081, $0000, $0000) ; F2 - Moldorm Soul
%InventoryItem($F3, $0081, $0000, $0000) ; F3 - Helmasuar Soul
%InventoryItem($F4, $0081, $0000, $0000) ; F4 - Arrghus Soul
%InventoryItem($F5, $0081, $0000, $0000) ; F5 - Mothula Soul
%InventoryItem($F6, $0081, $0000, $0000) ; F6 - Blind Soul
%InventoryItem($F7, $0081, $0000, $0000) ; F7 - Kholdstare Soul
%InventoryItem($F8, $0081, $0000, $0000) ; F8 - Vitreous Soul
%InventoryItem($F9, $0081, $0000, $0000) ; F9 - Trinexx Soul
%InventoryItem($F0, $0001, $0000, $0000) ; F0 -
%InventoryItem($F1, $0001, $0000, $0000) ; F1 -
%InventoryItem($F2, $0001, $0000, $0000) ; F2 -
%InventoryItem($F3, $0001, $0000, $0000) ; F3 -
%InventoryItem($F4, $0001, $0000, $0000) ; F4 -
%InventoryItem($F5, $0001, $0000, $0000) ; F5 -
%InventoryItem($F6, $0001, $0000, $0000) ; F6 -
%InventoryItem($F7, $0001, $0000, $0000) ; F7 -
%InventoryItem($F8, $0001, $0000, $0000) ; F8 -
%InventoryItem($F9, $0001, $0000, $0000) ; F9 -
%InventoryItem($FA, $0001, $0000, $0000) ; FA -
%InventoryItem($FB, $0001, $0000, $0000) ; FB -
%InventoryItem($FC, $0001, $0000, $0000) ; FC -
@@ -1196,16 +1196,16 @@ ItemReceiptGraphicsOffsets:
dw $0 ; ED -
dw $0 ; EE -
dw $0 ; EF -
dw $1C20 ; F0 - Armos Soul
dw $1C60 ; F1 - Lanmolas Soul
dw $1CA0 ; F2 - Moldorm Soul
dw $1D20 ; F3 - Helmasuar Soul
dw $1D60 ; F4 - Arrghus Soul
dw $1DA0 ; F5 - Mothula Soul
dw $1DE0 ; F6 - Blind Soul
dw $2020 ; F7 - Kholdstare Soul
dw $2060 ; F8 - Vitreous Soul
dw $20A0 ; F9 - Trinexx Soul
dw $0 ; F0 -
dw $0 ; F1 -
dw $0 ; F2 -
dw $0 ; F3 -
dw $0 ; F4 -
dw $0 ; F5 -
dw $0 ; F6 -
dw $0 ; F7 -
dw $0 ; F8 -
dw $0 ; F9 -
dw $0 ; FA -
dw $0 ; FB -
dw $0 ; FC -
@@ -1437,7 +1437,7 @@ StandingItemGraphicsOffsets:
dw $0960 ; D0 - Bee trap
dw $0 ; D1 - Apples
dw $0 ; D2 - Fairy
dw $11E0 ; D3 - Chicken
dw BigDecompressionBuffer+$0140 ; D3 - Chicken
dw $01E0 ; D4 - Big Magic
dw $11E0 ; D5 - 5 Arrows
dw $0 ; D6 - Good Bee
@@ -1466,16 +1466,16 @@ StandingItemGraphicsOffsets:
dw $0 ; ED -
dw $0 ; EE -
dw $0 ; EF -
dw $1C20 ; F0 - Armos Soul
dw $1C60 ; F1 - Lanmolas Soul
dw $1CA0 ; F2 - Moldorm Soul
dw $1D20 ; F3 - Helmasuar Soul
dw $1D60 ; F4 - Arrghus Soul
dw $1DA0 ; F5 - Mothula Soul
dw $1DE0 ; F6 - Blind Soul
dw $2020 ; F7 - Kholdstare Soul
dw $2060 ; F8 - Vitreous Soul
dw $20A0 ; F9 - Trinexx Soul
dw $0 ; F0 -
dw $0 ; F1 -
dw $0 ; F2 -
dw $0 ; F3 -
dw $0 ; F4 -
dw $0 ; F5 -
dw $0 ; F6 -
dw $0 ; F7 -
dw $0 ; F8 -
dw $0 ; F9 -
dw $0 ; FA -
dw $0 ; FB -
dw $0 ; FC -

View File

@@ -376,7 +376,7 @@ TransferCommonToVRAM:
REP #$21
SEP #$10
LDA.w #BigDecompressionBuffer+$2000
LDA.w #BigDecompressionBuffer+$2400
LDX.b #BigDecompressionBuffer>>16
STA.w $4302
STX.w $4304

View File

@@ -1,4 +1,7 @@
; hooks
org $81DB19
JSL MaybeSkipSmashTerrain : BCS $81DB11
org $81E6B0
JSL RevealPotItem
RTS
@@ -39,6 +42,9 @@ org $86d180
org $86d18d ; <- 3518D - sprite_absorbable.asm : 274 (LDA $7EF36F : INC A : STA $7EF36F)
JSL KeyGet
org $86E24A
JSR MaybeSkipTerrainDebris
org $86f9f3 ; bank06.asm : 6732 (JSL SpritePrep_LoadProperties)
JSL LoadProperties_PreserveCertainProps
@@ -46,6 +52,11 @@ org $86828A
Sprite_SpawnSecret_SpriteSpawnDynamically:
JSL CheckSprite_Spawn
org $87B114
JSL MaybeUnableToLiftPotSfx
NOP #4
db $30 ; BMI
org $87B169
JSL PreventPotSpawn : NOP
@@ -78,7 +89,8 @@ org $80FDEE
InitializeMirrorHDMA:
org $89D62E
UWSpritesPointers: ; 0x250 bytes for 0x128 rooms' 16-bit pointers
;commenting out since this address can move
;UWSpritesPointers: ; 0x250 bytes for 0x128 rooms' 16-bit pointers
org $89D87E
UWPotsPointers: ; 0x250 bytes for 0x128 rooms' 16-bit pointers
@@ -671,7 +683,7 @@ KeyGet:
PHA
LDA.l StandingItemsOn : BNE +
PLA : RTL
+ LDY.w SprItemReceipt, X
+ LDY.w SprSourceItemId, X
LDA.w SprItemIndex, X : STA.w SpawnedItemIndex
LDA.w SprItemFlags, X : STA.w SpawnedItemFlag
STY.b Scrap00
@@ -685,7 +697,7 @@ KeyGet:
+ LSR : TAX
LDA.b Scrap00 : CMP.l KeyTable, X : BNE +
.countIt
LDA.l StandingItemCounterMask : AND.w SpawnedItemFlag : BEQ ++
LDA.l StandingItemCounterMask : AND SpawnedItemFlag : BEQ ++
JSL AddInventory
++ PLX : PLA : RTL
+ CMP.b #$AF : beq .countIt ; universal key
@@ -693,7 +705,7 @@ KeyGet:
.skip PLX
.receive
JSL Player_HaltDashAttackLong
TYA : JSL AttemptItemSubstitution : JSL ResolveLootIDLong : TAY
TYA : JSL AttemptItemSubstitution : TAY
JSL Link_ReceiveItem
PLA : DEC : RTL
@@ -701,7 +713,7 @@ KeyTable:
db $A0, $A0, $A2, $A3, $A4, $A5, $A6, $A7, $A8, $A9, $AA, $AB, $AC, $AD
BigKeyGet:
LDY.w SprItemReceipt, X
LDY.w SprSourceItemId, X
CPY.b #$32 : BNE +
STZ.w ItemReceiptMethod : LDY.b #$32 ; what we wrote over
PHX : JSL Link_ReceiveItem : PLX ; what we wrote over
@@ -773,7 +785,6 @@ CheckSprite_Spawn:
RTL
.check
LDA.b Scrap0D : CMP.b #$08 : BNE +
LDA.w LinkDashing : BNE .error
LDX.b #$0F
; loop looking for a Sprite with state 0A (carried by the player)
@@ -784,7 +795,9 @@ RTL
LDA.b #$00 : STZ.w SpriteAITable, X
LDA.b #$E4 : JSL Sprite_SpawnDynamically
BMI .error
LDA.b #$40 : TSB.w AButtonAct : RTL
LDA.w UseY1 : AND.b #$02 : BNE ++
LDA.b #$40 : TSB.w AButtonAct
++ RTL
.error
LDA.b #$3C ; SFX2_3C - error beep
@@ -803,15 +816,102 @@ PreventPotSpawn2:
LDA.b #$01 : TSB.b LinkStrafe ; what we wrote over
+ RTL
MaybeSkipTerrainDebris_long:
STZ.w SecretId ; what we wrote over
LDA.w SpriteTypeTable, X : CMP.b #$EC
BEQ .return
PLA : PLA : PLA : PLA : PLA
LDA.b #Sprite_ScheduleForBreakage_exit>>16 : PHA
PEA.w Sprite_ScheduleForBreakage_exit-1
.return
RTL
MaybeSkipSmashTerrain:
STY.w ManipIndex : LDA.w ManipTileMapX, Y ; what we wrote over
PHA
SEP #$30
LDX.b #$0F
- LDA.w SpriteAITable, X : BEQ .continue
DEX
BPL -
.skip
PLA : PLA
LDA.b #$3C : STA.w SFX2 ; error beep
SEC
RTL
.continue
REP #$30
PLA
CLC
RTL
MaybeUnableToLiftPotSfx:
- LDA.w SpriteAITable,X : BEQ .return
DEX
BPL -
LDA.b #$3C : STA.w SFX2 ; error beep
LDA.b #$FF
.return
RTL
CheckIfPotIsSpecial:
TXA ; give index to A so we can do a CMP.l
CMP.l $018550 ; see if our current index is that of object 230
BEQ .specialpot
BNE .normal_pot
; Normal pot, so run the vanilla code
.special_pot
PHX
; get pot index and cache room ID offset
LDA.b RoomIndex : ASL : STA.b Scrap0E
TAX
LDA.b $08
BIT.b $BF : BVC .upper ; if $BF has bit 14 set, it's upper layer
ORA.w #$2000 ; set the lower layer bit ($2000)
.upper
STA.b $90 ; cache tilemap offset
LDA.l UWPotsPointers,X : TAX
LDY.w #$0000
.next_pot
LDA.l UWPotsPointers&$FF0000, X ; read only the bank
CMP.w #$FFFF
BEQ .nothing
AND.w #$3FFF ; mask out the first three bits (used for item indicators and layer)
CMP.b $90 ; check against the tilemap offset
BEQ .get_flag
INX #3
INY #2
BRA .next_pot
.get_flag
TYX
LDA.l BitFieldMasks,X
LDX.b Scrap0E ; get room ID
STA.b Scrap0E
LDA.l RoomPotData,X
BRA .check_pot
.nothing
INC ; from FFFF, A is now 0000 so the AND always fails
.check_pot
LDY.b $08 : PLX
AND.b Scrap0E
BEQ .exit ; zero flag will be set, which is what we want
LDX.w #$0E82 ; the normal pot obj. See RoomDrawObjectData_#obj0E82
.normal_pot
; Normal pot, so run the vanilla code
LDA.l CurrentWorld ; check for dark world
.specialpot ; zero flag already set, so gtg
RTL
.exit
RTL
SetTheSceneFix:
STZ.b $6C

View File

@@ -5,31 +5,14 @@
;--------------------------------------------------------------------------------
LampCheck:
LDA.l LightConeModifier : BNE .lamp
LDA.l LampCone : AND.b #$10 : BNE .lamp ; always on
LDA.l LampEquipment : BNE .lamp ; skip if we already have lantern
LDA.l LampCone : AND.b #$10 : BNE .lamp
LDA.w DungeonID : CMP.b #$04 : BCS + ; are we en HC?
LDA.l LampCone : AND.b #$01 : RTL
LDA.l LampCone : RTL
+ : TDC
.lamp
RTL
;================================================================================
; Dark Room checks
;--------------------------------------------------------------------------------
; Output: 0 for normal room, 1 for darkness
;--------------------------------------------------------------------------------
DarkRoomCheck:
LDA.l LampCone : AND.b #$20 : BNE .no_dark
LDA.b [$0D], Y
AND.b #$01
RTL
.no_dark
LDA.b $A0 : ORA.b $A1 : BNE .not_dark
LDA.b #$01 ; ganon's room
RTL
.not_dark
LDA.b #$00 ; not ganon's room, so no darkness
RTL
;================================================================================
;--------------------------------------------------------------------------------
; Output: 0 locked, 1 open
;--------------------------------------------------------------------------------

View File

@@ -2,6 +2,13 @@
; Maiden Crystal Fixes
;================================================================================
pushpc
org $9ECE25
STZ.w $1F00 : NOP : NOP ; fix to allow VRAM corruption during Blind fight
pullpc
;--------------------------------------------------------------------------------
; MaidenCrystalScript
;--------------------------------------------------------------------------------

135
menu/compress.py Normal file
View File

@@ -0,0 +1,135 @@
import sys
import os
# Compression function reverse-engineered from ALTTP's decompression routine at $00E7DE
def compress(data):
out = bytearray()
i = 0
while i < len(data):
# Check for repeating byte pattern
if i + 1 < len(data) and data[i] == data[i + 1]:
length = 2
while i + length < len(data) and data[i] == data[i + length] and length < 32:
length += 1
# Repeating byte: 0x20-0x3F
out.append(0x20 | (length - 1))
out.append(data[i])
i += length
continue
# Check for incremental byte pattern
if i + 2 < len(data) and data[i + 1] == data[i] + 1 and data[i + 2] == data[i] + 2:
length = 3
while i + length < len(data) and data[i + length] == data[i] + length and length < 32:
length += 1
# Incremental: 0x60-0x7F
out.append(0x60 | (length - 1))
out.append(data[i])
i += length
continue
# Check for repeating word pattern (alternating two bytes)
if i + 3 < len(data):
# Check if we have an alternating pattern: A B A B...
byte_a = data[i]
byte_b = data[i + 1]
length = 2
while i + length < len(data) and length < 32:
if length % 2 == 0:
if data[i + length] != byte_a:
break
else:
if data[i + length] != byte_b:
break
length += 1
if length >= 4: # Need at least 4 bytes (2 alternations) to make it worthwhile
# Repeating word: 0x40-0x5F
out.append(0x40 | (length - 1))
out.append(byte_a)
out.append(byte_b)
i += length
continue
# Check for copy from past (LZ with absolute offset)
best_len = 0
best_off = 0
search_start = max(0, i - 65536) # Can reference anywhere in output
for j in range(search_start, i):
length = 0
while i + length < len(data) and data[j + length] == data[i + length] and length < 1024:
length += 1
if length >= 2 and length > best_len:
best_len = length
best_off = j # Absolute offset, not relative!
if best_len >= 2:
# Copy from past: 0x80-0xDF or 0xE0-0xFE (extended)
# Offset is ABSOLUTE position in the output buffer
if best_len <= 32:
# Standard copy: 0x80-0xDF (5 bits for length-1, 16 bits for absolute offset)
out.append(0x80 | ((best_len - 1) & 0x1F))
out.append(best_off & 0xFF)
out.append((best_off >> 8) & 0xFF)
else:
# Extended copy: 0xE0-0xFE
if best_len > 1024:
best_len = 1024
# Command byte: 111LLLLL where L is length bits
cmd = 0xE0 | (((best_len - 1) >> 8) & 0x1F)
out.append(cmd)
out.append((best_len - 1) & 0xFF)
out.append(best_off & 0xFF)
out.append((best_off >> 8) & 0xFF)
i += best_len
continue
# Raw copy (no pattern found)
size = 1
while size < 32 and i + size < len(data):
# Don't extend raw copy if we find a better pattern ahead
if i + size + 1 < len(data) and data[i + size] == data[i + size + 1]:
break
if i + size + 2 < len(data) and data[i + size + 1] == data[i + size] + 1:
break
# Check LZ
found_lz = False
for j in range(max(0, i + size - 2048), i + size):
if i + size + 1 < len(data) and data[j] == data[i + size] and data[j + 1] == data[i + size + 1]:
found_lz = True
break
if found_lz:
break
size += 1
# Raw copy: 0x00-0x1F
out.append(size - 1)
out.extend(data[i:i + size])
i += size
# End marker
out.append(0xFF)
return out
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: python compress.py <input_file> <output_file>")
sys.exit(1)
input_file_path = sys.argv[1]
output_file_path = sys.argv[2]
if not os.path.exists(input_file_path):
print(f"Error: Input file not found at {input_file_path}")
sys.exit(1)
with open(input_file_path, 'rb') as f:
input_data = f.read()
compressed_data = compress(input_data)
with open(output_file_path, 'wb') as f:
f.write(compressed_data)
print(f"Successfully compressed '{input_file_path}' to '{output_file_path}'")

112
menu/decompress.py Normal file
View File

@@ -0,0 +1,112 @@
import sys
def decompress(compressed_data):
out = bytearray()
i = 0
while i < len(compressed_data):
cmd = compressed_data[i]
if cmd == 0xFF:
# End marker
break
i += 1
# Decode based on top 3 bits
top_bits = cmd & 0xE0
if cmd < 0xE0:
# Standard commands
length = (cmd & 0x1F) + 1
if top_bits == 0x00:
# Raw copy
out.extend(compressed_data[i:i+length])
i += length
elif top_bits == 0x20:
# Repeating byte
byte_val = compressed_data[i]
out.extend([byte_val] * length)
i += 1
elif top_bits == 0x40:
# Repeating word - alternates between two bytes
byte_a = compressed_data[i]
byte_b = compressed_data[i+1]
for j in range(length):
if j % 2 == 0:
out.append(byte_a)
else:
out.append(byte_b)
i += 2
elif top_bits == 0x60:
# Incremental
start_val = compressed_data[i]
for j in range(length):
out.append((start_val + j) & 0xFF)
i += 1
elif top_bits >= 0x80:
# Copy from past (absolute offset)
offset = compressed_data[i] | (compressed_data[i+1] << 8)
for j in range(length):
out.append(out[offset + j])
i += 2
else:
# Extended command (0xE0-0xFE)
# Command type from bits 5-7 (after shifting)
cmd_type = ((cmd << 3) & 0xE0)
# Length from bits 0-1 of command (high) + next byte (low)
length_high = cmd & 0x03
length_low = compressed_data[i]
length = (length_high << 8) | length_low
length += 1
i += 1
if cmd_type == 0x00:
# Extended raw copy
out.extend(compressed_data[i:i+length])
i += length
elif cmd_type == 0x20:
# Extended repeating byte
byte_val = compressed_data[i]
out.extend([byte_val] * length)
i += 1
elif cmd_type == 0x40:
# Extended repeating word - alternates between two bytes
byte_a = compressed_data[i]
byte_b = compressed_data[i+1]
for j in range(length):
if j % 2 == 0:
out.append(byte_a)
else:
out.append(byte_b)
i += 2
elif cmd_type == 0x60:
# Extended incremental
start_val = compressed_data[i]
for j in range(length):
out.append((start_val + j) & 0xFF)
i += 1
elif cmd_type >= 0x80:
# Extended copy from past
offset = compressed_data[i] | (compressed_data[i+1] << 8)
for j in range(length):
out.append(out[offset + j])
i += 2
return out
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: python decompress.py <input_file> <output_file>")
sys.exit(1)
with open(sys.argv[1], 'rb') as f:
compressed = f.read()
decompressed = decompress(compressed)
with open(sys.argv[2], 'wb') as f:
f.write(decompressed)
print(f"Decompressed {len(compressed)} bytes to {len(decompressed)} bytes")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -9,7 +9,7 @@ UploadMenuOnlyIcons:
REP #$20
LDA.w #MenuOnlyIcons : STA.w $4342
LDA.w #$1801 : STA.w $4340
LDA.w #$03A0 : STA.w $4345
LDA.w #$0240 : STA.w $4345
LDA.w #$0F800>>1 : STA.w $2116
SEP #$20
@@ -20,4 +20,4 @@ UploadMenuOnlyIcons:
RTL
MenuOnlyIcons:
incbin "drfont.2bpp"
incbin "drfont.2bpp"

View File

@@ -40,7 +40,7 @@ dw $0000
warnpc $8ABE2E
org $8ABE2E
; located posx/posy, dislocated posx/posy, prize pox/posy
; located posx/posy, dislocated posx/posy, prize posx/posy
; located = proper location of icon (default: if you have map)
; dislocated = location of icon if proper location is hidden from player
; highest bit on first posx indicates which world it should show in
@@ -49,27 +49,27 @@ WorldMapIcon_pos:
.hc
dw $FF00, $FF00, $FF00, $FF00, $FF00, $FF00
.ep
dw $0F31, $0620, $FF00, $FF00, $0F31, $0620
dw $0F30, $06E0, $FF00, $FF00, $0F30, $06E0
.dp
dw $0108, $0D70, $FF00, $FF00, $0108, $0D70
dw $0170, $0E50, $FF00, $FF00, $0170, $0E50
.at
dw $FF00, $FF00, $FF00, $FF00, $FF00, $FF00
.sp
dw $8759, $0ED0, $FF00, $FF00, $8759, $0ED0
dw $8790, $0FD0, $FF00, $FF00, $8790, $0FD0
.pod
dw $8F40, $0620, $FF00, $FF00, $8F40, $0620
dw $8F30, $06E0, $FF00, $FF00, $8F30, $06E0
.mm
dw $8100, $0CA0, $FF00, $FF00, $8100, $0CA0
dw $8160, $0D80, $FF00, $FF00, $8160, $0D80
.sw
dw $8082, $00B0, $FF00, $FF00, $8082, $00B0
dw $80F0, $0160, $FF00, $FF00, $80F0, $0160
.ip
dw $8CA0, $0DA0, $FF00, $FF00, $8CA0, $0DA0
dw $8CB0, $0E80, $FF00, $FF00, $8CB0, $0E80
.toh
dw $08D0, $0080, $FF00, $FF00, $08D0, $0080
dw $0900, $0130, $FF00, $FF00, $0900, $0130
.tt
dw $81D0, $0780, $FF00, $FF00, $81D0, $0780
dw $8240, $0840, $FF00, $FF00, $8240, $0840
.tr
dw $8F11, $0103, $FF00, $FF00, $8F11, $0103
dw $8F30, $01B0, $FF00, $FF00, $8F30, $01B0
.gt
dw $FF00, $FF00, $FF00, $FF00, $FF00, $FF00
@@ -324,21 +324,34 @@ WorldMap_DrawTile:
SEP #$20
LDX.b Scrap0B : TXA : STA.b (OAMPtr+2)
INC.b OAMPtr+2
JSR WorldMap_CalculateOAMCoordinates
LDX.b Scrap0A : BEQ +
LDA.b Scrap0E : CLC : ADC.b #$04 : STA.b Scrap0E
LDA.b Scrap0F : CLC : ADC.b #$04 : STA.b Scrap0F
+
LDX.b Scrap0B : BEQ +
LDA.b Scrap0E : SEC : SBC.b #$04 : STA.b Scrap0E
LDA.b Scrap0F : SEC : SBC.b #$04 : STA.b Scrap0F
+
REP #$20
PLA : STA.b Scrap00
LDA.l $7EC10A : BIT.w #$4000 : SEP #$20 : BNE .raw_coords ; use raw OAM coordinates
JSR WorldMap_CalculateOAMCoordinates
BCS .apply_offsets
REP #$20
BRA .exit
.raw_coords
STA.b Scrap0E
LDA.l $7EC108 : STA.b Scrap0F
.apply_offsets
LDX.b Scrap0A : BNE .aligned ; prize number/overlay: no offset
LDX.b Scrap0B : BEQ +
; 16x16 sprite: -8 pixels
LDA.b Scrap0E : SEC : SBC.b #$08 : STA.b Scrap0E
LDA.b Scrap0F : SBC.b #$08 : STA.b Scrap0F
BRA .aligned
+
; 8x8 sprite: -4 pixels
LDA.b Scrap0E : SEC : SBC.b #$04 : STA.b Scrap0E
LDA.b Scrap0F : SBC.b #$04 : STA.b Scrap0F
.aligned
REP #$20
LDA.b Scrap0E : STA.b (OAMPtr)
INC.b OAMPtr : INC.b OAMPtr
LDA.b Scrap0C : STA.b (OAMPtr)
INC.b OAMPtr : INC.b OAMPtr
.exit
PLA : STA.b Scrap00
RTS
; Y - dungeon index
@@ -423,6 +436,78 @@ WorldMap_CheckPrizeCollected:
RTS
warnpc $8AC3B1
org $8AC3B6
; ---------------------------------------------------------------------------------------------------
; Y coordinate calculation: Quadratic approximation
; Formula: Y_oam = 0x16 + (Y * 118 >> 12) + ((Y>>4)^2 * 49 >> 8)
; Accurate to within ±1.5 pixels across entire range
; ---------------------------------------------------------------------------------------------------
REP #$20
LDA.l $7EC108 : ASL #4 ; world Y coordinate
PHA
; calculate linear term: (Y * 118) >> 12
SEP #$20
LDA.b #$76
JSR WorldMap_MultiplyAxB ; (Y>>4) * 118
REP #$20
STA.b Scrap00 ; linear term stored at high byte (Scrap01)
; calculate quadratic term: ((Y>>4)^2 * 49) >> 8
LDA.b 1,S
SEP #$20
XBA : TAX : XBA : TXA
JSR WorldMap_MultiplyAxB ; (Y>>4) ^ 2
LDA.b #$31
JSR WorldMap_MultiplyAxB ; multiply by 49
XBA ; quadratic term
; combine: 0x16 + linear_term + quadratic_term
CLC : ADC.b Scrap01 ; add linear term
ADC.b #$16 ; add fixed offset
STA.b Scrap0F
REP #$20
PLA ; world Y coordinate
; ---------------------------------------------------------------------------------------------------
; Calculate half_width for perspective: 91 + (Y_shifted * 28 / 256)
; The world map appears wider at the bottom than at the top, simulating perspective
; Top (Y=0): X range 0x26-0xDC (half-width: 91), Bottom (Y=FFF): X range 0x08-0xF6 (half-width: 119)
; ---------------------------------------------------------------------------------------------------
SEP #$20
LDA.b #$1C ; width increase factor
JSR WorldMap_MultiplyAxB
XBA : CLC : ADC.b #$5B ; add fixed half-width
STA.b Scrap00
; ---------------------------------------------------------------------------------------------------
; Calculate X offset: X_offset = (X_from_center * half_width * 2) / 256
; where X_from_center = (world_X >> 4) - 128
; The center X is at 129 (0x81)
; ---------------------------------------------------------------------------------------------------
REP #$20
LDA.l $7EC10A : LSR #4 ; world X coordinate
SEP #$20
SEC : SBC.b #$80 ; subtract 128 (center point)
PHP ; preserve carry
BPL + : EOR.b #$FF : INC : + ; absolute value
PHA
LDA.b Scrap00 : ASL : XBA ; half-width x 2
PLA
JSR WorldMap_MultiplyAxB
XBA
PLP : BCS +
STA.b Scrap00
LDA.b #$81 : SEC : SBC.b Scrap00 ; center X position - offset
BRA .store_and_exit
+ CLC : ADC.b #$81 ; center X position + offset
.store_and_exit
STA.b Scrap0E
SEP #$30
JMP WorldMap_CalculateOAMCoordinates_exit_successfully
warnpc $8AC433
pullpc
WorldMap_LoadChrHalfSlot:

View File

@@ -1,22 +0,0 @@
;================================================================================
; Mimic Direction Check
;--------------------------------------------------------------------------------
; Output: 0 for darkness, 1 for lamp cone
;--------------------------------------------------------------------------------
MimicDirection:
LDA.b $F0
AND.b #$0F
BNE .done
LDA.l MimicDash
BEQ .done
LDA.w $0372
BEQ .done
LDA.w $0374
BNE .make_zero
LDA.b $67
.done
RTL
.make_zero
LDA.b #$00
RTL

View File

@@ -427,8 +427,6 @@ StoreMusicOnDeath:
MSUInit:
PHP
LDA.b #$00
STA.l MSULoadedTrack
JSL MSUResumeReset
LDA.l NoBGM : BNE .done
@@ -499,6 +497,7 @@ MSUInit:
;--------------------------------------------------------------------------------
MSUResumeReset:
LDA.b #$00
STA.l MSULoadedTrack
STA.l MSUResumeTrack
STA.l MSUResumeTime : STA.l MSUResumeTime+1 : STA.l MSUResumeTime+2 : STA.l MSUResumeTime+3
STA.l MSUResumeControl

View File

@@ -96,15 +96,14 @@ Overworld_DetermineMusic:
CMP.b #$43 : BEQ .darkMountain
CMP.b #$45 : BEQ .darkMountain
CMP.b #$47 : BEQ .darkMountain
LDX.b #$09 ; default dark world theme
BRA .default_set
+
LDX.b #$02 ; hyrule field theme
LDA.l CurrentWorld : BEQ +
LDX.b #$09 ; default dark world theme
.default_set
; Check if we're entering the village
+ LDA.b OverworldIndex : CMP.b #$18 : BNE +
LDA.b OverworldIndex : CMP.b #$18 : BNE +
; Check what phase we're in
; LDA ProgressIndicator : CMP.b #$03 : !BGE .bunny
LDX.b #$07 ; Default village theme (phase <3)
@@ -174,24 +173,21 @@ RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; Additional dark world checks to determine whether or not to fade out music
; on mosaic transitions
;
; On entry, A = $8A (overworld area being loaded)
Overworld_MosaicDarkWorldChecks:
CMP.b #$40 : BEQ .checkCrystals
CMP.b #$42 : BEQ .checkCrystals
CMP.b #$50 : BEQ .checkCrystals
CMP.b #$51 : BNE .doFade
pushpc
org $82AD6C
; Determine whether or not to fade out music on mosaic transitions
OverworldMosaicTransition_HandleSong:
LDA.b GameSubMode : CMP.b #$0D : BNE .dont_fade
LDA.w CurrentControlRequest : CMP.b #$04 : BEQ .dont_fade
BRA .fade_song
.checkCrystals
LDA.l CrystalsField : CMP.b #$7F : BEQ .done
warnpc $82ADA0
org $82ADA0
.fade_song
org $82ADA5
.dont_fade
.doFade
LDA.b #$F1 : STA.w MusicControlRequest ; thing we wrote over, fade out music
.done
RTL
pullpc
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
@@ -230,3 +226,22 @@ FallingMusicFadeOut:
.return
RTL
;--------------------------------------------------------------------------------
FixHalfVolumeOnSpawnExitToOverworld:
BEQ .exit : STA.w MusicControlRequest ; what we wrote over
LDA.w DungeonID : BNE .exit
LDA.b LinkPosY+1 : ROR : LDA.b LinkPosY : ROR
CMP.b #$DC : BCS .exit ; check if link loading in room from a spawn
; set queue to half volume to trigger full volume on exit
LDA.b #$F2 : STA.w MusicControlQueue
.exit
RTL
;--------------------------------------------------------------------------------
FixPreAgaMusicFadeOut:
LDA.l DRMode : TAX : CPX.b #$01 : BCS .exit_no_fade+1
LDA.b RoomIndex : CMP.w #$0030 : BEQ .exit_and_fade ; what we
CMP.w #$0040 : BEQ .exit_and_fade ; wrote over
.exit_no_fade
SEC : RTL
.exit_and_fade
CLC : RTL
;--------------------------------------------------------------------------------

View File

@@ -23,14 +23,8 @@ NewHUD_DrawBombs:
BRA .draw
.finite
LDA.w BombCapacity : BEQ .no_bomb_bag
LDA.w BombsEquipment
JSR HUDHex2Digit
BRA .draw
.no_bomb_bag
LDY.w #!BlankTile
TYX
.draw
STY.w HUDBombCount+0

View File

@@ -1188,7 +1188,7 @@ MaybeFlagCompassTotalPickup:
RTL
MaybeFlagMapTotalPickup:
; LDA.l MapHUDMode : AND.b #$0F : BEQ .done
LDA.l MapHUDMode : AND.b #$0F : BEQ .done
LDA.w DungeonID : BMI .done
LDA.w ItemReceiptID : CMP.b #$33 : BEQ .set_flag
REP #$20
@@ -1210,7 +1210,7 @@ MaybeFlagDungeonTotalsEntrance:
LDA.l CompassMode : AND.w #$000F : BEQ .maps ; Skip if we're not showing compass counts
JSR FlagCompassCount
.maps
; LDA.l MapHUDMode : AND.w #$000F : BEQ .done
LDA.l MapHUDMode : AND.w #$000F : BEQ .done
LDX.w DungeonID
JSR FlagMapCount
.done
@@ -1225,7 +1225,7 @@ FlagCompassCount:
RTS
;--------------------------------------------------------------------------------
FlagMapCount:
; CMP.w #$0002 : BEQ .mapShown
CMP.w #$0002 : BEQ .mapShown
LDA.l MapMode : AND.w #$00FF : BEQ .mapShown
LDA.l MapField : AND.l DungeonItemMasks, X : BEQ .done ; skip if we don't have map
.mapShown

View File

@@ -138,7 +138,7 @@ RTL
ItemSet_Mushroom:
PHA
LDA.l NpcFlags+1 : ORA.b #$10 : STA.l NpcFlags+1
LDY.w SprItemReceipt, X ; Retrieve stored item type
LDY.w SprSourceItemId, X ; Retrieve stored item type
BNE +
; if for any reason the item value is 0 reload it, just in case
%GetPossiblyEncryptedItem(MushroomItem, SpriteItemValues) : TAY

File diff suppressed because it is too large Load Diff

View File

@@ -168,7 +168,7 @@ RTL
;--------------------------------------------------------------------------------
ChangeBootsColorForFakeBoots:
LDA.l FakeBoots : AND.w #$00FF : BEQ +
LDA.l EquipmentSRAM+$15 : AND.w #$00FF : BNE +
LDA.l BootsEquipment : AND.w #$00FF : BNE +
LDA.w #$F851 ; address of ItemMenu_ItemIcons_usused_nothing, which has the fake boots now
BRA ++
+ LDA.w #$F821 ; address of ItemMenu_ItemIcons_boots
@@ -464,40 +464,7 @@ dw $2990 ; green pendant
dw $298B ; blue pendant
dw $299B ; red pendant
;================================================================================
DrawBossSouls:
PHP : PHB : PHK : PLB
REP #$30 ; Set 16-bit accumulator & index registers
LDX.w #$0000 ; Paint entire box black & draw empty pendants and crystals
-
LDA.l .row0, X : STA.w GFXStripes+$02EA, X
LDA.l .row1, X : STA.w GFXStripes+$032A, X
LDA.l .row2, X : STA.w GFXStripes+$036A, X
LDA.l .row3, X : STA.w GFXStripes+$03AA, X
LDA.l .row4, X : STA.w GFXStripes+$03EA, X
LDA.l .row5, X : STA.w GFXStripes+$042A, X
LDA.l .row6, X : STA.w GFXStripes+$046A, X
LDA.l .row7, X : STA.w GFXStripes+$04AA, X
LDA.l .row8, X : STA.w GFXStripes+$04EA, X
INX #2 : CPX.w #$0014 : BCC -
PLB : PLP
RTL
;================================================================================
.row0 dw $28FB, $28F9, $28F9, $28F9, $28F9, $28F9, $28F9, $28F9, $28F9, $68FB
.row1 dw $28FC, $31A4, $31A5, $24F5, $31A6, $31A7, $24F5, $31A8, $31A9, $68FC
.row2 dw $28FC, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $68FC
.row3 dw $28FC, $31AA, $31AB, $24F5, $31AC, $31AD, $24F5, $31AE, $31AF, $68FC
.row4 dw $28FC, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $68FC
.row5 dw $28FC, $31B0, $31B1, $24F5, $31B2, $31B3, $24F5, $31B4, $31B5, $68FC
.row6 dw $28FC, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $24F5, $68FC
.row7 dw $28FC, $24F5, $31B6, $31B7, $24F5, $24F5, $31B8, $31B9, $24F5, $68FC
.row8 dw $A8FB, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $A8F9, $E8FB
;================================================================================
DrawPendantCrystalDiagram:
LDA.l HudFlag : AND.b #$40 : BEQ +
JML.l DrawBossSouls
+
PHP : PHB : PHK : PLB
REP #$30 ; Set 16-bit accumulator & index registers
LDX.w #$0000 ; Paint entire box black & draw empty pendants and crystals

28
ram.asm
View File

@@ -221,6 +221,8 @@ ItemReceiptMethod = $7E02E9 ;
;
TileActBE = $7E02EF ; Bitfield used by breakables and entrances. b b b b d d d d
; b = Breakables | d = Entrances
LinkThud = $7E02F8 ; When set, guarantees a thud on landing
FollowerNoDraw = $7E02F9 ; When set, prevents follower from drawing and forces a game mode check
UseY1 = $7E0301 ; Bitfield for Y-item usage: b p - a x z h r
; b = Boomerang | p = Powder | a = Bow | x = Hammer (tested, never set)
; z = Rods (tested, never set) | h = Hammer | r = Rods
@@ -229,6 +231,8 @@ CurrentYItem = $7E0303 ;
AButtonAct = $7E0308 ; Bitfield for A-actions. $80 = Carry/toss | $02 Prayer | $01 = Tree pull
CarryAct = $7E0309 ; Bitfield for carrying. $02 = Tossing | $01 = Lifting
;
LinkIFrames = $7E031F ; Countdown for Link's invincibility frames after taking damage.
;
LinkSwimDirection = $7E0340 ; Bitfield for swim direction. (.... udlr)
;
LinkDeepWater = $7E0345 ; Set when Link is in deep water.
@@ -270,6 +274,8 @@ DungeonID = $7E040C ; High byte mostly unused but sometimes read.
;
TransitionDirection = $7E0418 ; OW: 0=N 1=S 2=W 3=E UW: 0=S 1=N 2=E 3=W
;
ManipIndex = $7E042C ; Index of manipulable tile. Word length.
;
TrapDoorFlag = $7E0468 ; Flag that is set when trap doors are down. 2 bytes
;
LayerAdjustment = $7E047A ; Flags layer adjustments. Arms EG.
@@ -283,6 +289,8 @@ OWEntranceCutscene = $7E04C6 ;
;
HeartBeepTimer = $7E04CA ;
;
ManipTileMapX = $7E0540 ; Tilemap X position of manipulable tile. $10 x 2 bytes
;
CameraTargetN = $7E0610 ; Camera scroll target for directions NSEW
CameraTargetS = $7E0612 ;
CameraTargetW = $7E0614 ;
@@ -324,7 +332,7 @@ SpawnedItemFlag = $7E0726 ; 0x02 - one for pot, 2 for sprite drop
SpawnedItemMWPlayer = $7E0728 ; Player Id for spawned item if Multiworld item 0x02
;
EnemyDropIndicator = $7E072A ; Used by HUD to indicate enemy drops remaining
SkipBeeTrapDisguise = $7E072C ; Flag to skip bee trap disguise during draw routine
SkipBeeTrapDisguise = $7E072D ; Flag to skip bee trap disguise during draw routine
SprDropsItem = $7E0730 ; Array for whether a sprite drops an item 0x16
SprItemReceipt = $7E0740 ; Array for item id for each sprite 0x16
@@ -346,6 +354,8 @@ TransparencyFlag = $7E0ABD ; Flags transparency effects e.g. in Thieves T
;
OWTransitionFlag = $7E0ABF ; Used for certain transitions like smith, witch, etc.
;
DuckPose = $7E0AF4 ; Used for duck gfx (2 bytes), zero value stops duck drawing in gfx slot
;
ItemGFXPtr = $7E0AFA ; Pointer for item receipt graphics transfers
; $0000 - no transfer, do nothing
; bit 7 reset - offset into ROM table
@@ -363,6 +373,7 @@ EnemyStunTimer = $7E0B58 ; Auto-decrementing timer for stunned enemies.
;
BowDryFire = $7E0B9A ; If set, arrows are deleted immediately
;
SecretId = $7E0B9C ; Controls the secret spawned from bushes, pots, rocks, etc.
SaveFileIndex = $7E0B9D ;
;
SpriteAncillaInteract = $7E0BA0 ; If nonzero, ancillae do not interact with the sprite. $10 bytes.
@@ -437,7 +448,8 @@ SpriteSubPixelZ = $7E0F90 ;
CurrentSpriteSlot = $7E0FA0 ; Holds the current sprite/ancilla's index
;
FreezeSprites = $7E0FC1 ; "Seems to freeze sprites"
;
LinkPosXCache = $7E0FC2 ; Cache of Link's coordinates
LinkPosYCache = $7E0FC4 ; - Done at the beginning of Link_Main every frame
GfxChrHalfSlotVerify = $7E0FC6 ; Mirrors $0AAA, set to >= $03 when VRAM has temp graphics loaded
PrizePackIndexes = $7E0FC7 ; $07 bytes. One for each prize pack.
;
@@ -687,8 +699,7 @@ MapTotalsWRAM: skip $10 ; / on boot for tracking.
skip $20 ; Reserved for general dungeon tracking data. May have over
; allocated here. Feel free to reassign.
MapCompassFlag: skip 2 ; Used to flag overworld map drawing.
SpriteInvincibilityFlag: skip $10 ; Used for boss soul shuffle
skip $2E ; Unused
skip $3E ; Unused
skip $260 ; Unused
DialogBuffer: skip $100 ; Dialog Buffer
;
@@ -842,9 +853,13 @@ endmacro
%assertRAM(CutsceneFlag, $7E02E4)
%assertRAM(ItemReceiptMethod, $7E02E9)
%assertRAM(TileActBE, $7E02EF)
%assertRAM(LinkThud, $7E02F8)
%assertRAM(FollowerNoDraw, $7E02F9)
%assertRAM(UseY1, $7E0301)
%assertRAM(CurrentYItem, $7E0303)
%assertRAM(AButtonAct, $7E0308)
%assertRAM(CarryAct, $7E0309)
%assertRAM(LinkIFrames, $7E031F)
%assertRAM(LinkSwimDirection, $7E0340)
%assertRAM(LinkDeepWater, $7E0345)
%assertRAM(TileActIce, $7E0348)
@@ -865,6 +880,7 @@ endmacro
%assertRAM(OverworldIndexMirror, $7E040A)
%assertRAM(DungeonID, $7E040C)
%assertRAM(TransitionDirection, $7E0418)
%assertRAM(ManipIndex, $7E042C)
%assertRAM(TrapDoorFlag, $7E0468)
%assertRAM(LayerAdjustment, $7E047A)
%assertRAM(RoomIndexMirror, $7E048E)
@@ -872,6 +888,7 @@ endmacro
%assertRAM(Map16ChangeIndex, $7E04AC)
%assertRAM(OWEntranceCutscene, $7E04C6)
%assertRAM(HeartBeepTimer, $7E04CA)
%assertRAM(ManipTileMapX, $7E0540)
%assertRAM(CameraTargetN, $7E0610)
%assertRAM(CameraTargetS, $7E0612)
%assertRAM(CameraTargetW, $7E0614)
@@ -901,7 +918,7 @@ endmacro
%assertRAM(SpawnedItemFlag, $7E0726)
%assertRAM(SpawnedItemMWPlayer, $7E0728)
%assertRAM(EnemyDropIndicator, $7E072A)
%assertRAM(SkipBeeTrapDisguise, $7E072C)
%assertRAM(SkipBeeTrapDisguise, $7E072D)
%assertRAM(SprDropsItem, $7E0730)
%assertRAM(SprItemReceipt, $7E0740)
%assertRAM(SprItemIndex, $7E0750)
@@ -922,6 +939,7 @@ endmacro
%assertRAM(OverlordYHigh, $7E0B20)
%assertRAM(EnemyStunTimer, $7E0B58)
%assertRAM(BowDryFire, $7E0B9A)
%assertRAM(SecretId, $7E0B9C)
%assertRAM(SaveFileIndex, $7E0B9D)
%assertRAM(SpriteAncillaInteract, $7E0BA0)
%assertRAM(AncillaVelocityY, $7E0C22)

View File

@@ -466,7 +466,6 @@ Shopkeeper_BuyItem:
PLX
LDA.l ShopInventory, X
JSL AttemptItemSubstitution
JSL ResolveLootIDLong
TAY : JSL Link_ReceiveItem
LDA.l ShopInventory+3, X : INC : STA.l ShopInventory+3, X
LDA.b #$00 : STA.l ShopEnableCount

152
souls.asm
View File

@@ -1,152 +0,0 @@
;================================================================================
; Boss Souls
;================================================================================
SoulPaletteSet:
LDA.l SpriteInvincibilityFlag, X
BEQ .normal
LDA.b #$FF
STA.w $0CFE
RTL
.normal
CMP.b #$08
BNE +
LDA.l $7FFA3C, X
STA.w $0CFE
+
RTL
;================================================================================
SoulPaletteApply:
AND.w #$F1FF
PHA
LDA.w $0CFE
AND.w #$00FF
CMP.w #$00FF
BEQ .blackout
.ice
PLA
ORA.w #$0400
RTL
.blackout
PLA
ORA.w #$0600
RTL
;================================================================================
HelmasaurPaletteFix:
LDA.w $0B89, X
AND.b #$F1
PHA
LDA.l SpriteInvincibilityFlag, X
BEQ .normal
.blackout
PLA
ORA.b #$0A
STA.w $0B89, X
RTL
.normal
PLA
STA.w $0B89, X
RTL
;================================================================================
HelmasaurHammerFix:
LDA.l SpriteInvincibilityFlag, X
BEQ .normal
LDA.b #$00
RTL
.normal
LDA.w $0301
AND.b #$0A
RTL
;================================================================================
MoldormPaletteFix:
.b
LDA.b #$0B
BRA .apply
.d
LDA.b #$0D
.apply
PHA
LDA.l SpriteInvincibilityFlag, X
BEQ .normal
PLA
LDA.b #$07
BRA .write
.normal
PLA
.write
STA.w $0F50, X
RTL
;================================================================================
CheckInvincibleFlag:
LDA.l SpriteInvincibilityFlag, X
BEQ .normal
LDA.w $0E20, X
SEC
RTL
.normal
JML.l IsItReallyAMimic
;================================================================================
CheckBossSoul:
PHA : PHX
LDA.b #$00
STA.l SpriteInvincibilityFlag, X
; check if boss id
LDX.b #.boss_ids_end-.boss_ids-1
TYA
- CMP.l .boss_ids, X
BEQ .match
DEX
BPL -
.normal
PLX : PLA
STA.w $0E60, X
AND.b #$0F
STA.w $0F50, X
RTL
.match
; X is boss index
; make palette black
LDA.b #$00
LDX.b #$1D
- STA.l $7EC462, X
STA.l $7EC662, X
DEX
BPL -
LDA.b #$01
STA.b $15 ; update palette
PLX
LDA.b #$01
STA.l SpriteInvincibilityFlag, X
PLA
ORA.b #$40
STA.w $06E0, X
AND.b #$01
ORA.b #$06
STA.w $0F50, X
RTL
.boss_ids:
db $53 ; armos
db $54 ; lanmolas
db $09 ; moldorm
db $92 ; helma king
db $8C ; arrghus
db $8D ; arrghus puff
db $88 ; mothula
db $CE ; blind
db $A2 ; khold
db $A3 ; khold shell
db $BD ; vitreous big eye
db $BE ; vitreous small eye
db $CB ; trinexx
db $CC ; trinexx
db $CD ; trinexx
db $7A ; agahnim
..end

View File

@@ -212,8 +212,8 @@ FollowerIndicator: skip 1 ; $00 = No Follower | $01 = Zelda | $04 = Ol
; $06 = Blind Maiden | $07 = Frog | $08 = Dwarf
; $09 = Locksmith | $0A = Kiki | $0C = Purple Chest
; $0D = Big Bomb
FollowerXCoord: skip 2 ; \ Cached X and Y overworld coordinates of dropped follower
FollowerYCoord: skip 2 ; / (16-bit integers)
FollowerYCoord: skip 2 ; \ Cached X and Y overworld coordinates of dropped follower
FollowerXCoord: skip 2 ; / (16-bit integers)
DroppedFollowerIndoors: skip 1 ; $00 = Dropped follower outdoors | $01 = Dropped follower indoors
DroppedFollowerLayer: skip 1 ; $00 = Upper layer | $01 =.lower layer
FollowerDropped: skip 1 ; Set to $80 when a follower exists and has been dropped somewhere
@@ -237,9 +237,7 @@ CompassCountDisplay: skip 2 ; Compass count display flags (bitfield)
; High Byte: x c e d a s p m
; x = Sewers | c = Hyrule Castle | e = Eastern Palace | d = Desert Palace
; a = Castle Tower | s = Swamp Palace | p = PoD | m = Mire
BossSoulMissing: skip 2 ; bitfield for boss soul acquisition
; 0 = has soul, 1 = soul missing
skip 8 ;
skip 10 ;
Aga2Duck: skip 1 ; Used in lieu of pyramid hole for checking if the duck should come
; 0 = Haven't called post-Aga 2 bird | 1 = Have called post-Aga 2 bird
NpcFlags: skip 2 ; l - c s t k z o (bitfield)
@@ -364,7 +362,21 @@ TRCollectedKeys: skip 1 ; | Turtle Rock
GTCollectedKeys: skip 1 ; / Ganon's Tower
skip 2 ; Reserved for previous table
FileMarker: skip 1 ; $FF = Active save file | $00 = Inactive save file
skip 13 ; Unused
DungeonAllCollectedKeys: ; \ Key Counters. Counts all keys for a dungeon. Chests and drops.
; | Note, this label is not indexed like others due to space. Sewers has no decicated entry.
HCAllCollectedKeys: skip 1 ; | Hyrule Castle
EPAllCollectedKeys: skip 1 ; | Eastern Palace
DPAllCollectedKeys: skip 1 ; | Desert Palace
CTAllCollectedKeys: skip 1 ; | Agahnim's Tower
SPAllCollectedKeys: skip 1 ; | Swamp Palace
PDAllCollectedKeys: skip 1 ; | Palace of Darkness
MMAllCollectedKeys: skip 1 ; | Misery Mire
SWAllCollectedKeys: skip 1 ; | Skull Woods
IPAllCollectedKeys: skip 1 ; | Ice Palace
THAllCollectedKeys: skip 1 ; | Tower of Hera
TTAllCollectedKeys: skip 1 ; | Thieves' Town
TRAllCollectedKeys: skip 1 ; | Turtle Rock
GTAllCollectedKeys: skip 1 ; / Ganon's Tower
InverseChecksumWRAM: skip 2 ; Vanilla Inverse Checksum. Don't write unless computing checksum.
;================================================================================
@@ -514,8 +526,8 @@ endmacro
%assertSRAM(NpcFlagsVanilla, $7EF3C9)
%assertSRAM(CurrentWorld, $7EF3CA)
%assertSRAM(FollowerIndicator, $7EF3CC)
%assertSRAM(FollowerXCoord, $7EF3CD)
%assertSRAM(FollowerYCoord, $7EF3CF)
%assertSRAM(FollowerYCoord, $7EF3CD)
%assertSRAM(FollowerXCoord, $7EF3CF)
%assertSRAM(DroppedFollowerIndoors, $7EF3D1)
%assertSRAM(DroppedFollowerLayer, $7EF3D2)
%assertSRAM(FollowerDropped, $7EF3D3)
@@ -626,6 +638,7 @@ endmacro
%assertSRAM(TRCollectedKeys, $7EF4EC)
%assertSRAM(GTCollectedKeys, $7EF4ED)
%assertSRAM(FileMarker, $7EF4F0)
%assertSRAM(DungeonAllCollectedKeys, $7EF4F1)
;--------------------------------------------------------------------------------
%assertSRAM(ExtendedSaveDataWRAM, $7F6000)
%assertSRAM(ExtendedFileNameWRAM, $7F6000)

View File

@@ -115,38 +115,76 @@ DecrementSmallKeys:
STA.l CurrentSmallKeys ; thing we wrote over, write small key count
JSL UpdateKeys
RTL
;--------------------------------------------------------------------------------
CountChestKeyLong:
PHX : PHP
SEP #$30
PHX : PHP
SEP #$30
JSR CountChestKey
PLP : PLX
RTL
PLP : PLX
RTL
;--------------------------------------------------------------------------------
CountChestKey:
PHA : PHX
LDA.l !MULTIWORLD_ITEM_PLAYER_ID : BNE .done
LDA.l StatsLocked : BNE .done
CPY.b #$24 : BEQ .this_dungeon
TYA
AND.b #$0F : CMP.b #$02 : BCC .hc_sewers
TAX
LDA.l DungeonCollectedKeys,X : INC : STA.l DungeonCollectedKeys,X
BRA .done
.this_dungeon
LDA.w DungeonID : CMP.b #$03 : BCC .hc_sewers
LSR : TAX
LDA.l DungeonCollectedKeys,X : INC : STA.l DungeonCollectedKeys,X
BRA .done
PHA : PHX
LDA.l !MULTIWORLD_ITEM_PLAYER_ID : BNE .done
LDA.l StatsLocked : BNE .done
CPY.b #$24 : BEQ .this_dungeon
TYA
AND.b #$0F : CMP.b #$02 : BCC .hc_sewers
TAX
LDA.l DungeonCollectedKeys,X : INC : STA.l DungeonCollectedKeys,X
BRA .done
.hc_sewers
LDA.l SewerCollectedKeys : INC
STA.l SewerCollectedKeys : STA.l HCCollectedKeys
.this_dungeon
LDA.w DungeonID : CMP.b #$03 : BCC .hc_sewers
LSR : TAX
LDA.l DungeonCollectedKeys,X : INC : STA.l DungeonCollectedKeys,X
BRA .done
.done
PLX : PLA
RTS
.hc_sewers
LDA.l SewerCollectedKeys : INC
STA.l SewerCollectedKeys : STA.l HCCollectedKeys
.done
PLX : PLA
RTS
; Expects 16 bit index mode upon entering. 8-bit Acumulator
; This approach doesn't currently work - potentially dead code
CountAllKey:
PHP : PHA : PHX
SEP #$10
LDA.l !MULTIWORLD_ITEM_PLAYER_ID : BNE .done
CPY.b #$24 : BEQ .this_dungeon
TYA : AND.b #$0F : CMP.b #$02 : BCC .hc_sewers
BRA .all_dungoens
.this_dungeon
LDA.w DungeonID : CMP.b #$03 : BCC .hc_sewers
LSR
.all_dungoens
STA.b Scrap00 : TAX ; store dungeon index in X, $00
LDA.l DungeonAllCollectedKeys-1, X : INC : STA.l DungeonAllCollectedKeys-1, X
REP #$10 : PLX : PHX ; 16 bit index
LDA.l InventoryTable_properties, X : BIT.b #$40 : BEQ .done
SEP #$10 : LDX.b Scrap00
LDA.l DungeonCollectedKeys,X : INC : STA.l DungeonCollectedKeys,X
BRA .done
.hc_sewers
LDA.l HCAllCollectedKeys : INC : STA.l HCAllCollectedKeys
REP #$10 : PLX : PHX ; 16 bit index
LDA.l InventoryTable_properties, X : BIT.b #$40 : BEQ .done
LDA.l SewerCollectedKeys : INC
STA.l SewerCollectedKeys : STA.l HCCollectedKeys
.done
REP #$10
PLX : PLA : PLP
RTL
;--------------------------------------------------------------------------------
IncrementAgahnim2Sword:

View File

@@ -111,7 +111,7 @@ dw $000A ; #$0A - Default (10 decimal)
;--------------------------------------------------------------------------------
org $B08038 ; PC 0x180038
LampCone:
db $01 ; #$00 = Off - #$01 = On in Sewers (default) - #$10 = On Always - #$20 = No Dark Rooms
db $01 ; #$00 = Off - #$01 = Sewers only (default) - #$11 = Always On
;--------------------------------------------------------------------------------
org $B08039 ; PC 0x180039
ItemCounterHUD:
@@ -190,8 +190,11 @@ QuickSwapFlag:
db $00 ; #$00 = Off (default) - #$01 = On
;--------------------------------------------------------------------------------
org $B0804C ; PC 0x18004C
SmithTravelsFreely:
db $00 ; #$00 = Off (default) - #$01 = On (frog/smith can enter multi-entrance doors)
FollowerTravelAllowed:
db $00
; #$00 = Off (default)
; #$01 = On (frog/smith can enter multi-entrance doors)
; #$02 = Follower Shuffle Enabled
;--------------------------------------------------------------------------------
org $B0804D ; PC 0x18004D
EscapeAssist: ; ScrubMode:
@@ -420,17 +423,7 @@ db $01 ; #$00 = Original Behavior - #$01 = Randomizer Behavior (Default)
Bugfix_PodEG:
db $01 ; #$00 = Original Behavior - #$01 = Randomizer Behavior (Default)
;--------------------------------------------------------------------------------
org $B080A5 ; PC 0x1800A5
MimicDash:
db $00 ; #$00 = Original Behavior (default) - #$01 = Mimics move when link dashes
CrystalSwitchBook:
db $00 ; #$00 = Original Behavior (default) - #$01 = Book can flip crystal switch
;--------------------------------------------------------------------------------
; 0x1800A7 - 0x1800AE (unused)
;--------------------------------------------------------------------------------
org $B080AF ; PC 0x1800AF
MultiworldJunkItemTimer:
db $00 ; number of frames to show junk items in a multiworld (#$00 = no change)
; 0x1800A5 - 0x1800AF (unused)
;--------------------------------------------------------------------------------
org $B080B0 ; 0x1800B0-0x1800BF
StaticDecryptionKey:
@@ -899,38 +892,84 @@ org $B08196 ; PC 0x180196-0x180197
TotalItemCount: ; Total item count for HUD. Only counts items that use "item get" animation.
dw $00D8 ; 216
org $B08198 ; PC 0x180198-0x1801A9
GanonsTowerOpenAddress: ; 0x180198-0x180199
dw CrystalCounter ; Target address for GT open check
GanonsTowerOpenTarget: ; 0x18019A-0x18019B
dw $0007 ; Target amount for GT open modes to compare
GanonsTowerOpenMode: ; 0x18019C-0x18019D
dw $0001 ; $00 = Vanilla | $01 = Compare target with address
PedPullAddress: ; 0x18019E-0x18019F
dw PendantCounter ; Target address for ped pull check
PedPullTarget: ; 0x1801A0-0x1801A1
dw $0003 ; Target amount for ped pull modes to check
PedCheckMode: ; 0x1801A2-0x1801A3
dw $0000 ; $00 = vanilla | $01 = Compare address to target value
GanonVulnerableAddress: ; 0x1801A4-0x1801A5
dw CrystalCounter ; Target address for ped pull check
GanonVulnerableTarget: ; 0x1801A6-0x1801A7
dw $0007 ; Target amount for Ganon vulnerability modes to compare
GanonVulnerableMode: ; 0x1801A8-0x1801A9
dw $0000 ; #$00 = Off (default)
; #$01 = On
; #$02 = Require All Dungeons
; #$03 = Require "GanonVulnerableTarget" Crystals and Aga2
; #$04 = Require "GanonVulnerableTarget" Crystals
; #$05 = Require "GoalItemRequirement" Goal Items
; #$06 = Light Speed
; #$07 = Require All Crystals and Crystal Bosses
; #$08 = Require All Crystal Bosses only
; #$09 = Require All Dungeons No Agahnim
; #$0A = Require 100% Item Collection
; #$0B = Require 100% Item Collection and All Dungeons
org $B08198 ; PC 0x180198-0x1801D7 (variable tables, $FF terminated)
GoalConditionTable:
dw GanonsTowerOpen
dw GanonVulnerable
dw PedPull
dw MurahdahlaComplete
GanonsTowerOpen:
db $82 ; Crystal Count >= Default 7
db $FF
GanonVulnerable:
db $82 ; Crystal Count >= Default 7
db $07 ; Agahnim 2 defeated
db $FF
PedPull:
db $81 ; Pendant Count >= Default 3
db $FF
MurahdahlaComplete:
db $88 ; Triforce Pieces >= Default Goal
db $FF
; These are lists of conditions to check for various goals,
; each terminated by #$FF.
; First byte is condition type, with most significant bit
; indicating the default value should be used, else the
; following byte/s indicate the custom target value.
; -----------------------------------------------------------
; Condition Types:
; #$00 = Always Invulnerable
; #$01 = Require Pendants - Default is 3
; #$02 = Require Crystals - Default is 7
; #$03 = Require Pendant Bosses - Default is 3
; #$04 = Require Crystal Bosses - Default is 7
; #$05 = Require Prize Bosses - Default is 10
; #$06 = Require Agahnim 1
; #$07 = Require Agahnim 2
; #$08 = Require Goal Items (ie. Triforce Pieces) - Default is value at GoalItemRequirement
; #$09 = Require Item Collection - Default is Max Collection Rate
; #$0A = Require Custom Goal
; -----------------------------------------------------------
; For Custom Goal, one byte indicates the bitfield options,
; followed by two bytes for the target address, followed
; by one or two bytes for the custom target value.
; Options bitfield:
; ---b accc
; b - bank flag - 0 = $7E - 1 = $7F
; a - addressing mode - 0 = 8-bit - 1 = 16-bit
; c - comparison mode
; 0 = minimum (>=)
; 1 = exact (==)
; 2 = bitfield any
; 3 = bitfield match
; 4 = count bits set in bitfield
; 5-7 = reserved
;--------------------------------------------------------------------------------
; 0x18019A - 0x1801FF (unused)
org $B081D8 ; PC 0x1801D8 - 0x1801FE
GanonsTowerOpenGfx: ; 0x1801D8-0x1801E5
dw $0000 ; Gfx used for GT open animation, similar to StandingItemGraphicsOffsets
dw $0000, $0000, $0000, $0000, $0000, $0000
GanonsTowerOpenPalette: ; 0x1801E6-0x1801EC
db $00 ; Palette for GanonsTowerOpenGfx
db $00, $00, $00, $00, $00, $00
; -VHPPCCC (VertFlip, HorizFlip, Priority, ColorPalette)
PedPullGfx: ; 0x1801ED-0x1801F2
dw $0000 ; Gfx used for ped pull animation, similar to StandingItemGraphicsOffsets
dw $0000, $0000
PedPullPalette: ; 0x1801F3-0x1801F5
db $00 ; Palette for PedPullGfx
db $00, $00
; -VHPPCCC (VertFlip, HorizFlip, Priority, ColorPalette)
MurahdahlaGfx: ; 0x1801F6-0x1801FB
dw $0000 ; Gfx used for ped pull animation, similar to StandingItemGraphicsOffsets
dw $0000, $0000
MurahdahlaPalette: ; 0x1801FC-0x1801FE
db $00 ; Palette for MurahdahlaGfx
db $00, $00
; -VHPPCCCO (VertFlip, HorizFlip, Priority, ColorPalette)
;--------------------------------------------------------------------------------
; 0x1801FF (unused)
;================================================================================
org $B08200 ; PC 0x180200 - 0x18020B
RedClockAmount:
@@ -1021,14 +1060,14 @@ org $B08220 ; PC 0x180220
org $B08240 ; PC 0x180240
StartingAreaExitOffset:
db $00, $00, $00, $00, $00, $00, $00
;--------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
org $B08247 ; PC 0x180247
; For any starting areas in single entrance caves you can specify the overworld door here
; to enable drawing the doorframes These values should be the overworld door index+1.
; A value of zero will draw no door frame.
StartingAreaOverworldDoor:
db $00, $00, $00, $00, $00, $00, $00
;--------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; 0x18024E - 0x18024F (unused)
;-------------------------------------------------------------------------------
; $308250 (0x180250) - $30829F (0x18029F)
@@ -1043,11 +1082,50 @@ dw $0000 : db $00 : dw $0000, $0000, $0000, $0000, $0000, $0000, $0000 : db $00,
dw $0000 : db $00 : dw $0000, $0000, $0000, $0000, $0000, $0000, $0000 : db $00, $00, $00
;--------------------------------------------------------------------------------
; 0x1802A0 - 0x1802BF (unused)
;---------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; $3082C0 (0x1802C0) - $3082D7 (0x1802D7)
org $B082C0
; Follower data
; First byte is the Follower ID awarded at each of the locations
; Next 2 bytes are OAM address references to the head/body gfx
Follower_Zelda: ; PC 0x1802C0
db $01
.vram
dw $CCCE
Follower_OldMan: ; PC 0x1802C3
db $04
.vram
dw $ACAE
Follower_Maiden: ; PC 0x1802C6
db $06
.vram
dw $CCCE
Follower_Frog: ; PC 0x1802C9
db $07
.vram
dw $C8EE
Follower_Locksmith: ; PC 0x1802CC
db $09
.vram
dw $EAEC
Follower_Kiki: ; PC 0x1802CF
db $0A
.vram
dw $C0C2
Follower_PurpleChest: ; PC 0x1802D2
db $0C
.vram
dw $C8EE
Follower_SuperBomb: ; PC 0x1802D5
db $0D
.vram
dw $AE4E
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; 0x1802C0 - 0x1802FF (unused)
;---------------------------------------------------------------------------------
; 0x1802D8 - 0x1802FF (unused)
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; $308300 (0x180300) - $30834F (0x18034F)
org $B08300 ; PC 0x180300

View File

@@ -19,7 +19,14 @@ RTL
;--------------------------------------------------------------------------------
SetTabletItemFlag:
PHA
LDA.b OverworldIndex : CMP.b #$03 : BEQ .ether ; if we're on the map where ether is, we're the ether tablet
; Rain state fix: convert DW screen ID to LW if in rain state
LDA.b OverworldIndex
BIT.b #$40 : BEQ +
LDA.l ProgressIndicator : CMP.b #$02
LDA.b OverworldIndex : BCS ++ : AND.b #$BF
++
+
CMP.b #$03 : BEQ .ether ; if we're on the map where ether is, we're the ether tablet
.bombos
JSR ItemSet_BombosTablet : BRA .done
.ether
@@ -69,6 +76,12 @@ RTL
IsMedallion:
REP #$20 ; set 16-bit accumulator
LDA.b OverworldIndex
; Rain state fix: In rain state DW, use LW screen ID for tablet lookup
BIT.w #$0040 : BEQ +
LDA.l ProgressIndicator : AND.w #$00FF : CMP.w #$0002
LDA.b OverworldIndex : BCS ++ : AND.w #$00BF
++
+
CMP.w #$03 : BNE + ; Death Mountain
LDA.b LinkPosX : CMP.w #1890 : !BGE ++
SEC

View File

@@ -435,7 +435,7 @@ LoadItemPalette:
; Out: A - Sprite palette index
PHX : PHY : PHB
LDA.b #PalettesVanillaBank>>16 : STA.b Scrap0C
PEA $7E00
PEA.w $7E00
PLB : PLB
REP #$30
@@ -520,3 +520,20 @@ AuxPaletteCheck:
REP #$30
PLX
RTS
CountBits:
; In: A - value to count bits set in
; Out: A - number of bits set
; Flexible to use with 8 or 16-bit mode
PHX : TAX
PHY : PHP
SEP #$20
LDA.b 1,S : BIT.b #$20 : BNE +
PLP : TXA : LDX.w #$000F : LDY.w #$0000
BRA ++
+ PLP : TXA : LDX.b #$07 : LDY.b #$00
++ - LSR : BCC +
INY
+ DEX : BPL -
TYA : PLY : PLX
RTL

View File

@@ -37,6 +37,7 @@ CopyFontToVRAM = $80E596
LoadCommonSprites_in_file_select = $80E784
PaletteFilter_TheEndSprite = $80EC03
PrepDungeonExit = $80F945
SaveDeathCount = $80F9DD
Mirror_InitHdmaSettings = $80FDEE
Dungeon_LoadRoom = $81873A
Underworld_HandleRoomTags = $81C2FD
@@ -73,12 +74,15 @@ SpritePrep_MagicShopAssistant = $85F521
Player_ApplyRumbleToSprites = $8680FA
Sprite_Main = $868328
Utility_CheckIfHitBoxesOverlapLong = $8683E6
Sprite_Get16BitCoords_long = $8684BD
Sprite_TransmuteToBomb = $86AD58
Sprite_PrepAndDrawSingleLargeLong = $86DBF8
Sprite_PrepAndDrawSingleSmallLong = $86DC00
Sprite_DrawShadowLong = $86DC5C
Sprite_DrawShadowCustomLong = $86DC64
DashKey_Draw = $86DD40
Sprite_PrepOAMCoordLong = $86E41C
Sprite_CheckTileCollisionLong = $86E49C
Sprite_ApplySpeedTowardsPlayerLong = $86EA18
Sprite_DirectionToFacePlayerLong = $86EAA6
Sprite_CheckDamageToPlayerSameLayerLong = $86F12F
@@ -91,9 +95,11 @@ Player_HaltDashAttackLong = $8791B3
Link_ReceiveItem = $87999D
Link_ReceiveItem_cool_pose = $8799EE
Link_ReceiveItem_not_cool_pose = $8799F2
HandleFollowersAfterMirroring = $87AA8B
LinkHop_FindArbitraryLandingSpot = $87E359
Link_HandleMovingAnimation_FullLongEntry = $87E68F
Link_CheckForEdgeScreenTransition = $87F413
Link_CheckForEdgeScreenTransition_prevent_transition = $87F42C
Sprite_CheckIfPlayerPreoccupied = $87F4AA
FlashGanonTowerPalette_next_thunder = $87FA81
FlashGanonTowerPalette_bright_white = $87FAAC
@@ -117,6 +123,8 @@ AncillaAdd_GTCutscene = $899B6F
AddDoorDebris_spawn_failed = $899C39
AddAncillaLong = $899D04
Ancilla_CheckIfAlreadyExistsLong = $899D1A
Follower_Initialize = $899EE8
Sprite_BecomeFollower = $899F25
Ancilla_TerminateSelectInteractives = $89AC57
GiveRupeeGift = $89AD58
Sprite_SetSpawnedCoords = $89AE64
@@ -130,6 +138,7 @@ InitializeSaveFile = $8CDB3E
InitializeSaveFile_build_checksum = $8CDBC0
InitializeSaveFile_checksum_done = $8CDBDB
SpritePrep_LoadProperties = $8DB818
ResetSpriteProperties = $8DB871
GetRandomInt = $8DBA71
OAM_AllocateFromRegionA = $8DBA80
OAM_AllocateFromRegionB = $8DBA84
@@ -141,6 +150,7 @@ Sound_SetSfxPanWithPlayerCoords = $8DBB67
Sound_SetSfx1PanLong = $8DBB6E
Sound_SetSfx2PanLong = $8DBB7C
Sound_SetSfx3PanLong = $8DBB8A
SpriteDraw_Maiden = $8DCE4F
SpriteDraw_Stumpy = $8DD030
HUD_RefreshIconLong = $8DDB7F
Equipment_UpdateEquippedItemLong = $8DDD32
@@ -194,6 +204,7 @@ Sprite_BagOfPowder = $85F644
MagicShopAssistant_Main = $85F893
Sprite_SpawnSecret_SetCoords = $8682A5
Chicken_SpawnAvengerChicken = $86A7DB
Sprite_ScheduleForBreakage_exit = $86E273
Link_PerformRead = $87B4DB
Link_PerformOpenChest_no_replacement = $87B59F
Link_CheckNewAPress = $87B5A9
@@ -211,6 +222,8 @@ Ancilla29_MilestoneItemReceipt_skip_crystal_sfx = $88CAE5
Ancilla29_MilestoneItemReceipt_no_sparkle = $88CB2E
Ancilla_SetOAM_XY = $88F6F3
Ancilla_AddAncilla = $899CCE
WorldMap_CalculateOAMCoordinates_exit_successfully = $8AC51F
WorldMap_MultiplyAxB = $8AC57F
UpdateHUD = $8DDFA9
UpdateEquippedItem = $8DDFAF
DrawProgressIcons = $8DE9C8
@@ -234,6 +247,16 @@ CrystalMaiden_KickOutOfDungeon = $9ECF35
GoldBee_Dormant_exit = $9EDE89
GoldBee_SpawnSelf = $9EDE8A
;===================================================================================================
; Spliced routines (use JML directly since the hook left these methods)
;===================================================================================================
Sprite_4C_Geldman_do_indeed_draw = $85B8C0
Sprite_4C_Geldman_continue = $85B8C3
Sprite_91_StalfosKnight_continue = $9EAAB5
SpriteDraw_Blob_bad_gfx = $9EB20D
SpriteDraw_Blob_head_popping_out = $9EB24E
;===================================================================================================
; Palettes
;===================================================================================================
@@ -267,6 +290,7 @@ WorldMap_RedXChars = $8ABF70
WorldMap_CalculateOAMCoordinates = $8AC3B1
WorldMap_HandleSpriteBlink = $8AC52E
WorldMapIcon_AdjustCoordinate = $8AC59B
WorldMap_LightWorldTilemap = $8AC739
WorldMap_DarkWorldTilemap = $8AD739
DungeonMapBossRooms = $8AE817
DamageSubclassValue = $8DB8F1
@@ -279,4 +303,5 @@ Overworld_Entrance_ID = $9BBB73
SwordPaletteOffsets = $9BEBB4
ShieldPaletteOffsets = $9BEBC1
LinkMailPalettesOffsets = $9BEC06
Sprite_ReducedTileInteractionTable = $9DF6CF
RoomData_ObjectDataPointers = $9F8000

View File

@@ -1,12 +1,3 @@
;================================================================================
; Spawn Zelda (or not)
;--------------------------------------------------------------------------------
SpawnZelda:
LDA.l FollowerIndicator : CMP.b #$08 : BEQ + ; don't spawn if dwarf is present
CMP.b #$07 : BEQ + ; don't spawn if frog is present
CMP.b #$0C : BEQ + ; don't spawn if purple chest is present
CLC
+ RTL
;--------------------------------------------------------------------------------
EndRainState:
LDA.l InitProgressIndicator : BIT.b #$80 : BNE + ; check for instant post-aga