Code: Select all
; *************************************************************
; ClearSprite
; Clears the sprite counter
; *************************************************************
ClearSprites:
move.b #0, (sprite_count) ; set sprite count to 0
rts
; *************************************************************
; AddSprite
; Adds a sprite to the sprite table and increments counter
; d0 - sprites y position
; d1 - width and height tile bits
; d2 - special (flipping, palette index, priority)
; d3 - tile id
; d4 - sprites x position
; a0 - sprite table
; *************************************************************
AddSprite:
move.b (sprite_count), d5 ; sprint count in d5
move.b d5, d6 ; d6 is used to calculate the sprite table offset
cmp #80, d5 ; are there too many sprites in the table already?
blt SpriteLimitNotReached ; if not branch
rts ; return
SpriteLimitNotReached:
lsl.b #$03, d6 ; calculate sprite table offset (sprite count * sprite size)
add.w d6, a0 ; increment address by offset
move.w d0, (a0) ; move sprites y position into table
addq.l #4, a0 ; increment address by a word
move.b d1, (a0) ; move sprites demensions into table
addq.l #2, a0 ; increment address by a byte
move.b d2, (a0) ; save sprites special bits in table
addq.l #2, a0 ; increment address by a byte
addq.l #1, d5 ; increment d5(sprite_count) by 1
move.b d5, (a0) ; index of next sprite is d5(sprite_count +1)
addq.l #2, a0 ; increment address by a byte
move.b d3, (a0) ; save sprites tile id in table
addq.l #2, a0 ; increment address by a byte
move.w d4, a0 ; save sprites x position in table
addq #1, (sprite_count) ; increment sprite counter by 1
rts
; *************************************************************
; Updates and draws the sprite table
; *************************************************************
UpdateSprites:
lea (spritelist_table), a0 ; sprite table in a0
move.b (sprite_count), d0 ; load sprite counter into d0
and.l #0x000000FF, d0
mulu.w #SizeSpriteDesc, d0 ; Offset into sprite table
swap d0 ; To upper word
or.l #vdp_write_sprite_table, d0 ; Add to write address
move.l d0, vdp_control ; Set read address
move.l (a0)+, vdp_data ; 8 bytes of data
move.l (a0)+, vdp_data
rts
Code: Select all
LoadSpriteTables:
; a0 --- Sprite data address
; d0 (b) Number of sprites
move.l #vdp_write_sprite_table, vdp_control
and.l #0x000000FF, d0
subq.b #0x1, d0 ; Minus 1 for counter
@AttrCopy:
move.l (a0)+, vdp_data ; 8 bytes of data
move.l (a0)+, vdp_data
dbra d0, @AttrCopy
rts
Code: Select all
OK so you want an arbitrary number of sprites
1) Reserve 640 bytes in RAM for a table *Complete*
2) Make a ClearSprites function that sets the sprite count to 0 *Complete?*
3) Make an AddSprite function that inserts a sprite into the table
(may want to check that there aren't too many sprites, i.e. 80)
4) Make an UpdateSprites function that loads the table to VRAM
:P
Incrementing a0
addq.l #1, a0
Replace #1 with a value from 1 to 8
Or replace addq with add if you need a larger value
:v
Storing offset to a0
lea (a0,d5.w), a0
-or-
add.w d5, a0
Pick either
Both do the job here
Then every frame:
1) Call ClearSprites at the beginning
2) Call AddSprite for every sprite you want to draw
3) Call UpdateSprites at the end
You don't need to keep track of sprites once added.
Also if you do run into the limit (80 sprites), huuuuh, I'd say to just drop the excess sprites (i.e. just return without adding them)
Sincerely,
Scorpion Illuminati