Wednesday, August 30, 2017

Act transitions, part 3: Icecap Zone

Icecap Zone's act transition also doesn't happen during the act 1 results. In fact, it holds the dubious honor of being the only transition which doesn't involve a screen lock: it takes place inside the long corridor right before the final star post.

While it was definitely a bold move, if you're going fast enough, the tunnel is unfortunately not long enough to cover up the load time, and you can catch the act 2 background while it's still decompressing. ICZ1's transition event specifically only waits for the Kosinski-compressed chunks/blocks to decompress and not the KosM tiles, almost certainly because otherwise, you would run straight into the act 1 loopback as the art slowly loads.
    tst.w   (Kos_decomp_queue_count).w
    bne.w   loc_53938
    move.w  #$501,(Current_zone_and_act).w
There's another quirk with this transition, and it has to do with the previously mentioned star post. If you hit it, and then enter/exit the bonus stage or lose a life, the title card will read "act 1", but the music playing will be that of act 2.

Internally, the game tracks two distinct values for the current zone and act. The first one is the actual zone and act, and picks which level actually gets loaded. The other is the apparent zone and act, which is what the game says the current level is. Specifically, the title card object uses the apparent act to give you an act 1 card when you're really in act 2.
    lea     (ArtKosM_TitleCardNum2).l,a1
    cmpi.w  #$1600,(Current_zone_and_act).w
    beq.s   loc_2D716
    cmpi.w  #$1700,(Current_zone_and_act).w
    beq.s   loc_2D716                       ; Death Egg Boss and LRZ Boss show act 2
    tst.b   (Apparent_act).w
    bne.s   loc_2D716
    lea     (ArtKosM_TitleCardNum1).l,a1

    move.w  #$A7A0,d2
    jsr     (Queue_Kos_Module).l
    lea     TitleCard_LevelGfx(pc),a1
The code that picks the level's music however, does not, so it picks the song for the level you're actually in, which is act 2. But wait a second. Angel Island Zone 1 also features a star post directly after the act transition, but when you spawn there, the game correctly plays the act 1 song.

Actually, the logic for the AIZ1 starpost is completely hardcoded into the music picking code. When you respawn from a big ring, the value of Last_star_post_hit is not restored by the time this code runs, so it picks the act 2 song again.
    move.w  (Current_zone_and_act).w,d0
    ror.b   #1,d0
    lsr.w   #7,d0
    lea     (LevelMusic_Playlist).l,a1
    move.b  (a1,d0.w),d0
    cmpi.w  #1,(Current_zone_and_act).w
    bne.s   loc_622A
    cmpi.b  #3,(Last_star_post_hit).w
    bne.s   loc_622A
    moveq   #1,d0

    move.w  d0,(Level_music).w
    bsr.w   Play_Sound
Incidentally, this code is not present in standalone Sonic 3, so spawning in the act 2 layout will always play act 2 music.


  1. You'd think they would have tied the music selection to the apparent act rather than hardcoding it to the checkpoints.
    Is there any reason/limitation to why they resorted to this?

    1. There's no apparent reason. It seems to just be a crummy bugfix.

    2. I know restarting from a checkpoint plays the correct music in Sonic 3 & Knuckles, but they didn't fix returning from a Special Stage ring.

  2. What about night to morning transission on ice cap is it tied to the mini boss or in something else?