Implement framework for adjusting VBuff tables to handle boundary transitions

This commit is contained in:
Lucas Scharenbroich 2022-06-06 11:23:00 -05:00
parent 36d57f7c2d
commit b6202ca44c
6 changed files with 292 additions and 115 deletions

View File

@ -246,3 +246,5 @@ _SpriteBits EXT
_SpriteBitsNot EXT _SpriteBitsNot EXT
VBuffArray EXT VBuffArray EXT
_stamp_step EXT _stamp_step EXT
VBuffVertTableSelect EXT
VBuffHorzTableSelect EXT

View File

@ -19,27 +19,72 @@ InitSprites
cpx #$FFFE cpx #$FFFE
bne :loop2 bne :loop2
; Set the VBuff array addresses for each sprite, since they're static ; Initialize the VBuff offset values for the different cases
ldx #0 TILE_STORE_SPAN equ {TILE_STORE_WIDTH*2}
lda #VBuffArray LAST_ROW equ {TILE_STORE_SPAN*{TILE_STORE_HEIGHT-1}}
:loop3 sta _Sprites+VBUFF_ARRAY_ADDR,x NEXT_TO_LAST_ROW equ {TILE_STORE_SPAN*{TILE_STORE_HEIGHT-2}}
clc LAST_COL equ {TILE_STORE_WIDTH-1}*2
adc #4*2 ; skip ahead 4 tiles NEXT_TO_LAST_COL equ {TILE_STORE_WIDTH-2}*2
inx
inx lda #0 ; Normal row, Normal column
cpx #8*2 ldx #0
bcc :loop3 jsr _SetVBuffValues
lda #8
ldx #LAST_COL ; Normal row, Last column
jsr _SetVBuffValues
lda #16
ldx #NEXT_TO_LAST_COL ; Normal row, Next-to-Last column
jsr _SetVBuffValues
lda #24 ; Last row, normal column
ldx #LAST_ROW
jsr _SetVBuffValues
lda #32
ldx #LAST_ROW+LAST_COL ; Last row, Last column
jsr _SetVBuffValues
lda #40
ldx #LAST_ROW+NEXT_TO_LAST_COL ; Last row, Next-to-Last column
jsr _SetVBuffValues
lda #48 ; Next-to-Last row, normal column
ldx #NEXT_TO_LAST_ROW
jsr _SetVBuffValues
lda #56
ldx #NEXT_TO_LAST_ROW+LAST_COL ; Next-to-Last row, Last column
jsr _SetVBuffValues
lda #64
ldx #NEXT_TO_LAST_ROW+NEXT_TO_LAST_COL ; Next-to-Last row, Next-to-Last column
jsr _SetVBuffValues
; Set the VBuff array addresses for each sprite, since they're static
;
; NOTE: Can remove later
; ldx #0
; lda #VBuffArray
;:loop3 sta _Sprites+VBUFF_ARRAY_ADDR,x
; clc
; adc #4*2 ; skip ahead 4 tiles
; inx
; inx
; cpx #8*2
; bcc :loop3
; Now do the second set of sprites ; Now do the second set of sprites
lda #VBuffArray+{3*{TILE_STORE_WIDTH*2}} ; lda #VBuffArray+{3*{TILE_STORE_WIDTH*2}}
:loop4 sta _Sprites+VBUFF_ARRAY_ADDR,x ;:loop4 sta _Sprites+VBUFF_ARRAY_ADDR,x
clc ; clc
adc #4*2 ; skip ahead 4 tiles ; adc #4*2 ; skip ahead 4 tiles
inx ; inx
inx ; inx
cpx #16*2 ; cpx #16*2
bcc :loop4 ; bcc :loop4
; Initialize the Page 2 pointers ; Initialize the Page 2 pointers
ldx #$100 ldx #$100
@ -53,6 +98,53 @@ InitSprites
jsr _CacheSpriteBanks jsr _CacheSpriteBanks
rts rts
; Call with X-register set to TileStore tile and Acc set to the VBuff slot offset
_SetVBuffValues
COL_BYTES equ 4 ; VBUFF_TILE_COL_BYTES
ROW_BYTES equ 384 ; VBUFF_TILE_ROW_BYTES
clc
adc #VBuffArray
sec
sbc TileStoreLookup,x
sta tmp0
ldy TileStoreLookup,x
lda #{0*COL_BYTES}+{0*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+2,x
lda #{1*COL_BYTES}+{0*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+4,x
lda #{2*COL_BYTES}+{0*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+1*{TS_LOOKUP_SPAN*2},x
lda #{0*COL_BYTES}+{1*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+1*{TS_LOOKUP_SPAN*2}+2,x
lda #{1*COL_BYTES}+{1*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+1*{TS_LOOKUP_SPAN*2}+4,x
lda #{2*COL_BYTES}+{1*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+2*{TS_LOOKUP_SPAN*2},x
lda #{0*COL_BYTES}+{2*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+2*{TS_LOOKUP_SPAN*2}+2,x
lda #{1*COL_BYTES}+{2*ROW_BYTES}
sta (tmp0),y
ldy TileStoreLookup+2*{TS_LOOKUP_SPAN*2}+4,x
lda #{2*COL_BYTES}+{2*ROW_BYTES}
sta (tmp0),y
rts
; _RenderSprites ; _RenderSprites
; ;
; The function is responsible for updating all of the rendering information based on any changes ; The function is responsible for updating all of the rendering information based on any changes

View File

@ -88,7 +88,7 @@ _CalcDirtySprite
lsr lsr
tax tax
lda TileStoreLookupYTable,x lda TileStoreLookupYTable,x
sta RowTop ; Even numbers from [0, 100] (50 elements) sta RowTop ; Even numbers from [0, 100] (51 elements)
; Get the position of the top edge within the tile and then add it to the sprite's height ; Get the position of the top edge within the tile and then add it to the sprite's height
; to calculate the number of tiles that are overlapped. We use the actual width and height ; to calculate the number of tiles that are overlapped. We use the actual width and height
@ -112,7 +112,12 @@ _CalcDirtySprite
adc StartXMod164 adc StartXMod164
pha pha
and #$FFFC and #$FFFC
lsr ; Even numbers from [0, 160] (80 elements) lsr ; Even numbers from [0, 160] (81 elements)
; cmp #TILE_STORE_WIDTH*2
; bcc :x_in_range
; sbc #TILE_STORE_WIDTH*2
;:x_in_range
sta tmp3
adc RowTop adc RowTop
sta _Sprites+TS_LOOKUP_INDEX,y ; This is the index into the TileStoreLookup table sta _Sprites+TS_LOOKUP_INDEX,y ; This is the index into the TileStoreLookup table
@ -174,9 +179,17 @@ _CalcDirtySprite
; Create an offset value for loading the calculated VBUFF addresses within the core renderer by ; Create an offset value for loading the calculated VBUFF addresses within the core renderer by
; subtracting the actual TileStore offset from the sprite's vbuff address array ; subtracting the actual TileStore offset from the sprite's vbuff address array
;
; The X-register still has the TileStoreLookupYTable index, which we re-use to get a VBuff
; array selector for the vertical location
lda VBuffVertTableSelect,x ; A bunch of 12, 24 or 36 values
clc
ldx tmp3
adc VBuffHorzTableSelect,x ; A bunch of 0, 4 or 8 values
clc
adc #VBuffArray
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
lda _Sprites+VBUFF_ARRAY_ADDR,y
sec sec
sbc TileStoreLookup,x sbc TileStoreLookup,x
sta tmp1 ; Spill this value to direct page temp space sta tmp1 ; Spill this value to direct page temp space
@ -245,20 +258,20 @@ ROW equ TILE_STORE_WIDTH*2 ; This many bytes to the nex
COL equ 2 ; This many bytes for each element COL equ 2 ; This many bytes for each element
:mark1x1 :mark1x1
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; get the address of this sprite's vbuff values ; ldx _Sprites+VBUFF_ARRAY_ADDR,y ; get the address of this sprite's vbuff values
lda _Sprites+TS_VBUFF_BASE,y ; get the starting vbuff address ; lda _Sprites+TS_VBUFF_BASE,y ; get the starting vbuff address
sta: {0*ROW}+{0*COL},x ; Put in the vbuff address ; sta: {0*ROW}+{0*COL},x ; Put in the vbuff address
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2} TSSetSprite 0*{TS_LOOKUP_SPAN*2}
rts rts
:mark1x2 :mark1x2
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{1*COL},x ; sta: {0*ROW}+{1*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0
@ -266,13 +279,13 @@ COL equ 2 ; This many bytes for each e
rts rts
:mark1x3 :mark1x3
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{1*COL},x ; sta: {0*ROW}+{1*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{2*COL},x ; sta: {0*ROW}+{2*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0
@ -281,11 +294,11 @@ COL equ 2 ; This many bytes for each e
rts rts
:mark2x1 :mark2x1
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_ROW_BYTES ; adc #VBUFF_TILE_ROW_BYTES
sta: {1*ROW}+{0*COL},x ; sta: {1*ROW}+{0*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0
@ -293,15 +306,15 @@ COL equ 2 ; This many bytes for each e
rts rts
:mark2x2 :mark2x2
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{1*COL},x ; sta: {0*ROW}+{1*COL},x
adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{0*COL},x ; sta: {1*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{1*COL},x ; sta: {1*ROW}+{1*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0
@ -311,19 +324,19 @@ COL equ 2 ; This many bytes for each e
rts rts
:mark2x3 :mark2x3
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{1*COL},x ; sta: {0*ROW}+{1*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{2*COL},x ; sta: {0*ROW}+{2*COL},x
adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES} ; adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES}
sta: {1*ROW}+{0*COL},x ; sta: {1*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{1*COL},x ; sta: {1*ROW}+{1*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{2*COL},x ; sta: {1*ROW}+{2*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0
@ -335,13 +348,13 @@ COL equ 2 ; This many bytes for each e
rts rts
:mark3x1 :mark3x1
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_ROW_BYTES ; adc #VBUFF_TILE_ROW_BYTES
sta: {1*ROW}+{0*COL},x ; sta: {1*ROW}+{0*COL},x
adc #VBUFF_TILE_ROW_BYTES ; adc #VBUFF_TILE_ROW_BYTES
sta: {2*ROW}+{0*COL},x ; sta: {2*ROW}+{0*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0
@ -350,19 +363,19 @@ COL equ 2 ; This many bytes for each e
rts rts
:mark3x2 :mark3x2
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{1*COL},x ; sta: {0*ROW}+{1*COL},x
adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{0*COL},x ; sta: {1*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{1*COL},x ; sta: {1*ROW}+{1*COL},x
adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_ROW_BYTES-VBUFF_TILE_COL_BYTES
sta: {2*ROW}+{0*COL},x ; sta: {2*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {2*ROW}+{1*COL},x ; sta: {2*ROW}+{1*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0
@ -374,25 +387,25 @@ COL equ 2 ; This many bytes for each e
rts rts
:mark3x3 :mark3x3
ldx _Sprites+VBUFF_ARRAY_ADDR,y ; ldx _Sprites+VBUFF_ARRAY_ADDR,y
lda _Sprites+TS_VBUFF_BASE,y ; lda _Sprites+TS_VBUFF_BASE,y
sta: {0*ROW}+{0*COL},x ; sta: {0*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{1*COL},x ; sta: {0*ROW}+{1*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {0*ROW}+{2*COL},x ; sta: {0*ROW}+{2*COL},x
adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES} ; adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES}
sta: {1*ROW}+{0*COL},x ; sta: {1*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{1*COL},x ; sta: {1*ROW}+{1*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {1*ROW}+{2*COL},x ; sta: {1*ROW}+{2*COL},x
adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES} ; adc #VBUFF_TILE_ROW_BYTES-{2*VBUFF_TILE_COL_BYTES}
sta: {2*ROW}+{0*COL},x ; sta: {2*ROW}+{0*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {2*ROW}+{1*COL},x ; sta: {2*ROW}+{1*COL},x
adc #VBUFF_TILE_COL_BYTES ; adc #VBUFF_TILE_COL_BYTES
sta: {2*ROW}+{2*COL},x ; sta: {2*ROW}+{2*COL},x
ldx _Sprites+TS_LOOKUP_INDEX,y ldx _Sprites+TS_LOOKUP_INDEX,y
TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0 TSSetSprite 0*{TS_LOOKUP_SPAN*2}+0

View File

@ -287,10 +287,14 @@ dobit1 mac
beq last_bit beq last_bit
tax tax
lda (SPRITE_VBUFF_PTR+{]1*2}),y lda (SPRITE_VBUFF_PTR+{]1*2}),y
clc
adc _Sprites+TS_VBUFF_BASE+{]1*2}
sta sprite_ptr0+{]2*4} sta sprite_ptr0+{]2*4}
txa txa
jmp ]3 jmp ]3
last_bit lda (SPRITE_VBUFF_PTR+{]1*2}),y last_bit lda (SPRITE_VBUFF_PTR+{]1*2}),y
clc ; pre-adjust these later
adc _Sprites+TS_VBUFF_BASE+{]1*2}
jmp ]4 jmp ]4
next_bit next_bit
<<< <<<

View File

@ -59,7 +59,7 @@ TileStoreLookup ENT
lup TILE_STORE_HEIGHT lup TILE_STORE_HEIGHT
TileStoreData ]row*2*TILE_STORE_WIDTH TileStoreData ]row*2*TILE_STORE_WIDTH
TileStoreData ]row*2*TILE_STORE_WIDTH TileStoreData ]row*2*TILE_STORE_WIDTH
dw ]row*2*TILE_STORE_WIDTH dw ]row*2*TILE_STORE_WIDTH,]row*2*TILE_STORE_WIDTH+2
]row equ ]row+1 ]row equ ]row+1
--^ --^
@ -68,14 +68,17 @@ TileStoreLookup ENT
lup TILE_STORE_HEIGHT lup TILE_STORE_HEIGHT
TileStoreData ]row*2*TILE_STORE_WIDTH TileStoreData ]row*2*TILE_STORE_WIDTH
TileStoreData ]row*2*TILE_STORE_WIDTH TileStoreData ]row*2*TILE_STORE_WIDTH
dw ]row*2*TILE_STORE_WIDTH dw ]row*2*TILE_STORE_WIDTH,]row*2*TILE_STORE_WIDTH+2
]row equ ]row+1 ]row equ ]row+1
--^ --^
; Last row ; Last two rows
TileStoreData 0*2*TILE_STORE_WIDTH TileStoreData 0*2*TILE_STORE_WIDTH
TileStoreData 0*2*TILE_STORE_WIDTH TileStoreData 0*2*TILE_STORE_WIDTH
dw 0*2*TILE_STORE_WIDTH dw 0*2*TILE_STORE_WIDTH,0*2*TILE_STORE_WIDTH+2
TileStoreData 1*2*TILE_STORE_WIDTH
TileStoreData 1*2*TILE_STORE_WIDTH
dw 1*2*TILE_STORE_WIDTH,1*2*TILE_STORE_WIDTH+2
;------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------
; ;
@ -408,14 +411,73 @@ ScreenModeHeight ENT
dw 200,192,200,176,160,160,160,128,144,192,102,1 dw 200,192,200,176,160,160,160,128,144,192,102,1
; VBuff arrays for each sprite. We need at least a 3x3 block for each sprite and the shape of the ; VBuff arrays for each sprite. We need at least a 3x3 block for each sprite and the shape of the
; array must match the TileStore structure. The TileStore is 41 blocks wide. To keep things simple ; array must match the TileStore structure. The TileStore is 41 blocks wide.
; we allocate 8 sprites in the first row and 8 more sprites in the 4th row. So we need to allocate a
; total of 6 rows of TileStore space
; ;
; It is *critical* that this array be placed in a memory location that is greater than the largest ; It is *critical* that this array be placed in a memory location that is greater than the largest
; TileStore offset. ; TileStore offset because the engine maintaines a per-sprite pointer equal to the VBuff array
VBuffArray ENT ; address minut the TileStore offset for the top-left corner of that sprite. This allows all of
ds 6*{TILE_STORE_WIDTH*2} ; the sprites to share the same table, but the result of the subtraction has to be positive.
;
; Each block of data contains fixed offsets for the relative position of vbuff addresses. There
; are multiple copies of the array to handle cases where a sprite needs to transition across the
; boundary.
;
; For example. If a sprite is drawn in the last column, but is two blocks wide, the TileIndex
; value for the first column is $52 and the second column is $00. Since the pointer to the
; VBuffArray is pre-adjusted by the first column's size, the first offset value will be read
; from (VBuffArray - $52)[$52] = VBuffArray[0], which is correct. However, the second column will be
; read from (VBuffArray - $52)[$00] which is one row off from the correct value's location.
;
; The wrapping also need to account for vertical wrapping. Consider a 16x16 sprite with its top-left
; conder inside the physical tile that is the bottom-right-most tile in the Tile Store. So, the
; lookup index for this tile is (26*41*2)-2 = 2130. When using the lookup table, each step to the
; right or down will cause wrap-around. So the lookup addresses look like this
;
; +------+------+ +------+------+
; | $852 | $800 | | $000 | $004 |
; +------+------+ --> +------+------+
; | $052 | $000 | | $030 | $034 |
; +------+------+ +------+------+
;
; We need to maintain 9 different lookup table variations, which is equal to the number of tile
; in the largest sprite (3x3 tiles = 9 different border cases)
;COL_BYTES equ 4 ; VBUFF_TILE_COL_BYTES
;ROW_BYTES equ 384 ; VBUFF_TILE_ROW_BYTES
; Define the offset values
;___NA_NA___ equ 0
;ROW_0_COL_0 equ {{0*COL_BYTES}+{0*ROW_BYTES}}
;ROW_0_COL_1 equ {{1*COL_BYTES}+{0*ROW_BYTES}}
;ROW_0_COL_2 equ {{2*COL_BYTES}+{0*ROW_BYTES}}
;ROW_1_COL_0 equ {{0*COL_BYTES}+{1*ROW_BYTES}}
;ROW_1_COL_1 equ {{1*COL_BYTES}+{1*ROW_BYTES}}
;ROW_1_COL_2 equ {{2*COL_BYTES}+{1*ROW_BYTES}}
;ROW_2_COL_0 equ {{0*COL_BYTES}+{2*ROW_BYTES}}
;ROW_2_COL_1 equ {{1*COL_BYTES}+{2*ROW_BYTES}}
;ROW_2_COL_2 equ {{2*COL_BYTES}+{2*ROW_BYTES}}
; Allocate an amount of space equal to a TileStore block because we could have vertical wrap around.
; The rest of the values are in just the first few rows following this block
;
; The first block of 4 values is the "normal" case, (X in [0, N-3], Y in [0, M-3]), so no wrap around is needed
; The second block is (X = N-1, Y in [0, M-3])
; The third block is (X = N-2, Y in [0, M-3])
; The fourth block is (X in [0, N-3], Y = M-1)
; The fifth block is (X = N-1, Y = M-1)
; The sixth block is (X = N-2, Y = M-1)
; The seventh block is (X in [0, N-3], Y = M-2)
; The eighth block is (X = N-1, Y = M-2)
; The ninth block is (X = N-2, Y = M-2)
VBuffVertTableSelect ENT
ds 51*2
VBuffHorzTableSelect ENT
ds 81*2
VBuffStart ds TILE_STORE_SIZE
VBuffArray ENT
ds {TILE_STORE_WIDTH*2}*3
; Convert sprite index to a bit position ; Convert sprite index to a bit position
_SpriteBits ENT _SpriteBits ENT

View File

@ -77,12 +77,16 @@ VBUFF_ARRAY_ADDR equ {MAX_SPRITES*40} ; Fixed address where this spri
;TILE_STORE_ADDR_9 equ {MAX_SPRITES*28} ;TILE_STORE_ADDR_9 equ {MAX_SPRITES*28}
;TILE_STORE_ADDR_10 equ {MAX_SPRITES*30} ;TILE_STORE_ADDR_10 equ {MAX_SPRITES*30}
; 51 rows by 81 columns + 2 extra rows and columns for sprite sizes ; 52 rows by 82 columns + 2 extra rows and columns for sprite sizes
; ;
; 53 rows = TILE_STORE_HEIGHT + TILE_STORE_HEIGHT + 1 ; 53 rows = TILE_STORE_HEIGHT + TILE_STORE_HEIGHT + 1
; 83 cols = TILE_STORE_WIDTH + TILE_STORE_WIDTH + 1 ; 83 cols = TILE_STORE_WIDTH + TILE_STORE_WIDTH + 1
TS_LOOKUP_WIDTH equ 81 ;
TS_LOOKUP_HEIGHT equ 51 ; TILE_STORE_WIDTH equ 41
; TILE_STORE_HEIGHT equ 26
TS_LOOKUP_WIDTH equ 82
TS_LOOKUP_HEIGHT equ 52
TS_LOOKUP_BORDER equ 2 TS_LOOKUP_BORDER equ 2
TS_LOOKUP_SPAN equ {TS_LOOKUP_WIDTH+TS_LOOKUP_BORDER} TS_LOOKUP_SPAN equ {TS_LOOKUP_WIDTH+TS_LOOKUP_BORDER}
TS_LOOKUP_ROWS equ {TS_LOOKUP_HEIGHT+TS_LOOKUP_BORDER} TS_LOOKUP_ROWS equ {TS_LOOKUP_HEIGHT+TS_LOOKUP_BORDER}