mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-09-29 02:55:06 +00:00
Move to tables of dispatch tuples to set tile rendering information
This commit is contained in:
parent
d3da96a834
commit
12b05139c2
144
src/Tiles.s
144
src/Tiles.s
@ -110,14 +110,10 @@ InitTiles
|
|||||||
; sta TileStore+TS_BASE_TILE_DISP,x
|
; sta TileStore+TS_BASE_TILE_DISP,x
|
||||||
bra :out
|
bra :out
|
||||||
:fast
|
:fast
|
||||||
lda #_TBConstTile0 ; Use the special tile 0 routines
|
lda #0 ; Initialize with Tile 0
|
||||||
; ldal FastTileProcs
|
ldy #FastOverZero
|
||||||
stal K_TS_BASE_TILE_DISP,x
|
jsr _SetTileProcs
|
||||||
lda #_TBConstTileDataToDP2
|
|
||||||
; ldal FastTileCopy
|
|
||||||
stal K_TS_COPY_TILE_DATA,x
|
|
||||||
ldal FastSpriteSub
|
|
||||||
stal K_TS_SPRITE_TILE_DISP,x
|
|
||||||
:out
|
:out
|
||||||
|
|
||||||
; lda DirtyTileProcs ; Fill in with the first dispatch address
|
; lda DirtyTileProcs ; Fill in with the first dispatch address
|
||||||
@ -197,8 +193,11 @@ _SetTile
|
|||||||
|
|
||||||
lda EngineMode
|
lda EngineMode
|
||||||
bit #ENGINE_MODE_DYN_TILES+ENGINE_MODE_TWO_LAYER
|
bit #ENGINE_MODE_DYN_TILES+ENGINE_MODE_TWO_LAYER
|
||||||
beq :fast
|
bne :not_fast
|
||||||
|
brl _SetTileFast
|
||||||
|
:nochange rts
|
||||||
|
|
||||||
|
:not_fast
|
||||||
lda TileStore+TS_TILE_ID,y
|
lda TileStore+TS_TILE_ID,y
|
||||||
and #TILE_VFLIP_BIT+TILE_HFLIP_BIT ; get the lookup value
|
and #TILE_VFLIP_BIT+TILE_HFLIP_BIT ; get the lookup value
|
||||||
xba
|
xba
|
||||||
@ -215,46 +214,116 @@ _SetTile
|
|||||||
tax
|
tax
|
||||||
; ldal TileProcs,x
|
; ldal TileProcs,x
|
||||||
; sta TileStore+TS_BASE_TILE_DISP,y
|
; sta TileStore+TS_BASE_TILE_DISP,y
|
||||||
bra :out
|
jmp _PushDirtyTileY ; on the next call to _ApplyTiles
|
||||||
|
|
||||||
:fast
|
; Specialized check for when the engine is in "Fast" mode. If is a simple decision tree based on whether
|
||||||
|
; the tile priority bit is set, and whether this is the special tile 0 or not.
|
||||||
|
_SetTileFast
|
||||||
tyx
|
tyx
|
||||||
lda TileStore+TS_TILE_ID,y ; First, check if the sprites are over or under
|
lda TileStore+TS_TILE_ID,x
|
||||||
bit #TILE_PRIORITY_BIT
|
bit #TILE_PRIORITY_BIT
|
||||||
beq :fast_over
|
beq :fast_over
|
||||||
ldal FastSpriteSub+2
|
:fast_under bit #TILE_ID_MASK
|
||||||
bra :fast_under
|
beq :fast_under_zero
|
||||||
:fast_over ldal FastSpriteSub
|
ldy #FastUnderNonZero
|
||||||
:fast_under stal K_TS_SPRITE_TILE_DISP,x
|
jsr _SetTileProcs
|
||||||
|
jmp _PushDirtyTileX
|
||||||
|
|
||||||
lda TileStore+TS_TILE_ID,y ; Now, set the draw and copy routines based on H/V bits
|
:fast_under_zero ldy #FastUnderZero
|
||||||
bit #TILE_ID_MASK ; unless it's the special Tile 0
|
jsr _SetTileProcs
|
||||||
beq :fast_0
|
jmp _PushDirtyTileX
|
||||||
and #TILE_VFLIP_BIT+TILE_HFLIP_BIT ; get the lookup value
|
|
||||||
xba
|
|
||||||
tax
|
|
||||||
phx
|
|
||||||
|
|
||||||
ldal FastTileProcs,x
|
:fast_over bit #TILE_ID_MASK
|
||||||
tyx
|
beq :fast_over_zero
|
||||||
stal K_TS_BASE_TILE_DISP,x
|
ldy #FastOverNonZero
|
||||||
|
jsr _SetTileProcs
|
||||||
|
jmp _PushDirtyTileX
|
||||||
|
|
||||||
plx
|
:fast_over_zero ldy #FastOverZero
|
||||||
ldal FastTileCopy,x
|
jsr _SetTileProcs
|
||||||
tyx
|
jmp _PushDirtyTileX
|
||||||
stal K_TS_COPY_TILE_DATA,x
|
|
||||||
bra :out
|
|
||||||
:fast_0
|
|
||||||
lda #_TBConstTile0 ; Use the special tile 0 routines
|
|
||||||
stal K_TS_BASE_TILE_DISP,x
|
|
||||||
lda #_TBConstTileDataToDP2
|
|
||||||
stal K_TS_COPY_TILE_DATA,x
|
|
||||||
|
|
||||||
:out
|
:out
|
||||||
jmp _PushDirtyTileY ; on the next call to _ApplyTiles
|
jmp _PushDirtyTileY ; on the next call to _ApplyTiles
|
||||||
|
|
||||||
:nochange rts
|
; X = Tile Store offset
|
||||||
|
; Y = table address
|
||||||
|
; A = TILE_ID
|
||||||
|
;
|
||||||
|
; see TileProcTables in static/TileStore.s
|
||||||
|
bnkPtr equ blttmp
|
||||||
|
tblPtr equ blttmp+4
|
||||||
|
stpTmp equ blttmp+8
|
||||||
|
_SetTileProcs
|
||||||
|
and #TILE_VFLIP_BIT+TILE_HFLIP_BIT ; get the lookup value
|
||||||
|
xba
|
||||||
|
sta stpTmp ; save it
|
||||||
|
|
||||||
|
; Set a long pointer to this bank
|
||||||
|
phk
|
||||||
|
phk
|
||||||
|
pla
|
||||||
|
and #$00FF
|
||||||
|
stz bnkPtr ; pointer to this bank
|
||||||
|
sta bnkPtr+2
|
||||||
|
|
||||||
|
sty tblPtr ; pointer to the table
|
||||||
|
sta tblPtr+2
|
||||||
|
|
||||||
|
; Lookup the base tile procedure
|
||||||
|
|
||||||
|
clc
|
||||||
|
ldy #0
|
||||||
|
lda [tblPtr],y ; load address of the base tile proc array
|
||||||
|
adc stpTmp ; add the offset
|
||||||
|
tay
|
||||||
|
lda [bnkPtr],y ; load the actual value
|
||||||
|
stal K_TS_BASE_TILE_DISP,x ; store it in the dispatch table
|
||||||
|
|
||||||
|
; Lookup the tile copy routine
|
||||||
|
|
||||||
|
clc
|
||||||
|
ldy #2
|
||||||
|
lda [tblPtr],y ; load address to the tile copy proc array
|
||||||
|
adc stpTmp
|
||||||
|
tay
|
||||||
|
lda [bnkPtr],y
|
||||||
|
stal K_TS_COPY_TILE_DATA,x
|
||||||
|
|
||||||
|
; Finally, load in the last two addresses directly
|
||||||
|
|
||||||
|
ldy #4
|
||||||
|
lda [tblPtr],y
|
||||||
|
stal K_TS_SPRITE_TILE_DISP,x
|
||||||
|
|
||||||
|
ldy #6
|
||||||
|
lda [tblPtr],y
|
||||||
|
stal K_TS_ONE_SPRITE,x
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; TileProcTables
|
||||||
|
;
|
||||||
|
; Tables of tuples used to populate the K_TS_* dispatch arrays for different combinations. Easier to maintain
|
||||||
|
; than a bunch of conditional code. Each "table" address holds four pointers to routines to handle the four
|
||||||
|
; combinations of HFLIP and VFLIP bits.
|
||||||
|
;
|
||||||
|
; First address: A table of routines that render a tile when there is no sprite present
|
||||||
|
; Second address: A table of routines that copy a tile into the direct page workspace
|
||||||
|
; Third address: The general sprite routine; currently only used for Over/Under selection
|
||||||
|
; Fourth address: The specific sprite routine to use when only one sprite intersects the tile
|
||||||
|
FastOverNonZero dw FastTileProcs,FastTileCopy,FastSpriteOver,_OneSpriteFastOver
|
||||||
|
FastOverZero dw FastTileProcs0,FastTileCopy0,FastSpriteOver,_OneSpriteFastOver0
|
||||||
|
FastUnderNonZero dw FastTileProcs,FastTileCopy,FastSpriteUnder,_OneSpriteFastUnder
|
||||||
|
FastUnderZero dw FastTileProcs0,FastTileCopy0,FastSpriteUnder,_OneSpriteFastUnder0
|
||||||
|
|
||||||
|
; The routines will come from this table when ENGINE_MODE_TWO_LAYER and ENGINE_MODE_DYN_TILES
|
||||||
|
; are both off.
|
||||||
|
FastTileProcs dw _TBCopyDataFast,_TBCopyDataFast,_TBCopyDataVFast,_TBCopyDataVFast
|
||||||
|
FastTileCopy dw _CopyTileDataToDP2,_CopyTileDataToDP2,_CopyTileDataToDP2V,_CopyTileDataToDP2V
|
||||||
|
|
||||||
|
FastTileProcs0 dw _TBConstTile0,_TBConstTile0,_TBConstTile0,_TBConstTile0
|
||||||
|
FastTileCopy0 dw _TBConstTileDataToDP2,_TBConstTileDataToDP2,_TBConstTileDataToDP2,_TBConstTileDataToDP2
|
||||||
|
|
||||||
; SetBG0XPos
|
; SetBG0XPos
|
||||||
;
|
;
|
||||||
@ -455,3 +524,4 @@ b_15_3 endbit 15;3;]4
|
|||||||
K_TS_BASE_TILE_DISP ds TILE_STORE_SIZE ; draw the tile without a sprite
|
K_TS_BASE_TILE_DISP ds TILE_STORE_SIZE ; draw the tile without a sprite
|
||||||
K_TS_COPY_TILE_DATA ds TILE_STORE_SIZE ; copy the tile into temp storage (used when tile below sprite)
|
K_TS_COPY_TILE_DATA ds TILE_STORE_SIZE ; copy the tile into temp storage (used when tile below sprite)
|
||||||
K_TS_SPRITE_TILE_DISP ds TILE_STORE_SIZE ; select the sprite routine for this tile
|
K_TS_SPRITE_TILE_DISP ds TILE_STORE_SIZE ; select the sprite routine for this tile
|
||||||
|
K_TS_ONE_SPRITE ds TILE_STORE_SIZE ; specialized sprite routine when only one sprite covers the tile
|
@ -27,33 +27,6 @@ _TBCopyTileDataAndMaskToCBuffV
|
|||||||
jsr _TBCopyTileDataToCBuffV
|
jsr _TBCopyTileDataToCBuffV
|
||||||
jmp _TBCopyTileMaskToCBuffV
|
jmp _TBCopyTileMaskToCBuffV
|
||||||
|
|
||||||
_CopyTileDataToDP2
|
|
||||||
]line equ 0
|
|
||||||
lup 8
|
|
||||||
lda tiledata+{]line*4},y
|
|
||||||
sta tmp_tile_data+{]line*4}
|
|
||||||
|
|
||||||
lda tiledata+{]line*4}+2,y
|
|
||||||
sta tmp_tile_data+{]line*4}+2
|
|
||||||
]line equ ]line+1
|
|
||||||
--^
|
|
||||||
rts
|
|
||||||
|
|
||||||
_CopyTileDataToDP2V
|
|
||||||
]src equ 7
|
|
||||||
]dest equ 0
|
|
||||||
lup 8
|
|
||||||
lda tiledata+{]src*4},y
|
|
||||||
sta tmp_tile_data+{]dest*4}
|
|
||||||
|
|
||||||
lda tiledata+{]src*4}+2,y
|
|
||||||
sta tmp_tile_data+{]dest*4}+2
|
|
||||||
]src equ ]src-1
|
|
||||||
]dest equ ]dest+1
|
|
||||||
--^
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
|
||||||
_TBCopyTileDataToCBuff
|
_TBCopyTileDataToCBuff
|
||||||
]line equ 0
|
]line equ 0
|
||||||
lup 8
|
lup 8
|
||||||
|
@ -9,6 +9,8 @@ _RenderTileFast
|
|||||||
lda TileStore+TS_SPRITE_FLAG,x ; any sprites on this line?
|
lda TileStore+TS_SPRITE_FLAG,x ; any sprites on this line?
|
||||||
bne :sprites
|
bne :sprites
|
||||||
|
|
||||||
|
_OneSpriteFastUnder0
|
||||||
|
_RenderNoSprite
|
||||||
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
|
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
|
||||||
pha ; and put on the stack for later. Has TileStore bank in high byte.
|
pha ; and put on the stack for later. Has TileStore bank in high byte.
|
||||||
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
|
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
|
||||||
@ -17,12 +19,6 @@ _RenderTileFast
|
|||||||
jmp (K_TS_BASE_TILE_DISP,x) ; go to the tile copy routine
|
jmp (K_TS_BASE_TILE_DISP,x) ; go to the tile copy routine
|
||||||
:sprites jmp (K_TS_SPRITE_TILE_DISP,x) ; go to the sprite+tile routine
|
:sprites jmp (K_TS_SPRITE_TILE_DISP,x) ; go to the sprite+tile routine
|
||||||
|
|
||||||
; The TS_BASE_TILE_DISP routines will come from this table when ENGINE_MODE_TWO_LAYER and
|
|
||||||
; ENGINE_MODE_DYN_TILES are both off.
|
|
||||||
FastTileProcs dw _TBCopyDataFast,_TBCopyDataFast,_TBCopyDataVFast,_TBCopyDataVFast
|
|
||||||
FastTileCopy dw _CopyTileDataToDP2,_CopyTileDataToDP2,_CopyTileDataToDP2V,_CopyTileDataToDP2V
|
|
||||||
FastSpriteSub dw FastSpriteOver,FastSpriteUnder
|
|
||||||
|
|
||||||
; Optimized routines to render sprites on top of the tile data and update the code field
|
; Optimized routines to render sprites on top of the tile data and update the code field
|
||||||
; assuming that the opcode will never need to be reset, e.g. all of the instructions are
|
; assuming that the opcode will never need to be reset, e.g. all of the instructions are
|
||||||
; PEA opcodes, so only the operands need to be set.
|
; PEA opcodes, so only the operands need to be set.
|
||||||
@ -38,12 +34,16 @@ FastSpriteOver
|
|||||||
; so we have to calculate the sprite dispatch subrotine to copy the sprite data into the direct
|
; so we have to calculate the sprite dispatch subrotine to copy the sprite data into the direct
|
||||||
; page space and then merge it with the tile data at the end.
|
; page space and then merge it with the tile data at the end.
|
||||||
FastSpriteUnder
|
FastSpriteUnder
|
||||||
rts
|
|
||||||
txy
|
txy
|
||||||
SpriteBitsToVBuffAddrs OneSpriteFastUnder;OneSpriteFastUnder;OneSpriteFastUnder;OneSpriteFastUnder
|
SpriteBitsToVBuffAddrs OneSpriteFastUnder;OneSpriteFastUnder;OneSpriteFastUnder;OneSpriteFastUnder
|
||||||
|
|
||||||
; This handles sprite with the tile above
|
; This handles sprites with the tile above
|
||||||
OneSpriteFastUnder
|
OneSpriteFastUnder
|
||||||
|
tyx
|
||||||
|
jmp (K_TS_ONE_SPRITE,x)
|
||||||
|
|
||||||
|
; General copy
|
||||||
|
_OneSpriteFastUnder
|
||||||
tax
|
tax
|
||||||
jsr _CopySpriteDataToDP2 ; preserves Y
|
jsr _CopySpriteDataToDP2 ; preserves Y
|
||||||
|
|
||||||
@ -90,14 +90,33 @@ _CopySpriteDataToDP2
|
|||||||
; A = vbuff address
|
; A = vbuff address
|
||||||
; Y = tile store address
|
; Y = tile store address
|
||||||
OneSpriteFast
|
OneSpriteFast
|
||||||
sta sprite_ptr0
|
|
||||||
tyx
|
tyx
|
||||||
|
jmp (K_TS_ONE_SPRITE,x)
|
||||||
|
|
||||||
|
; Specialize when the tile is Tile 0
|
||||||
|
_OneSpriteFastOver0
|
||||||
|
ldy TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
|
||||||
|
phy ; and put on the stack for later. Has TileStore bank in high byte.
|
||||||
|
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
|
||||||
|
tax
|
||||||
|
plb
|
||||||
|
|
||||||
|
]line equ 0
|
||||||
|
lup 8
|
||||||
|
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||||
|
sta: $0004+{]line*$1000},y
|
||||||
|
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||||
|
sta: $0001+{]line*$1000},y
|
||||||
|
]line equ ]line+1
|
||||||
|
--^
|
||||||
|
plb
|
||||||
|
rts
|
||||||
|
|
||||||
|
; General copy
|
||||||
|
_OneSpriteFastOver
|
||||||
|
sta sprite_ptr0
|
||||||
ldy TileStore+TS_TILE_ADDR,x ; load the tile address
|
ldy TileStore+TS_TILE_ADDR,x ; load the tile address
|
||||||
pei DP2_TILEDATA_AND_TILESTORE_BANKS ; copy the tile. Setting the bank
|
jsr (K_TS_COPY_TILE_DATA,x) ; This routine *must* preserve X register
|
||||||
plb ; saves 16 cycles and costs 14, so it's
|
|
||||||
jsr (K_TS_COPY_TILE_DATA,x) ; a small win, but we really do it to be
|
|
||||||
plb ; able to preserve the X register
|
|
||||||
|
|
||||||
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
|
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
|
||||||
pha ; and put on the stack for later. Has TileStore bank in high byte.
|
pha ; and put on the stack for later. Has TileStore bank in high byte.
|
||||||
@ -261,3 +280,35 @@ FourSpritesFast
|
|||||||
|
|
||||||
plb
|
plb
|
||||||
jmp _CopyDP2ToCodeField
|
jmp _CopyDP2ToCodeField
|
||||||
|
|
||||||
|
_CopyTileDataToDP2
|
||||||
|
pei DP2_TILEDATA_AND_TILESTORE_BANKS ; Setting the bank saves 16 cycles and costs 14, so it's a bit faster,
|
||||||
|
plb ; but we really do it to preserve the X register
|
||||||
|
]line equ 0
|
||||||
|
lup 8
|
||||||
|
lda tiledata+{]line*4},y
|
||||||
|
sta tmp_tile_data+{]line*4}
|
||||||
|
|
||||||
|
lda tiledata+{]line*4}+2,y
|
||||||
|
sta tmp_tile_data+{]line*4}+2
|
||||||
|
]line equ ]line+1
|
||||||
|
--^
|
||||||
|
plb
|
||||||
|
rts
|
||||||
|
|
||||||
|
_CopyTileDataToDP2V
|
||||||
|
pei DP2_TILEDATA_AND_TILESTORE_BANKS ; Setting the bank saves 16 cycles and costs 14, so it's a bit faster,
|
||||||
|
plb ; but we really do it to preserve the X register
|
||||||
|
]src equ 7
|
||||||
|
]dest equ 0
|
||||||
|
lup 8
|
||||||
|
lda tiledata+{]src*4},y
|
||||||
|
sta tmp_tile_data+{]dest*4}
|
||||||
|
|
||||||
|
lda tiledata+{]src*4}+2,y
|
||||||
|
sta tmp_tile_data+{]dest*4}+2
|
||||||
|
]src equ ]src-1
|
||||||
|
]dest equ ]dest+1
|
||||||
|
--^
|
||||||
|
plb
|
||||||
|
rts
|
Loading…
Reference in New Issue
Block a user