Porting Bosses to Other Zones in Sonic 2

Discussion in 'Discussion & Q&A' started by Psi, Feb 18, 2023.

  1. Psi

    Psi Well-Known Member Member

    Joined:
    Dec 20, 2014
    Messages:
    102
    I know this is semi-commonly done in Sonic 2 hacks, so I wanna ask how it's done. Basically I'm trying to port several bosses into different parts of one level right now, though I wanna start off simple and just get the Emerald Hill boss in first.

    Here is my code right now:

    Code:
    LevEvents_001:
        moveq    #0,d0
        move.b    (Dynamic_Resize_Routine).w,d0
        move.w    LevEvents_EGZ_Index(pc,d0.w),d0
        jmp    LevEvents_EGZ_Index(pc,d0.w)
    ; ===========================================================================
    ; off_E66E:
    LevEvents_EGZ_Index:
        dc.w LevEvents_EGZ_Routine1 - LevEvents_EGZ_Index    ; 0
        dc.w LevEvents_EGZ_Routine2 - LevEvents_EGZ_Index    ; 2
        dc.w LevEvents_EGZ_Routine3 - LevEvents_EGZ_Index    ; 4
        dc.w LevEvents_EGZ_Routine4 - LevEvents_EGZ_Index    ; 6
    ; ===========================================================================
    LevEvents_EGZ_Routine1:
        cmpi.w    #$F00,(Camera_X_pos).w
        bcs.s    return_EGZ0
        move.w    (Camera_X_pos).w,(Camera_Min_X_pos).w
        move.w    (Camera_X_pos).w,(Tails_Min_X_pos).w
        move.w    #$220,(Camera_Max_Y_pos).w
        move.w    #$220,(Tails_Max_Y_pos).w
        addq.b    #2,(Dynamic_Resize_Routine).w ; => LevEvents_EHZ2_Routine2
    
    return_EGZ0:
        rts
    ; ---------------------------------------------------------------------------
    loc_EGZ6A2:
        move.w    #$10A0,(Camera_Max_X_pos).w
        move.w    #$10A0,(Tails_Max_X_pos).w
        rts
    ; ===========================================================================
    LevEvents_EGZ_Routine2:
        cmpi.w    #$1060,(Camera_X_pos).w
        bcs.s    return_EGZ1
        move.w    #$1060,(Camera_Min_X_pos).w
        move.w    #$10A0,(Camera_Max_X_pos).w
        move.w    #$1060,(Tails_Min_X_pos).w
        move.w    #$10A0,(Tails_Max_X_pos).w
        addq.b    #2,(Dynamic_Resize_Routine).w ; => LevEvents_EHZ2_Routine3
        move.w    #$F9,d0
        bsr.w    JmpTo3_PlayMusic
        clr.b    ($FFFFF73A).w
        move.b    #2,(Current_Boss_ID).w
        moveq    #$29,d0
        bsr.w    JmpTo2_LoadPLC
    
    return_EGZ1:
        rts
    ; ===========================================================================
    ; loc_E6EE:
    LevEvents_EGZ_Routine3:
        cmpi.w    #$218,(Camera_Y_pos).w
        bcs.s    +
        move.w    #$218,(Camera_Min_Y_pos).w
        move.w    #$218,($FFFFEEFC).w
    +
        addq.b    #1,($FFFFF73A).w
        cmpi.b    #$5A,($FFFFF73A).w
        bcs.s    return_EGZ2
        bsr.w    JmpTo_SingleObjLoad
        bne.s    +
    
        move.b    #$56,(a1) ; load obj56 (EHZ boss)
        move.b    #$81,subtype(a1)
        move.w    #$1140,x_pos(a1)
        move.w    #$2C6,y_pos(a1)
    +
        addq.b    #2,(Dynamic_Resize_Routine).w ; => LevEvents_EHZ2_Routine4
        move.w    #$93,d0
        bsr.w    JmpTo3_PlayMusic
    
    return_EGZ2:
        rts
    ; ===========================================================================
    ; loc_E738:
    LevEvents_EGZ_Routine4:
        tst.b    ($FFFFF7A7).w
        beq.s    return_EGZ3
        move.w    (Camera_X_pos).w,(Camera_Min_X_pos).w
        move.w    (Camera_Max_X_pos).w,(Tails_Max_X_pos).w
        move.w    (Camera_X_pos).w,(Tails_Min_X_pos).w
    
    return_EGZ3:
        rts
    As you can see it is basically just a copy of EHZ's level event routine with the position moved over, however nothing appears. The screen lock, music change and even the PLC for the boss all load, but Eggman NEVER shows up.

    Is there anything else I need to edit to get him on there, parts of the boss code itself seem to have camera and position checks, do they ALL need to be edited too or are some just relative?
     
  2. Spanner

    Spanner The Tool Member

    Joined:
    Aug 9, 2007
    Messages:
    2,570
    Yes as far as I remember the bosses are hard coded so you need to change the code so they either use the new positions, or are changed to relative positioning so they can be applied anywhere.
     
    Pokepunch likes this.
  3. Dark Shamil Khan

    Dark Shamil Khan TASer lol Member

    Joined:
    Nov 7, 2021
    Messages:
    91
    Location:
    Pakistan
    If I remember correctly. You need to change the position of the boss to load and then it would work.
    Or do a lazy and make the level end at the exact placement as the boss location you're trying to put in =P.
    (If that made sense)
     
  4. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    Most bosses in Sonic 2 handle movement and positioning very differently then most objects, they use different variables and they're hardcoded to spawn at and move too very specific positions (instead of say, moving down or teleporting to 100 pixels below the current position, it will move to x = 2000 y = 100 or spawn there, dumb stuff like that). You'd either have to change all the hardcoded positions in the boss to fit the new location, or renovate the boss code to not have any hardcoded positions, both of which are kind of a pain.

    Alternatively, you can just use the exact same position the boss was originally supposed to spawn at, and everything will work as normal. This is what most hacks do, but it might require chopping up the level layout and either adding filler or shortening it if you already have one.