Add address in sprite plane for tile rendering; use in tile dispatcher

This commit is contained in:
Lucas Scharenbroich 2021-10-27 00:14:19 -05:00
parent cc18c67491
commit 2feb6f590b
4 changed files with 49 additions and 25 deletions

View File

@ -392,7 +392,7 @@ ReadControl ENT
; put blitter/Tiles00001.s
; put blitter/Tiles00010.s
; put blitter/Tiles00011.s
; put blitter/Tiles10000.s
put blitter/Tiles01000.s
; put blitter/Tiles10001.s
; put blitter/Tiles10010.s
; put blitter/Tiles10011.s

View File

@ -37,9 +37,10 @@ _RenderSprites
bra :loop
:out rts
; This is the complicated part; we need to draw the sprite into the sprite place, but then
; This is the complicated part; we need to draw the sprite into the sprite plane, but then
; calculate the code field tiles that this sprite potentially overlaps with and mark those
; tiles as dirty.
; tiles as dirty and store the appropriate sprite plane address that those tiles need to copy
; from.
:render
phx ; stash the X register
jsr _DrawTileSprite ; draw the sprite into the sprite plane
@ -76,20 +77,45 @@ _RenderSprites
lsr
lsr
lsr
tay
; Mark the tile as dirty
tay
plx
jsr _GetTileStoreOffset ; Get the tile store value
jsr _PushDirtyTile ; Enqueue for processing (Returns offset in Y-register)
plx ; Pull the stashed tile column
jsr _GetTileStoreOffset ; Get the tile store value
jsr _PushDirtyTile ; Enqueue for processing (Returns offset in Y-register)
lda #TILE_SPRITE_BIT ; Mark this tile as having a sprite, regardless of whether it was already enqueued
lda #TILE_SPRITE_BIT ; Mark this tile as having a sprite, regardless of whether it was already enqueued
sta TileStore+TS_SPRITE_FLAG,y
plx ; Restore the X register
; To calculate the sprite plane coordinate for this tile column. We really just have to compensate
; for the StartXMod164 mod 4 value, so the final value is (SPRITE_X + (StartXMod164 mod 4)) & 0xFFFC
; for the horizontal and (SPRITE_Y + (StartYMod208 mod 8)) & 0xFFF8
;
; The final address is (Y + NUM_BUFF_LINES) * 256 + X
lda StartYMod208
and #$0007
clc
adc _Sprites+SPRITE_Y,x
and #$00F8
clc
adc #NUM_BUFF_LINES
xba
sta tmp2
lda StartXMod164
and #$0003
clc
adc _Sprites+SPRITE_X,x
and #$00FC
clc
adc tmp2
sta TileStore+TS_SPRITE_ADDR,y
; TODO: Mark adjacent tiles as dirty based on tmp0 and tmp1 values
plx ; Restore the X register
brl :next
; _GetTileAt

View File

@ -49,12 +49,13 @@ TILE_HFLIP_BIT equ $0200
TILE_CTRL_MASK equ $FE00
TILE_PROC_MASK equ $F800 ; Select tile proc for rendering
; Temporary direct page locatinos used by some of the complext tile renderers
; Temporary direct page locatinos used by some of the complex tile renderers
_X_REG equ tiletmp
_Y_REG equ tiletmp+2
_T_PTR equ tiletmp+4 ; Copy of the tile address pointer
_BASE_ADDR equ tiletmp+6 ; Copy of BTableLow for this tile
_SPR_X_REG equ tiletmp+8 ; Cache address of sprite plane source for a tile
; Low-level function to take a tile descriptor and return the address in the tiledata
; bank. This is not too useful in the fast-path because the fast-path does more
@ -111,6 +112,11 @@ _RenderTileBG1
_RenderTile2
lda TileStore+TS_TILE_ID,y ; build the finalized tile descriptor
ora TileStore+TS_SPRITE_FLAG,y
bpl :nosprite ; save a few cycles on average -- the sprite flag is $8000, so easy bpl/bmi test
ldx TileStore+TS_SPRITE_ADDR,y
stx _SPR_X_REG
:nosprite
and #TILE_CTRL_MASK
xba
tax
@ -164,7 +170,7 @@ TileProcs dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 01110 : high-priority fringed masked normal tiles
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 01111 : high-priority fringed masked dynamic tiles
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10000 : normal tiles w/sprite
dw _TBSolidSpriteTile_00,_TBSolidSpriteTile_0H,_TBSolidSpriteTile_V0,_TBSolidSpriteTile_VH ; 10000 : normal tiles w/sprite
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10001 : dynamic tiles w/sprite
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10010 : masked normal tiles w/sprite
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10011 : masked dynamic tiles w/sprite
@ -476,13 +482,14 @@ TILE_STORE_SIZE equ {MAX_TILES*2} ; The tile store contains a tile descri
; TileStore+TS_TILE_ID : Tile descriptor
; TileStore+TS_DIRTY : $FFFF is clean, otherwise stores a back-reference to the DirtyTiles array
; TileStore+TS_SPRITE_FLAG : Set to TILE_SPRITE_BIT is a sprite is present at this tile location
; TileStore+TS_SPRITE_ADDR ; Address of the tile in the sprite plane
; TileStore+TS_TILE_ADDR : Address of the tile in the tile data buffer
; TIleStore+TS_CODE_ADDR_LOW : Low word of the address in the code field that receives the tile
; TileStore+TS_CODE_ADDR_HIGH : High word of the address in the code field that receives the tile
; TileStore+TS_WORD_OFFSET : Logical number of word for this location
; TileStore+TS_BASE_ADDR : Copy of BTableAddrLow
TileStore ds TILE_STORE_SIZE*8
TileStore ds TILE_STORE_SIZE*9
TS_TILE_ID equ TILE_STORE_SIZE*0
TS_DIRTY equ TILE_STORE_SIZE*1
TS_SPRITE_FLAG equ TILE_STORE_SIZE*2
@ -491,6 +498,7 @@ TS_CODE_ADDR_LOW equ TILE_STORE_SIZE*4 ; const value
TS_CODE_ADDR_HIGH equ TILE_STORE_SIZE*5 ; const value
TS_WORD_OFFSET equ TILE_STORE_SIZE*6
TS_BASE_ADDR equ TILE_STORE_SIZE*7
TS_SPRITE_ADDR equ TILE_STORE_SIZE*8
; A list of dirty tiles that need to be updated in a given frame
DirtyTileCount ds 2

View File

@ -4,18 +4,8 @@
; data from the sprite plane, tile data and write to the code field (which are all in different banks),
; there is no way to do everything inline, so a composite tile is created on the fly and written to
; a direct page buffer. This direct page buffer is then used to render the tile.
_TBSolidSpriteTile dw _TBSolidSpriteTile_00
dw _TBSolidSpriteTile_0H
dw _TBSolidSpriteTile_V0
dw _TBSolidSpriteTile_VH
dw _TBFastSpriteTile_00
dw _TBFastSpriteTile_0H
dw _TBFastSpriteTile_V0
dw _TBFastSpriteTile_VH
_TBSolidSpriteTile_00
jsr _TBCopyTileDataToCBuff ; Copy the tile into the compositing buffer
jsr _TBCopyTileDataToCBuff ; Copy the tile into the compositing buffer (using correct x-register)
jsr _TBApplySpriteData ; Overlay the data form the sprite plane (and copy into the code field)
jmp _TBFillPEAOpcode ; Fill in the code field opcodes
@ -68,8 +58,6 @@ _TBApplySpriteData
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
ldx _X_REG ; restore the original value
rts
; Copy tile data into the direct page compositing buffer. The main reason to do this in full passes is
@ -113,6 +101,7 @@ _TBCopyTileDataToCBuffV
sta blttmp+{]dest*4}+2
]src equ ]src-1
]dest equ ]dest+1
--^
rts
_TBCopyTileDataToCBuffVH
@ -126,6 +115,7 @@ _TBCopyTileDataToCBuffVH
sta blttmp+{]dest*4}+2
]src equ ]src-1
]dest equ ]dest+1
--^
rts
; Copy just the data into the code field from the composite buffer