don't click here

Sonic 3 Hacking

Discussion in 'Engineering & Reverse Engineering' started by RetroKoH, Feb 7, 2013.

  1. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    I won't have much time over the next couple of days, but I will get to work on a page for this fix... I'll hold off on posting on the wiki until we can get all of the related fixes together though... Unfortunately you must be a Wiki Sysop to move pages stuff around on the wiki so if I slap something up prematurely and something else is brought up, I can't move the page... alas...
     
  2. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    Been two years since I've last posted in this thread... WOW. I can't believe that. Anyway got something here. Another graphical oddity that I stumbled upon completely by accident... to the best of my knowledge, this bug's never been seen or reported before. Go to the first section of vines in AIZ 1... just before that is the Rhinobot, two sets of spikes and a ledge. Now, playing as Tails, go to this area and get hit by the spikes closest to the swinging vine. Then quickly get on the vine before Tails stops flickering.

    My point to this post is that if you get hurt with Tails and grab onto an object while he is flickering, his Tails will completely disappear until you let go of said object. I don't know if this happens in Sonic 2 but it's worth looking into. I'll do so myself as well when I can get around to it.
     
  3. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    So, it seems Monitor_Give_SuperSonic is bugged: When Knuckles uses the monitor, he goes Super, but doesn't have the Super stars, and instead uses the Hyper after-image. Note that Sonic goes straight up Hyper instead of Super, so it's likely that it was intended for Knuckles to go Hyper upon using the S monitor.

    The fix is simple: under loc_1DB02, set Super_Sonic_Knux_flag to '-1'. I've pushed a commit to the Git disassembly detailing this and its fix.

    Edit, some ending-related code also suffers from this. The fix would go under loc_86524. Who knows, maybe Hyper (or Super) Knuckles was a last-minute addition.
     
  4. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    S3K has that neat feature where the debug mode HUD is only active when you're in debug placement mode, though it does have a slight flaw: when returning to normal, the HUD reverts to normal, too, but the timer resets to 0:00 until the next second passes. Oddly enough, S3K added the ability for the timer to be drawn at its actual value mid-second, but doesn't use it here. Fixing this is as simple as inserting 'move.b #$80,(Update_HUD_timer).w' in between the other Update_HUD writes in loc_92C0C.
     
  5. RetroKoH

    RetroKoH

    Member
    1,662
    22
    18
    Project Sonic 8x16
    I'm glad you pointed this out, as I was looking to import the Sonic 3 HUD code to my hack... as well, implementing centiseconds. This would certainly help, I think.
     
  6. theyogwog

    theyogwog

    Member
    31
    0
    0
    S3K Analysis
    Hey Sonic 3 hackers, I have a question about this game's level design, hoping maybe someone here could help. I'm wondering, on average how much would you say the shape of terrain has to do with unseen technical details compared to more obvious factors? How is the general layout of the foreground influenced by the constraints of the Genesis hardware and how does that affect other aspects of level design?

    For example, the start of AIZ1: before the first Monkey Dude there's a small hill that slopes down into a curve; but why the hill? Of course it is an outdoor environment so it's naturally going to be rugged and maybe it has other purposes, too. But beyond that, isn't the main concern setting up for the rest of the pieces used to assemble the landscape, so that everything in the area can fit together properly?

    I only ask because I'm just interested in getting to understand S3's level design better, figured you guys would know as much about it as anyone.
     
  7. Fred

    Fred

    Taking a break Oldbie
    1,563
    117
    43
    Portugal
    Sonic 3 Unlocked
    AIZ1 is a very meticulously-crafted stage when it comes to camera work. Right at the start, the bottom edge of the screen is locked up a little high, to frame in the Tornado, Super Sonic and the scrolling horizon line all on the screen without having them overlap one another. After that, the bottom boundary needs to be moved down a bit in order to frame in the tree with the first Monkey Dude, to avoid players getting hit by a coconut falling from the skies. Thus, the layout introduces a slope that forces Sonic up towards the center of the screen, so the camera doesn't awkwardly fall down a bit when the screen changes size.

    Then there's some steps to raise Sonic up again, before lowering the camera for the swinging vine area and framing in the second Monkey Dude tree, and then a second set of steps before the loop to lower the frame all the way down to the lake. Then it sends you up to raise the camera higher for the hollow tree sequence, and finishes the sequence by locking the camera vertically, with a few downward steps to frame in Sonic a little lower than the horizon line where all the Fire Breath minibosses will fly by.

    It doesn't stop there. After the miniboss encounter the starpost is up on a ledge to force Sonic up again, so the camera can drop down to reveal the rest of the stage unnoticed. Then, right before the actual miniboss fight, as either character, the layout forces you to jump up somewhere high to lock the camera vertically again, before having you descend into the boss area, via ledge drop as Knuckles or a slope as Sonic and Tails.

    I could go on all day, but I need to go back to fixing bugs in S3C. :) Suffice to say, most other levels didn't get nearly as much attention save for the boss areas, but MHZ in general is also pretty sharp. Must have to do with being the first stage in each game and the need to give off a good first impression.
     
  8. AURORA☆FIELDS

    AURORA☆FIELDS

    The cute one here Tech Member
    216
    24
    18
    Finland
    AMPS
    I don't see any topic like this made before. Its time we have one, eh?!

    So, I've come accross this bug, which exists in both Sonic 3 and Sonic & Knuckles. This happens when you carry Super/Hyper Sonic, and drop him on a solid object with horizontal speed. There is glitchyness without super/hyper and with dropping him on ground too, but the effects of solid object are more noticeable:
    [​IMG]


    Well, turns out, herpdiderp, they forgot to clear Sonic's animation. This code which we will add goes to $14466 in Sonic & Knuckles ROM (according to my disassembly anyway). This is loc_14466 in S3K Hayate and latest version of S3K Git as of this post. The code we will add is as follows:
    Code (Text):
    1. GIT:   
    2.         sf  anim(a1)        ; clear animation number (set to 0)
    3. Older:
    4.         sf  $20(a1)     ; clear animation number (set to 0)
    All this will do, is clear the animation number, so the next frame Sonic's last animation will be invalidated and he will begin walking or running
     
  9. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    https://forums.sonicretro.org/?showtopic=30778
     
  10. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    And here I thought S2 was the only one to carelessly use an uninitialised register.

    I was testing Sonic 3 Complete with a build of Genesis Plus GX with the error printing enabled, and noticed a warning appear at the start of HCZ when playing as Knuckles. Apparently, something was writing to an abnormal address, $2A7500. I switched to a vanilla S3K ROM, and confirmed that it happened there, too.

    Luckily, the debug print gave me a PC address, so finding the cause was easy:

    Code (ASM):
    1. loc_6834:
    2.         cmpi.w  #$100,(Current_zone_and_act).w
    3.         bne.s   loc_6886
    4.         move.b  #$1B,$20(a1)
    5.         cmpi.w  #3,(Player_mode).w
    6.         bne.s   loc_685C
    7.         move.w  #$2121,$20(a1)
    8.         move.b  #1,$23(a1)
    9.         move.b  #0,$24(a0)
    10.  
    11. loc_685C:
    Note that last instruction: it uses a0 instead of a1. Surprise, a0 is never initialised, hence why it writes to such a strange address.
     
  11. Fred

    Fred

    Taking a break Oldbie
    1,563
    117
    43
    Portugal
    Sonic 3 Unlocked
    Nothing happens though, right? I mean, $2A7500 is a ROM address.

    I'm guessing that line is probably useless and $24(a1) is always 0 at that point anyway.
     
  12. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    I figure it's about time I crosspost this:

    So, in S&K, when you're climbing a wall with Knuckles and stop, he resets to a certain frame of his animation. In KiS2, this isn't the case - his animation just freezes. At first I thought this was a bug in KiS2, or maybe a missing feature, but upon looking at the code, it turned out to be a bug in S&K!

    Basically, S&K added some extra collision code for whatever reason, but what the programmer didn't catch is that the new code overwrites a certain register, which was being used to control Knuckles's animation.

    This post on Sonic 3 Unlocked, and the comment of mine that it quotes, goes into more detail.

    Code (ASM):
    1. loc_16E10:
    2.  
    3.         move.b  (Ctrl_1_logical).w,d0
    4.         andi.b  #3,d0
    5.         bne.s   loc_16E34
    6.         move.b  $46(a0),d5
    7.         move.w  $14(a0),d2
    8.         addi.w  #9,d2
    9.         move.w  $10(a0),d3
    10.         bsr.w   sub_F828
    11.         tst.w   d1
    12.         bmi.w   loc_16D6E
    13.  
    14. loc_16E34:
    15.         tst.w   d1
    16.         beq.s   loc_16E60
    Fixing this is a little more complex than just backing d1 up to the stack: with the way the code is arranged, you have to be careful to not cause a memory leak. The fix I used basically required I change that last check, and some of the code after it, to use a different register entirely.
     
  13. Fred

    Fred

    Taking a break Oldbie
    1,563
    117
    43
    Portugal
    Sonic 3 Unlocked
    Cheers, I figured that might have been you. Nice sleuthing.
     
  14. muteKi

    muteKi

    Fuck it Member
    7,850
    131
    43
    I can't get into my wiki account (and haven't for years, to the point that I don't know the account credentials). However, I should note that the RAM map for Sonic 3K would appear to be missing detail for the loaded save data ($E668-$E6AB). I've been messing with the save data in Sonic 3 AIR which I understand to exactly replicate this data.
    For the values at relative addresses $6-$7 of a given save file's data, each pair of bytes represents the collection status of a given emerald. Every second bit (i.e., if we call the leftmost bit 0, these would be 1, 3, etc. -- let's call them odd bits then) represents the collection status of a given chaos emerald. So, having all the chaos emeralds and only the chaos emeralds (i.e., Super Sonic enabled) is represented by the value 0x5554 in memory (in binary 01 01 01 01 01 01 01 00). Why only the odd bits? The even bits are used to represent the status of the super emeralds associated with them. If they are 0 then that means that the given super emerald is not active (i.e., have not been to hidden palace since getting the chaos emerald), but if they are 1 then it means that the super emerald is active (so if you have any of them set to 1 then no super for you). The second bit again represents whether or not the emerald is collected -- so having all the super emeralds looks like 0xFFFE in memory. The last two bits do not appear to be used for anything despite each game having a hidden 8th stage.​

    I assume then (based partly on vague recollection and the knowledge that some zones have more than 8 special stages across each act) that each bit in bytes 04-05 stores the status for each individual special stage ring in a zone. What I'm not certain on at the moment is if the first byte exclusively stores the first act's ring status and the second byte the second; I didn't bother to test.​

    Of course this makes me wonder why the same data is duplicated in a less space-efficient manner in FFB2 to FFB8...​