Monday, September 4, 2017

Act transitions, part 6: deferred execution

In the lower route through Lava Reef Zone 1, there's a section where the path is overlapped by a pool of lava that rises and lowers periodically. This effect is accomplished by temporarily hijacking the background plane, as we've previously seen in other levels. Yet again, however, the legendary GoldS manages to find a way to break it.

You see, there's three triggers to enable or disable the rising lava, one on each side you might approach the area: from the left, from the right, and from above. However, he developers didn't expect that you might leave the area through the bottom, which is possible if the lava rises above your position while you're frozen in place from a super transformation.


When you do this, the rising lava effect keeps running throughout the rest of the level, as evidenced by the blanked-out background. If you clear the level under these circumstances, the act 2 title card shows up, act 2 music begins playing, the palette changes, the camera unlocks, the whole shebang... except you're still in the act 1 layout.


So what's going on? Well, act 2 music starts playing because the level results object changes the apparent act to act 2.
loc_2DD06:
    move.b  #1,(Apparent_act).w     ; Change to act 2 if in act 1
    ...
The act 2 palette gets loaded because when the act 1 boss is defeated, it leaves behind an object that makes the rocks turn blue once the player progresses beyond a certain point.
loc_78B08:
    cmpi.w  #$2C0,(Camera_X_pos).w
    blo.w   locret_78536
    move.w  #$2C0,(Camera_min_X_pos).w
    lea     (Pal_LRZ2).l,a1
    lea     (Normal_palette_line_2).w,a2
    moveq   #7,d6

loc_78B24:
    move.l  (a1)+,(a2)+
    dbf     d6,loc_78B24
    ...
At the end of act 1, the camera position is clearly past $2C0. For this reason, the object doesn't actually spawn until the title card goes away, at which point we're presumably in act 2. But since we're still in act 1, the camera position remains the same, which explains why the rocks turn blue as soon as the title card disappears.

It should be obvious by this point: all we experienced were the side effects. The act 2 layout wasn't loaded because the main event, the act transition, didn't actually run. The reason for that is simple:
LRZ1_BackgroundEvent:
    move.w  ($FFFFEEC2).w,d0
    jmp     loc_56BC2(pc,d0.w)
; ---------------------------------------------------------------------------

loc_56BC2:
    bra.w   loc_56BD2           ; Normal
; ---------------------------------------------------------------------------
    bra.w   loc_56C6E           ; Rising lava #1
; ---------------------------------------------------------------------------
    bra.w   loc_56C88           ; Rising lava #2
; ---------------------------------------------------------------------------
    bra.w   loc_56CAA           ; Transition
; ---------------------------------------------------------------------------

loc_56BD2:
    tst.w   ($FFFFEEC6).w
    beq.s   loc_56C28
    clr.w   ($FFFFEEC6).w
    movem.l d7-a0/a2-a3,-(sp)
    lea     (LRZ2_128x128_Secondary_Kos).l,a1
    lea     ($FFFF0180).l,a2
    jsr     (Queue_Kos).l
    lea     (LRZ2_16x16_Secondary_Kos).l,a1
    lea     ($FFFF9128).w,a2
    jsr     (Queue_Kos).l
    lea     (ArtKosM_LRZ2_Secondary).l,a1
    move.w  #$1200,d2
    jsr     (Queue_Kos_Module).l
    moveq   #$30,d0
    jsr     (Load_PLC).l
    movem.l (sp)+,d7-a0/a2-a3
    move.w  #$C,($FFFFEEC2).w
    bra.w   loc_56D16
The act transition, like in any other level, is handled by the background event routine. More specifically, it is handled by the normal background event routine, which is only running when the rising lava isn't active. The level results object did set the transition flag at $EEC6 just like it usually does, it's just that no one was listening.

This can be verified by going back to the rising lava area, and then leaving through one of the intended exits. The rising lava is disabled, the background event routine returns to normal, sees the transition flag is set, and starts loading act 2 right there on the spot. Then, because you're far earlier in the level than expected, the camera position is again set to a negative value, promptly causing the game to lock up once more.

4 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Is it possible to achieve arbitrary code execution in S3&K this way, or can we jump to any code you want.
    Possibly if the RAM corruption happens to corrupt the system stack (normally located at 0xFFFFFDF0), can arbitrary code execution happen?

    ReplyDelete
  3. would it be possible to get an explanation as to why exactly the game doesn't crash instantaneously like it would've done in MGZ or ICZ? if i'm remembering correctly the game's graphics get mauled, and the game crashes afterwards, not to mention the setup for the 'megaglitch' which when performing a spindash for some reason actually allows you to see the camera moving all the way to that extremely high positive value without crashing?

    ReplyDelete
    Replies
    1. He kind of explains it here. There's no actual act transition taking place. In the case of MGZ and ICZ, we're dealing with an act transition happening when you're not in the right place, whereas here you're in a place where the act transition SHOULD happen, but doesn't. It wouldn't crash. The graphics going wonky is simply the fact that the game's not given any reason to load back any old patterns.

      Delete