2022-04-25 21:34:54 +00:00
|
|
|
; Basic tile functions
|
|
|
|
|
2022-05-18 05:34:25 +00:00
|
|
|
; Copy tileset data from a pointer in memory to the tiledata back
|
|
|
|
; X = high word
|
|
|
|
; A = low word
|
|
|
|
_LoadTileSet
|
|
|
|
sta tmp0
|
2022-05-19 03:49:14 +00:00
|
|
|
stx tmp1
|
2022-05-18 05:34:25 +00:00
|
|
|
ldy #0
|
|
|
|
tyx
|
|
|
|
:loop lda [tmp0],y
|
|
|
|
stal tiledata,x
|
|
|
|
dex
|
|
|
|
dex
|
|
|
|
dey
|
|
|
|
dey
|
|
|
|
bne :loop
|
|
|
|
rts
|
|
|
|
|
2022-04-25 21:34:54 +00:00
|
|
|
|
|
|
|
; 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
|
|
|
|
; incremental calculations, but it is handy for other utility functions
|
|
|
|
;
|
|
|
|
; A = tile descriptor
|
|
|
|
;
|
|
|
|
; The address is the TileID * 128 + (HFLIP * 64)
|
|
|
|
_GetTileAddr
|
|
|
|
asl ; Multiply by 2
|
2022-05-18 05:34:25 +00:00
|
|
|
bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set
|
|
|
|
beq :no_flip
|
2022-04-25 21:34:54 +00:00
|
|
|
inc ; Set the LSB
|
|
|
|
:no_flip asl ; x4
|
|
|
|
asl ; x8
|
|
|
|
asl ; x16
|
|
|
|
asl ; x32
|
|
|
|
asl ; x64
|
|
|
|
asl ; x128
|
|
|
|
rts
|
|
|
|
|
|
|
|
; Ignore the horizontal flip bit
|
|
|
|
_GetBaseTileAddr
|
|
|
|
asl ; Multiply by 2
|
|
|
|
asl ; x4
|
|
|
|
asl ; x8
|
|
|
|
asl ; x16
|
|
|
|
asl ; x32
|
|
|
|
asl ; x64
|
|
|
|
asl ; x128
|
|
|
|
rts
|
|
|
|
|
|
|
|
|
2022-04-29 17:38:04 +00:00
|
|
|
; Helper function to get the address offset into the tile cachce / tile backing store
|
|
|
|
; X = tile column [0, 40] (41 columns)
|
|
|
|
; Y = tile row [0, 25] (26 rows)
|
|
|
|
_GetTileStoreOffset
|
|
|
|
phx ; preserve the registers
|
|
|
|
phy
|
|
|
|
|
|
|
|
jsr _GetTileStoreOffset0
|
|
|
|
|
|
|
|
ply
|
|
|
|
plx
|
|
|
|
rts
|
|
|
|
|
|
|
|
_GetTileStoreOffset0
|
|
|
|
tya
|
|
|
|
asl
|
|
|
|
tay
|
|
|
|
txa
|
|
|
|
asl
|
|
|
|
clc
|
|
|
|
adc TileStoreYTable,y
|
|
|
|
rts
|
|
|
|
|
2022-04-25 21:34:54 +00:00
|
|
|
; Initialize the tile storage data structures. This takes care of populating the tile records with the
|
|
|
|
; appropriate constant values.
|
|
|
|
InitTiles
|
|
|
|
:col equ tmp0
|
|
|
|
:row equ tmp1
|
|
|
|
:vbuff equ tmp2
|
|
|
|
|
2022-06-01 18:55:04 +00:00
|
|
|
; Initialize the Tile Store
|
2022-04-25 21:34:54 +00:00
|
|
|
|
|
|
|
ldx #TILE_STORE_SIZE-2
|
|
|
|
lda #25
|
|
|
|
sta :row
|
|
|
|
lda #40
|
|
|
|
sta :col
|
|
|
|
lda #$8000
|
|
|
|
sta :vbuff
|
|
|
|
|
|
|
|
:loop
|
|
|
|
|
2022-06-01 18:55:04 +00:00
|
|
|
; The first set of values in the Tile Store that are changed during each frame based on the actions
|
2022-04-25 21:34:54 +00:00
|
|
|
; that are happening
|
|
|
|
|
|
|
|
lda #0
|
2022-05-20 04:40:45 +00:00
|
|
|
sta TileStore+TS_TILE_ID,x ; clear the tile store with the special zero tile
|
|
|
|
sta TileStore+TS_TILE_ADDR,x
|
|
|
|
sta TileStore+TS_SPRITE_FLAG,x ; no sprites are set at the beginning
|
|
|
|
sta TileStore+TS_DIRTY,x ; none of the tiles are dirty
|
2022-04-25 21:34:54 +00:00
|
|
|
|
2022-06-01 18:55:04 +00:00
|
|
|
; Set the default tile rendering functions
|
|
|
|
|
|
|
|
lda EngineMode
|
|
|
|
bit #ENGINE_MODE_DYN_TILES+ENGINE_MODE_TWO_LAYER
|
|
|
|
beq :fast
|
|
|
|
; ldal TileProcs
|
|
|
|
; sta TileStore+TS_BASE_TILE_DISP,x
|
|
|
|
bra :out
|
|
|
|
:fast
|
2022-06-14 19:21:51 +00:00
|
|
|
lda #0 ; Initialize with Tile 0
|
|
|
|
ldy #FastOverZero
|
|
|
|
jsr _SetTileProcs
|
|
|
|
|
2022-06-01 18:55:04 +00:00
|
|
|
:out
|
|
|
|
|
2022-04-25 21:34:54 +00:00
|
|
|
; lda DirtyTileProcs ; Fill in with the first dispatch address
|
|
|
|
; stal TileStore+TS_DIRTY_TILE_DISP,x
|
|
|
|
;
|
|
|
|
; lda TileProcs ; Same for non-dirty, non-sprite base case
|
|
|
|
; stal TileStore+TS_BASE_TILE_DISP,x
|
|
|
|
|
2022-06-01 18:55:04 +00:00
|
|
|
|
2022-04-25 21:34:54 +00:00
|
|
|
; The next set of values are constants that are simply used as cached parameters to avoid needing to
|
|
|
|
; calculate any of these values during tile rendering
|
|
|
|
|
|
|
|
lda :row ; Set the long address of where this tile
|
|
|
|
asl ; exists in the code fields
|
|
|
|
tay
|
2022-05-19 02:00:06 +00:00
|
|
|
lda #>TileStore ; get middle 16 bits: "00 -->BBHH<-- LL"
|
|
|
|
and #$FF00 ; merge with code field bank
|
|
|
|
ora BRowTableHigh,y
|
2022-05-20 04:40:45 +00:00
|
|
|
sta TileStore+TS_CODE_ADDR_HIGH,x ; High word of the tile address (just the bank)
|
2022-05-19 02:00:06 +00:00
|
|
|
|
2022-04-25 21:34:54 +00:00
|
|
|
lda BRowTableLow,y
|
2022-05-20 04:40:45 +00:00
|
|
|
sta TileStore+TS_BASE_ADDR,x ; May not be needed later if we can figure out the right constant...
|
2022-04-25 21:34:54 +00:00
|
|
|
|
|
|
|
lda :col ; Set the offset values based on the column
|
|
|
|
asl ; of this tile
|
|
|
|
asl
|
2022-05-20 04:40:45 +00:00
|
|
|
sta TileStore+TS_WORD_OFFSET,x ; This is the offset from 0 to 82, used in LDA (dp),y instruction
|
2022-04-25 21:34:54 +00:00
|
|
|
|
|
|
|
tay
|
|
|
|
lda Col2CodeOffset+2,y
|
|
|
|
clc
|
2022-05-20 04:40:45 +00:00
|
|
|
adc TileStore+TS_BASE_ADDR,x
|
|
|
|
sta TileStore+TS_CODE_ADDR_LOW,x ; Low word of the tile address in the code field
|
2022-04-25 21:34:54 +00:00
|
|
|
|
|
|
|
dec :col
|
|
|
|
bpl :hop
|
|
|
|
dec :row
|
|
|
|
lda #40
|
|
|
|
sta :col
|
|
|
|
:hop
|
|
|
|
|
|
|
|
dex
|
|
|
|
dex
|
|
|
|
bpl :loop
|
|
|
|
rts
|
2022-04-29 17:38:04 +00:00
|
|
|
|
|
|
|
; Set a tile value in the tile backing store. Mark dirty if the value changes
|
|
|
|
;
|
|
|
|
; A = tile id
|
|
|
|
; X = tile column [0, 40] (41 columns)
|
|
|
|
; Y = tile row [0, 25] (26 rows)
|
|
|
|
;
|
|
|
|
; Registers are not preserved
|
|
|
|
_SetTile
|
|
|
|
pha
|
|
|
|
jsr _GetTileStoreOffset0 ; Get the address of the X,Y tile position
|
2022-05-19 02:39:39 +00:00
|
|
|
tay
|
2022-04-29 17:38:04 +00:00
|
|
|
pla
|
|
|
|
|
2022-05-19 02:39:39 +00:00
|
|
|
cmp TileStore+TS_TILE_ID,y ; Only set to dirty if the value changed
|
2022-04-29 17:38:04 +00:00
|
|
|
beq :nochange
|
|
|
|
|
2022-05-19 02:39:39 +00:00
|
|
|
sta TileStore+TS_TILE_ID,y ; Value is different, store it.
|
2022-04-29 17:38:04 +00:00
|
|
|
jsr _GetTileAddr
|
2022-05-19 02:39:39 +00:00
|
|
|
sta TileStore+TS_TILE_ADDR,y ; Committed to drawing this tile, so get the address of the tile in the tiledata bank for later
|
2022-04-29 17:38:04 +00:00
|
|
|
|
|
|
|
; Set the standard renderer procs for this tile.
|
|
|
|
;
|
|
|
|
; 1. The dirty render proc is always set the same.
|
|
|
|
; 2. If BG1 and DYN_TILES are disabled, then the TS_BASE_TILE_DISP is selected from the Fast Renderers, otherwise
|
|
|
|
; it is selected from the full tile rendering functions.
|
|
|
|
; 3. The copy process is selected based on the flip bits
|
|
|
|
;
|
|
|
|
; When a tile overlaps the sprite, it is the responsibility of the Render function to compose the appropriate
|
|
|
|
; functionality. Sometimes it is simple, but in cases of the sprites overlapping Dynamic Tiles and other cases
|
|
|
|
; it can be more involved.
|
|
|
|
|
2022-06-12 10:28:12 +00:00
|
|
|
lda EngineMode
|
|
|
|
bit #ENGINE_MODE_DYN_TILES+ENGINE_MODE_TWO_LAYER
|
2022-06-14 19:21:51 +00:00
|
|
|
bne :not_fast
|
|
|
|
brl _SetTileFast
|
|
|
|
:nochange rts
|
2022-06-12 10:28:12 +00:00
|
|
|
|
2022-06-14 19:21:51 +00:00
|
|
|
:not_fast
|
2022-05-19 02:39:39 +00:00
|
|
|
lda TileStore+TS_TILE_ID,y
|
2022-04-29 17:38:04 +00:00
|
|
|
and #TILE_VFLIP_BIT+TILE_HFLIP_BIT ; get the lookup value
|
|
|
|
xba
|
2022-05-19 02:39:39 +00:00
|
|
|
tax
|
|
|
|
; ldal DirtyTileProcs,x
|
|
|
|
; sta TileStore+TS_DIRTY_TILE_DISP,y
|
2022-04-29 17:38:04 +00:00
|
|
|
|
2022-05-19 02:39:39 +00:00
|
|
|
; ldal CopyTileProcs,x
|
|
|
|
; sta TileStore+TS_DIRTY_TILE_COPY,y
|
2022-04-29 17:38:04 +00:00
|
|
|
|
2022-05-19 02:39:39 +00:00
|
|
|
lda TileStore+TS_TILE_ID,y ; Get the non-sprite dispatch address
|
2022-04-29 17:38:04 +00:00
|
|
|
and #TILE_CTRL_MASK
|
|
|
|
xba
|
2022-05-19 02:39:39 +00:00
|
|
|
tax
|
|
|
|
; ldal TileProcs,x
|
|
|
|
; sta TileStore+TS_BASE_TILE_DISP,y
|
2022-06-14 19:21:51 +00:00
|
|
|
jmp _PushDirtyTileY ; on the next call to _ApplyTiles
|
2022-04-29 17:38:04 +00:00
|
|
|
|
2022-06-14 19:21:51 +00:00
|
|
|
; 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
|
2022-06-12 10:28:12 +00:00
|
|
|
tyx
|
2022-06-14 19:21:51 +00:00
|
|
|
lda TileStore+TS_TILE_ID,x
|
2022-06-12 10:28:12 +00:00
|
|
|
bit #TILE_PRIORITY_BIT
|
|
|
|
beq :fast_over
|
2022-06-14 19:21:51 +00:00
|
|
|
:fast_under bit #TILE_ID_MASK
|
|
|
|
beq :fast_under_zero
|
|
|
|
ldy #FastUnderNonZero
|
|
|
|
jsr _SetTileProcs
|
|
|
|
jmp _PushDirtyTileX
|
|
|
|
|
|
|
|
:fast_under_zero ldy #FastUnderZero
|
|
|
|
jsr _SetTileProcs
|
|
|
|
jmp _PushDirtyTileX
|
|
|
|
|
|
|
|
:fast_over bit #TILE_ID_MASK
|
|
|
|
beq :fast_over_zero
|
|
|
|
ldy #FastOverNonZero
|
|
|
|
jsr _SetTileProcs
|
|
|
|
jmp _PushDirtyTileX
|
|
|
|
|
|
|
|
:fast_over_zero ldy #FastOverZero
|
|
|
|
jsr _SetTileProcs
|
|
|
|
jmp _PushDirtyTileX
|
|
|
|
|
|
|
|
:out
|
|
|
|
jmp _PushDirtyTileY ; on the next call to _ApplyTiles
|
|
|
|
|
|
|
|
; 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
|
2022-06-12 10:28:12 +00:00
|
|
|
and #TILE_VFLIP_BIT+TILE_HFLIP_BIT ; get the lookup value
|
|
|
|
xba
|
2022-06-14 19:21:51 +00:00
|
|
|
sta stpTmp ; save it
|
2022-06-12 10:28:12 +00:00
|
|
|
|
2022-06-14 19:21:51 +00:00
|
|
|
; Set a long pointer to this bank
|
|
|
|
phk
|
|
|
|
phk
|
|
|
|
pla
|
|
|
|
and #$00FF
|
|
|
|
stz bnkPtr ; pointer to this bank
|
|
|
|
sta bnkPtr+2
|
2022-06-08 22:34:23 +00:00
|
|
|
|
2022-06-14 19:21:51 +00:00
|
|
|
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
|
2022-06-14 13:12:33 +00:00
|
|
|
stal K_TS_COPY_TILE_DATA,x
|
2022-06-12 10:28:12 +00:00
|
|
|
|
2022-06-14 19:21:51 +00:00
|
|
|
; Finally, load in the last two addresses directly
|
2022-04-29 17:38:04 +00:00
|
|
|
|
2022-06-14 19:21:51 +00:00
|
|
|
ldy #4
|
|
|
|
lda [tblPtr],y
|
|
|
|
stal K_TS_SPRITE_TILE_DISP,x
|
2022-04-29 17:38:04 +00:00
|
|
|
|
2022-06-14 19:21:51 +00:00
|
|
|
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
|
2022-04-29 17:38:04 +00:00
|
|
|
|
|
|
|
; SetBG0XPos
|
|
|
|
;
|
|
|
|
; Set the virtual horizontal position of the primary background layer. In addition to
|
|
|
|
; updating the direct page state locations, this routine needs to preserve the original
|
|
|
|
; value as well. This is a bit subtle, because if this routine is called multiple times
|
|
|
|
; with different values, we need to make sure the *original* value is preserved and not
|
|
|
|
; continuously overwrite it.
|
|
|
|
;
|
|
|
|
; We assume that there is a clean code field in this routine
|
|
|
|
_SetBG0XPos
|
|
|
|
cmp StartX
|
|
|
|
beq :out ; Easy, if nothing changed, then nothing changes
|
|
|
|
|
|
|
|
ldx StartX ; Load the old value (but don't save it yet)
|
|
|
|
sta StartX ; Save the new position
|
|
|
|
|
|
|
|
lda #DIRTY_BIT_BG0_X
|
|
|
|
tsb DirtyBits ; Check if the value is already dirty, if so exit
|
|
|
|
bne :out ; without overwriting the original value
|
|
|
|
|
|
|
|
stx OldStartX ; First change, so preserve the value
|
|
|
|
:out rts
|
|
|
|
|
|
|
|
|
|
|
|
; SetBG0YPos
|
|
|
|
;
|
|
|
|
; Set the virtual position of the primary background layer.
|
|
|
|
_SetBG0YPos
|
|
|
|
cmp StartY
|
|
|
|
beq :out ; Easy, if nothing changed, then nothing changes
|
|
|
|
|
|
|
|
ldx StartY ; Load the old value (but don't save it yet)
|
|
|
|
sta StartY ; Save the new position
|
|
|
|
|
|
|
|
lda #DIRTY_BIT_BG0_Y
|
|
|
|
tsb DirtyBits ; Check if the value is already dirty, if so exit
|
|
|
|
bne :out ; without overwriting the original value
|
|
|
|
|
|
|
|
stx OldStartY ; First change, so preserve the value
|
|
|
|
:out rts
|
2022-05-31 13:43:26 +00:00
|
|
|
|
|
|
|
; Macro helper for the bit test tree
|
|
|
|
; dobit bit_position,dest;next;exit
|
|
|
|
dobit mac
|
|
|
|
lsr
|
|
|
|
bcc next_bit
|
|
|
|
beq last_bit
|
|
|
|
tax
|
2022-06-02 17:28:49 +00:00
|
|
|
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
2022-06-07 15:05:52 +00:00
|
|
|
clc
|
|
|
|
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
2022-05-31 13:43:26 +00:00
|
|
|
sta sprite_ptr0+{]2*4}
|
|
|
|
txa
|
|
|
|
jmp ]3
|
2022-06-02 17:28:49 +00:00
|
|
|
last_bit lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
2022-06-07 15:05:52 +00:00
|
|
|
clc ; pre-adjust these later
|
|
|
|
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
2022-05-31 13:43:26 +00:00
|
|
|
sta sprite_ptr0+{]2*4}
|
|
|
|
jmp ]4
|
|
|
|
next_bit
|
|
|
|
<<<
|
|
|
|
|
|
|
|
; Specialization for the first sprite which can just return the vbuff address
|
|
|
|
; in a register if there is only one sprite intersecting the tile
|
2022-06-02 17:28:49 +00:00
|
|
|
; dobit bit_position,dest;next;exit
|
2022-05-31 13:43:26 +00:00
|
|
|
dobit1 mac
|
|
|
|
lsr
|
|
|
|
bcc next_bit
|
|
|
|
beq last_bit
|
|
|
|
tax
|
2022-06-02 17:28:49 +00:00
|
|
|
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
2022-06-06 16:23:00 +00:00
|
|
|
clc
|
|
|
|
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
2022-05-31 13:43:26 +00:00
|
|
|
sta sprite_ptr0+{]2*4}
|
|
|
|
txa
|
|
|
|
jmp ]3
|
2022-06-02 17:28:49 +00:00
|
|
|
last_bit lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
2022-06-06 16:23:00 +00:00
|
|
|
clc ; pre-adjust these later
|
|
|
|
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
2022-05-31 13:43:26 +00:00
|
|
|
jmp ]4
|
|
|
|
next_bit
|
|
|
|
<<<
|
|
|
|
|
|
|
|
; If we find a last bit (4th in this case) and will exit
|
|
|
|
stpbit mac
|
|
|
|
lsr
|
|
|
|
bcc next_bit
|
2022-06-02 17:28:49 +00:00
|
|
|
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
2022-06-07 15:05:52 +00:00
|
|
|
clc ; pre-adjust these later
|
|
|
|
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
2022-05-31 13:43:26 +00:00
|
|
|
sta sprite_ptr0+{]2*4}
|
|
|
|
jmp ]3
|
|
|
|
next_bit
|
|
|
|
<<<
|
|
|
|
|
|
|
|
; Last bit test which *must* be set
|
|
|
|
endbit mac
|
2022-06-02 17:28:49 +00:00
|
|
|
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
2022-06-07 15:05:52 +00:00
|
|
|
clc ; pre-adjust these later
|
|
|
|
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
2022-05-31 13:43:26 +00:00
|
|
|
sta sprite_ptr0+{]2*4}
|
|
|
|
jmp ]3
|
|
|
|
<<<
|
|
|
|
|
|
|
|
; OPTIMIZATION:
|
|
|
|
;
|
|
|
|
; bit #$00FF ; Optimization to skip the first 8 bits if they are all zeros
|
|
|
|
; bne norm_entry
|
|
|
|
; xba
|
|
|
|
; jmp skip_entry
|
|
|
|
;
|
|
|
|
; Placed at the entry point
|
|
|
|
|
|
|
|
; This is a complex, but fast subroutine that is called from the core tile rendering code. It
|
|
|
|
; Takes a bitmap of sprites in the Accumulator and then extracts the VBuff addresses for the
|
|
|
|
; target TileStore entry and places them in specific direct page locations.
|
|
|
|
;
|
|
|
|
; Inputs:
|
|
|
|
; A = sprite bitmap (assumed to be non-zero)
|
|
|
|
; Y = tile store index
|
|
|
|
; D = second work page
|
|
|
|
; B = vbuff array bank
|
|
|
|
; Output:
|
|
|
|
; X =
|
|
|
|
;
|
|
|
|
; ]1 address of single sprite process
|
|
|
|
; ]2 address of two sprite process
|
|
|
|
; ]3 address of three sprite process
|
|
|
|
; ]4 address of four sprite process
|
|
|
|
|
|
|
|
SpriteBitsToVBuffAddrs mac
|
|
|
|
dobit1 0;0;b_1_1;]1
|
|
|
|
dobit1 1;0;b_2_1;]1
|
|
|
|
dobit1 2;0;b_3_1;]1
|
|
|
|
dobit1 3;0;b_4_1;]1
|
|
|
|
dobit1 4;0;b_5_1;]1
|
|
|
|
dobit1 5;0;b_6_1;]1
|
|
|
|
dobit1 6;0;b_7_1;]1
|
|
|
|
dobit1 7;0;b_8_1;]1
|
|
|
|
dobit1 8;0;b_9_1;]1
|
|
|
|
dobit1 9;0;b_10_1;]1
|
|
|
|
dobit1 10;0;b_11_1;]1
|
|
|
|
dobit1 11;0;b_12_1;]1
|
|
|
|
dobit1 12;0;b_13_1;]1
|
|
|
|
dobit1 13;0;b_14_1;]1
|
|
|
|
dobit1 14;0;b_15_1;]1
|
2022-06-02 17:28:49 +00:00
|
|
|
endbit 15;0;]1
|
2022-05-31 13:43:26 +00:00
|
|
|
|
|
|
|
b_1_1 dobit 1;1;b_2_2;]2
|
|
|
|
b_2_1 dobit 2;1;b_3_2;]2
|
|
|
|
b_3_1 dobit 3;1;b_4_2;]2
|
|
|
|
b_4_1 dobit 4;1;b_5_2;]2
|
|
|
|
b_5_1 dobit 5;1;b_6_2;]2
|
|
|
|
b_6_1 dobit 6;1;b_7_2;]2
|
|
|
|
b_7_1 dobit 7;1;b_8_2;]2
|
|
|
|
b_8_1 dobit 8;1;b_9_2;]2
|
|
|
|
b_9_1 dobit 9;1;b_10_2;]2
|
|
|
|
b_10_1 dobit 10;1;b_11_2;]2
|
|
|
|
b_11_1 dobit 11;1;b_12_2;]2
|
|
|
|
b_12_1 dobit 12;1;b_13_2;]2
|
|
|
|
b_13_1 dobit 13;1;b_14_2;]2
|
|
|
|
b_14_1 dobit 14;1;b_15_2;]2
|
|
|
|
b_15_1 endbit 15;1;]2
|
|
|
|
|
|
|
|
b_2_2 dobit 2;2;b_3_3;]3
|
|
|
|
b_3_2 dobit 3;2;b_4_3;]3
|
|
|
|
b_4_2 dobit 4;2;b_5_3;]3
|
|
|
|
b_5_2 dobit 5;2;b_6_3;]3
|
|
|
|
b_6_2 dobit 6;2;b_7_3;]3
|
|
|
|
b_7_2 dobit 7;2;b_8_3;]3
|
|
|
|
b_8_2 dobit 8;2;b_9_3;]3
|
|
|
|
b_9_2 dobit 9;2;b_10_3;]3
|
|
|
|
b_10_2 dobit 10;2;b_11_3;]3
|
|
|
|
b_11_2 dobit 11;2;b_12_3;]3
|
|
|
|
b_12_2 dobit 12;2;b_13_3;]3
|
|
|
|
b_13_2 dobit 13;2;b_14_3;]3
|
|
|
|
b_14_2 dobit 14;2;b_15_3;]3
|
|
|
|
b_15_2 endbit 15;2;]3
|
|
|
|
|
|
|
|
b_3_3 stpbit 3;3;]4
|
|
|
|
b_4_3 stpbit 4;3;]4
|
|
|
|
b_5_3 stpbit 5;3;]4
|
|
|
|
b_6_3 stpbit 6;3;]4
|
|
|
|
b_7_3 stpbit 7;3;]4
|
|
|
|
b_8_3 stpbit 8;3;]4
|
|
|
|
b_9_3 stpbit 9;3;]4
|
|
|
|
b_10_3 stpbit 10;3;]4
|
|
|
|
b_11_3 stpbit 11;3;]4
|
|
|
|
b_12_3 stpbit 12;3;]4
|
|
|
|
b_13_3 stpbit 13;3;]4
|
|
|
|
b_14_3 stpbit 14;3;]4
|
|
|
|
b_15_3 endbit 15;3;]4
|
2022-06-08 22:34:23 +00:00
|
|
|
<<<
|
|
|
|
|
|
|
|
; Store some tables in the K bank that will be used exclusively for jmp (abs,x) dispatch
|
2022-06-12 10:28:12 +00:00
|
|
|
|
|
|
|
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)
|
2022-06-14 19:21:51 +00:00
|
|
|
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
|