(Sonic 1) How to Work With Resizing

Discussion in 'Tutorials' started by Iso Kilo, Feb 1, 2020.

  1. Iso Kilo

    Iso Kilo Local Wolf-Fox Member

    Joined:
    Oct 9, 2017
    Messages:
    251
    Location:
    Small Town in BC, Canada
    Credits to @MarkeyJester for teaching me how to do this.
    Resizing the levels in Sonic 1 is a useful skill when it comes to porting/creating new levels. However, not everyone knows how to do it, due to a lack of documentation. This guide will explain how to work with it.

    Making it easier to edit
    This is a step for the Hivebrain, and Hivebrain based disassemblies. GitHub, and GitHub based disassemblies already have this. This makes it so you don't need to edit the boundaries in a hex editor, and it looks a lot cleaner. Simply replace the contents of LevelSizeArray with this:
    Code:
            ; GHZ
            dc.w $0004, $0000, $24BF, $0000, $0300, $0060 ; Act 1
            dc.w $0004, $0000, $1EBF, $0000, $0300, $0060 ; Act 2
            dc.w $0004, $0000, $2960, $0000, $0300, $0060 ; Act 3
            dc.w $0004, $0000, $2ABF, $0000, $0300, $0060 ; Act 4 (Unused)
            ; LZ
            dc.w $0004, $0000, $19BF, $0000, $0530, $0060 ; Act 1
            dc.w $0004, $0000, $10AF, $0000, $0720, $0060 ; Act 2
            dc.w $0004, $0000, $202F, $FF00, $0800, $0060 ; Act 3
            dc.w $0004, $0000, $20BF, $0000, $0720, $0060 ; Act 4 (Scrap Brain Act 3)
            ; MZ
            dc.w $0004, $0000, $17BF, $0000, $01D0, $0060 ; Act 1
            dc.w $0004, $0000, $17BF, $0000, $0520, $0060 ; Act 2
            dc.w $0004, $0000, $1800, $0000, $0720, $0060 ; Act 3
            dc.w $0004, $0000, $16BF, $0000, $0720, $0060 ; Act 4 (Unused)
            ; SLZ
            dc.w $0004, $0000, $1FBF, $0000, $0640, $0060 ; Act 1
            dc.w $0004, $0000, $1FBF, $0000, $0640, $0060 ; Act 2
            dc.w $0004, $0000, $2000, $0000, $06C0, $0060 ; Act 3
            dc.w $0004, $0000, $3EC0, $0000, $0720, $0060 ; Act 4 (Unused)
            ; SYZ
            dc.w $0004, $0000, $22C0, $0000, $0420, $0060 ; Act 1
            dc.w $0004, $0000, $28C0, $0000, $0520, $0060 ; Act 2
            dc.w $0004, $0000, $2C00, $0000, $0620, $0060 ; Act 3
            dc.w $0004, $0000, $2EC0, $0000, $0620, $0060 ; Act 4 (Unused)
            ; SBZ
            dc.w $0004, $0000, $21C0, $0000, $0720, $0060 ; Act 1
            dc.w $0004, $0000, $1E40, $FF00, $0800, $0060 ; Act 2
            dc.w $0004, $2080, $2460, $0510, $0510, $0060 ; Act 3 (Final Zone)
            dc.w $0004, $0000, $3EC0, $0000, $0720, $0060 ; Act 4 (Unused)
            ; Ending
            dc.w $0004, $0000, $0500, $0110, $0110, $0060 ; Act 1 (Good Ending)
            dc.w $0004, $0000, $0DC0, $0110, $0110, $0060 ; Act 2 (Bad Ending)
            dc.w $0004, $0000, $2FFF, $0000, $0320, $0060 ; Act 3 (Unused)
            dc.w $0004, $0000, $2FFF, $0000, $0320, $0060 ; Act 4 (Unused)
            even

    The format
    Now we need to understand the format, this way you can get right to editing. Everything here is split into 6 words. Each word defines an element, with said elements being;
    Code:
    Unused, left boundary, right boundary, top boundary, bottom boundary, Y camera shift
    What is contained in unused doesn't matter, however all entries use 4.

    For most cases, the left boundary is set to 0, as that's the left side of the screen. You'll notice that it is $2080 in Final Zone, this is because FZ just uses the layout of SBZ2, but further along. LZ4, or SBZ3 is also closer to the right, that's just how the layout is designed.

    The right side boundary will obviously vary wildly. In the ending, the bad ending and good ending have different right side boundaries to make Sonic get to the end area sooner or later so the music matches up with the cutscene. With the good ending, you have to watch the emeralds go into the air and whatnot, taking a longer time, while in the bad ending Sonic just stands there for a bit.

    Most of the levels use $0000 as the top boundary, as that is simply the top of the screen. But levels like LZ3 and SBZ2 use $FF00 for vertical wrapping, if you want a level with vertical wrapping use this value as well.

    Once again, the bottom boundary will vary depending on the level.

    The Y camera shift I haven't been able to determine it's function (It was described to me in a vague way), however the default value is 60, according to MarkeyJester the value is 60 due to this equation - It's the screen's height, divided by 2, minus 16, in hex. So $E0/2 = $70. $70-$10 = $60. It's best just to leave these as $60.

    Something to note while editing, 0, 0 is the top left, so by adding values, you're going either more to the right, or down.

    Dynamic level resizing
    If you were to say-lower the level by a chunk in Green Hill, you'd notice that the camera would immediately scroll up and kill Sonic. That's because the LevelSizeArray values only apply for a frame. Immediately after, DynScrResizeLoad takes control. Let's look at the example of Green Hill 1
    Code:
    Resize_GHZ1:
            move.w    #$300,($FFFFF726).w ; set lower    y-boundary
            cmpi.w    #$1780,($FFFFF700).w ; has the camera reached $1780 on x-axis?
            bcs.s    locret_6E08    ; if not, branch
            move.w    #$400,($FFFFF726).w ; set lower    y-boundary
    
    locret_6E08:
            rts    
    The comments pretty much explains itself. This is what handles the event when the player reaches the S-Tube, in which the boundary will scroll down. You can modify this however you please to get different level events. I'll provide the RAM addresses you can use for setting boundaries and checking positions:
    Code:
    Left Target Boundary - $FFFFF720
    Right Target Boundary - $FFFFF722
    Top Target Boundary - $FFFFF724
    Bottom Target Boundary - $FFFFF726
    Level X Position - $FFFFF700
    Level Y Position - $FFFFF704
    You can use other RAM addresses, as well, for really special conditions. Say the camera will scroll up for Tails, or down for Sonic (If you chose to add extra characters)
    This should be everything you'd need to edit the level bounds and events, so enjoy modifying or creating them!
     
    Last edited: Feb 2, 2020
  2. Ashuro

    Ashuro Anti-Cosmic Metal Of Death Member

    Joined:
    Sep 27, 2014
    Messages:
    530
    Location:
    France
    Very good.