Sprite sorting by priority flag
Posted: Wed Jan 06, 2016 6:40 am
Whoa, I think this is the first time ever I actually take advantage of the linked list in the sprite table. Normally I just put sprites consecutively but I had gotten tired of ghosts going behind doors in Dragon's Castle and I didn't feel like coming up with a way to sort the objects for drawing (Star Chaser already got way too overengineered that way) so I've just made a routine that goes through the whole table and changes the links so first all the high priority sprites appear then all the low priority sprites (sprites with the same priority remain with the same order).
Here's the code if anybody cares.
Here's the code if anybody cares.
Code: Select all
;****************************************************************************
; SortSprites
; Relinks the sprites so they're sorted by their priority flag. This allows
; you to draw sprites in any order (something useful when drawing objects
; in-game, as you can't tell in which order the objects will be drawn).
;----------------------------------------------------------------------------
; breaks: all
;----------------------------------------------------------------------------
; QUIRK: this subroutine assumes that the first sprite will always appear on
; top of everything else (it fails to sort that one). This is not a problem
; in-game, where the HUD is always first (and HUD is high priority sprites).
; Don't use this subroutine unless really needed...
;****************************************************************************
SortSprites:
moveq #0, d0 ; Last high priority sprite
moveq #0, d1 ; Last low priority sprite
moveq #0, d2 ; First low priority sprite
move.b (NumSprites), d3 ; How many sprites are there?
bne.s @HasSprites
rts
@HasSprites:
lea (SpriteBuf), a0 ; Sprite table buffer
moveq #0, d7
@Loop:
move.w d7, d6 ; Check priority of the next sprite
lsl.w #3, d6
lea (a0,d6.w), a6
clr.b 3(a6)
btst.b #7, 4(a6)
bne.s @High
tst.b d2 ; Is it the first low priority
bne.s @NoFirstLow ; sprite? (we need to know so we
move.b d7, d2 ; can link both "sublists" later)
move.b d7, d1
bra.s @Ready
@NoFirstLow:
move.w d1, d6 ; Link this sprite to the previous
lsl.w #3, d6 ; low priority one
lea (a0,d6.w), a5
move.b d7, 3(a5)
move.b d7, d1
bra.s @Ready
@High:
move.w d0, d6 ; Link this sprite to the previous
lsl.w #3, d6 ; high priority one
lea (a0,d6.w), a5
move.b d7, 3(a5)
move.b d7, d0
@Ready:
addq.w #1, d7 ; Process next sprite
cmp.b d3, d7
bne.s @Loop
@End:
tst.b d2 ; Ensure the high priority sprites
beq.s @NoLow ; are followed by the low priority
move.w d0, d6 ; ones (if any)
lsl.w #3, d6
lea (a0,d6.w), a6
move.b d2, 3(a6)
@NoLow:
rts ; End of subroutine