Friday, September 8, 2017

After boss, cleanup!

Alright, one last detail related to act transitions. When the end sign object spawns at the end of act 1, it calls a function named AfterBoss_Cleanup. Similar to the dynamic resize routines, this function doesn't actually do anything for most levels, but it still plays an important role for the ones where the transition occurs prior to the act 1 boss.
AfterBoss_Cleanup:
    moveq   #0,d0
    lea     (Current_zone_and_act).w,a1
    move.b  (a1)+,d0
    add.b   d0,d0
    add.b   (a1)+,d0
    add.b   d0,d0
    move.w  off_83C1C(pc,d0.w),d0
    jmp     off_83C1C(pc,d0.w)
; ---------------------------------------------------------------------------
off_83C1C:
    dc.w loc_83C7C-off_83C1C
    dc.w loc_83C90-off_83C1C
    dc.w locret_83CA6-off_83C1C
    dc.w locret_83CA6-off_83C1C
    dc.w loc_83CA8-off_83C1C
    dc.w loc_83CA8-off_83C1C
    dc.w locret_83CB2-off_83C1C
    dc.w locret_83CB2-off_83C1C
    dc.w locret_83CB2-off_83C1C
    dc.w locret_83CB2-off_83C1C
    dc.w locret_83CB2-off_83C1C
    dc.w loc_83CB4-off_83C1C
    dc.w loc_83CC0-off_83C1C
    dc.w loc_83CC0-off_83C1C
    dc.w loc_83CC0-off_83C1C
    dc.w loc_83CC0-off_83C1C
    dc.w locret_83CCC-off_83C1C
    dc.w locret_83CCC-off_83C1C
    dc.w locret_83CCC-off_83C1C
    dc.w locret_83CCC-off_83C1C
    ...
As you may recall, when a boss spawns, it typically loads its palette over the level's enemy palette. This will temporarily screw up all objects that use it, such as um, enemies. That is, if the boss doesn't outright load its own graphics over the enemy art. Regardless, we can rely on the eventual act transition to load act 2's palette and PLCs and fix everything.

...Unless the boss takes place in the act 2 layout, in which case the act transition has already happened, and act 2 will continue using the same art and palette! In this scenario, the function ensures everything is properly reloaded.
loc_83C90:
    lea     (Pal_AIZFire).l,a1
    jsr     (PalLoad_Line1).l
    lea     PLC_83CCE(pc),a1
    jmp     (Load_PLC_Raw).l
If that were the whole story though, only AIZ2 and ICZ2 would have cleanup functions, which is obviously not the case. First off, no other act 2 code is ever called, because no other act 2 spawns an end sign object.

Next, although Mushroom Hill Zone's act transition does occur during the level results, it does not immediately load the autumn-esque act 2 palette, instead keeping the act 1 colors around a little while longer. As such, the cleanup function reloads the enemy palette, in order to correctly display the blue mushrooms in the intro area.
loc_83CC0:
    lea     (Pal_MHZ2).l,a1
    jmp     (PalLoad_Line1).l
Marble Garden Zone's cleanup function reloads the monitor, spike and spring art, which seems useless and is undone by the end sign loading its own graphics. Angel Island Zone 1's cleanup function reloads the entire level palette, and is called by the cutscene Knuckles object in order to scrub away the intro colors, I assume.

Once again, however, there's something weird going on:
    dc.w loc_83CC0-off_83C1C    ; LBZ1
    dc.w loc_83CC0-off_83C1C    ; LBZ2
    dc.w loc_83CC0-off_83C1C    ; MHZ1
    dc.w loc_83CC0-off_83C1C    ; MHZ2
Like the dynamic resize routines before it, the AfterBoss_Cleanup function's jump table clearly contains some incorrect pointers. This time, both acts of Launch Base Zone are pointing at palette cleanup code meant for Mushroom Hill Zone. When I first saw this, I figured it must be impossible to observe it in practice, because the act transition will come along and fix everything before anything using the enemy palette comes up on screen. Wrong!


In Knuckles' route, one of the floor chunks happens to include a piece of the large rotating drums prevalent throughout the stage. Those drums happen to use the enemy palette, and so sure enough...


...when the end sign object spawns, the drums' colors switch over to those of MHZ's blue mushrooms, and then, when the act transition is triggered, they finally take on their proper act 2 colors.

5 comments:

  1. Just a heads up: on the 15th of September, you'll hit 100 posts. That means it would be 20 weeks since the blog started.

    ReplyDelete
  2. Does this by any chance happen in Sonic 3 (alone)?

    ReplyDelete
    Replies
    1. Excellent question. It does not, because the jump table only has entries up to and including Launch Base Zone, which itself correctly points to a return stub.

      This also means that spawning any end signs in Mushroom Valley Zone and beyond would crash the game, though.

      Delete
    2. Okay, that makes sense. For once S3&K actually introduces a glitch instead of fixing one.

      Delete
    3. Oh, there are plenty more of those.

      Delete