diff --git a/LTTP_RND_GeneralBugfixes.asm b/LTTP_RND_GeneralBugfixes.asm index 7f80e37..6da526e 100644 --- a/LTTP_RND_GeneralBugfixes.asm +++ b/LTTP_RND_GeneralBugfixes.asm @@ -74,6 +74,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 diff --git a/boots.asm b/boots.asm index b92a873..4ffa676 100644 --- a/boots.asm +++ b/boots.asm @@ -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 diff --git a/bossicons.asm b/bossicons.asm index b4530cc..9e7e29a 100644 --- a/bossicons.asm +++ b/bossicons.asm @@ -17,15 +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 - if !FEATURE_FIX_BASEROM - LDA.w #$0089 - else - LDA.w #$0028 ; set the bank to 28 for now - endif - STA.b Scrap02 + LDA.w #bank(UWSpritesData) : STA.b Scrap02 LDY.w #$0001 ; to skip the "sort" ; get first byte to make sure it isn't an empty room diff --git a/bugfixes.asm b/bugfixes.asm index 687351e..85f3cbc 100644 --- a/bugfixes.asm +++ b/bugfixes.asm @@ -238,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 diff --git a/doorrando/hudadditions.asm b/doorrando/hudadditions.asm index bc5638e..73cf87f 100644 --- a/doorrando/hudadditions.asm +++ b/doorrando/hudadditions.asm @@ -167,9 +167,7 @@ DrHudDungeonItemsAdditions: jsr ConvertToDisplay2 : sta.w $1644, y + iny #2 : lda.w #$24f5 : sta.w $1644, y phx : ldx.b Scrap00 - LDA.l CompassMode : BIT.w #$0002 : BNE .skip_map_check - LDA.l MapField : AND.l DungeonMask, x : BEQ .key_info_done ; must have map - .skip_map_check + 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 diff --git a/follower.asm b/follower.asm index b1386cc..b33ada0 100644 --- a/follower.asm +++ b/follower.asm @@ -23,7 +23,7 @@ JSL SpritePrep_OldManFollower : NOP #2 : db $F0 ; BEQ org $9DFF18 JSL SpriteDraw_OldManFollower org $9EE9BC -JSL Follower_CheckMessageCollision +JSL OldMan_WaitForCollision org $9EE9CC JSL OldMan_BecomeFollower : NOP #2 @@ -631,6 +631,15 @@ SpriteDraw_OldManFollower: 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 diff --git a/gk/check_loot.asm b/gk/check_loot.asm index 9fd599b..54f8d19 100644 --- a/gk/check_loot.asm +++ b/gk/check_loot.asm @@ -368,7 +368,13 @@ CheckEnemies: ASL A TAX - LDA.l UWSpritesPointers, X + + ; get sprite pointer table + LDA.l $89C298 : STA.b $04 + LDA.w #$0089 : STA.b $06 + TXY + ; get sprite pointer for room + LDA.b [$04], Y INC A ; skip the layered/unlayered indicator STA.b $04 LDA.w #bank(UWSpritesData) diff --git a/hooks.asm b/hooks.asm index c380407..82ab111 100755 --- a/hooks.asm +++ b/hooks.asm @@ -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 @@ -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 ;-------------------------------------------------------------------------------- diff --git a/keydrop/standing_items.asm b/keydrop/standing_items.asm index aa3c160..f06ac28 100644 --- a/keydrop/standing_items.asm +++ b/keydrop/standing_items.asm @@ -89,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 if !FEATURE_FIX_BASEROM org $81DB67 diff --git a/menu/overworldmap.asm b/menu/overworldmap.asm index 9ac349d..187b924 100644 --- a/menu/overworldmap.asm +++ b/menu/overworldmap.asm @@ -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: diff --git a/newitems.asm b/newitems.asm index b04478f..e7c44ab 100755 --- a/newitems.asm +++ b/newitems.asm @@ -1190,7 +1190,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 @@ -1212,7 +1212,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 + LDA.l MapHUDMode : AND.w #$000F : BEQ .done LDX.w DungeonID JSR FlagMapCount .done diff --git a/owrando.asm b/owrando.asm index 57a29ea..9162b56 100644 --- a/owrando.asm +++ b/owrando.asm @@ -6,18 +6,18 @@ OWFlags: dw 0 OWReserved: dw 0 +OWFog: +db 0 ; 0: disabled - 1: fog clears after visiting either world version of a screen - 2: fog clears after visiting the current world version of a screen org $aa8010 OWVersionInfo: dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000 ;Hooks -org $82a929 -OWDetectTransitionReturn: +org $82a92C +JSL OWDetectEdgeTransition ; JSL Link_CheckForEdgeScreenTransition -org $82a939 -OverworldHandleTransitions_SpecialTrigger: -JSL OWDetectEdgeTransition -BCS OWDetectTransitionReturn +org $82a936 +OverworldHandleTransitions_PerformEdgeTransition: org $82a999 jsl OWEdgeTransition : nop #4 ;LDA $02A4E3,X : ORA $7EF3CA @@ -106,20 +106,34 @@ jsl OWOldManSpeed org $8aba6c ; < ? - Bank0a.asm:474 () jsl OWMapWorldCheck16 : nop -; Mixed Overworld Map +; Custom Overworld Map org $8ABA99 WorldMap_LoadDarkWorldMap: LDA.b GameMode : CMP.b #$14 ; attract module BEQ .vanilla_light - LDA.l OWMode+1 : AND.b #!FLAG_OW_MIXED : BNE .mixed + LDA.l OWFlags : AND.b #!FLAG_OW_CUSTOM_MAP : BNE .custom LDA.b OverworldIndex : AND.b #$40 BEQ .vanilla_light - .mixed - PHB : PHK : PLB - JSL LoadMapDarkOrMixed - PLB + .custom + STZ.b ScrapBuffer72 ; clear tile swap flag + JSL LoadMapDarkOrCustom_long + NOP #2 +warnpc $8ABAB5 .vanilla_light ; $0ABAB5 +org $8ABB32 +JSL LoadMapOppositeWorld + +org $8ABF78 +JSL WorldMap_SkipHandleSprites + +org $8ABA22 +JSL MoveLinkMapSprite + +org $8ABFF0 +JSL MoveMirrorPortalMapSprite +; Could insert similar hooks at $8AB860 and $8AB8AC for flute spots + ;(replacing -> LDA $8A : AND.b #$40) org $80d8c4 ; < ? - Bank00.asm:4068 () jsl OWWorldCheck @@ -227,6 +241,7 @@ OWMapWorldCheck16: { lda.b GameMode : cmp.w #$0014 : beq .return ; attract module, return with Z flag cleared jsl OWWorldCheck16 + eor.b ScrapBuffer72 ; apply tile swap flag .return rtl } @@ -387,51 +402,110 @@ OWMarkVisited: RTL } -LoadMapDarkOrMixed: +LoadMapDarkOrCustom: { - CMP.b #!FLAG_OW_MIXED : REP #$30 : BEQ .mixed + CMP.b #!FLAG_OW_CUSTOM_MAP : REP #$30 : BEQ .custom LDX.w #$03FE ; draw vanilla Dark World (what we wrote over) .copy_next LDA.w WorldMap_DarkWorldTilemap,X : STA.w GFXStripes,X DEX : DEX : BPL .copy_next BRL .end - .mixed + .custom LDX.b OverworldIndex LDA.l OWTileWorldAssoc,X - STA.b Scrap00 - LDY.w #$139C - LDX.w #$003F - .next_screen - PHX - LDA.l OWTileWorldAssoc,X - EOR.b Scrap00 AND.w #$0040 - BEQ .light - TYX : BRA .copy_screen - .light - TXA : AND.w #$0024 : LSR : TAX - TYA : SEC : SBC.l LWQuadrantOffsets,X - TYX : TAY - .copy_screen ; more efficient to have X on the right side - LDA.w $C739+$00,Y : STA.b $00,X - LDA.w $C739+$02,Y : STA.b $02,X - LDA.w $C739+$20,Y : STA.b $20,X - LDA.w $C739+$22,Y : STA.b $22,X - LDA.w $C739+$40,Y : STA.b $40,X - LDA.w $C739+$42,Y : STA.b $42,X - LDA.w $C739+$60,Y : STA.b $60,X - LDA.w $C739+$62,Y : STA.b $62,X - TXY : PLX - DEY : DEY : DEY : DEY ; move one screen left - TXA : AND.w #$0007 : BNE .same_row - TYA : SEC : SBC.w #$0060 : TAY ; move one screen row up + EOR.b ScrapBuffer72 ; apply tile swap flag + BEQ .draw_lw + LDA.w #OWMapGridDark + BRA .draw_dw + .draw_lw + LDA.w #OWMapGridLight + .draw_dw + STA.b Scrap00 + LDA.w #OWMapGridLight>>16 ; current program bank + STA.b Scrap02 + LDX.w #$139C + LDY.w #$003F + .next_cell + PHY + JSR GetOWMapTilemapOffsetToCopy + .copy_cell ; more efficient to have X on the right side + TAY + LDA.w WorldMap_LightWorldTilemap+$00,Y : STA.b $00,X + LDA.w WorldMap_LightWorldTilemap+$02,Y : STA.b $02,X + LDA.w WorldMap_LightWorldTilemap+$20,Y : STA.b $20,X + LDA.w WorldMap_LightWorldTilemap+$22,Y : STA.b $22,X + LDA.w WorldMap_LightWorldTilemap+$40,Y : STA.b $40,X + LDA.w WorldMap_LightWorldTilemap+$42,Y : STA.b $42,X + LDA.w WorldMap_LightWorldTilemap+$60,Y : STA.b $60,X + LDA.w WorldMap_LightWorldTilemap+$62,Y : STA.b $62,X + PLY + DEX : DEX : DEX : DEX ; move one screen left + TYA : AND.w #$0007 : BNE .same_row + TXA : SEC : SBC.w #$0060 : TAX ; move one screen row up .same_row - DEX - BPL .next_screen + DEY + BPL .next_cell .end SEP #$30 LDA.b #$15 : STA.b NMIINCR ; what we wrote over - RTL + RTS +} + +GetOWMapTilemapOffsetToCopy: +{ + LDA.l OWFog : AND.w #$00FF + CMP.w #$0001 : BEQ .parallel_fog + CMP.w #$0002 : BNE .no_fog + + LDA.b [Scrap00],Y : AND.w #$00FF + PHX + TAX + BIT.w #$0040 + BEQ .light_fog + LDA.l Overworld_ActualScreenID-$40,X : ORA.w #$0040 + BRA .dark_fog + .light_fog + LDA.l Overworld_ActualScreenID,X + .dark_fog + AND.w #$00FF + TAX + LDA.l OverworldEventDataWRAM,X + .check_visited_flag + PLX + AND.w #$0080 : BNE .no_fog + LDA.w #($D350-$C739) + RTS + + .parallel_fog + LDA.b [Scrap00],Y : AND.w #$003F + PHX + TAX + LDA.l Overworld_ActualScreenID,X + AND.w #$00FF + TAX + LDA.l OverworldEventDataWRAM,X + ORA.l OverworldEventDataWRAM+$40,X + BRA .check_visited_flag + + .no_fog + LDA.b [Scrap00],Y : AND.w #$0038 : ASL : ASL : ASL : ASL + STA.b Scrap03 + LDA.b [Scrap00],Y + BIT.w #$0040 + BEQ .light + AND.w #$0007 + ASL : ASL : ADC.w #$1000 : ADC.b Scrap03 + RTS + .light + PHX + AND.w #$0024 : LSR : TAX + LDA.b [Scrap00],Y + AND.w #$0007 + ASL : ASL : ADC.w #$1000 : ADC.b Scrap03 + SEC : SBC.l LWQuadrantOffsets,X + PLX + RTS LWQuadrantOffsets: dw $1000-$0210 ; top left @@ -441,6 +515,91 @@ LoadMapDarkOrMixed: dw $0400+$0210 ; bottom right } +LoadMapDarkOrCustom_long: +{ + PHB : LDA.b #WorldMap_DarkWorldTilemap>>16 : PHA : PLB + LDA.l OWFlags : AND.b #!FLAG_OW_CUSTOM_MAP + JSR LoadMapDarkOrCustom + PLB + RTL +} +LoadMapOppositeWorld: +{ + LDA.l OWFlags : AND.b #!FLAG_OW_ADJUST_DYNAMIC_MAP_SPRITE_POSITION : BEQ .vanilla + LDA.b ScrapBuffer72 : BEQ + + LDA.b Joy1B_All : AND.b #$30 : BNE .vanilla + STZ.b ScrapBuffer72 ; clear tile swap flag + BRA .new_tiles + + LDA.b Joy1B_New : AND.b #$30 : BEQ .vanilla + LDA.b #$40 : STA.b ScrapBuffer72 ; set tile swap flag +.new_tiles + JSL OverworldMap_InitGfx+$10 ; load palette + DEC.w SubModuleInterface + LDA.b #$0F : STA.b INIDISPQ + JSL LoadMapDarkOrCustom_long + LDA.b #$24 : STA.w SFX3 + PLA : PLA : PEA.w $BBAF ; skip everything upon return +.vanilla + LDA.b Joy1B_New : AND.b #$70 ; what we wrote over + RTL +} +WorldMap_SkipHandleSprites: +{ + LDA.l OWFlags : AND.b #!FLAG_OW_ADJUST_DYNAMIC_MAP_SPRITE_POSITION : BEQ .vanilla + LDA.b ScrapBuffer72 : BEQ .vanilla ; skip draw if no tile swap + PLA : PLA : PEA.w $C3AF ; exit without drawing sprites + RTL +.vanilla + LDA.b FrameCounter : AND.b #$10 ; what we wrote over + RTL +} + +MoveLinkMapSprite: +{ + STA.l $7EC10A ; what we overwrote + SEP #$20 + JSR MoveMapSprite + REP #$20 + RTL +} + +MoveMirrorPortalMapSprite: +{ + STA.l $7EC109 ; what we overwrote + JSR MoveMapSprite + RTL +} + +MoveMapSprite: +{ + LDA.l OWFlags : AND.b #!FLAG_OW_ADJUST_DYNAMIC_MAP_SPRITE_POSITION : BEQ .return + LDA.l $7EC10B : AND.b #$0E : LSR + STA.b Scrap00 + LDA.l $7EC109 : AND.b #$0E : ASL : ASL + ADC.b Scrap00 + STA.b Scrap00 + LDX.b OverworldIndex + LDA.l OWTileWorldAssoc,X + LDX.b Scrap00 + AND.b #$40 + BEQ .light + LDA.l OWMapGridDarkPositionByAbsolutePosition,X + BRA .dark + .light + LDA.l OWMapGridLightPositionByAbsolutePosition,X + .dark + TAX + AND.b #$07 : ASL + STA.b Scrap00 + LDA.l $7EC10B : AND.b #$01 : ORA.b Scrap00 : STA.l $7EC10B + TXA + AND.b #$38 : LSR : LSR + STA.b Scrap00 + LDA.l $7EC109 : AND.b #$01 : ORA.b Scrap00 : STA.l $7EC109 + .return + RTS +} + OWBonkDropPrepSprite: { LDA.b IndoorsFlag : BEQ + @@ -609,27 +768,26 @@ OWBonkDrops: JSL OWBonkSpritePrep .mark_collected ; S = Collected, FlagBitmask, X (row + 2) - PLA : BNE + ; S = FlagBitmask, X (row + 2) - TYX : JSL Sprite_IsOnscreen : BCC + - LDA.b IndoorsFlag : BEQ ++ + PLA : BEQ + : - : JMP .return : + ; S = FlagBitmask, X (row + 2) + TYX : JSL Sprite_IsOnscreen : BCC - + LDA.b IndoorsFlag : BEQ + LDA.l RoomDataWRAM[$0120].high : ORA.b 1,S : STA.l RoomDataWRAM[$0120].high LDA.w $0400 : ORA.b 1,S : STA.w $0400 BRA .increment_collection - ++ + + LDA.b OverworldIndex BIT.b #$40 : BEQ + LDA.l ProgressIndicator : CMP.b #$02 - LDA.b OverworldIndex : BCS ++ : AND.b #$BF - ++ + LDA.b OverworldIndex : BCS + : AND.b #$BF + TAX : LDA.l OverworldEventDataWRAM,X : ORA.b 1,S : STA.l OverworldEventDataWRAM,X .increment_collection REP #$20 LDA.l TotalItemCounter : INC : STA.l TotalItemCounter - INC.w UpdateHUDFlag SEP #$20 - + BRA .return + LDA.b #$01 : STA.l UpdateHUDFlag + BRA .return ; spawn itemget item .spawn_item ; A = item id ; Y = bonk sprite slot ; S = Collected, FlagBitmask, X (row + 2) @@ -738,20 +896,29 @@ OWBonkSpritePrep: org $aa9000 OWDetectEdgeTransition: { - JSL OWDestroyItemSprites + JSL Link_CheckForEdgeScreenTransition ; what we wrote over + BCS .return STZ.w RandoOverworldWalkDist LDA.l OWMode : ORA.l OWMode+1 : BEQ .vanilla + PHY JSR OWShuffle - LDA.w RandoOverworldTargetEdge : BMI .special + PLY + LDA.w RandoOverworldTargetEdge : BMI .specialOrDisabled .vanilla - REP #$31 : LDX.b Scrap02 : LDA.b OverworldMap16Buffer ; what we wrote over + CLC ; allow transition RTL + .specialOrDisabled + CMP.b #$FF : BNE .special + STZ.w RandoOverworldTargetEdge + PHB + JML Link_CheckForEdgeScreenTransition_prevent_transition .special REP #$30 AND.w #$0003 : TAY : ASL : TAX LDA.w #$007F : STA.w RandoOverworldTargetEdge JSR OWLoadSpecialArea SEC + .return RTL } OWDetectSpecialTransition: @@ -761,17 +928,23 @@ OWDetectSpecialTransition: TXA : AND.w #$0002 : LSR STA.w RandoOverworldTerrain LDA.l OWSpecialDestIndex,X : BIT.w #$0080 : BEQ .switch_to_edge + AND.w #$00FF : CMP.w #$00FF : BEQ .disabled AND.w #$0003 : TAY : ASL : TAX .normal JSR OWLoadSpecialArea .return RTL + .disabled + SEP #$30 + STZ.w RandoOverworldTargetEdge + RTL + .switch_to_edge STA.w RandoOverworldTargetEdge LDA.l OWEdgeDataOffset,X : STA.w RandoOverworldEdgeAddr PLA : SEP #$30 : PLA ; delete 3 bytes from stack - JSL Link_CheckForEdgeScreenTransition : BCS .return ; Link_CheckForEdgeScreenTransition + JSL Link_CheckForEdgeScreenTransition : BCS .return LDA.l Overworld_CheckForSpecialOverworldTrigger_Direction,X : STA.b Scrap00 : CMP.b #$08 : BNE .hobo LSR : STA.b LinkPosY : STZ.b BG2V ; move Link and camera to edge LDA.b #$06 : STA.b Scrap02 @@ -790,16 +963,15 @@ OWDetectSpecialTransition: LDA.b #$FF : STA.b LinkRecoilZ : STA.b $C7 STZ.b $3D : STZ.b LinkSpeed : STZ.w $032B : STZ.w LinkDashing : STZ.b LinkState .not_dashing - PLA : REP #$31 : PLA ; delete 3 bytes from stack - LDX.b Scrap02 - LDA.b OverworldMap16Buffer - JML OverworldHandleTransitions_SpecialTrigger+6 + PLA : PLA : PLA ; delete 3 bytes from stack + JML OverworldHandleTransitions_PerformEdgeTransition } OWEdgeTransition: { LDA.l OWMode : ORA.l OWMode+1 : BEQ .unshuffled LDY.w RandoOverworldTargetEdge : STZ.w RandoOverworldTargetEdge CPY.b #$7F : BEQ .unshuffled + JSL OWDestroyItemSprites REP #$10 LDX.w RandoOverworldEdgeAddr PHB : PHK : PLB @@ -1488,7 +1660,7 @@ dw $0b28, $0b38, $0010, $0b30, $1515, $1018, $0001, $000e dw $0b70, $0ba0, $0030, $0b88, $1515, $1020, $0000, $000f dw $0a40, $0b10, $00d0, $0aa8, $1d1d, $1006, $0000, $0010 dw $0350, $0390, $0040, $0370, $1821, $2060, $0000, $0011 -dw $0670, $06a8, $0038, $068c, $1b23, $2002, $0000, $0012 +dw $0670, $06a8, $0038, $068c, $1b23, $2004, $0000, $0012 dw $0898, $09b0, $0118, $0924, $1b24, $2054, $0000, $0013 dw $0a40, $0ba0, $0160, $0af0, $2525, $100e, $0000, $0014 dw $0c70, $0c90, $0020, $0c80, $1e26, $2002, $0000, $0015 @@ -1520,7 +1692,7 @@ dw $0b28, $0b38, $0010, $0b30, $5555, $1018, $0001, $002e dw $0b70, $0ba0, $0030, $0b88, $5555, $1020, $0000, $002f dw $0a40, $0b10, $00d0, $0aa8, $5d5d, $1006, $0000, $0030 dw $0350, $0390, $0040, $0370, $5861, $2060, $0000, $0031 -dw $0670, $06a8, $0038, $068c, $5b63, $2002, $0000, $0032 +dw $0670, $06a8, $0038, $068c, $5b63, $2004, $0000, $0032 dw $0898, $09b0, $0118, $0924, $5b64, $2054, $0000, $0033 dw $0a40, $0ba0, $0160, $0af0, $6565, $100e, $0000, $0034 dw $0c70, $0c90, $0020, $0c80, $5e66, $2002, $0000, $0035 @@ -1827,16 +1999,42 @@ db $74, $4e, $10, $b1, $00, $1c UWBonkPrizeData: db $ff, $00, $02, $b5, $00, $08 -; temporary fix - murahdahla replaces one of the bonk tree prizes -; so we copy the sprite table here and update the pointer -; longterm solution should be to spawn in murahdahla separately -org $89AE2A -Overworld_Sprites_Screen1A_2: -db $08, $0F, $41 ; yx:{ 0x080, 0x0F0 } -db $0E, $0C, $41 ; yx:{ 0x0E0, 0x0C0 } -db $11, $0D, $E3 ; yx:{ 0x110, 0x0D0 } -db $18, $0A, $D8 ; yx:{ 0x180, 0x0A0 } -db $18, $0F, $45 ; yx:{ 0x180, 0x0F0 } -db $FF ; END -org $89CA55 -dw Overworld_Sprites_Screen1A_2&$FFFF +org $AABC80 ;PC 153C80 +OWMapGridLight: +db $00, $01, $02, $03, $04, $05, $06, $07 +db $08, $09, $0A, $0B, $0C, $0D, $0E, $0F +db $10, $11, $12, $13, $14, $15, $16, $17 +db $18, $19, $1A, $1B, $1C, $1D, $1E, $1F +db $20, $21, $22, $23, $24, $25, $26, $27 +db $28, $29, $2A, $2B, $2C, $2D, $2E, $2F +db $30, $31, $32, $33, $34, $35, $36, $37 +db $38, $39, $3A, $3B, $3C, $3D, $3E, $3F +OWMapGridDark: +db $40, $41, $42, $43, $44, $45, $46, $47 +db $48, $49, $4A, $4B, $4C, $4D, $4E, $4F +db $50, $51, $52, $53, $54, $55, $56, $57 +db $58, $59, $5A, $5B, $5C, $5D, $5E, $5F +db $60, $61, $62, $63, $64, $65, $66, $67 +db $68, $69, $6A, $6B, $6C, $6D, $6E, $6F +db $70, $71, $72, $73, $74, $75, $76, $77 +db $78, $79, $7A, $7B, $7C, $7D, $7E, $7F + +org $AABD00 ;PC 153D00 +OWMapGridLightPositionByAbsolutePosition: +db $00, $01, $02, $03, $04, $05, $06, $07 +db $08, $09, $0A, $0B, $0C, $0D, $0E, $0F +db $10, $11, $12, $13, $14, $15, $16, $17 +db $18, $19, $1A, $1B, $1C, $1D, $1E, $1F +db $20, $21, $22, $23, $24, $25, $26, $27 +db $28, $29, $2A, $2B, $2C, $2D, $2E, $2F +db $30, $31, $32, $33, $34, $35, $36, $37 +db $38, $39, $3A, $3B, $3C, $3D, $3E, $3F +OWMapGridDarkPositionByAbsolutePosition: +db $00, $01, $02, $03, $04, $05, $06, $07 +db $08, $09, $0A, $0B, $0C, $0D, $0E, $0F +db $10, $11, $12, $13, $14, $15, $16, $17 +db $18, $19, $1A, $1B, $1C, $1D, $1E, $1F +db $20, $21, $22, $23, $24, $25, $26, $27 +db $28, $29, $2A, $2B, $2C, $2D, $2E, $2F +db $30, $31, $32, $33, $34, $35, $36, $37 +db $38, $39, $3A, $3B, $3C, $3D, $3E, $3F diff --git a/ram.asm b/ram.asm index 92da9a4..12b507e 100644 --- a/ram.asm +++ b/ram.asm @@ -235,6 +235,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. @@ -874,6 +876,8 @@ endmacro %assertRAM(UseY1, $7E0301) %assertRAM(CurrentYItem, $7E0303) %assertRAM(AButtonAct, $7E0308) +%assertRAM(CarryAct, $7E0309) +%assertRAM(LinkIFrames, $7E031F) %assertRAM(LinkSwimDirection, $7E0340) %assertRAM(LinkDeepWater, $7E0345) %assertRAM(TileActIce, $7E0348) diff --git a/vanillalabels.asm b/vanillalabels.asm index e91955e..b7c0c61 100644 --- a/vanillalabels.asm +++ b/vanillalabels.asm @@ -99,6 +99,7 @@ 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 @@ -221,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 @@ -295,6 +298,7 @@ WorldMap_RedXChars = $8ABF70 WorldMap_CalculateOAMCoordinates = $8AC3B1 WorldMap_HandleSpriteBlink = $8AC52E WorldMapIcon_AdjustCoordinate = $8AC59B +WorldMap_LightWorldTilemap = $8AC739 WorldMap_DarkWorldTilemap = $8AD739 DungeonMapRoomMarkerYBase = $8AE803 DungeonMapBossRooms = $8AE817