Add S3 Complete's Super transformation tweaks to Sonic 2

Discussion in 'Tutorials' started by ADudeCalledLeo, May 24, 2019.

  1. ADudeCalledLeo

    ADudeCalledLeo I'll make a ROM hack one of these days... Member

    Oct 21, 2017
    Null Space
    Now, we all know that getting all the Chaos Emeralds in Sonic 2 is a bit of a curse in disguise: if you have 50 rings, you won't be able to jump without transforming. In a platformer game.
    Sonic 3 & Knuckles is a bit better in this regard: you have to hit A/B/C again to transform. However, S3K is also the game that introduced mid-jump abilities (Sonic's Insta-Shield/elemental shield abilities, Tails' flight and Knuckles' glide), meaning that if you have all 7 Chaos/Super Emeralds and 50 rings, you won't be able to use these abilities. Also, Sonic's elemental shield abilities for some reason override super transformation, meaning you can't transform if you have a shield active as Sonic (so much for the godlike Super + Electric Shield).
    However, there's a third option: Sonic 3 Complete. This nifty little ROM hack of S3K adds a bunch of tweaks, including but not limited to the "Multi-Button Super Controls" and "Super Cancel" options, which respectively:
    1. Make going Super require pressing a different jump button than the one you used to jump in the first place, and
    2. Allow canceling Super mode by pressing a different jump button than the one you used to transform.
    IMO, this is the best way to pull off Super transformation, and this guide will show you how to implement just that in Sonic 2 (and Sonic 1, if you've already ported Super Sonic, obviously).

    NOTE: This guide is only for one player object (Sonic). You're gonna need to apply the same thing to other characters (if they have Super transformations, like Knuckles).
    Also, I'm not calling this a "port" since I don't know how S3C actually handles this. This is more of a "reimplementation" of sorts.

    First, you're gonna need a byte of RAM. Should be easy enough. I'll be calling this RAM address "Last_jump_press".

    Next, we need to remember what button the player pressed to jump. So, go to "Sonic_Jump". You should see this bit of code right below the label:
        move.b    (Ctrl_1_Press_Logical).w,d0
        andi.b    #button_B_mask|button_C_mask|button_A_mask,d0 ; is A, B or C pressed?
        beq.w    return_1AAE6    ; if not, return
    Directly below this, insert this instruction:
        move.b   d0,(Last_jump_press).w
    This copies the contents of d0, which is what player 1 pressed last, filtered to only the A, B and C buttons, to our new RAM address.

    Next, go to "Sonic_JumpHeight", and go 2 + labels down. You should see this:
       tst.b   y_vel(a0)       ; is Sonic exactly at the height of his jump?
       beq.s   Sonic_CheckGoSuper   ; if yes, test for turning into Super Sonic
    Eugh. Let's get rid of that, and instead, let's put this:
       ; this check prevents a bug in the WFZ cutscene that causes Sonic to transform and revert constantly
       tst.b   (Control_Locked).w   ; are controls locked?
       bne.s   +           ; if yes, branch
       move.b   (Ctrl_1_Press_Logical).w,d1
       andi.b   #button_B_mask|button_C_mask|button_A_mask,d1   ; is a jump button pressed?
       beq.s   +                       ; if not, branch
       move.b   (Last_jump_press).w,d0   ; get the button the player pressed to jump
       move.b   d1,(Last_jump_press).w   ; save the button the player pressed to transform
       and.b   d0,d1           ; did the same jump button get pressed?
       beq.s   Sonic_CheckGoSuper   ; if not, check for going Super
    The comments should be self-explanatory.

    That's transforming handled. Now for canceling. Go to "Sonic_CheckGoSuper", and directly under the label, you should see this code:
        tst.b    (Super_Sonic_flag).w    ; is Sonic already Super?
        bne.w    return_1ABA4    ; if yes, branch
    Change the label in the bne to "Sonic_RevertToNormal".
    Thanks to the new code we added to Sonic_JumpHeight, Sonic_CheckGoSuper will only be called if we pressed a different jump button from last time. That means that pressing a different jump button again after transforming will call Sonic_CheckGoSuper again... which, due to the branch we just modified, will jump to the code that reverts Sonic to normal. Thus, super canceling.

    And... that's it, pretty much!

    EDIT 21/11/2019: Removed some extraneous lines from the Sonic_JumpHeight code.
    Last edited: Nov 21, 2019