Generalize _DrawSprite to handle all sizes and flip bits.

This commit is contained in:
Lucas Scharenbroich 2021-11-20 12:00:21 -06:00
parent e65e6dac8b
commit 0cc28f9e6e
4 changed files with 225 additions and 50 deletions

View File

@ -8,7 +8,7 @@
use .\Defs.s use .\Defs.s
; Feature flags ; Feature flags
NO_INTERRUPTS equ 0 ; turn off for crossrunner debugging NO_INTERRUPTS equ 1 ; turn off for crossrunner debugging
NO_MUSIC equ 1 ; turn music + tool loading off NO_MUSIC equ 1 ; turn music + tool loading off
; External data provided by the main program segment ; External data provided by the main program segment

View File

@ -137,7 +137,14 @@ TILE_DYN_BIT equ $0800
TILE_VFLIP_BIT equ $0400 TILE_VFLIP_BIT equ $0400
TILE_HFLIP_BIT equ $0200 TILE_HFLIP_BIT equ $0200
; Tile Store Offsets (internals) ; Sprite constants
SPRITE_16X16 equ $1800
SPRITE_16X8 equ $1000
SPRITE_8X16 equ $0800
SPRITE_8X8 equ $0000
SPRITE_VFLIP equ $0400
SPRITE_HFLIP equ $0200
MAX_TILES equ {26*41} ; Number of tiles in the code field (41 columns * 26 rows) MAX_TILES equ {26*41} ; Number of tiles in the code field (41 columns * 26 rows)
TILE_STORE_SIZE equ {MAX_TILES*2} ; The tile store contains a tile descriptor in each slot TILE_STORE_SIZE equ {MAX_TILES*2} ; The tile store contains a tile descriptor in each slot

View File

@ -152,38 +152,7 @@ _RenderSprites
; Draw the sprite into the sprint plane buffer(s) ; Draw the sprite into the sprint plane buffer(s)
ldx _Sprites+VBUFF_ADDR,y ; Get the address in the sprite plane to draw at jsr _DrawSpriteY ; Use variant that takes the Y-register arg
lda _Sprites+TILE_DATA_OFFSET,y ; and the tile address of the tile
tay
jsr _DrawTileSprite ; draw the sprite into the sprite plane
tya
clc
adc #128
tay
txa
clc
adc #4
tax
jsr _DrawTileSprite
tya
clc
adc #128*31
tay
txa
clc
adc #{8*256}-4
tax
jsr _DrawTileSprite
tya
clc
adc #128
tay
txa
clc
adc #4
tax
jsr _DrawTileSprite
; Mark the appropriate tiles as dirty and as occupied by a sprite so that the ApplyTiles ; Mark the appropriate tiles as dirty and as occupied by a sprite so that the ApplyTiles
; subroutine will get the drawn data from the sprite plane into the code field where it ; subroutine will get the drawn data from the sprite plane into the code field where it
@ -501,7 +470,7 @@ _GetTileAt
clc clc
rts rts
; _DrawSprite ; _DrawSprites
; ;
; Draw the sprites on the _Sprite list into the Sprite Plane data and mask buffers. This is using the ; Draw the sprites on the _Sprite list into the Sprite Plane data and mask buffers. This is using the
; tile data right now, but could be replaced with compiled sprite routines. ; tile data right now, but could be replaced with compiled sprite routines.
@ -513,11 +482,7 @@ _DrawSprites
bne :skip bne :skip
phx phx
jsr _DrawSprite
lda _Sprites+VBUFF_ADDR,x ; Load the address in the sprite plane
ldy _Sprites+TILE_DATA_OFFSET,x ; Load the address in the tile data bank
tax
jsr _DrawTileSprite
plx plx
:skip :skip
inx inx
@ -525,11 +490,186 @@ _DrawSprites
bra :loop bra :loop
:out rts :out rts
; X = _Sprites array offset
_DrawSprite
txy
_DrawSpriteY
lda _Sprites+SPRITE_ID,y
and #$1E00 ; use bits 9, 10, 11 and 12 to dispatch
xba
tax
jmp (:draw_sprite,x)
:draw_sprite dw draw_8x8,draw_8x8h,draw_8x8v,draw_8x8hv
dw draw_8x16,draw_8x16h,draw_8x16v,draw_8x16hv
dw draw_16x8,draw_16x8h,draw_16x8v,draw_16x8hv
dw draw_16x16,draw_16x16h,draw_16x16,draw_16x16h
draw_8x8
draw_8x8h
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
tay
jmp _DrawTile8x8
draw_8x8v
draw_8x8hv
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
tay
jmp _DrawTile8x8V
draw_8x16
draw_8x16h
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
tay
jsr _DrawTile8x8
clc
txa
adc #{8*SPRITE_PLANE_SPAN}
tax
tya
adc #{128*32} ; 32 tiles to the next verical one, each tile is 128 bytes
tay
jmp _DrawTile8x8
draw_8x16v
draw_8x16hv
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
tay
jsr _DrawTile8x8V
clc
txa
adc #{8*SPRITE_PLANE_SPAN}
tax
tya
adc #{128*32}
tay
jmp _DrawTile8x8V
draw_16x8
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
tay
jsr _DrawTile8x8
clc
txa
adc #4
tax
tya
adc #128 ; Next tile is 128 bytes away
tay
jmp _DrawTile8x8
draw_16x8h
clc
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
pha
adc #128
tay
jsr _DrawTile8x8
txa
adc #4
tax
ply
jmp _DrawTile8x8
draw_16x8v
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
tay
jsr _DrawTile8x8V
clc
txa
adc #4
tax
tya
adc #128
tay
jmp _DrawTile8x8V
draw_16x8hv
clc
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
pha
adc #128
tay
jsr _DrawTile8x8V
txa
adc #4
tax
ply
jmp _DrawTile8x8V
draw_16x16
clc
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
tay
jsr _DrawTile8x8
txa
adc #4
tax
tya
adc #128
tay
jsr _DrawTile8x8
txa
adc #{8*SPRITE_PLANE_SPAN}-4
tax
tya
adc #{128*{32-1}}
tay
jsr _DrawTile8x8
txa
adc #4
tax
tya
adc #128
tay
jmp _DrawTile8x8
draw_16x16h
clc
ldx _Sprites+VBUFF_ADDR,y
lda _Sprites+TILE_DATA_OFFSET,y
pha
adc #128
tay
jsr _DrawTile8x8
txa
adc #4
tax
ply
jsr _DrawTile8x8
txa
adc #{8*SPRITE_PLANE_SPAN}-4
tax
tya
adc #{128*32}
pha
adc #128
tay
jsr _DrawTile8x8
txa
adc #4
tax
ply
jmp _DrawTile8x8
DrawTileSprite ENT DrawTileSprite ENT
jsr _DrawTileSprite jsr _DrawTile8x8
rtl rtl
_DrawTileSprite ; X = sprite vbuff address
; Y = tile data pointer
_DrawTile8x8
phb phb
pea #^tiledata ; Set the bank to the tile data pea #^tiledata ; Set the bank to the tile data
plb plb
@ -560,6 +700,41 @@ _DrawTileSprite
plb plb
rts rts
; X = sprite vbuff address
; Y = tile data pointer
;
; Draws the tile vertically flipped
_DrawTile8x8V
phb
pea #^tiledata ; Set the bank to the tile data
plb
]line equ 0
lup 8
lda: tiledata+32+{{7-]line}*4},y
andl spritemask+{]line*256},x
stal spritemask+{]line*256},x
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
and: tiledata+32+{{7-]line}*4},y
ora: tiledata+{{7-]line}*4},y
stal spritedata+{]line*SPRITE_PLANE_SPAN},x
lda: tiledata+32+{{7-]line}*4}+2,y
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
stal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
and: tiledata+32+{{7-]line}*4}+2,y
ora: tiledata+{{7-]line}*4}+2,y
stal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
]line equ ]line+1
--^
plb ; pop extra byte
plb
rts
; Erase is easy -- set an 8x8 area of the data region to all $0000 and the corresponding mask ; Erase is easy -- set an 8x8 area of the data region to all $0000 and the corresponding mask
; resgion to all $FFFF ; resgion to all $FFFF
; ;
@ -739,12 +914,6 @@ _UpdateSprite
lda _Sprites+VBUFF_ADDR,x ; Save the previous draw location for erasing lda _Sprites+VBUFF_ADDR,x ; Save the previous draw location for erasing
sta _Sprites+OLD_VBUFF_ADDR,x sta _Sprites+OLD_VBUFF_ADDR,x
; lda _Sprites+SPRITE_X,x
; sta _Sprites+OLD_SPRITE_X,x
; lda _Sprites+SPRITE_Y,x
; sta _Sprites+OLD_SPRITE_Y,x
lda tmp0 ; Update the X coordinate lda tmp0 ; Update the X coordinate
sta _Sprites+SPRITE_X,x sta _Sprites+SPRITE_X,x

View File

@ -67,8 +67,7 @@ _GetTileAddr
bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set
beq :no_flip beq :no_flip
inc ; Set the LSB inc ; Set the LSB
:no_flip and #TILE_ID_MASK*2 ; Mask out non-id bits :no_flip asl ; x4
asl ; x4
asl ; x8 asl ; x8
asl ; x16 asl ; x16
asl ; x32 asl ; x32