diff --git a/src/CoreImpl.s b/src/CoreImpl.s index fc1dd8c..9043d3e 100644 --- a/src/CoreImpl.s +++ b/src/CoreImpl.s @@ -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 diff --git a/src/GTE.s b/src/GTE.s deleted file mode 100644 index 9af47d7..0000000 --- a/src/GTE.s +++ /dev/null @@ -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 diff --git a/src/Render.s b/src/Render.s index 2a6c6bd..804aee9 100644 --- a/src/Render.s +++ b/src/Render.s @@ -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 diff --git a/src/Tiles.s b/src/Tiles.s index ad55581..19e5c78 100644 --- a/src/Tiles.s +++ b/src/Tiles.s @@ -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 diff --git a/src/Tool.s b/src/Tool.s index bd8970c..0d5bab1 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -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 diff --git a/src/render/Dirty.s b/src/render/Dirty.s index 932f1db..85f1f32 100644 --- a/src/render/Dirty.s +++ b/src/render/Dirty.s @@ -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 \ No newline at end of file