Friday, September 22, 2017

Out of sight, out of mind

Previously, I mentioned how when an object calls the Draw_Sprite function, bit 7 of its render_flags is set depending on whether or not the object is currently on-screen. Solid objects actually use this information for an optimization pass: if the object is off-screen, it will not bother processing collision with either player. This can be abused by using the spin dash or Hyper Sonic's double jump attack to temporarily outrun the camera, as seen here.
loc_1DF88:
    tst.b   4(a0)
    bpl.w   loc_1E0A2
    ...
In practice however, the SolidObjectFull function must keep running, because if it doesn't clear the player's "standing on object" flag properly, then we might just end up triggering the slope glitch again. The solution is to only skip over to the on-screen test once the appropriate bit on the object's status bitfield has been cleared, signaling that the player did not collide with the object on the previous frame.
SolidObjectFull:
    lea     (Player_1).w,a1
    moveq   #3,d6
    movem.l d1-d4,-(sp)
    bsr.s   sub_1DC74
    movem.l (sp)+,d1-d4
    ...

sub_1DC74:
    btst    d6,$2A(a0)
    beq.w   loc_1DF88
    move.w  d1,d2
    add.w   d2,d2
    btst    #1,$2A(a1)
    bne.s   loc_1DC98
    move.w  $10(a1),d0
    sub.w   $10(a0),d0
    add.w   d1,d0
    bmi.s   loc_1DC98
    cmp.w   d2,d0
    blo.s   loc_1DCAC
    ...
That's not the end of it, though: the second player object receives an additional optimization. If player 2 is offscreen, the main body of the SolidObjectFull function does not run at all. The result is that 2P Tails does not interact with any solid objects whenever he is off-screen, as seen here.
SolidObjectFull:
    lea     (Player_1).w,a1
    moveq   #3,d6
    movem.l d1-d4,-(sp)
    bsr.s   sub_1DC74
    movem.l (sp)+,d1-d4
    lea     (Player_2).w,a1
    tst.b   4(a1)
    bpl.w   locret_1DCB4
    addq.b  #1,d6

sub_1DC74:
    btst    d6,$2A(a0)
    beq.w   loc_1DF88
    ...
This extra optimization turns out to be overkill, because if Tails happened to be standing on a solid object when he got scrolled offscreen, then the object will once again fail to clear his "standing on object" flag, triggering the slope glitch all over again, as seen here.

No comments:

Post a Comment