Sprite sorting by priority flag

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
Very interested
Posts: 915
Joined: Thu Apr 10, 2008 3:03 pm

Sprite sorting by priority flag

Post by Sik » 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.

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...

    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
    lea     (SpriteBuf), a0             ; Sprite table buffer
    moveq   #0, d7
    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
    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
    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
    addq.w  #1, d7                      ; Process next sprite
    cmp.b   d3, d7
    bne.s   @Loop
    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)
    rts                                 ; End of subroutine
Sik is pronounced as "seek", not as "sick".

Post Reply