Files
alttpr-baserom/doorrando/normal.asm
aerinon 096157e981 Changes graphical status of standard exits when blocking exits in rain
Fixes graphical issues with sanctuary and swamp hub lobbies
Major fix for decoupled doors landing area
Fix for multiworld absorbables
2023-02-24 14:22:42 -07:00

442 lines
11 KiB
NASM

WarpLeft:
lda.l DRMode : beq .end
lda $040c : cmp.b #$ff : beq .end
lda $20 : ldx $aa
jsr CalcIndex
!add #$06 : ldy #$01 ; offsets in A, Y
jsr LoadRoomHorz
.end
jsr Cleanup
rtl
WarpRight:
lda.l DRMode : beq .end
lda $040c : cmp.b #$ff : beq .end
lda $20 : ldx $aa
jsr CalcIndex
!add #$12 : ldy #$ff ; offsets in A, Y
jsr LoadRoomHorz
.end
jsr Cleanup
rtl
WarpUp:
lda.l DRMode : beq .end
lda $040c : cmp.b #$ff : beq .end
lda $22 : ldx $a9
jsr CalcIndex
ldy #$02 ; offsets in A, Y
jsr LoadRoomVert
.end
jsr Cleanup
rtl
; Checks if $a0 is equal to <Room>. If it is, opens its stonewall if it's there
macro StonewallCheck(Room)
lda $a0 : cmp.b #<Room> : bne ?end
lda.l <Room>*2+$7ef000 : ora #$80 : sta.l <Room>*2+$7ef000
?end
endmacro
WarpDown:
lda.l DRMode : beq .end
lda $040c : cmp.b #$ff : beq .end
lda $22 : ldx $a9
jsr CalcIndex
!add #$0c : ldy #$ff ; offsets in A, Y
jsr LoadRoomVert
%StonewallCheck($43)
.end
jsr Cleanup
rtl
; carry set = use link door like normal
; carry clear = we are in dr mode, never use linking doors
CheckLinkDoorR:
lda.l DRMode : bne +
lda $7ec004 : sta $a0 ; what we wrote over
sec : rtl
+ clc : rtl
CheckLinkDoorL:
lda.l DRMode : bne +
lda $7ec003 : sta $a0 ; what we wrote over
sec : rtl
+ clc : rtl
TrapDoorFixer:
lda $fe : and #$0038 : beq .end
xba : asl #2 : sta $00
stz $0468 : lda $068c : ora $00 : sta $068c
.end
stz $fe ; clear our fe here because we don't need it anymore
rts
Cleanup:
lda.l DRFlags : and #$10 : beq +
stz $047a
+ inc $11
lda $ef
rts
;A needs be to the low coordinate, x needs to be either 0 for left,upper or non-zero for right,down
; This sets A (00,02,04) and stores half that at $04 for later use, (src door)
CalcIndex: ; A->low byte of Link's Coord, X-> Link's quadrant, DoorOffset x 2 -> A, DoorOffset -> $04 (vert/horz agnostic)
cpx.b #00 : bne .largeDoor
cmp.b #$d0 : bcc .smallDoor
lda #$01 : bra .done ; Middle Door
.smallDoor lda #$00 : bra .done
.largeDoor lda #$02
.done
sta $04
asl
rts
; Y is an adjustment for main direction of travel
; A is a door table row offset
LoadRoomHorz:
{
phb : phk : plb
sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack
lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00-$01
lda $00 : cmp #$03 : bne .gtg
jsr HorzEdge : pla : bcs .end
sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
.gtg ;Good to Go!
pla ; Throw away normal room (don't fill up the stack)
lda $a0 : and.b #$0F : asl a : !sub $23 : !add $06 : sta $02
ldy #$00 : jsr ShiftVariablesMainDir
lda $01 : and #$80 : beq .normal
ldy $06 : cpy #$ff : beq +
lda $01 : jsr LoadEastMidpoint : bra ++
+ lda $01 : jsr LoadWestMidpoint
++ jsr PrepScrollToEdge : bra .scroll
.normal
jsr PrepScrollToNormal
.scroll
lda $01 : and #$40 : pha
jsr ScrollY
pla : beq .end
ldy #$06 : jsr ApplyScroll
.end
plb ; restore db register
rts
}
; Y is an adjustment for main direction of travel (stored at $06)
; A is a door table row offset (stored a $07)
LoadRoomVert:
{
phb : phk : plb
sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack
lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00-$01
lda $00 : cmp #$03 : bne .gtg
jsr VertEdge : pla : bcs .end
sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
.gtg ;Good to Go!
pla ; Throw away normal room (don't fill up the stack)
lda $a0 : and.b #$F0 : lsr #3 : !sub $21 : !add $06 : sta $02
lda $01 : and #$80 : beq .notEdge
ldy #$01 : jsr ShiftVariablesMainDir
ldy $06 : cpy #$ff : beq +
lda $01 : jsr LoadSouthMidpoint : bra ++
+ lda $01 : jsr LoadNorthMidpoint
++ jsr PrepScrollToEdge : bra .scroll
.notEdge
lda $01 : and #$03 : cmp #$03 : bne .normal
jsr ScrollToInroomStairs
stz $046d
bra .end
.normal
ldy #$01 : jsr ShiftVariablesMainDir
jsr PrepScrollToNormal
.scroll
lda $01 : and #$40 : sta $046d
jsr ScrollX
.end
plb ; restore db register
rts
}
LookupNewRoom: ; expects data offset to be in A
{
rep #$30 : and #$00FF ;sanitize A reg (who knows what is in the high byte)
sta $00 ; offset in 00
lda $a2 : tax ; probably okay loading $a3 in the high byte
lda.w DoorOffset,x : and #$00FF ;we only want the low byte
asl #3 : sta $02 : !add $02 : !add $02 ;multiply by 24 (data size)
!add $00 ; should now have the offset of the address I want to load
tax : lda.w DoorTable,x : sta $00
and #$00FF : sta $a0 ; assign new room
sep #$30
rts
}
; INPUTS-- Y: Direction Index , $02: Shift Value
; Sets high bytes of various registers
ShiftVariablesMainDir:
{
lda.w CoordIndex,y : tax
lda $21,x : !add $02 : sta $21,x ; coordinate update
lda.w CameraIndex,y : tax
lda $e3,x : !add $02 : sta $e3,x ; scroll register high byte
lda.w CamQuadIndex,y : tax
lda $0605,x : !add $02 : sta $0605,x ; high bytes of these guys
lda $0607,x : !add $02 : sta $0607,x
lda $0601,x : !add $02 : sta $0601,x
lda $0603,x : !add $02 : sta $0603,x
rts
}
; Normal Flags should be in $01
ScrollToInroomStairs:
{
jsr PrepScrollToInroomStairs
ldy #$01 : jsr ShiftVariablesMainDir
jsr ScrollX
ldy #$00 : jsr ApplyScroll
lda $a0 : and #$0f : cmp #$0f : bne +
stz $e0 : stz $e2 ; special case camera fix
lda #$1f : sta $e1 : sta $e3
+
rts
}
; Direction should be in $06, Shift Value (see above) in $02 and other info in $01
; Sets $02, $04, $05, $ee, $045e, $045f and things related to Y coordinate
PrepScrollToInroomStairs:
{
lda $01 : and #$30 : lsr #3 : tay
lda.w InroomStairsX,y : sta $04
lda.w InroomStairsX+1,y : sta $05
lda $06 : cmp #$ff : beq .south
lda.w InroomStairsY+1,y : bne +
inc $045f ; flag indicating special screen transition
dec $02 ; shift variables further
stz $aa
lda $a8 : and #%11111101 : sta $a8
stz $0613 ; North scroll target
inc $0603 : inc $0607
dec $0619 : dec $061b
+
lda.w InroomStairsY,y : !add #$20 : sta $20
!sub #$38 : sta $045e
lda $01 : and #$40 : beq +
lda $20 : !add #$20 : sta $20
stz $045f
+
dec $21
%StonewallCheck($1b)
bra ++
.south
lda.w InroomStairsY+1,y : beq +
inc $045f ; flag indicating special screen transition
inc $02 ; shift variables further
lda #$02 : sta $aa
lda $a8 : ora #%00000010 : sta $a8
inc $0611 ; South scroll target
dec $0603 : dec $0607
inc $0619 : inc $061b
+
lda.w InroomStairsY,y : !sub #$20 : sta $20
!add #$38 : sta $045e
lda $01 : and #$40 : beq +
lda $20 : !sub #$20 : sta $20
stz $045f
+
inc $21
++
lda $01 : and #$04 : lsr #2 : sta $ee : bne +
stz $0476
+ rts
}
; Target pixel should be in A, other info in $01
; Sets $04 $05 and $ee
PrepScrollToEdge:
{
sta $04 : lda $01 : and #$20 : beq +
lda #01
+ sta $05
lda $01 : and #$10 : beq +
lda #01
+ sta $ee : bne +
stz $0476
+ rts
}
; Normal Flags should be in $01
; Sets $04 $05 and $ee, and $fe
PrepScrollToNormal:
{
lda $01 : sta $fe : and #$04 : lsr #2 : sta $ee ; trap door and layer
bne +
stz $0476
+ stz $05 : lda #$78 : sta $04
lda $01 : and #$03 : beq .end
cmp #$02 : !bge +
lda #$f8 : sta $04 : bra .end
+ inc $05
.end rts
}
StraightStairsAdj:
{
stx $0464 : sty $012e ; what we wrote over
lda.l DRMode : beq +
lda $045e : bne .toInroom
lda $046d : beq .noScroll
sta $22
ldy #$00 : jsr ApplyScroll
stz $046d
.noScroll
jsr GetTileAttribute : tax
lda $11 : cmp #$12 : beq .goingNorth
lda $a2 : cmp #$51 : bne ++
rep #$20 : lda #$0018 : !add $20 : sta $20 : sep #$20 ; special fix for throne room
jsr GetTileAttribute : tax
++ lda.l StepAdjustmentDown, X : bra .end
; lda $ee : beq .end
; rep #$20 : lda #$ffe0 : !add $20 : sta $20 : sep #$20
.goingNorth
cpx #$00 : bne ++
lda $a0 : cmp #$51 : bne ++
lda #$36 : bra .end ; special fix for throne room
++ ldy $ee : cpy #$00 : beq ++
inx
++ lda.l StepAdjustmentUp, X
.end
pha : lda $0462 : and #$04 : bne ++
pla : !add #$f6 : pha
++ pla : !add $0464 : sta $0464
+ rtl
.toInroom
lda #$32 : sta $0464 : stz $045e
rtl
}
GetTileAttribute:
{
phk : pea.w .jslrtsreturn-1
pea.w $02802c
jml CalculateTransitionLanding ; mucks with x/y sets a to Tile Attribute, I think
.jslrtsreturn
rts
}
; 0 open edge
; 1 nrm door high
; 2 straight str
; 3 nrm door low
; 4 trap door high
; 5 trap door low (none of these exist on North direction)
StepAdjustmentUp: ; really North Stairs
db $00, $f6, $1a, $18, $16, $38
StepAdjustmentDown: ; really South Stairs
db $d0, $f6, $10, $1a, $f0, $00
StraightStairsFix:
{
pha
lda.l DRMode : bne +
pla : !add $20 : sta $20 : rtl ;what we wrote over
+ pla : rtl
}
StraightStairLayerFix:
{
lda.l DRMode : beq +
lda $ee : rtl
+ lda $01c322, x : rtl ; what we wrote over
}
DoorToStraight:
{
pha
lda.l DRMode : beq .skip
pla : bne .end
pha
lda $a0 : cmp #$51 : bne .skip
lda #$04 : sta $4e
.skip pla
; the ldx $0418 is now taken care of by TransitionCalculateLanding_Fix
.end cmp #$02 ;what we wrote over
rtl
}
DoorToInroom:
{
ldx $045e : bne .end
sta $0020, y ; what we wrote over
.end
ldx #$00 ; what we wrote over
rtl
}
DoorToInroomEnd:
{
ldy $045e : beq .vanilla
cmp $045e : bne .return
stz $045e ; clear
.return
rtl
.vanilla
cmp $02c034, x ; what we wrote over
rtl
}
StraightStairsTrapDoor:
{
lda $0464 : bne +
; reset function
.reset phk : pea.w .jslrtsreturn-1
pea.w $02802c
jml $028c73 ; $10D71 .reset label of Bank02
.jslrtsreturn
lda $0468 : bne ++
lda $a0 : cmp.b #$ac : bne .animateTraps
lda $0403 : and.b #$20 : bne .animateTraps
lda $0403 : and.b #$10 : beq ++
.animateTraps
lda #$05 : sta $11
inc $0468 : stz $068e : stz $0690
++ JSL Underworld_DoorDown_Call : rtl
+ JML Dungeon_ApproachFixedColor ; what we wrote over
}
InroomStairsTrapDoor:
{
lda $0200 : cmp #$05 : beq .reset
lda $b0 : jml $008781 ; what we wrote over (essentially)
.reset
pla : pla : pla
jsl StraightStairsTrapDoor_reset
jml $028b15 ; just some RTS in bank 02
}
HandleSpecialDoorLanding: {
LDA.l $7F2000,X ; what we wrote over
SEP #$30
; A = tiletype
HandleIncomingDoorState:
PHA
LDA.l DRMode : BEQ .noDoor
PLA : PHA : AND.b #$FA : CMP.b #$80 : bne .noDoor
.setDoorState
LDA.w $0418 : AND.b #$02 : BNE + : INC
+ STA.b $6C
.noDoor
PLA
CMP #$34 : bne + ; inroom stairs
PHA : LDA #$26 : STA $045E : PLA
+
RTL
}