Complete Dynamic Tile renderer

This commit is contained in:
Lucas Scharenbroich 2022-06-21 23:13:28 -05:00
parent 76a9710114
commit 4c1dba0f68
7 changed files with 200 additions and 216 deletions

View File

@ -15,7 +15,7 @@
TSZelda EXT ; tileset buffer
MAX_SPRITES equ 16
MAX_SPRITES equ 1
ScreenX equ 0
ScreenY equ 2
@ -24,6 +24,8 @@ Tmp1 equ 6
KeyState equ 8
Selected equ 10
Flips equ 12
DTile equ 14
Tmp2 equ 16
; Typical init
phk
@ -95,6 +97,8 @@ HERO_SPRITE equ SPRITE_16X16+1
; Manually fill in the 41x26 tiles of the TileStore with a test pattern of trees
; lda #TILE_DYN_BIT+TILE_PRIORITY_BIT+0 ; fill the screen the the dynamic tile slot 0
lda #TILE_DYN_BIT+0 ; fill the screen the the dynamic tile slot 0
jsr _fillTileStore
ldx #0
@ -145,6 +149,14 @@ HERO_SPRITE equ SPRITE_16X16+1
ldy #6
jsr _drawTreeFront
; Set up the dynamic tile
lda #65
sta DTile
pei DTile
pea $0000
_GTECopyTileToDynamic ; Copy DTile into the first dynamic tile slot
; Initialize the frame counter
stz FrameCount
@ -273,9 +285,19 @@ HERO_SPRITE equ SPRITE_16X16+1
brl :next
:10 cmp #$0A
bne :next
bne :11
dec ScreenY
:11 cmp #'y'
bne :next
lda DTile
inc
and #$007F
sta DTile
pha
pea $0000
_GTECopyTileToDynamic
:next
; inc ScreenX
@ -283,7 +305,7 @@ HERO_SPRITE equ SPRITE_16X16+1
pei ScreenY
_GTESetBG0Origin
; brl no_animate
brl no_animate
stz Tmp0
stz Tmp1
@ -433,11 +455,11 @@ GTEStartUp
brk $02
:ok2
clc ; Give GTE a page of direct page memory
clc ; Give GTE a page of direct page memory
tdc
adc #$0100
pha
pea $0000 ; No extra capabilities
pea #ENGINE_MODE_DYN_TILES ; Enable Dynamic Tiles
lda MyUserId ; Pass the userId for memory allocation
pha
_GTEStartUp
@ -448,15 +470,20 @@ GTEStartUp
rts
_fillTileStore
sta Tmp2
stz Tmp0
:oloop
stz Tmp1
:iloop
pei Tmp1
pei Tmp0
pea #129
pei Tmp2
_GTESetTile
lda Tmp2
eor #TILE_PRIORITY_BIT
sta Tmp2
lda Tmp1
inc
sta Tmp1

View File

@ -150,7 +150,7 @@ InitTiles
asl ; of this tile
asl
sta 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
@ -158,6 +158,11 @@ InitTiles
; adc TileStore+TS_BASE_ADDR,x
sta TileStore+TS_CODE_ADDR_LOW,x ; Low word of the tile address in the code field
lda JTableOffset,y
clc
adc :base
sta TileStore+TS_JMP_ADDR,x ; Address of the snippet handler for this tile
dec :col
bpl :hop
dec :row
@ -269,7 +274,7 @@ _SetTile
lda newTileId ; Otherwise chose one of the two dynamic tuples
and #TILE_PRIORITY_BIT
beq :pickDynProc ; If the Priority bit is not set, pick the first entry
lda #1 ; If the Priority bit is set, pick the other one
lda #1 ; If the Priority bit is set, pick the other one
:pickDynProc ldy #DynProcs
jsr _SetTileProcs

View File

@ -58,6 +58,8 @@ _CallTable
adrl _TSRemoveSprite-1
adrl _TSGetSeconds-1
adrl _TSCopyTileToDynamic-1
_CTEnd
_GTEAddSprite MAC
UserTool $1000+GTEToolNum
@ -351,6 +353,24 @@ _TSGetSeconds
_TSExit #0;#0
_TSCopyTileToDynamic
:dynId equ FirstParam+0
:tileId equ FirstParam+2
_TSEntry
lda EngineMode
bit #ENGINE_MODE_DYN_TILES
beq :notEnabled
lda :tileId,s
tax
lda :dynId,s
tay
jsr CopyTileToDyn
:notEnabled
_TSExit #0;#4
; Insert the GTE code
put Math.s

View File

@ -351,123 +351,6 @@ ClearTile
rep #$20
rts
; Helper functions to copy tile data to the appropriate location in Bank 0
; X = tile ID
; Y = dynamic tile ID
CopyTileToDyn ENT
txa
jsr _GetTileAddr
tax
tya
and #$001F ; Maximum of 32 dynamic tiles
asl
asl ; 4 bytes per page
adc BlitterDP ; Add to the bank 00 base address
adc #$0100 ; Go to the next page
tay
jsr CopyTileDToDyn ; Copy the tile data
jsr CopyTileMToDyn ; Copy the tile mask
rtl
; X = address of tile
; Y = tile address in bank 0
CopyTileDToDyn
phb
pea $0000
plb
plb
ldal tiledata+0,x
sta: $0000,y
ldal tiledata+2,x
sta: $0002,y
ldal tiledata+4,x
sta $0100,y
ldal tiledata+6,x
sta $0102,y
ldal tiledata+8,x
sta $0200,y
ldal tiledata+10,x
sta $0202,y
ldal tiledata+12,x
sta $0300,y
ldal tiledata+14,x
sta $0302,y
ldal tiledata+16,x
sta $0400,y
ldal tiledata+18,x
sta $0402,y
ldal tiledata+20,x
sta $0500,y
ldal tiledata+22,x
sta $0502,y
ldal tiledata+24,x
sta $0600,y
ldal tiledata+26,x
sta $0602,y
ldal tiledata+28,x
sta $0700,y
ldal tiledata+30,x
sta $0702,y
plb
rts
; Helper function to copy tile mask to the appropriate location in Bank 0
;
; X = address of tile
; Y = tile address in bank 0
;
; Argument are the same as CopyTileDToDyn, the code takes care of adjust offsets.
; This make is possible to call the two functions back-to-back
;
; ldx tileAddr
; ldy dynTileAddr
; jsr CopyTileDToDyn
; jsr CopyTileMToDyn
CopyTileMToDyn
phb
pea $0000
plb
plb
ldal tiledata+32+0,x
sta: $0080,y
ldal tiledata+32+2,x
sta: $0082,y
ldal tiledata+32+4,x
sta $0180,y
ldal tiledata+32+6,x
sta $0182,y
ldal tiledata+32+8,x
sta $0280,y
ldal tiledata+32+10,x
sta $0282,y
ldal tiledata+32+12,x
sta $0380,y
ldal tiledata+32+14,x
sta $0382,y
ldal tiledata+32+16,x
sta $0480,y
ldal tiledata+32+18,x
sta $0482,y
ldal tiledata+32+20,x
sta $0580,y
ldal tiledata+32+22,x
sta $0582,y
ldal tiledata+32+24,x
sta $0680,y
ldal tiledata+32+26,x
sta $0682,y
ldal tiledata+32+28,x
sta $0780,y
ldal tiledata+32+30,x
sta $0782,y
plb
rts
; CopyBG0Tile
;
; A low-level function that copies 8x8 tiles directly into the code field space.

View File

@ -69,8 +69,8 @@ DynamicOver
sec
lda _JTBL_CACHE
sbc #32 ; All the snippets are 32 bytes wide and, since we're
sta _JTBL_CACHE ; within one tile, the second column is consecutive
sbc #SNIPPET_SIZE ; Advance to the next snippet (Reverse indexing)
sta _JTBL_CACHE
clc
lda _OP_CACHE
@ -95,7 +95,7 @@ DynamicUnder
lda TileStore+TS_TILE_ID,x ; Get the original tile descriptor
and #$007F ; clamp to < (32 * 4)
ora #$B500
ora #$3580 ; Pre-calc the AND $80,x opcode + operand
xba
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
@ -115,8 +115,8 @@ DynamicUnder
sec
lda _JTBL_CACHE
sbc #32 ; All the snippets are 32 bytes wide and, since we're
sta _JTBL_CACHE ; within one tile, the second column is consecutive
sbc #SNIPPET_SIZE
sta _JTBL_CACHE
clc
lda _OP_CACHE
@ -181,7 +181,7 @@ mixed cmp #$FFFF ; All 1's in the mask is a fully
lda #$004C ; JMP to handler
sta: {]2},y
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$F000} ; adjust for the current row offset
ora #{]2&$7000} ; adjust for the current row offset
sta: {]2}+1,y
tax ; This becomes the new address that we use to patch in
@ -228,22 +228,138 @@ CopyDynUnder MAC
; bra *+16
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$F000} ; adjust for the current row offset
sta: ]2+1,y
tay ; This becomes the new address that we use to patch in
ora #{]2&$7000} ; adjust for the current row offset
sta: {]2}+1,y
tax ; This becomes the new address that we use to patch in
lda #$00A9 ; LDA #DATA
sta: $0000,y
ldal tmp_sprite_data+{]1},x
sta: $0001,y
sta: $0000,x
lda tmp_sprite_data+{]1}
sta: $0001,x
lda _OP_CACHE
sta: $0003,y ; AND $80,x
sta: $0003,x ; AND $80,x
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
sta: $0005,y ; ORA $00,x
sta: $0005,x ; ORA $00,x
lda #$0E80 ; branch to the prologue (BRA *+16)
sta: $0007,y
sta: $0007,x
eom
ldy _Y_REG ; restore original y-register value and move on
eom
; Helper functions to move tile data into the dynamic tile space
; Helper functions to copy tile data to the appropriate location in Bank 0
; X = tile ID
; Y = dynamic tile ID
CopyTileToDyn
txa
jsr _GetTileAddr
tax
tya
and #$001F ; Maximum of 32 dynamic tiles
asl
asl ; 4 bytes per page
adc BlitterDP ; Add to the bank 00 base address
adc #$0100 ; Go to the next page
tay
jsr CopyTileDToDyn ; Copy the tile data
jmp CopyTileMToDyn ; Copy the tile mask
; X = address of tile
; Y = tile address in bank 0
CopyTileDToDyn
phb
pea $0000
plb
plb
ldal tiledata+0,x
sta: $0000,y
ldal tiledata+2,x
sta: $0002,y
ldal tiledata+4,x
sta $0100,y
ldal tiledata+6,x
sta $0102,y
ldal tiledata+8,x
sta $0200,y
ldal tiledata+10,x
sta $0202,y
ldal tiledata+12,x
sta $0300,y
ldal tiledata+14,x
sta $0302,y
ldal tiledata+16,x
sta $0400,y
ldal tiledata+18,x
sta $0402,y
ldal tiledata+20,x
sta $0500,y
ldal tiledata+22,x
sta $0502,y
ldal tiledata+24,x
sta $0600,y
ldal tiledata+26,x
sta $0602,y
ldal tiledata+28,x
sta $0700,y
ldal tiledata+30,x
sta $0702,y
plb
rts
; Helper function to copy tile mask to the appropriate location in Bank 0
;
; X = address of tile
; Y = tile address in bank 0
;
; Argument are the same as CopyTileDToDyn, the code takes care of adjust offsets.
; This make is possible to call the two functions back-to-back
;
; ldx tileAddr
; ldy dynTileAddr
; jsr CopyTileDToDyn
; jsr CopyTileMToDyn
CopyTileMToDyn
phb
pea $0000
plb
plb
ldal tiledata+32+0,x
sta: $0080,y
ldal tiledata+32+2,x
sta: $0082,y
ldal tiledata+32+4,x
sta $0180,y
ldal tiledata+32+6,x
sta $0182,y
ldal tiledata+32+8,x
sta $0280,y
ldal tiledata+32+10,x
sta $0282,y
ldal tiledata+32+12,x
sta $0380,y
ldal tiledata+32+14,x
sta $0382,y
ldal tiledata+32+16,x
sta $0480,y
ldal tiledata+32+18,x
sta $0482,y
ldal tiledata+32+20,x
sta $0580,y
ldal tiledata+32+22,x
sta $0582,y
ldal tiledata+32+24,x
sta $0680,y
ldal tiledata+32+26,x
sta $0682,y
ldal tiledata+32+28,x
sta $0780,y
ldal tiledata+32+30,x
sta $0782,y
plb
rts

View File

@ -34,77 +34,6 @@ ThreeSprites tyx
FourSprites tyx
jmp CopyFourSpritesDataAndMaskToDP
; Simple pair of routines that copies just the tile data to the direct page workspace. Data Bank
; must be set to the TileData bank in entry.
;
; Preserves the X-register
CopyTileDataToDPA
]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
; Given a populate tmp_sprite_data buffer to use as a base, merge it with a tile and write to the
; code field
MergeSpriteWithTileFast
ldx TileStore+TS_TILE_ADDR,y
lda TileStore+TS_CODE_ADDR_HIGH,y ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
lda TileStore+TS_CODE_ADDR_LOW,y ; load the address of the code field
tay
plb
]line equ 0
lup 8
lda tmp_sprite_data+{]line*4}
andl tiledata+{]line*4}+32,x
oral tiledata+{]line*4},x
sta: $0004+{]line*$1000},y
lda tmp_sprite_data+{]line*4}+2
andl tiledata+{]line*4}+32+2,x
oral tiledata+{]line*4}+2,x
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
plb
rts
MergeSpriteWithTileSlow
ldx TileStore+TS_TILE_ADDR,y
lda TileStore+TS_CODE_ADDR_HIGH,y ; load the bank of the target code field line
pha ; and put on the stack for later. Has TileStore bank in high byte.
lda TileStore+TS_CODE_ADDR_LOW,y ; load the address of the code field
tay
plb
]line equ 0
lup 8
lda tmp_sprite_data+{]line*4}
andl tiledata+{]line*4}+32,x
oral tiledata+{]line*4},x
sta: $0004+{]line*$1000},y
lda tmp_sprite_data+{]line*4}+2
andl tiledata+{]line*4}+32+2,x
oral tiledata+{]line*4}+2,x
sta: $0001+{]line*$1000},y
]line equ ]line+1
--^
jmp _FillPEAOpcode
; Now, implement the generic Two, Three and Four sprite routines for both Over and Under rendering. These
; are fairly involved, so we try to only have a single implementation of them for now without excessve
; specialization.

View File

@ -156,7 +156,8 @@ OneSpriteSlowUnderV
; Dynamic tiles with one sprite.
OneSpriteDynamicUnder
ldx sprite_ptr0
txy
tax
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
@ -165,10 +166,12 @@ OneSpriteDynamicUnder
sta tmp_sprite_data+{]line*4}+2
]line equ ]line+1
--^
tyx
jmp DynamicUnder
OneSpriteDynamicOver
ldx sprite_ptr0
txy
tax
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
@ -178,9 +181,10 @@ OneSpriteDynamicOver
ldal spritemask+{]line*SPRITE_PLANE_SPAN},x
sta tmp_sprite_mask+{]line*4}
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
sta tmp_sprite_mask+{]line*4}+2
]line equ ]line+1
--^
tyx
jmp DynamicOver