diff --git a/src/Core.s b/src/Core.s index 06bba05..d3f88a5 100644 --- a/src/Core.s +++ b/src/Core.s @@ -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 diff --git a/src/Sprite.s b/src/Sprite.s index c74235e..73f7046 100644 --- a/src/Sprite.s +++ b/src/Sprite.s @@ -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 diff --git a/src/blitter/Tiles.s b/src/blitter/Tiles.s index 04d54d8..86426d4 100644 --- a/src/blitter/Tiles.s +++ b/src/blitter/Tiles.s @@ -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 diff --git a/src/blitter/Tiles01000.s b/src/blitter/Tiles01000.s index d238d9a..e9031e6 100644 --- a/src/blitter/Tiles01000.s +++ b/src/blitter/Tiles01000.s @@ -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