Fix some small bugs with tile rendering; tiles display but crash after scrolling 8 bytes

This commit is contained in:
Lucas Scharenbroich 2021-08-06 14:42:18 -05:00
parent d01791b440
commit 39639d54b5
4 changed files with 69 additions and 13 deletions

View File

@ -65,14 +65,21 @@ Render
; used in all of the other loops
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
; _ApplyBG0Xpos need to be split because we have to set the offsets, then draw in any updated tiles, and
; finally patch out the code field. Right now, the BRA operand is getting overwritten by tile data.
jsr _ApplyBG0XPosPre
lda #$FFFF ; Force a tile refresh
jsr _UpdateBG0TileMap
jsr _ApplyBG0XPos ; Patch the PEA instructions with exit BRA opcode
; jsr _ApplyBG1YPos ; Adjust the index values into the BG1 bank buffer
; jsr _ApplyBG1XPos ; Adjust the direct page pointers to the BG1 bank
; Copy any tiles that have come into view
jsr _UpdateBG0TileMap
; The code fields are locked in now and reder to be rendered
jsr ShadowOff
@ -98,3 +105,10 @@ Render
rts

View File

@ -2,7 +2,7 @@
;
; This module contains higher-level functions than the low-level tile rendering routines. The
; goal here is to take a rectangular tilemap data structure and efficiently render it into
; code buffer. Especially inportant is to only draw new tiles as they come into view.
; code buffer. Especially important is to only draw new tiles as they come into view.
;
; Also, we maintain a tilemap cache to track the current state of the tiles rendered into
; the code field so if, by chance, a tile that comes into view is the same as a tile that
@ -10,6 +10,13 @@
; in actual games since the primary background is often large empty areas, or runs
; of repeating tiles.
; _UpdateBG0TileMap
;
; Fill in dirty tiles into the BG0 buffer.
;
; A = $FFFF re-render the entire playfield. Otherwise only render difference from the old
; coordinates.
_UpdateBG0TileMap
:Left equ tmp0
:Right equ tmp1
@ -31,29 +38,38 @@ _UpdateBG0TileMap
:BlkX equ tmp12
:BlkY equ tmp13
:Refresh equ tmp14
cmp #$FFFF
lda #0
rol
sta :Refresh ; 1 if A = $FFFF, 0 otherwise
lda StartY ; calculate the tile index of the current location
and #$FFF8
lsr
lsr
lsr
sta BG0TileOriginY
lda OldStartY
and #$FFF8
lsr
lsr
lsr
sta OldBG0TileOriginY
lda StartX
and #$FFF8
and #$FFFC
lsr
lsr
sta BG0TileOriginX
lda OldStartX
and #$FFF8
and #$FFFC
lsr
lsr
sta OldBG0TileOriginY
sta OldBG0TileOriginX
; Figure out the two rectangular regions that need to be updated. We check for changes in Y-direction
; first because it's a bit more efficient to redraw tiles in long horizontal strips, because we do not
@ -83,6 +99,12 @@ _UpdateBG0TileMap
lda ScreenTileHeight
sta :Bottom
; If we are supposed to refresh the while field, just do that and return
lda :Refresh
beq :NoRefresh
jmp :DrawRectBG0 ; Let the DrawRectBG0 RTS take care of the return for us
:NoRefresh
lda BG0TileOriginY
cmp OldBG0TileOriginY
beq :NoYUpdate ; if equal, don't change Y
@ -323,3 +345,13 @@ _UpdateBG0TileMap
bne :loop
rts

View File

@ -125,6 +125,15 @@ _RestoreBG0Opcodes
; x_exit = (164 - x) % 164
; x_enter = (164 - x - width) % 164
;
; Small routine to put the data in a consistent state. Called before any routines need to draw on
; the code buffer, but before we patch out the instructions.
_ApplyBG0XPosPre
lda StartX ; This is the starting byte offset (0 - 163)
jsr Mod164
sta StartXMod164
rts
_ApplyBG0XPos
:virt_line equ tmp1
@ -189,11 +198,7 @@ _ApplyBG0XPos
;
; So, in short, the entry tile position is rounded up from the x-position and the exit
; tile position is rounded down.
lda StartX ; This is the starting byte offset (0 - 163)
jsr Mod164 ;
sta StartXMod164
;
; Now, the left edge of the screen is pushed last, so we need to exit one instruction *after*
; the location (163 - StartX % 164)
;
@ -215,7 +220,6 @@ _ApplyBG0XPos
; | JMP loop |
; +-----------+
lda #163
sec
sbc StartXMod164
@ -746,3 +750,5 @@ SetCodeEntryOpcode

View File

@ -47,7 +47,7 @@ CopyTile
plb ; set the bank
pla ; pop the tile ID
jsr :ClearTile ; :_CopyTile
jsr :CopyTileMem0
plx ; pop the x-register
plb ; restore the data bank and return
@ -145,6 +145,7 @@ CopyTile
:CopyTileMem sec
sbc #$0010
:CopyTileMem0
asl
asl
asl
@ -235,3 +236,6 @@ CopyTile
sta $7003,y
rep #$20
rts