don't click here

Everything That I Know About Sonic the Hedgehog's Source Code

Discussion in 'General Sonic Discussion' started by Clownacy, Mar 30, 2022.

  1. DigitalDuck

    DigitalDuck

    Arriving four years late. Member
    5,358
    446
    63
    Lincs, UK
    TurBoa, S1RL
    It's not supposed to represent anything; sometimes it's based on a numerical constant (typically phi or sqrt(2)) but in this case it just seems to be an arbitrary number.

    Although it's slightly weird to use an even number, usually an odd number is used for seeds (due to most random number generators using bitshifting and powers of 2, although it doesn't really matter in the grand scheme of things). Maybe that's why they added 1 for Sonic & Knuckles.
     
  2. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    367
    362
    63
    Canada
    Here's some more speculation, ever notice how... basic the dust and splash effects in Sonic 2 are? They only ever use white.
    upload_2024-4-23_19-6-52.png
    By Sonic 3, they realized they could use more colors and updated... Only the skidding dust puff.
    upload_2024-4-23_19-15-57.png
    My theory is that these were intended to use a routine to convert 1bpp graphics into 4bpp graphics.
    A 1bpp conversion routine is present in Sonic 1 Megaplay for the highscore font.
    Code (Text):
    1. Load_1bppGFX:
    2.         move.w    (a5)+,d7
    3.         lea        ($C00000).l,a6
    4.  
    5. loc_1E44A:
    6.         move.l    (a5)+,d3
    7.         moveq    #7,d0
    8.  
    9. loc_1E44E:
    10.         moveq    #3,d4
    11.         moveq    #0,d5
    12.  
    13. loc_1E452:
    14.         rol.w    #4,d5
    15.         rol.l    #1,d3
    16.         bcc.s    loc_1E45A
    17.         or.b    d1,d5
    18.  
    19. loc_1E45A:
    20.         dbf        d4,loc_1E452
    21.         move.w    d5,(a6)
    22.         dbf        d0,loc_1E44E
    23.         dbf        d7,loc_1E44A
    24.         rts
    And the font used on the highscore table also happens to be in the Mega Drive version's prototype, although in the 4bpp format.

    So here's what I'm thinking the timeline is.
    The Mega Drive and Megaplay versions of Sonic 1 were developed simultaneously. In early versions, the font for the highscore table was 4bpp. They later realized that they could save on ROM size by storing it in ROM as 1bpp. The routine to convert the art is present in the source code, although was not built into the Mega Drive ROM. Come Sonic 2, they need to make these dust sprites and intended to use the 1bpp conversion routine. But the dust art ended up needing to be loaded dynamically, possibly at the fault of Tails? So they made the dust use DPLCs and the DMA queue system, which is not exactly compatible with the 1bpp system. So ultimately the art was converted to 4bpp and never had it's art touched up despite it costing no extra ROM data.
     
    • Like Like x 2
    • Informative Informative x 1
    • List
  3. BenoitRen

    BenoitRen

    Tech Member
    443
    191
    43
    Sonic 3 stores which character you have selected in three places:
    • 0xEF4C: player(s) chosen in data select (NO SAVE)
    • 0xFF08: player(s) chosen in data select
    • 0xFF0A: player(s) chosen in level select
    What makes it even stranger is that on each level load, 0xFF08 gets overwritten by 0xFF0A.

    Why did they do this? And, more importantly, how would they have been named? The currently used terms "player mode" and "player option" feel arbitrary.
     
    • Informative Informative x 1
    • List
  4. Blue Spikeball

    Blue Spikeball

    Member
    2,365
    963
    93
    That's weird.

    Question. If 0xFF08 (data select character) gets overwritten by 0xFF0A (level select character), then how come when you start the game from data select it uses the right character, rather than whoever you chose in level select?

    I assume the current character is stored somewhere else?
     
  5. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    367
    362
    63
    Canada
    That's not quite how those variables work. 0xFF0A indicates what option you selected on the data select and level select. And 0xFF08 is your current character ID in general. Logically, 0xFF0A would overwrite 0xFF08 when it has to load a level. And 0xEF4C just gets written into 0xFF0A... Which makes using a whole byte for it seem kind of useless to me but I'm not familiar with S3K as much to understand that decision.
     
    • Like Like x 1
    • Informative Informative x 1
    • List
  6. Vertette

    Vertette

    Member
    303
    173
    43
    That would a lot of sense, I've seen other games around that era use similar compression techniques. A lot of SNES games store their font as 2bpp.
     
  7. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    367
    362
    63
    Canada
    Well the SNES' VDP has different bit depths for graphics built into it. The Mega Drive natively only supports 4bpp so you had to write routines to convert lower bit depths.
     
    • Informative Informative x 1
    • List
  8. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,262
    1,433
    93
    your mom
    On top of that, the SNES uses the planar format, where each bit in a pixel is stored on a separate bitplane, which the SNES takes advantage of to easily add support for different levels of bit depth. The Genesis uses the packed pixel format of 4BPP, where each pixel is stored as a single 4-bit value in a linear fashion.
     
  9. Black Squirrel

    Black Squirrel

    no reverse gear Wiki Sysop
    8,660
    2,536
    93
    Northumberland, UK
    steamboat wiki
    Skidding I'm not sure, but splashing is probably conscious - it'll be sharing Sonic's palette line, you'll want it compatible with any colour of water, and you want it to be obvious that you're entering/exiting. If you had shades of grey it might look a bit strange, and while you could use a different palette line, there's probably a reason it doesn't.
     
  10. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    367
    362
    63
    Canada
    The water doesn't oscillate in Sonic 2 like it does in Sonic 1, so it'd be pretty difficult for the splash sprite to dip below the water and use the water palette. Even if it did, the water surface objects can cover it up for the most part. Said water surface object also sharing Sonic's palette and using the greys regardless. So I honestly doubt that it's a visibility thing.
     
  11. BenoitRen

    BenoitRen

    Tech Member
    443
    191
    43
    I'm porting spring code, which calls collision checking code more than once, so I've been looking into it.

    How do we know that what the Sonic 2 disassembly calls SolidObject was called hitchk in the original code? I can't find that label in the Sonic 2 prototype label dumps, so it must come from Sonic CD. But the function in Sonic CD looks nothing like SolidObject. The dumps have references to local "rideon" labels, but there doesn't seem to be a global label referring to collision.

    (below some rambling about observations I've made, which may not be relevant)

    Sonic CD's version of spring code also seems odd in that it doesn't call hitchk directly.

    For instance, sjumpmove calls ride_on_chk_s, which delegates to ride_on_chk, which delegates to hitchk. Then we have sdushmove (sdashmove in Sonic 3), which calls ride_on_chk_s1, which also delegates to ride_on_chk.

    Meanwhile, in Sonic 3, both routines call SolidObjectFull_1P, which seems to be the equivalent of Sonic 2's SolidObject_Always_SingleCharacter.
     
  12. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    367
    362
    63
    Canada
    It's hitchk. Edit oh you were asking how we know, give me a bit to find out.
    Yeah so from what I can tell hitchk comes from Sonic CD's spring code, as it matches the position of where SolidObject is called in Sonic 1. The rideon routines seem to only be used by the spring so I'm not seeing an issue. Sonic CD's version of it seems to actually use the hitbox variables rather than using a collision size index list like Sonic 1 but that's the only difference.
     
    Last edited: Apr 27, 2024
    • Informative Informative x 2
    • List
  13. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,262
    1,433
    93
    your mom
    A good chunk of Sonic CD's SolidObject code is derived from Sonic 1, but was modified to automatically calculate the solid hitbox size using the object's width and height variables, to handle Sonic being squished without needing to place a dedicated invisible object to handle it, and to handle the solidity type all in one package, instead of using a separate function to handle top-solid platforms, for instance.
     
    • Informative Informative x 3
    • Like Like x 1
    • List
  14. BenoitRen

    BenoitRen

    Tech Member
    443
    191
    43
    Ah, so this one of those instances where Sonic CD diverges from Sonic 1 (and by extension, Sonic 2 and 3).

    Thanks! So it definitely is hitchk, then. That leaves me with finding a good name for SolidObjectFull_1P / SolidObject_Always_SingleCharacter, because Sonic CD only ever had one playable character. Maybe I'll just call it hitchk_sub or something.

    EDIT: I just remembered I had another question. What are these "flip revolutions" I see mentioned on the wiki when documenting Sonic 2 and Sonic 3's sprite status object?
     
    Last edited: Apr 27, 2024
  15. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    367
    362
    63
    Canada
    I believe those variables handle Sonic's twirling animation on things like corkscrews and Launch Base's pipe thingy
     
  16. Brainulator

    Brainulator

    Regular garden-variety member Member
    It should be noted that "atariridesub" is found in the Sonic 2 Nick Arcade prototype, and it is called by the "masin"/capsule object, which is nearly unchanged from Sonic 1 at that point in time.
     
  17. Cooljerk

    Cooljerk

    Professional Electromancer Oldbie
    4,522
    214
    43
    There used to be a 2-player mode in early Sonic CD builds. I wonder if there are still routines in the final build related to that.

    edit: at least the 510 build has 2-player mode.
     
  18. Devon

    Devon

    A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Tech Member
    1,262
    1,433
    93
    your mom
    A lot of it was removed, but there are some remnants. There's an object (I don't remember which one, I think it was the grey boulder in Palmtree Panic) that calls the SolidObject function twice, due to a failure to properly remove the 2P functionality.
     
  19. BenoitRen

    BenoitRen

    Tech Member
    443
    191
    43
    That's probably a routine that delegates to hitchk/SolidObject. Sonic 3's capsule object does it too with chk_switch_ride and chk_switchu_ride.
     
  20. BenoitRen

    BenoitRen

    Tech Member
    443
    191
    43
    Hackers with more experience are probably already aware of this, but Sonic 3 isn't consistent with where it stores the address of its parent object. According to official symbol data, it should be at address 0x46 of the sprite status object, yet several objects store it at address 0x3E instead.

    I've been referencing Sonic 2's disassembly as well recently, and noticed that the address objects are documented as usually storing their parent's address at is 0x3E.

    My hypothesis is that objects in Sonic 3 that use address 0x3E are old Sonic 2 objects that they didn't update to follow the new convention.
     
    • Like Like x 1
    • Agree Agree x 1
    • Informative Informative x 1
    • List