Merge branch 'DoorDev' into DoorShuffleStandardModeDev

This commit is contained in:
tolmar
2019-09-14 22:15:55 -07:00
9 changed files with 333 additions and 295 deletions

View File

@@ -837,6 +837,7 @@ class Door(object):
self.doorIndex = doorIndex
self.layer = layer # 0 for normal floor, 1 for the inset layer
self.toggle = toggle
self.trap = 0x0
self.quadrant = 2
self.shiftX = 78
self.shiftY = 78
@@ -859,8 +860,9 @@ class Door(object):
def getTarget(self, toggle):
if self.type == DoorType.Normal:
layer = 4 * (self.layer ^ 1 if toggle else self.layer)
return [self.roomIndex, layer + self.doorIndex]
bitmask = 4 * (self.layer ^ 1 if toggle else self.layer)
bitmask += 0x08 * int(self.trap)
return [self.roomIndex, bitmask + self.doorIndex]
if self.type == DoorType.SpiralStairs:
bitmask = int(self.layer) << 2
bitmask += 0x10 * int(self.zeroHzCam)

View File

@@ -11,7 +11,7 @@ Right = 2
# layer numbers
High = 0
Low = 1
#Quadrants - just been using this in my head - no reason to keep them labeled this way
# Quadrants - just been using this in my head - no reason to keep them labeled this way
A = 0
S = 1
Z = 2
@@ -23,7 +23,6 @@ LTH = 2 # Low to High 10
LTL = 3 # Low to Low 11
def create_doors(world, player):
world.doors += [
# hyrule castle
@@ -60,8 +59,8 @@ def create_doors(world, player):
create_dir_door(player, 'Hyrule Dungeon South Abyss Catwalk West Edge', DoorType.Open, Direction.West, 0x82, None, High),
create_dir_door(player, 'Hyrule Dungeon Guardroom Catwalk Edge', DoorType.Open, Direction.East, 0x81, None, High),
create_dir_door(player, 'Hyrule Dungeon Guardroom Abyss Edge', DoorType.Open, Direction.West, 0x81, None, High),
create_dir_door(player, 'Hyrule Dungeon Guardroom N', DoorType.Normal, Direction.North, 0x81, Left, Low), # todo: is this a toggle door?
create_dir_door(player, 'Hyrule Dungeon Armory S', DoorType.Normal, Direction.South, 0x71, Left, Low), # not sure what the layer should be here
create_dir_door(player, 'Hyrule Dungeon Guardroom N', DoorType.Normal, Direction.North, 0x81, Left, Low),
create_dir_door(player, 'Hyrule Dungeon Armory S', DoorType.Normal, Direction.South, 0x71, Left, Low),
create_small_key_door(player, 'Hyrule Dungeon Armory Interior Key Door N', DoorType.Interior, Direction.North, 0x71, Left, High),
create_small_key_door(player, 'Hyrule Dungeon Armory Interior Key Door S', DoorType.Interior, Direction.South, 0x71, Left, High),
create_spiral_stairs(player, 'Hyrule Dungeon Armory Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x71, 0, HTL, A, 0x11, 0xa8, True),
@@ -70,7 +69,7 @@ def create_doors(world, player):
create_spiral_stairs(player, 'Hyrule Dungeon Cellblock Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x80, 0, HTH, A, 0x1a, 0x44),
# sewers
create_blocked_door(player, 'Sewers Behind Tapestry S', DoorType.Normal, Direction.South, 0x41, Mid, High),
create_blocked_door(player, 'Sewers Behind Tapestry S', DoorType.Normal, Direction.South, 0x41, Mid, High, False, 0x2),
create_spiral_stairs(player, 'Sewers Behind Tapestry Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x41, 0, HTH, S, 0x12, 0xb0),
create_spiral_stairs(player, 'Sewers Rope Room Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x42, 0, HTH, S, 0x1b, 0x9c),
create_dir_door(player, 'Sewers Rope Room North Stairs', DoorType.StraightStairs, Direction.North, 0x42, Mid, High),
@@ -83,7 +82,7 @@ def create_doors(world, player):
create_small_key_door(player, 'Sewers Secret Room Key Door S', DoorType.Normal, Direction.South, 0x11, Right, High),
create_spiral_stairs(player, 'Sewers Secret Room Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x11, 0, LTH, S, 0x33, 0x6c, True),
create_spiral_stairs(player, 'Sewers Pull Switch Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x02, 0, HTL, S, 0x12, 0x80),
create_toggle_door(player, 'Sewers Pull Switch S', DoorType.Normal, Direction.South, 0x02, Mid, Low),
create_toggle_door(player, 'Sewers Pull Switch S', DoorType.Normal, Direction.South, 0x02, Mid, Low, 0x2),
# logically one way the sanc, but should be linked - also toggle
create_blocked_door(player, 'Sanctuary N', DoorType.Normal, Direction.North, 0x12, Mid, 0, True),
@@ -94,12 +93,12 @@ def create_doors(world, player):
create_dir_door(player, 'Eastern Cannonball Ledge WN', DoorType.Normal, Direction.West, 0xb9, Top, High),
create_small_key_door(player, 'Eastern Cannonball Ledge Key Door EN', DoorType.Normal, Direction.East, 0xb9, Top, High),
create_dir_door(player, 'Eastern Courtyard Ledge S', DoorType.Normal, Direction.South, 0xa9, Mid, High),
create_dir_door(player, 'Eastern Courtyard Ledge W', DoorType.Normal, Direction.West, 0xa9, Mid, High),
create_dir_door(player, 'Eastern Courtyard Ledge E', DoorType.Normal, Direction.East, 0xa9, Mid, High),
create_dir_door(player, 'Eastern Courtyard Ledge W', DoorType.Normal, Direction.West, 0xa9, Mid, High, 0x2),
create_dir_door(player, 'Eastern Courtyard Ledge E', DoorType.Normal, Direction.East, 0xa9, Mid, High, 0x1),
create_dir_door(player, 'Eastern Map Area W', DoorType.Normal, Direction.West, 0xaa, Mid, High),
create_dir_door(player, 'Eastern Compass Area E', DoorType.Normal, Direction.East, 0xa8, Mid, High),
create_dir_door(player, 'Eastern Compass Area EN', DoorType.Normal, Direction.East, 0xa8, Top, Low),
create_blocked_key_door(player, 'Eastern Compass Area SW', DoorType.Normal, Direction.South, 0xa8, Right, High),
create_blocked_door(player, 'Eastern Compass Area SW', DoorType.Normal, Direction.South, 0xa8, Right, High, False, True),
create_dir_door(player, 'Eastern Courtyard WN', DoorType.Normal, Direction.West, 0xa9, Top, Low),
create_dir_door(player, 'Eastern Courtyard EN', DoorType.Normal, Direction.East, 0xa9, Top, Low),
create_big_key_door(player, 'Eastern Courtyard N', DoorType.Normal, Direction.North, 0xa9, Mid, High),
@@ -141,29 +140,31 @@ def create_big_key_door(player, name, type, direction, room, doorIndex, layer):
return d
def create_blocked_door(player, name, type, direction, room, doorIndex, layer, toggle=False):
def create_blocked_door(player, name, type, direction, room, doorIndex, layer, toggle=False, key=False, trap=0x0):
d = Door(player, name, type, direction, room, doorIndex, layer, toggle)
d.blocked = True
d.smallKey = key
d.trap = trap
return d
def create_blocked_key_door(player, name, type, direction, room, doorIndex, layer, toggle=False):
d = Door(player, name, type, direction, room, doorIndex, layer, toggle)
d.blocked = True
d.smallKey = True
return d
def create_dir_door(player, name, type, direction, room, doorIndex, layer):
return Door(player, name, type, direction, room, doorIndex, layer)
def create_toggle_door(player, name, type, direction, room, doorIndex, layer):
return Door(player, name, type, direction, room, doorIndex, layer, True)
def create_spiral_stairs(player, name, type, direction, room, doorIndex, layer, quadrant, shiftY, shiftX, zeroHzCam = False, zeroVtCam = False):
def create_dir_door(player, name, type, direction, room, doorIndex, layer, trap=0x0):
d = Door(player, name, type, direction, room, doorIndex, layer)
d.quadrant = quadrant
d.shiftY = shiftY
d.shiftX = shiftX
d.zeroHzCam = zeroHzCam
d.zeroVtCam = zeroVtCam
d.trap = trap
return d
def create_toggle_door(player, name, type, direction, room, doorIndex, layer, trap=0x0):
d = Door(player, name, type, direction, room, doorIndex, layer, True)
d.trap = trap
return d
def create_spiral_stairs(player, name, type, direction, room,
door_index, layer, quadrant, shift_y, shift_x, zero_hz_cam=False, zero_vt_cam=False):
d = Door(player, name, type, direction, room, door_index, layer)
d.quadrant = quadrant
d.shiftY = shift_y
d.shiftX = shift_x
d.zeroHzCam = zero_hz_cam
d.zeroVtCam = zero_vt_cam
return d

2
Rom.py
View File

@@ -18,7 +18,7 @@ from EntranceShuffle import door_addresses
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'efb85e71cf7d9bc0401c6683992d6e2f'
RANDOMIZERBASEHASH = '05390999d13b1c365bafcc17d2870fec'
class JsonRom(object):

View File

@@ -139,7 +139,15 @@ A -> 0468
0468++
0 -> 0690
InterRoom:
pre
01b6b5 sta $0468 (01) in this case
01b7ce stz 468 x2
post
028acc inc $0468
028ad2 stz $0690
01d391 inc $0690 x 10 during animation
Other transition stuff
@@ -159,3 +167,9 @@ Places where sta $e2 happens
028750 Module_Dungeon
0286ef Module_Dungeon
Stuff about big key door south
1e -> Y
1aab1 ldx ce06,y (where y is 1e = ce24) loads 2a80, but should be 2ac8 for the gfx
not detected as big key door - need to look into tile attributes

View File

@@ -1,6 +1,12 @@
!add = "clc : adc"
!sub = "sec : sbc"
; Free RAM notes
; Normal doors use $0127 for scrolling indicator
; Normal doors use $AB to store the trap door indicator
; Spiral doors use $045e to store stair type
; Gfx uses $b1 to for sub-sub-sub-module thing
; Hooks into various routines
org $02b5c4 ; -- moving right routine 135c4
@@ -14,6 +20,8 @@ jsl WarpUp
org $02bd80
jsl AdjustTransition
nop
org $01b714
jsl TrapDoorFixer
;turn off linking doors -- see .notRoomLinkDoor label in Bank02.asm
org $02b5a6
@@ -34,13 +42,13 @@ jsl SpiralWarp
; Graphics fix
org $028961
org $02895d
Splicer:
jsl GfxFixer
lda $b1 : beq .done
rts
nop #5
.done
nop
org $00fda4
Dungeon_InitStarTileCh:
@@ -52,6 +60,8 @@ PrepTransAuxGfx:
;Dungeon_LoadCustomTileAttr:
;org $01fec1
;Dungeon_ApproachFixedColor_variable:
org $a0f432 ; Rando version -- needs to be after hooks and loadroom.asm I think?
Dungeon_LoadRoom_RANDO:
org $1bee74 ;(PC: 0dee74)
Palette_DungBgMain:
org $1bec77
@@ -61,257 +71,13 @@ Palette_SpriteAux2:
org $1bece4
Palette_SpriteAux1:
;Kill big key (1e) check for south doors - not that easy unfortunately
;org $1aa90
;nop #5
;Main Code
org $278000 ;138000
WarpLeft:
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 $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 $040c : cmp.b #$ff : beq .end
lda $22 : ldx $a9
jsr CalcIndex
ldy #$02 ; offsets in A, Y
jsr LoadRoomVert
.end
jsr Cleanup
rtl
WarpDown:
lda $040c : cmp.b #$ff : beq .end
lda $22 : ldx $a9
jsr CalcIndex
!add #$0c : ldy #$ff ; offsets in A, Y
jsr LoadRoomVert
.end
jsr Cleanup
rtl
Cleanup:
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 #$90 : 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
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
pla : 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 $aa : lsr : sta $07
lda $a0 : and.b #$F0 : lsr #3 : !add $07 : !sub $21 : sta $02 : sta $03
jsr ShiftLowCoord
jsr ShiftQuad
jsr ShiftCameraBounds
ldy #$01 : jsr ShiftVariablesSubDir ; flip direction
lda $01 : and.b #$04 : lsr #2
sta.b $EE
.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
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
pla : 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
ldy #$01 : jsr ShiftVariablesMainDir
lda $a0 : and.b #$0F : asl a : !add $a9 : !sub $23 : sta $02 : sta $03
jsr ShiftLowCoord
jsr ShiftQuad
jsr ShiftCameraBounds
ldy #$00 : jsr ShiftVariablesSubDir ; flip direction
lda $01 : and.b #$04 : lsr #2
sta.b $EE
.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 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 DoorTable,x : sta $00
and #$00FF : sta $a0 ; assign new room
sep #$30
rts
}
; INPUTS-- X: Direction Index , $02: Shift Value
; Sets high bytes of various registers
ShiftVariablesMainDir:
{
lda CoordIndex,y : tax
lda $21,x : !add $02 : sta $21,x ; coordinate update
lda CameraIndex,y : tax
lda $e3,x : !add $02 : sta $e3,x ; scroll register high byte
lda 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
}
ShiftLowCoord:
{
lda $01 : and.b #$03 ; high byte index
jsr CalcOpposingShift
lda $0127 : and.b #$f0 : cmp.b #$20 : bne .lowDone
lda OppCoordIndex,y : tax
lda #$80 : !add $20,x : sta $20,x
.lowDone
rts
}
; expects A to be (0,1,2) (dest number) and (0,1,2) (src door number) to be stored in $04
; $0127 will be set to a bitmask aaaa qxxf
; a - amount of adjust
; f - flag, if set, then amount is pos, otherwise neg.
; q - quadrant, if set, then quadrant needs to be modified
CalcOpposingShift:
{
stz $0127 ; set up (can you zero out 127 alone?)
cmp.b $04 : beq .noOffset ; (equal, no shifts to do)
phy : tay ; reserve these
lda $04 : tax : tya : !sub $04 : sta $04 : cmp.b #$00 : bpl .shiftPos
lda #$40
cpx.b #$01 : beq .skipNegQuad
ora #$08
.skipNegQuad
sta $0127 : lda $04 : cmp.b #$FE : beq .done ;already set $0127
lda $0127 : eor #$60
bra .setDone
.shiftPos
lda #$41
cpy.b #$01 : beq .skipPosQuad
ora #$08
.skipPosQuad
sta $0127 : lda $04 : cmp.b #$02 : bcs .done ;already set $0127
lda $0127 : eor #$60
.setDone sta $0127
.done ply
.noOffset rts
}
ShiftQuad:
{
lda $0127 : and #$08 : cmp.b #$00 : beq .quadDone
lda ShiftQuadIndex,y : tax ; X should be set to either 1 (vertical) or 2 (horizontal) (for a9,aa quadrant)
lda $0127 : and #$01 : cmp.b #$00 : beq .decQuad
inc $02
txa : sta $a8, x ; alter a9/aa
bra .quadDone
.decQuad
dec $02
lda #$00 : sta $a8, x ; alter a9/aa
.quadDone rts
}
ShiftVariablesSubDir:
{
lda CoordIndex,y : tax
lda $21,x : !add $02 : sta $21,x ; coordinate update
lda CameraIndex,y : tax
lda $e3,x : !add $03 : sta $e3,x ; scroll register high byte
lda CamQuadIndex,y : tax
lda $0601,x : !add $02 : sta $0601,x
lda $0605,x : !add $02 : sta $0605,x ; high bytes of these guys
lda $0603,x : !add $03 : sta $0603,x
lda $0607,x : !add $03 : sta $0607,x
rts
}
ShiftCameraBounds:
{
lda CamBoundIndex,y : tax ; should be 0 for horz travel (vert bounds) or 4 for vert travel (horz bounds)
rep #$30
lda $0127 : and #$00f0 : asl #2 : sta $06
lda $0127 : and #$0001 : cmp #$0000 : beq .subIt
lda $0618, x : !add $06 : sta $0618, x
lda $061A, x : !add $06 : sta $061A, x
sep #$30
rts
.subIt
lda $0618, x : !sub $06 : sta $0618, x
lda $061A, x : !sub $06 : sta $061A, x
sep #$30
rts
}
AdjustTransition:
{
lda $0127 : and #$00F0 : lsr
sep #$20 : cmp $0126 : bcc .reset
rep #$20
phy : ldy #$06 ; operating on vertical registers during horizontal trans
cpx.b #$02 : bcs .horizontalScrolling
ldy #$00 ; operate on horizontal regs during vert trans
.horizontalScrolling
lda $0127 : and #$0001 : asl : tax
lda.l OffsetTable,x : adc $00E2,y : and.w #$FFFE : sta $00E2,y : sta $00E0,y
ply : bra .done
.reset ; clear the 0127 variable so to not disturb intra-tile doors
stz $0127
.done
rep #$20 : lda $00 : and #$01fc
rtl
}
incsrc normal.asm
incsrc spiral.asm
incsrc gfx.asm
@@ -336,7 +102,7 @@ CamBoundIndex: ; Horizontal 1st
db 0, 4 ; Camera Bounds $0618-$61f
OppCamBoundIndex: ; Horizontal 1st
db 4, 0 ; Camera Bounds $0618-$61f
CamBoundBaseLine: ; X camera stuff is 1st column todo Y camera is not right yet
CamBoundBaseLine: ; X camera stuff is 1st column todo Y camera needs more testing
dw $007f, $0077 ; Left/Top camera bounds when at edge or layout frozen
dw $0007, $000b ; Left/Top camera bounds when not frozen + appropriate low byte $22/$20 (preadj. by #$78/#$6c)
dw $00ff, $010b ; Right/Bot camera bounds when not frozen + appropriate low byte $20/$22

View File

@@ -1,24 +1,21 @@
GfxFixer:
{
lda $b1 : bne .stage2
jsl Dungeon_LoadRoom_RANDO ; let's only call this guy once - may fix star tiles and slower loads
jsl Dungeon_InitStarTileCh
jsl LoadTransAuxGfx
;jsl Dungeon_LoadCustomTileAttr
jsl PrepTransAuxGfx
lda #$09 : sta $17 : sta $0710
inc $b1
rtl
.stage2
cmp #$01 : bne .stage3
lda #$0a : sta $17 : sta $0710
inc $b1
rtl
.stage3
jsl Palette_SpriteAux3
jsl Palette_SpriteAux2
jsl Palette_SpriteAux1
jsl Palette_DungBgMain
jsr CgramAuxToMain
inc $b1
rtl
.stage2
lda #$0a : sta $17 : sta $0710
stz $b1 : inc $b0
rtl
}

258
asm/normal.asm Normal file
View File

@@ -0,0 +1,258 @@
WarpLeft:
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 $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 $040c : cmp.b #$ff : beq .end
lda $22 : ldx $a9
jsr CalcIndex
ldy #$02 ; offsets in A, Y
jsr LoadRoomVert
.end
jsr Cleanup
rtl
WarpDown:
lda $040c : cmp.b #$ff : beq .end
lda $22 : ldx $a9
jsr CalcIndex
!add #$0c : ldy #$ff ; offsets in A, Y
jsr LoadRoomVert
.end
jsr Cleanup
rtl
TrapDoorFixer:
lda $ab : and #$0018 : beq .end
xba : asl #3 : sta $00
stz $0468 : lda $068c : ora $00 : sta $068c
.end
stz $ab ; clear our ab here because we don't need it anymore
lda $a0 : dec : tax
rtl
Cleanup:
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 #$90 : 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
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
pla : 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 $aa : lsr : sta $07
lda $a0 : and.b #$F0 : lsr #3 : !add $07 : !sub $21 : sta $02 : sta $03
jsr ShiftLowCoord
jsr ShiftQuad
jsr ShiftCameraBounds
ldy #$01 : jsr ShiftVariablesSubDir ; flip direction
lda $01 : sta $ab : and #$04 : lsr #2
sta $ee
lda $01 : and #$10 : beq .end : stz $0468
.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
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
pla : 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
ldy #$01 : jsr ShiftVariablesMainDir
lda $a0 : and.b #$0F : asl a : !add $a9 : !sub $23 : sta $02 : sta $03
jsr ShiftLowCoord
jsr ShiftQuad
jsr ShiftCameraBounds
ldy #$00 : jsr ShiftVariablesSubDir ; flip direction
lda $01 : sta $ab : and #$04 : lsr #2
sta $ee
.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 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 DoorTable,x : sta $00
and #$00FF : sta $a0 ; assign new room
sep #$30
rts
}
; INPUTS-- X: Direction Index , $02: Shift Value
; Sets high bytes of various registers
ShiftVariablesMainDir:
{
lda CoordIndex,y : tax
lda $21,x : !add $02 : sta $21,x ; coordinate update
lda CameraIndex,y : tax
lda $e3,x : !add $02 : sta $e3,x ; scroll register high byte
lda 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
}
ShiftLowCoord:
{
lda $01 : and.b #$03 ; high byte index
jsr CalcOpposingShift
lda $0127 : and.b #$f0 : cmp.b #$20 : bne .lowDone
lda OppCoordIndex,y : tax
lda #$80 : !add $20,x : sta $20,x
.lowDone
rts
}
; expects A to be (0,1,2) (dest number) and (0,1,2) (src door number) to be stored in $04
; $0127 will be set to a bitmask aaaa qxxf
; a - amount of adjust
; f - flag, if set, then amount is pos, otherwise neg.
; q - quadrant, if set, then quadrant needs to be modified
CalcOpposingShift:
{
stz $0127 ; set up (can you zero out 127 alone?)
cmp.b $04 : beq .noOffset ; (equal, no shifts to do)
phy : tay ; reserve these
lda $04 : tax : tya : !sub $04 : sta $04 : cmp.b #$00 : bpl .shiftPos
lda #$40
cpx.b #$01 : beq .skipNegQuad
ora #$08
.skipNegQuad
sta $0127 : lda $04 : cmp.b #$FE : beq .done ;already set $0127
lda $0127 : eor #$60
bra .setDone
.shiftPos
lda #$41
cpy.b #$01 : beq .skipPosQuad
ora #$08
.skipPosQuad
sta $0127 : lda $04 : cmp.b #$02 : bcs .done ;already set $0127
lda $0127 : eor #$60
.setDone sta $0127
.done ply
.noOffset rts
}
ShiftQuad:
{
lda $0127 : and #$08 : cmp.b #$00 : beq .quadDone
lda ShiftQuadIndex,y : tax ; X should be set to either 1 (vertical) or 2 (horizontal) (for a9,aa quadrant)
lda $0127 : and #$01 : cmp.b #$00 : beq .decQuad
inc $02
txa : sta $a8, x ; alter a9/aa
bra .quadDone
.decQuad
dec $02
lda #$00 : sta $a8, x ; alter a9/aa
.quadDone rts
}
ShiftVariablesSubDir:
{
lda CoordIndex,y : tax
lda $21,x : !add $02 : sta $21,x ; coordinate update
lda CameraIndex,y : tax
lda $e3,x : !add $03 : sta $e3,x ; scroll register high byte
lda CamQuadIndex,y : tax
lda $0601,x : !add $02 : sta $0601,x
lda $0605,x : !add $02 : sta $0605,x ; high bytes of these guys
lda $0603,x : !add $03 : sta $0603,x
lda $0607,x : !add $03 : sta $0607,x
rts
}
ShiftCameraBounds:
{
lda CamBoundIndex,y : tax ; should be 0 for horz travel (vert bounds) or 4 for vert travel (horz bounds)
rep #$30
lda $0127 : and #$00f0 : asl #2 : sta $06
lda $0127 : and #$0001 : cmp #$0000 : beq .subIt
lda $0618, x : !add $06 : sta $0618, x
lda $061A, x : !add $06 : sta $061A, x
sep #$30
rts
.subIt
lda $0618, x : !sub $06 : sta $0618, x
lda $061A, x : !sub $06 : sta $061A, x
sep #$30
rts
}
AdjustTransition:
{
lda $0127 : and #$00F0 : lsr
sep #$20 : cmp $0126 : bcc .reset
rep #$20
phy : ldy #$06 ; operating on vertical registers during horizontal trans
cpx.b #$02 : bcs .horizontalScrolling
ldy #$00 ; operate on horizontal regs during vert trans
.horizontalScrolling
lda $0127 : and #$0001 : asl : tax
lda.l OffsetTable,x : adc $00E2,y : and.w #$FFFE : sta $00E2,y : sta $00E0,y
ply : bra .done
.reset ; clear the 0127 variable so to not disturb intra-tile doors
stz $0127
.done
rep #$20 : lda $00 : and #$01fc
rtl
}

View File

@@ -1,7 +1,7 @@
RecordStairType: {
pha
sta $a0
lda $0e : sta $045e
pla : sta $a0 : lda $063d, x
lda $063d, x
rtl
}

File diff suppressed because one or more lines are too long