Sprite sorting by priority flag

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

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

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
Sik is pronounced as "seek", not as "sick".

Post Reply