mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-11-29 11:50:25 +00:00
Start to split the tiles into high-level and low-level code
This commit is contained in:
parent
5745482ef6
commit
e5da3991cd
124
src/Tiles.s
Normal file
124
src/Tiles.s
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
; Basic tile functions
|
||||||
|
|
||||||
|
|
||||||
|
; 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 ENT
|
||||||
|
jsr _GetTileAddr
|
||||||
|
rtl
|
||||||
|
_GetTileAddr
|
||||||
|
asl ; Multiply by 2
|
||||||
|
bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set
|
||||||
|
beq :no_flip
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
; 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
|
||||||
|
|
||||||
|
; Fill in the TileStoreYTable. This is just a table of offsets into the Tile Store for each row. There
|
||||||
|
; are 26 rows with a stride of 41
|
||||||
|
ldy #0
|
||||||
|
lda #0
|
||||||
|
:yloop
|
||||||
|
sta TileStoreYTable,y
|
||||||
|
clc
|
||||||
|
adc #41*2
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
cpy #26*2
|
||||||
|
bcc :yloop
|
||||||
|
|
||||||
|
; Next, initialize the Tile Store itself
|
||||||
|
|
||||||
|
ldx #TILE_STORE_SIZE-2
|
||||||
|
lda #25
|
||||||
|
sta :row
|
||||||
|
lda #40
|
||||||
|
sta :col
|
||||||
|
lda #$8000
|
||||||
|
sta :vbuff
|
||||||
|
|
||||||
|
:loop
|
||||||
|
|
||||||
|
; The first set of values in the Tile Store are changed during each frame based on the actions
|
||||||
|
; that are happening
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
stal TileStore+TS_TILE_ID,x ; clear the tile store with the special zero tile
|
||||||
|
stal TileStore+TS_TILE_ADDR,x
|
||||||
|
stal TileStore+TS_SPRITE_FLAG,x ; no sprites are set at the beginning
|
||||||
|
stal TileStore+TS_DIRTY,x ; none of the tiles are dirty
|
||||||
|
|
||||||
|
; 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
|
||||||
|
|
||||||
|
lda :vbuff ; array of sprite vbuff addresses per tile
|
||||||
|
stal TileStore+TS_VBUFF_ARRAY_ADDR,x
|
||||||
|
clc
|
||||||
|
adc #32
|
||||||
|
sta :vbuff
|
||||||
|
|
||||||
|
; 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
|
||||||
|
lda BRowTableHigh,y
|
||||||
|
stal TileStore+TS_CODE_ADDR_HIGH,x ; High word of the tile address (just the bank)
|
||||||
|
lda BRowTableLow,y
|
||||||
|
stal TileStore+TS_BASE_ADDR,x ; May not be needed later if we can figure out the right constant...
|
||||||
|
|
||||||
|
lda :col ; Set the offset values based on the column
|
||||||
|
asl ; of this tile
|
||||||
|
asl
|
||||||
|
stal TileStore+TS_WORD_OFFSET,x ; This is the offset from 0 to 82, used in LDA (dp),y instruction
|
||||||
|
|
||||||
|
tay
|
||||||
|
lda Col2CodeOffset+2,y
|
||||||
|
clc
|
||||||
|
adcl TileStore+TS_BASE_ADDR,x
|
||||||
|
stal TileStore+TS_CODE_ADDR_LOW,x ; Low word of the tile address in the code field
|
||||||
|
|
||||||
|
dec :col
|
||||||
|
bpl :hop
|
||||||
|
dec :row
|
||||||
|
lda #40
|
||||||
|
sta :col
|
||||||
|
:hop
|
||||||
|
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
bpl :loop
|
||||||
|
rts
|
@ -41,39 +41,12 @@
|
|||||||
TILE_CTRL_MASK equ $FE00
|
TILE_CTRL_MASK equ $FE00
|
||||||
TILE_PROC_MASK equ $F800 ; Select tile proc for rendering
|
TILE_PROC_MASK equ $F800 ; Select tile proc for rendering
|
||||||
|
|
||||||
; Low-level function to take a tile descriptor and return the address in the tiledata
|
; Use some temporary space for the spriteIdx array (maximum of 4 entries)
|
||||||
; 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 ENT
|
|
||||||
jsr _GetTileAddr
|
|
||||||
rtl
|
|
||||||
_GetTileAddr
|
|
||||||
asl ; Multiply by 2
|
|
||||||
bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set
|
|
||||||
beq :no_flip
|
|
||||||
inc ; Set the LSB
|
|
||||||
:no_flip asl ; x4
|
|
||||||
asl ; x8
|
|
||||||
asl ; x16
|
|
||||||
asl ; x32
|
|
||||||
asl ; x64
|
|
||||||
asl ; x128
|
|
||||||
rts
|
|
||||||
|
|
||||||
; Ignore the horizontal flip bit
|
stkSave equ tmp9
|
||||||
_GetBaseTileAddr
|
screenAddr equ tmp10
|
||||||
asl ; Multiply by 2
|
tileAddr equ tmp11
|
||||||
asl ; x4
|
spriteIdx equ tmp12
|
||||||
asl ; x8
|
|
||||||
asl ; x16
|
|
||||||
asl ; x32
|
|
||||||
asl ; x64
|
|
||||||
asl ; x128
|
|
||||||
rts
|
|
||||||
|
|
||||||
; On entry
|
; On entry
|
||||||
;
|
;
|
||||||
@ -115,7 +88,7 @@ _RenderTile2
|
|||||||
bne do_dirty_sprite
|
bne do_dirty_sprite
|
||||||
|
|
||||||
; Handle the non-sprite tile blit
|
; Handle the non-sprite tile blit
|
||||||
|
CopyNoSprites
|
||||||
sep #$20
|
sep #$20
|
||||||
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
|
pha ; and put on the stack for later
|
||||||
@ -182,75 +155,75 @@ dirty_sprite_dispatch
|
|||||||
; because that code draws directly to the graphics screen, and this code draws
|
; because that code draws directly to the graphics screen, and this code draws
|
||||||
; to a temporary budder that has a different stride.
|
; to a temporary budder that has a different stride.
|
||||||
|
|
||||||
ldy TileStore+TS_VBUFF_ARRAY_ADDR,x ; base address of the VBUFF sprite address array for this tile
|
; ldy TileStore+TS_VBUFF_ARRAY_ADDR,x ; base address of the VBUFF sprite address array for this tile
|
||||||
|
;
|
||||||
|
; lsr
|
||||||
|
; bcc :loop_0_bit_1
|
||||||
|
; dobit $0000;sprite_ptr0;:loop_1_bit_1;CopyOneSprite
|
||||||
|
|
||||||
lsr
|
;:loop_0_bit_1 lsr
|
||||||
bcc :loop_0_bit_1
|
; bcc :loop_0_bit_2
|
||||||
dobit $0000;sprite_ptr0;:loop_1_bit_1;CopyOneSprite
|
; dobit $0002;sprite_ptr0;:loop_1_bit_2;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_1 lsr
|
;:loop_0_bit_2 lsr
|
||||||
bcc :loop_0_bit_2
|
; bcc :loop_0_bit_3
|
||||||
dobit $0002;sprite_ptr0;:loop_1_bit_2;CopyOneSprite
|
; dobit $0004;sprite_ptr0;:loop_1_bit_3;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_2 lsr
|
;:loop_0_bit_3 lsr
|
||||||
bcc :loop_0_bit_3
|
; bcc :loop_0_bit_4
|
||||||
dobit $0004;sprite_ptr0;:loop_1_bit_3;CopyOneSprite
|
; dobit $0006;sprite_ptr0;:loop_1_bit_4;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_3 lsr
|
;:loop_0_bit_4 lsr
|
||||||
bcc :loop_0_bit_4
|
; bcc :loop_0_bit_5
|
||||||
dobit $0006;sprite_ptr0;:loop_1_bit_4;CopyOneSprite
|
; dobit $0008;sprite_ptr0;:loop_1_bit_5;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_4 lsr
|
;:loop_0_bit_5 lsr
|
||||||
bcc :loop_0_bit_5
|
; bcc :loop_0_bit_6
|
||||||
dobit $0008;sprite_ptr0;:loop_1_bit_5;CopyOneSprite
|
; dobit $000A;sprite_ptr0;:loop_1_bit_6;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_5 lsr
|
;:loop_0_bit_6 lsr
|
||||||
bcc :loop_0_bit_6
|
; bcc :loop_0_bit_7
|
||||||
dobit $000A;sprite_ptr0;:loop_1_bit_6;CopyOneSprite
|
; dobit $000C;sprite_ptr0;:loop_1_bit_7;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_6 lsr
|
;:loop_0_bit_7 lsr
|
||||||
bcc :loop_0_bit_7
|
; bcc :loop_0_bit_8
|
||||||
dobit $000C;sprite_ptr0;:loop_1_bit_7;CopyOneSprite
|
; dobit $000E;sprite_ptr0;:loop_1_bit_8;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_7 lsr
|
;:loop_0_bit_8 lsr
|
||||||
bcc :loop_0_bit_8
|
; bcc :loop_0_bit_9
|
||||||
dobit $000E;sprite_ptr0;:loop_1_bit_8;CopyOneSprite
|
; dobit $0010;sprite_ptr0;:loop_1_bit_9;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_8 lsr
|
;:loop_0_bit_9 lsr
|
||||||
bcc :loop_0_bit_9
|
; bcc :loop_0_bit_10
|
||||||
dobit $0010;sprite_ptr0;:loop_1_bit_9;CopyOneSprite
|
; ldx: $0012,y
|
||||||
|
; stx spriteIdx
|
||||||
|
; cmp #0
|
||||||
|
; jne :loop_1_bit_10
|
||||||
|
; jmp CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_9 lsr
|
;:loop_0_bit_10 lsr
|
||||||
bcc :loop_0_bit_10
|
; bcc :loop_0_bit_11
|
||||||
ldx: $0012,y
|
; dobit $0014;sprite_ptr0;:loop_1_bit_11;CopyOneSprite
|
||||||
stx spriteIdx
|
|
||||||
cmp #0
|
|
||||||
jne :loop_1_bit_10
|
|
||||||
jmp CopyOneSprite
|
|
||||||
|
|
||||||
:loop_0_bit_10 lsr
|
;:loop_0_bit_11 lsr
|
||||||
bcc :loop_0_bit_11
|
; bcc :loop_0_bit_12
|
||||||
dobit $0014;sprite_ptr0;:loop_1_bit_11;CopyOneSprite
|
; dobit $0016;sprite_ptr0;:loop_1_bit_12;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_11 lsr
|
;:loop_0_bit_12 lsr
|
||||||
bcc :loop_0_bit_12
|
; bcc :loop_0_bit_13
|
||||||
dobit $0016;sprite_ptr0;:loop_1_bit_12;CopyOneSprite
|
; dobit $0018;sprite_ptr0;:loop_1_bit_13;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_12 lsr
|
;:loop_0_bit_13 lsr
|
||||||
bcc :loop_0_bit_13
|
; bcc :loop_0_bit_14
|
||||||
dobit $0018;sprite_ptr0;:loop_1_bit_13;CopyOneSprite
|
; dobit $001A;sprite_ptr0;:loop_1_bit_14;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_13 lsr
|
;:loop_0_bit_14 lsr
|
||||||
bcc :loop_0_bit_14
|
; bcc :loop_0_bit_15
|
||||||
dobit $001A;sprite_ptr0;:loop_1_bit_14;CopyOneSprite
|
; dobit $001C;sprite_ptr0;:loop_1_bit_15;CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_14 lsr
|
;:loop_0_bit_15 ldx: $001E,y
|
||||||
bcc :loop_0_bit_15
|
; stx spriteIdx
|
||||||
dobit $001C;sprite_ptr0;:loop_1_bit_15;CopyOneSprite
|
; jmp CopyOneSprite
|
||||||
|
|
||||||
:loop_0_bit_15 ldx: $001E,y
|
|
||||||
stx spriteIdx
|
|
||||||
jmp CopyOneSprite
|
|
||||||
|
|
||||||
; We can optimize later, for now just copy the sprite data and mask into its own
|
; We can optimize later, for now just copy the sprite data and mask into its own
|
||||||
; direct page buffer and combine with the tile data later
|
; direct page buffer and combine with the tile data later
|
||||||
@ -388,12 +361,10 @@ CopyOneSprite
|
|||||||
|
|
||||||
]line equ 0
|
]line equ 0
|
||||||
lup 8
|
lup 8
|
||||||
ldal tiledata,x
|
; ldal tiledata,x
|
||||||
and [spriteIdx]
|
; and [spriteIdx]
|
||||||
ora (spriteIdx)
|
; ora (spriteIdx)
|
||||||
sta tmp_sprite_data+{]line*4}
|
; sta tmp_sprite_data+{]line*4}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
|
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||||
sta tmp_sprite_data+{]line*4}
|
sta tmp_sprite_data+{]line*4}
|
||||||
@ -790,93 +761,6 @@ _CopyBG1Tile
|
|||||||
DirtyTileCount ds 2
|
DirtyTileCount ds 2
|
||||||
DirtyTiles ds TILE_STORE_SIZE ; At most this many tiles can possibly be update at once
|
DirtyTiles ds TILE_STORE_SIZE ; At most this many tiles can possibly be update at once
|
||||||
|
|
||||||
; 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
|
|
||||||
|
|
||||||
; Fill in the TileStoreYTable. This is just a table of offsets into the Tile Store for each row. There
|
|
||||||
; are 26 rows with a stride of 41
|
|
||||||
ldy #0
|
|
||||||
lda #0
|
|
||||||
:yloop
|
|
||||||
sta TileStoreYTable,y
|
|
||||||
clc
|
|
||||||
adc #41*2
|
|
||||||
iny
|
|
||||||
iny
|
|
||||||
cpy #26*2
|
|
||||||
bcc :yloop
|
|
||||||
|
|
||||||
; Next, initialize the Tile Store itself
|
|
||||||
|
|
||||||
ldx #TILE_STORE_SIZE-2
|
|
||||||
lda #25
|
|
||||||
sta :row
|
|
||||||
lda #40
|
|
||||||
sta :col
|
|
||||||
lda #$8000
|
|
||||||
sta :vbuff
|
|
||||||
|
|
||||||
:loop
|
|
||||||
|
|
||||||
; The first set of values in the Tile Store are changed during each frame based on the actions
|
|
||||||
; that are happening
|
|
||||||
|
|
||||||
lda #0
|
|
||||||
stal TileStore+TS_TILE_ID,x ; clear the tile store with the special zero tile
|
|
||||||
stal TileStore+TS_TILE_ADDR,x
|
|
||||||
stal TileStore+TS_SPRITE_FLAG,x ; no sprites are set at the beginning
|
|
||||||
stal TileStore+TS_DIRTY,x ; none of the tiles are dirty
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
lda :vbuff ; array of sprite vbuff addresses per tile
|
|
||||||
stal TileStore+TS_VBUFF_ARRAY_ADDR,x
|
|
||||||
clc
|
|
||||||
adc #32
|
|
||||||
sta :vbuff
|
|
||||||
|
|
||||||
; 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
|
|
||||||
lda BRowTableHigh,y
|
|
||||||
stal TileStore+TS_CODE_ADDR_HIGH,x ; High word of the tile address (just the bank)
|
|
||||||
lda BRowTableLow,y
|
|
||||||
stal TileStore+TS_BASE_ADDR,x ; May not be needed later if we can figure out the right constant...
|
|
||||||
|
|
||||||
lda :col ; Set the offset values based on the column
|
|
||||||
asl ; of this tile
|
|
||||||
asl
|
|
||||||
stal TileStore+TS_WORD_OFFSET,x ; This is the offset from 0 to 82, used in LDA (dp),y instruction
|
|
||||||
|
|
||||||
tay
|
|
||||||
lda Col2CodeOffset+2,y
|
|
||||||
clc
|
|
||||||
adcl TileStore+TS_BASE_ADDR,x
|
|
||||||
stal TileStore+TS_CODE_ADDR_LOW,x ; Low word of the tile address in the code field
|
|
||||||
|
|
||||||
dec :col
|
|
||||||
bpl :hop
|
|
||||||
dec :row
|
|
||||||
lda #40
|
|
||||||
sta :col
|
|
||||||
:hop
|
|
||||||
|
|
||||||
dex
|
|
||||||
dex
|
|
||||||
bpl :loop
|
|
||||||
rts
|
|
||||||
|
|
||||||
_ClearDirtyTiles
|
_ClearDirtyTiles
|
||||||
bra :hop
|
bra :hop
|
||||||
:loop
|
:loop
|
||||||
|
Loading…
Reference in New Issue
Block a user