don't click here

Sonic Jam Hacking

Discussion in 'Engineering & Reverse Engineering' started by Starman, Feb 18, 2021.

  1. muteKi

    muteKi

    Fuck it Member
    7,852
    131
    43
    I mean, they did bring Sonic 2 to PC but they just used the precursor to what is now Kega for it. Though there can be obvious advantages to actually translating the code over running an emulator, you don't have to worry as much about things like audio. For as much as there is to appreciate about S&K Collection and Sonic CD at the time, I find them hard to go back to specifically because of how awful the sound quality of SFX is. If you're going to write an emulator to emulate the way Genesis sound hardware works, may as well also build all the other parts too so that you can just run stuff out of the individual ROMs. Sure, more up-front investment but means you can sell more games.
     
  2. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    Extracted object (and ring) layouts from Sonic 1 and 2

    For the most part, they are totally compatible with the original Genesis ROMs. I say "mostly", because Jam actually adds a couple subtypes in Sonic 1 that will need to be ported over.

    The first is a new spike subtype, value 6x. It's basically just subtype 0x, but only the leftmost spike is displayed

    [​IMG]

    To implement this, add this line to the end of Spik_Var in "_incObj/36 Spikes.asm"
    Code (Text):
    1.         dc.b 6, $14

    Then, in "_maps/Spikes.asm" add this entry at the end of the index table
    Code (Text):
    1.         dc.w Map_Spike_06-Map_Spike_internal

    and then add this sprite data
    Code (Text):
    1. Map_Spike_06:    dc.b 1
    2.         dc.b $F0, 3, 0, 4, $E

    The other subtype is a new platform subtype, value 0D, It's basically just subtype 00, but its solid hitbox is expanded by 16 pixels, and also has higher drawing priority

    [​IMG]

    To implement this, add this set of code after obFrame(a0) is set in .setframe in "_incObj/18 Platforms.asm", rigth before the Plat_Solid label
    Code (Text):
    1.         cmpi.b    #$D,obSubtype(a0)
    2.         bne.s    Plat_Solid
    3.         move.b    #$28,obActWid(a0)
    4.         move.b    #3,obPriority(a0)

    Then, go to Plat_Move, and add this at the end of its index table
    Code (Text):
    1.         dc.w .type00-.index

    What's the purpose of these new subtypes? To artificially fill in gaps in this section of Green Hill Zone

    [​IMG]

    An additional note is that the original layouts do some small modifications, particularly with filling in gaps with a solid object and all that sort of stuff.
     
    Last edited: Aug 19, 2023
  3. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    Oh yeah, by the way, here's a tool I made for comparing object layouts for Sonic 1 and 2. Useful for tracking changes between revisions and the Jam layouts.

    UPDATE: Forgot to add the ring layout comparison tool.
     
    Last edited: Aug 20, 2023
    • Like Like x 3
    • Useful Useful x 2
    • List
  4. LuigiXHero

    LuigiXHero

    Member
    45
    33
    18
    Sonic 1 Character Pak
    A long while back (Around May of 2022) I actually went to devon for help with Jam stuff on the code side of things so I could get a definitive romhack together with the jam changes all packed up into one nice package. Was planning on making hacks for Sonic 2, knuckles in sonic 2 and S3K also but probably wont.

    The Main features:
    - includes Revision 00, Revision 01, Easy and Original Layouts.
    (Original is just Revision 01 but with a fix to prevent jumping over the level in SLZ2.)

    - Can enable or disable the level order for easy mode separately from Easy mode itself.
    (Easy mode has files for every level, there are some differences in the unused layouts)

    - Can enable or disable the spindash
    - Same with Time Overs
    - switch bug behavior between original and Jam's (or S2 I guess)

    [​IMG]
    https://github.com/LuigiXHero/Sonic1Jammed/releases

    Enjoy!
     
    Last edited: Aug 20, 2023
  5. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    Sonic Jam's "original" object layouts for Sonic 1 and 2 actually have a few additions.

    Sonic 1 only has one addition and it's this barrier object in Star Light Zone Act 2:
    [​IMG]

    This was added to prevent Sonic from jumping up over there like so:
    [​IMG]

    Other than this, the object layouts match REV01.

    Sonic 2 has a few additions. 2 in Emerald Hill Zone Act 2 and 1 in Aquatic Ruin Zone Act 2.

    The first addition in Emerald Hill is this small barrier object in the small gap between the wall and spring:
    [​IMG]

    This was added to prevent Sonic from clipping into that small corner from below, which can be done as Super Sonic easily:
    [​IMG]

    The other addition in Emerald Hill is this pathswapper in this corridor near the bottom of the level:
    [​IMG]
    Now, ideally, this is to prevent Sonic from getting stuck in this corridor, which can happen if Sonic gets swapped over to path 1 and somehow gets stuck in there, because in path 1, walls are set up there.
    [​IMG]

    However, I'm not quite sure how you can get stuck in there legitimately without the use of debug mode...
    [​IMG]

    At first, I thought maybe it Sonic could creep on the ledge and somehow activate that path 1 pathswapper, but I can't get that to happen, and every possible entrance around here is pretty much blocked off once Sonic is on path 1 here, so I dunno. If anyone has any ideas, let me know.

    The addition made in Aquatic Ruin is this:
    [​IMG]

    This adds an extra pathswapper that fixes Sonic being able to go into that loop section past that path 0 pathswapper and not being able to go up the loop without moving left past the pathswapper:
    [​IMG] [​IMG]

    And those are the object layout changes between the Genesis games and Sonic Jam's "original" mode.

    Be sure to give this a shot, if any one of you is interested. I've helped port over some changes made in Sonic Jam (you can find them by searching "JAM:" throughout the disassembly).
     
    Last edited: Aug 20, 2023
    • Like Like x 5
    • Informative Informative x 4
    • List
  6. Brainulator

    Brainulator

    Regular garden-variety member Member
    Do you know of any such differences for Sonic 3 & Knuckles? In addition, may I take it that the same changes to Sonic 2 were applied to Knuckles in Sonic 2?
     
  7. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    I've been focusing on Sonic 1 and 2 because I actually had ripped the data from them last year, and I only decided to look at them recently because I was helping someone else with a thing related to Jam and I found some free time to do so. Maybe I'll do Sonic 3K some day (that is if someone else doesn't before me), but I'm currently busy with work.

    Knuckles in Sonic 2 does have the same additions, except that this
    wasn't added, because Knuckles can't jump high enough to clip into that space, even when Super.
    [​IMG]
     
    • Informative Informative x 3
    • Like Like x 2
    • List
  8. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    Extracted object and ring layouts from Sonic 3 and Sonic & Knuckles
    Object and ring layout comparison tools

    Unlike Sonic 1 and 2, Sonic 3 & Knuckles is modular. Each zone's data is separated into their own files (ZONExx.SNx). As such, I had to figure out the addresses in which each file was loaded into to find and extract the data.

    With Sonic 3, no unplayable zones were given their own files, and instead would have blank object and ring layout data appended in the ACTTBL (start position, object layout, and ring layout index) files that are pointed to for those zone IDs instead. Sonic & Knuckles only does this for the ending (which does have its own file ZONEEND.SN4, but the (blank) layout data is excluded).

    Now let's get into differences between the Genesis object layouts and Jam's "Original" object layouts.

    First, let's check out Hydrocity Zone Act 2 in Sonic 3 alone only. First off, it removes the capsule after the boss.
    [​IMG]

    Basically, in Sonic 3 alone, it was possible to skip the boss by moving quickly enough towards the capsule. Sonic Jam basically applies the fix from Sonic & Knuckles by having the boss itself control when to spawn the capsule instead.
    [​IMG]

    They also removed these spikes from Knuckles' route for some reason, even though you can't play as Knuckles in Sonic 3 alone.
    [​IMG]

    On top of this, they actually bothered to add in the boss in this route as well.
    [​IMG]

    Let's go to Marble Garden Zone Act 1 now for Sonic 3 alone only. The only thing changed was that this object designed to kill the player when crushed here was moved down by 8 pixels.
    [​IMG]

    The reason they did this is basically due to the object being able to be touched if the collision engine hasn't caught up fully when Sonic is moving quick enough. This is explained in more depth by MarkeyJester.
    [​IMG]

    This is the only instance of this fix for all the crushers, and it's not even in the Sonic & Knuckles version! They most definitely only noticed the problem in this one case.

    Let's go to Carnival Night Zone Act 2 now for both Sonic 3 alone and Sonic & Knuckles. Here, this object designed was added to crush the player if the platform below goes up too high towards the ceiling was added.
    [​IMG]

    Without it, the player wouldn't get crushed, because the engine relies on separate objects to handle crushing if they're standing on a moving object. Without it, the player would clip through like this.
    [​IMG]

    The other addition in this stage is this solid object added in this corner, but only in Sonic 3 alone.
    [​IMG]

    The reason this is here is because Sonic 3 alone actually has an issue that stems as far back as Sonic 1, where if the player is not moving on the floor, but rather a wall or ceiling, then collision with solid terrain in front of them will not work properly, with the player phasing right through it in certain circumstances. See this for more information.
    [​IMG]

    Sonic & Knuckles fixes this bug, but only if the player is on a flat surface (0, 90, 180, or 270 degrees). Because of that, though, the Sonic & Knuckles version doesn't add this object, since it's unnecessary.

    Next, let's go to Icecap Zone Act 2 in Sonic 3 alone only. They added another object designed to crush the player if the platform they're on moves too close to the ceiling.
    [​IMG]

    Again, without it, the player would just clip through the ceiling.
    [​IMG]

    Oddly though, they didn't add it to the Sonic & Knuckles version, so you can perform that clip there.

    Let's go to Launch Base Zone Act 2 now for Sonic 3 alone only. These two objects were added.
    [​IMG]

    The left object kills the player if they touch it, and the right object acts as a wall that keeps the player from clipping inside, due to the bug I mentioned for Carnival Night Zone Act 2 in Sonic 3 alone.
    [​IMG]

    The Sonic & Knuckles version of course doesn't have this, since it fixes that bug. However, the Sonic & Knuckles version adds this solid block.
    [​IMG]

    In the original game, you can double jump over there (thanks to muteKi for pointing it out), but due to an issue with handling collision in blank rows (it reads from the ROM header when a layout row pointer is 0 due to the use of signed 16-bit addresses), it reads garbage collision data that prevents the player from advancing.
    [​IMG]

    However, in Sonic Jam, the way collision is read for blank layout rows was slightly altered due to the lack of support for reading signed 16-bit addresses on the SH-2, in which it adds the 16-bit value onto the base address for the game's variable space in RAM, so it'll end up reading from a blank chunk instead, so the effect from the above GIF doesn't happen, and the player can move past... and end up in Knuckles' boss arena.
    [​IMG]

    Beating the boss will result in a glitched cutscene that doesn't end, so they placed that solid block there to prevent the player from being able to jump over there and cause this.
    [​IMG]

    Thanks to nineko for pointing this out, as this same issue also exists in Sonic & Knuckles Collection.

    And that's it, those were the changes made to Jam's "original" object layouts. None of the Sonic & Knuckles specific zones were updated, just the Sonic 3 ones.
     
    Last edited: Aug 31, 2023
    • Like Like x 7
    • Informative Informative x 5
    • List
  9. BenoitRen

    BenoitRen

    Tech Member
    466
    204
    43
    Does this mean that Sonic Jam uses the original Sonic 3 program when playing the non-locked-on game instead of Sonic & Knuckles's?
     
  10. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    Indeed there is. Sonic 3 and Sonic & Knuckles both have separate files for the code (SONIC.SN3 and SONIC.SN4 respectively). Just like how the original lock-on works, Sonic 3 & Knuckles combined is the driven by Sonic & Knuckles, while Sonic 3 alone just drives itself.
     
    Last edited: Aug 27, 2023
    • Informative Informative x 1
    • List
  11. muteKi

    muteKi

    Fuck it Member
    7,852
    131
    43
    My guess is Hyper sonic double jump.

    The ceilings in the area above the knuckles route in marble garden 2 never had such an object applied, I presume?
     
  12. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,211
    439
    63
    Japan
    It's because of this bug. If they only changed that one, then they clearly were not aware of the severity of the issue. In fairness you have to be at the right spot and at the right speed, so perhaps they thought it was an isolated incident.
     
    • Informative Informative x 5
    • List
  13. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
  14. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,744
    338
    63
    SonLVL
    I wonder how those compare to Sonic & Knuckles Collection.
     
  15. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    I just checked, and they use the Genesis layouts, but do have their own minor differences. From what I've seen, though, it's just implementing a few Sonic & Knuckles changes into Sonic 3 alone, which are the Hydrocity Act 2 Knuckles cutscene object dynamically spawning the button and removal of all the end boss capsule from the object layouts in favor of also dynamically spawning them. That's it.

    Here's the rips I made. Should be noted that a lot of IDs are different, seems like the object table is a bit different in Sonic & Knuckles Collection.
     
    Last edited: Aug 31, 2023
  16. nineko

    nineko

    I am the Holy Cat Tech Member
    6,316
    489
    63
    italy
  17. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    The reason that is is because the original game reads a layout row pointer as a word, which gets sign extended. When the Y position is negative, it wraps back to the bottom. Launch Base Zone Act 2 has blank rows there (address 0), so the address expands as a ROM address, which goes into the ROM header and initial code, so garbage data is read.

    Sonic Jam and Sonic & Knuckles Collection instead add the pointer to the base address of the game's variable space in RAM (since m68k addressing doesn't apply here), and therefore, the effect is different, since it will read where a blank chunk lies instead, so it'll pretty much always read 0. If you implement that in the original, then you'll be able to perform the jumps.
    Code (Text):
    1. Find_Tile_FG:
    2.         lea    (Level_layout_header).w,a1
    3.         moveq    #-1,d0                    ; ADDED THIS
    4.         move.w    d2,d0
    5.         lsr.w    #5,d0
    6.         and.w    (Layout_row_index_mask).w,d0
    7.         move.w    8(a1,d0.w),d0
    8.         move.w    d3,d1
    9.         lsr.w    #3,d1
    10.         move.w    d1,d4
    11.         lsr.w    #4,d1
    12.         add.w    d1,d0
    13.         moveq    #-1,d1
    14.         clr.w    d1
    15.         movea.l    d0,a1                    ; CHANGED FROM MOVEA.W TO MOVEA.L

    So yeah, that DOES explain why the solid block in Launch Base was added for the Sonic & Knuckles version in Sonic Jam.
     
    Last edited: Sep 1, 2023
    • Informative Informative x 4
    • List
  18. Y’know, this seems just nice in general as a fix for the sewer chunk issue - could this perhaps be added to the SCHG tutorials for S3K?
     
  19. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,269
    1,439
    93
    your mom
    To be honest, I think a more proper fix would be to return a blank block if the Y position when retrieving a block is less than 0. The main problem is that even with the address fix, when picking which row of chunks to get a block from, it wraps to the bottom of the stage layout RAM if the Y position is less than 0 (of course, Y wrapping levels should be accounted for).
     
    Last edited: Sep 1, 2023
  20. Brainulator

    Brainulator

    Regular garden-variety member Member