Add a full complement of firty tile rendering functions

This commit is contained in:
Lucas Scharenbroich 2022-07-05 23:48:33 -05:00
parent 48fa068dfd
commit 4e21680063
6 changed files with 279 additions and 165 deletions

View File

@ -190,7 +190,7 @@ EngineReset
; stz EngineMode
stz DirtyBits
stz LastRender
stz LastRender ; Initialize as is a full render was performed
stz LastPatchOffset
stz BG1StartX
stz BG1StartXMod164

View File

@ -1,73 +0,0 @@
; Collection of the EXTernal labels exported by GTE. This is the closest thing
; we have to an API definition.
EngineStartUp EXT
EngineShutDown EXT
SetScreenMode EXT
ReadControl EXT
; Low-Level Functions
SetPalette EXT
GetVBLTicks EXT
GetVerticalCounter EXT
SetBorderColor EXT
; Tilemap functions
SetBG0XPos EXT
SetBG0YPos EXT
SetBG1XPos EXT
SetBG1YPos EXT
CopyBG0Tile EXT
CopyBG1Tile EXT
; SCB/Palette binding (high bit of array point indicates whether to bind to BG0 Y position (0)
; or BG1 Y position (1).
; SetSCBArray EXT
BltSCB EXT
; Rotation
ApplyBG1XPosAngle EXT
ApplyBG1YPosAngle EXT
CopyPicToField EXT
CopyBinToField EXT
CopyPicToBG1 EXT
CopyBinToBG1 EXT
AddTimer EXT
RemoveTimer EXT
DoTimers EXT
StartScript EXT
StopScript EXT
; Sprite functions
AddSprite EXT
MoveSprite EXT ; Set an existing sprite's position
UpdateSprite EXT ; Change an existing sprite's flags
RemoveSprite EXT
; Direct access to internals
DoScriptSeq EXT
GetTileAddr EXT
PushDirtyTile EXT ; A = address from GetTileStoreOffset, marks as dirty (will not mark the same tile more than once)
PopDirtyTile EXT ; No args, returns Y with tile store offset of the dirty tile
ApplyTiles EXT ; Drain the dirty tile queue and call RenderTile on each
GetTileStoreOffset EXT ; X = column, Y = row
TileStore EXT ; Tile store internal data structure
RenderDirty EXT ; Render only dirty tiles + sprites directly to the SHR screen
; GetSpriteVBuffAddr EXT ; X = x-coordinate (0 - 159), Y = y-coordinate (0 - 199). Return in Acc.
; Allocate a full 64K bank
AllocBank EXT
; Data references
;
; Super Hires line address lookup table for convenience
ScreenAddr EXT
OneSecondCounter EXT
BlitBuff EXT

View File

@ -20,6 +20,8 @@
; It's important to do _ApplyBG0YPos first because it calculates the value of StartY % 208 which is
; used in all of the other loops
_Render
; lda LastRender ; Check to see what kind of rendering was done on the last frame. If
; beq :no_change ; it was not this renderer,
jsr _DoTimers ; Run any pending timer tasks
stz SpriteRemovedFlag ; If we remove a sprite, then we need to flag a rebuild for the next frame
@ -37,7 +39,7 @@ _Render
jsr _UpdateBG0TileMap ; and the tile maps. These subroutines build up a list of tiles
; jsr _UpdateBG1TileMap ; that need to be updated in the code field
jsr _ApplyTilesFast ; This function actually draws the new tiles into the code field
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode
jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position
@ -129,10 +131,11 @@ _DoOverlay
:disp jsl $000000
rts
; The _ApplyTilesFast is the same as _ApplyTiles, but we use the _RenderTileFast subroutine
_ApplyTilesFast
; Run through all of the tiles on the DirtyTile list and render them
_ApplyTiles
ldx DirtyTileCount
phd ; sve the current direct page
tdc
clc
adc #$100 ; move to the next page
@ -141,48 +144,10 @@ _ApplyTilesFast
stx DP2_DIRTY_TILE_COUNT ; Cache the dirty tile count
jsr _PopDirtyTilesFast
tdc ; Move back to the original direct page
sec
sbc #$100
tcd
pld ; Move back to the original direct page
stz DirtyTileCount ; Reset the dirty tile count
rts
; The _ApplyTiles function is responsible for rendering all of the dirty tiles into the code
; field. In this function we switch to the second direct page which holds the temporary
; working buffers for tile rendering.
;
_ApplyTiles
tdc
clc
adc #$100 ; move to the next page
tcd
bra :begin
:loop
; Retrieve the offset of the next dirty Tile Store items in the X-register
jsr _PopDirtyTile2
; Call the generic dispatch with the Tile Store record pointer at by the X-register.
phb
; jsr _RenderTile2
plb
; Loop again until the list of dirty tiles is empty
:begin ldy DirtyTileCount
bne :loop
tdc ; Move back to the original direct page
sec
sbc #$100
tcd
rts
; This is a specialized render function that only updates the dirty tiles *and* draws them
; directly onto the SHR graphics buffer. The playfield is not used at all. In some way, this
; ignores almost all of the capabilities of GTE, but it does provide a convenient way to use

View File

@ -415,6 +415,17 @@ TwoLyrDynProcs
TwoLyrDynOver dw CopyDynamicTileTwoLyr,DynamicOverTwoLyr,OneSpriteDynamicOverTwoLyr
TwoLyrDynUnder dw CopyDynamicTileTwoLyr,DynamicUnderTwoLyr,OneSpriteDynamicUnderTwoLyr
; "Dirty" procs that are for dirty tile direct rendering. No moving background.
DirtyProcs
DirtyOverZA dw ConstTile0Dirty,SpriteOver0Dirty,OneSpriteDirtyOver0
DirtyOverZV dw ConstTile0Dirty,SpriteOver0Dirty,OneSpriteDirtyOver0
DirtyOverNA dw CopyTileADirty,SpriteOverADirty,OneSpriteDirtyOverA
DirtyOverNV dw CopyTileVDirty,SpriteOverVDirty,OneSpriteDirtyOverV
DirtyUnderZA dw ConstTile0Dirty,SpriteUnder0Dirty,SpriteUnder0Dirty
DirtyUnderZV dw ConstTile0Dirty,SpriteUnder0Dirty,SpriteUnder0Dirty
DirtyUnderNA dw CopyTileADirty,SpriteUnderADirty,OneSpriteDirtyUnderA
DirtyUnderNV dw CopyTileVDirty,SpriteUnderVDirty,OneSpriteDirtyUnderV
; SetBG0XPos
;
; Set the virtual horizontal position of the primary background layer. In addition to

View File

@ -725,6 +725,7 @@ _TSRefresh
put render/Slow.s
put render/Dynamic.s
put render/TwoLayer.s
put render/Dirty.s
put render/Sprite1.s
put render/Sprite2.s
put tiles/DirtyTileQueue.s

View File

@ -2,7 +2,8 @@
; A = tile address
; Y = screen address
DirtyTileZero
SpriteUnder0Dirty
ConstTile0Dirty
lda TileStore+TS_SCREEN_ADDR,x ; Get the on-screen address of this tile
tax
pei DP2_BANK01_AND_TILESTORE_BANKS
@ -13,11 +14,50 @@ DirtyTileZero
stz: {]line*SHR_LINE_WIDTH}+0,x
stz: {]line*SHR_LINE_WIDTH}+2,x
]line equ ]line+1
--^
plb
rts
DirtyTileA
; Sprite over a zero tile
OneSpriteDirtyOver0
ldy TileStore+TS_SCREEN_ADDR,x
tax
pei DP2_BANK01_AND_TILESTORE_BANKS
plb
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+0,x
sta: {]line*SHR_LINE_WIDTH}+0,y
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
sta: {]line*SHR_LINE_WIDTH}+2,y
]line equ ]line+1
--^
plb
rts
; Multiple sprites (copied to direct page temp space)
SpriteOver0Dirty
ldy TileStore+TS_SCREEN_ADDR,x
pei DP2_BANK01_AND_TILESTORE_BANKS
plb
]line equ 0
lup 8
lda tmp_sprite_data+{]line*4}+0
sta: {]line*SHR_LINE_WIDTH}+0,y
lda tmp_sprite_data+{]line*4}+2
sta: {]line*SHR_LINE_WIDTH}+2,y
]line equ ]line+1
--^
plb
rts
CopyTileADirty
ldy TileStore+TS_SCREEN_ADDR,x ; Get the on-screen address of this tile
lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated)
tax
@ -32,11 +72,12 @@ DirtyTileA
ldal tiledata+{]line*4}+2,x
sta: {]line*SHR_LINE_WIDTH}+2,y
]line equ ]line+1
--^
plb
rts
DirtyTileV
CopyTileVDirty
ldy TileStore+TS_SCREEN_ADDR,x ; Get the on-screen address of this tile
lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated)
tax
@ -54,19 +95,27 @@ DirtyTileV
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts
; DirtySpriteLine srcLine,destLine,dpAddr,offset
DirtySpriteLine mac
lda tiledata+{]1*TILE_DATA_SPAN}+]4,y
DirtySpriteOver mac
lda: tiledata+{]1*TILE_DATA_SPAN}+]4,y
andl spritemask+{]2*SPRITE_PLANE_SPAN}+]4,x
oral spritedata+{]2*SPRITE_PLANE_SPAN}+]4,x
sta ]3+]4
<<<
DirtySpriteUnder mac
ldal spritedata+{]2*SPRITE_PLANE_SPAN}+]4,x
and tiledata+{]1*TILE_DATA_SPAN}+32+]4,y
ora tiledata+{]1*TILE_DATA_SPAN}+]4,y
sta ]3+]4
<<<
; Special routine for a single sprite
OneSpriteDirtyA
OneSpriteDirtyOverA
ldy TileStore+TS_TILE_ADDR,x
lda TileStore+TS_SCREEN_ADDR,x
ldx sprite_ptr0
@ -80,37 +129,37 @@ OneSpriteDirtyA
_R0W1
DirtySpriteLine 0,0,$00,0
DirtySpriteLine 0,0,$00,2
DirtySpriteLine 1,1,$A0,0
DirtySpriteLine 1,1,$A0,2
DirtySpriteOver 0;0;$00;0
DirtySpriteOver 0;0;$00;2
DirtySpriteOver 1;1;$A0;0
DirtySpriteOver 1;1;$A0;2
tdc
adc #320
tcd
DirtySpriteLine 2,2,$00,0
DirtySpriteLine 2,2,$00,2
DirtySpriteLine 3,3,$A0,0
DirtySpriteLine 3,3,$A0,2
DirtySpriteOver 2;2;$00;0
DirtySpriteOver 2;2;$00;2
DirtySpriteOver 3;3;$A0;0
DirtySpriteOver 3;3;$A0;2
tdc
adc #320
tcd
DirtySpriteLine 4,4,$00,0
DirtySpriteLine 4,4,$00,2
DirtySpriteLine 5,5,$A0,0
DirtySpriteLine 5,5,$A0,2
DirtySpriteOver 4;4;$00;0
DirtySpriteOver 4;4;$00;2
DirtySpriteOver 5;5;$A0;0
DirtySpriteOver 5;5;$A0;2
tdc
adc #320
tcd
DirtySpriteLine 6,6,$00,0
DirtySpriteLine 6,6,$00,2
DirtySpriteLine 7,7,$A0,0
DirtySpriteLine 7,7,$A0,2
DirtySpriteOver 6;6;$00;0
DirtySpriteOver 6;6;$00;2
DirtySpriteOver 7;7;$A0;0
DirtySpriteOver 7;7;$A0;2
_R0W0
@ -119,7 +168,7 @@ OneSpriteDirtyA
pld
rts
OneSpriteDirtyV
OneSpriteDirtyUnderA
ldy TileStore+TS_TILE_ADDR,x
lda TileStore+TS_SCREEN_ADDR,x
ldx sprite_ptr0
@ -133,37 +182,144 @@ OneSpriteDirtyV
_R0W1
DirtySpriteLine 7,0,$00,0
DirtySpriteLine 7,0,$00,2
DirtySpriteLine 6,1,$A0,0
DirtySpriteLine 6,1,$A0,2
DirtySpriteUnder 0;0;$00;0
DirtySpriteUnder 0;0;$00;2
DirtySpriteUnder 1;1;$A0;0
DirtySpriteUnder 1;1;$A0;2
tdc
adc #320
tcd
DirtySpriteLine 5,2,$00,0
DirtySpriteLine 5,2,$00,2
DirtySpriteLine 4,3,$A0,0
DirtySpriteLine 4,3,$A0,2
DirtySpriteUnder 2;2;$00;0
DirtySpriteUnder 2;2;$00;2
DirtySpriteUnder 3;3;$A0;0
DirtySpriteUnder 3;3;$A0;2
tdc
adc #320
tcd
DirtySpriteLine 3,4,$00,0
DirtySpriteLine 3,4,$00,2
DirtySpriteLine 2,5,$A0,0
DirtySpriteLine 2,5,$A0,2
DirtySpriteUnder 4;4;$00;0
DirtySpriteUnder 4;4;$00;2
DirtySpriteUnder 5;5;$A0;0
DirtySpriteUnder 5;5;$A0;2
tdc
adc #320
tcd
DirtySpriteLine 1,6,$00,0
DirtySpriteLine 1,6,$00,2
DirtySpriteLine 0,7,$A0,0
DirtySpriteLine 0,7,$A0,2
DirtySpriteUnder 6;6;$00;0
DirtySpriteUnder 6;6;$00;2
DirtySpriteOver 7;7;$A0;0
DirtySpriteUnder 7;7;$A0;2
_R0W0
cli
plb
pld
rts
OneSpriteDirtyOverV
ldy TileStore+TS_TILE_ADDR,x
lda TileStore+TS_SCREEN_ADDR,x
ldx sprite_ptr0
phd
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
sei
clc
tcd
_R0W1
DirtySpriteOver 7;0;$00;0
DirtySpriteOver 7;0;$00;2
DirtySpriteOver 6;1;$A0;0
DirtySpriteOver 6;1;$A0;2
tdc
adc #320
tcd
DirtySpriteOver 5;2;$00;0
DirtySpriteOver 5;2;$00;2
DirtySpriteOver 4;3;$A0;0
DirtySpriteOver 4;3;$A0;2
tdc
adc #320
tcd
DirtySpriteOver 3;4;$00;0
DirtySpriteOver 3;4;$00;2
DirtySpriteOver 2;5;$A0;0
DirtySpriteOver 2;5;$A0;2
tdc
adc #320
tcd
DirtySpriteOver 1;6;$00;0
DirtySpriteOver 1;6;$00;2
DirtySpriteOver 0;7;$A0;0
DirtySpriteOver 0;7;$A0;2
_R0W0
cli
plb
pld
rts
OneSpriteDirtyUnderV
ldy TileStore+TS_TILE_ADDR,x
lda TileStore+TS_SCREEN_ADDR,x
ldx sprite_ptr0
phd
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
sei
clc
tcd
_R0W1
DirtySpriteUnder 7;0;$00;0
DirtySpriteUnder 7;0;$00;2
DirtySpriteUnder 6;1;$A0;0
DirtySpriteUnder 6;1;$A0;2
tdc
adc #320
tcd
DirtySpriteUnder 5;2;$00;0
DirtySpriteUnder 5;2;$00;2
DirtySpriteUnder 4;3;$A0;0
DirtySpriteUnder 4;3;$A0;2
tdc
adc #320
tcd
DirtySpriteUnder 3;4;$00;0
DirtySpriteUnder 3;4;$00;2
DirtySpriteUnder 2;5;$A0;0
DirtySpriteUnder 2;5;$A0;2
tdc
adc #320
tcd
DirtySpriteUnder 1;6;$00;0
DirtySpriteUnder 1;6;$00;2
DirtySpriteUnder 0;7;$A0;0
DirtySpriteUnder 0;7;$A0;2
_R0W0
@ -173,7 +329,7 @@ OneSpriteDirtyV
rts
; Generic routine for multiple sprites -- expect sprites to be in tmp_sprite_data and tmp_sprite_mask
SpriteDirtyA
SpriteOverADirty
ldy TileStore+TS_SCREEN_ADDR,x
lda TileStore+TS_TILE_ADDR,x
tax
@ -184,13 +340,13 @@ SpriteDirtyA
]line equ 0
lup 8
ldal tiledata+{]line*TILE_DATA_SPAN}+0,x
andl tmp_sprite_mask+{]line*4}+0
oral tmp_sprite_data+{]line*4}+0
and tmp_sprite_mask+{]line*4}+0
ora tmp_sprite_data+{]line*4}+0
sta: {]line*SHR_LINE_WIDTH}+0,y
ldal tiledata+{]line*TILE_DATA_SPAN}+2,x
andl tmp_sprite_mask+{]line*4}+2
oral tmp_sprite_data+{]line*4}+2
and tmp_sprite_mask+{]line*4}+2
ora tmp_sprite_data+{]line*4}+2
sta: {]line*SHR_LINE_WIDTH}+2,y
]line equ ]line+1
--^
@ -198,7 +354,32 @@ SpriteDirtyA
plb
rts
SpriteDirtyV
SpriteUnderADirty
ldy TileStore+TS_SCREEN_ADDR,x
lda TileStore+TS_TILE_ADDR,x
tax
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
]line equ 0
lup 8
lda tmp_sprite_data+{]line*4}+0
andl tiledata+{]line*TILE_DATA_SPAN}+32,x
oral tiledata+{]line*TILE_DATA_SPAN}+0,x
sta: {]line*SHR_LINE_WIDTH}+0,y
lda tmp_sprite_data+{]line*4}+2
andl tiledata+{]line*TILE_DATA_SPAN}+32+2,x
oral tiledata+{]line*TILE_DATA_SPAN}+2,x
sta: {]line*SHR_LINE_WIDTH}+2,y
]line equ ]line+1
--^
plb
rts
SpriteOverVDirty
ldy TileStore+TS_SCREEN_ADDR,x
lda TileStore+TS_TILE_ADDR,x
tax
@ -210,17 +391,46 @@ SpriteDirtyV
]dest equ 0
lup 8
ldal tiledata+{]src*TILE_DATA_SPAN}+0,x
andl tmp_sprite_mask+{]dest*4}+0
oral tmp_sprite_data+{]dest*4}+0
and tmp_sprite_mask+{]dest*4}+0
ora tmp_sprite_data+{]dest*4}+0
sta: {]dest*SHR_LINE_WIDTH}+0,y
ldal tiledata+{]src*TILE_DATA_SPAN}+2,x
andl tmp_sprite_mask+{]dest*4}+2
oral tmp_sprite_data+{]dest*4}+2
and tmp_sprite_mask+{]dest*4}+2
ora tmp_sprite_data+{]dest*4}+2
sta: {]dest*SHR_LINE_WIDTH}+2,y
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts
SpriteUnderVDirty
ldy TileStore+TS_SCREEN_ADDR,x
lda TileStore+TS_TILE_ADDR,x
tax
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
]src equ 7
]dest equ 0
lup 8
lda tmp_sprite_data+{]dest*4}+0
andl tiledata+{]src*TILE_DATA_SPAN}+32,x
oral tiledata+{]src*TILE_DATA_SPAN}+0,x
sta: {]dest*SHR_LINE_WIDTH}+0,y
lda tmp_sprite_data+{]dest*4}+2
andl tiledata+{]src*TILE_DATA_SPAN}+32+2,x
oral tiledata+{]src*TILE_DATA_SPAN}+2,x
sta: {]dest*SHR_LINE_WIDTH}+2,y
]src equ ]src-1
]dest equ ]dest+1
--^
plb
rts