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. Antheraea

    Antheraea

    Bug Hunter Member
    the chant was added in late IIRC, when they removed the graphics for the band in the sound test because they couldn't finish it and put the chant in the extra space.
     
  2. Kilo

    Kilo

    Starting new projects every week Tech Member
    1,209
    1,159
    93
    Canada
    Changes with the weather
    The band was never implemented in the first place there were no graphics to remove. The ROM space was likely planned for it, ended up not being used, and so the Sega chant was added.

    Edit: Also did my wiki update for the day. I lied about working on functions, sorry! However, I did do a lot of work on actors. Sonic 1 is effectively finished (aside from images) at least until we somehow uncover more names. Also added a bit to Sonic 2 and 3K. And I fixed up met in the Special Stage block table. Oh and put notes on actors that got renamed in other games as Devon mentioned.
     
    Last edited: Jan 9, 2025 at 7:11 PM
  3. ndiddy

    ndiddy

    Member
    41
    63
    18
    The video is from a show where they brought Vadim Gerasimov (programmer of the original DOS version of Tetris) around to meet various Japanese game developers. I don't think Naka's actually doing anything, they probably just had him load the final Sonic code onto dev hardware and step around in the debugger for b-roll purposes. The Sega chant was added in the final few days of crunch before the game shipped, so I don't think they would have brought a news crew and visitors into the office at that point.
     
    • Informative Informative x 2
    • Like Like x 1
    • Agree Agree x 1
    • List
  4. Kilo

    Kilo

    Starting new projects every week Tech Member
    1,209
    1,159
    93
    Canada
    Changes with the weather
    Now that you mention it, it does just seem like he's awkwardly staring at the screens scrolling through the code lol.
     
  5. Cooljerk

    Cooljerk

    Professional Electromancer Oldbie
    4,920
    589
    93
    I would put money on the graphic of Sonic singing into the microphone from the ending to Sonic 1 Game Gear being a modified asset intended for the Sega Genesis just like the title screen graphic was.

    FCJ7SXxXoAQPsXm.jpg
     
  6. Kilo

    Kilo

    Starting new projects every week Tech Member
    1,209
    1,159
    93
    Canada
    Changes with the weather
    So @TwoSpaces sent an unobfuscated version of Sonic 1 J2ME Part 2.
    Unfortunately it's mostly useless, almost everything got renamed into it's own thing. The only thing I got out of it was a single new actor name; shooter. Which I believe to be the SBZ teleporter trigger, here's the code:
    Code (Text):
    1.   private void shooter_nflag_move_ikeshita(int paramInt) {
    2.     byte b1 = 27;
    3.     byte b2 = 44;
    4.     int i = -1;
    5.     b1 = 5;
    6.     objectData[6] = objectData[2];
    7.     objectData[7] = objectData[3];
    8.     if (objectData[5] == 0) {
    9.       i = ObjectColChk(PlayerPosX(), PlayerPosY() - 12, ploldpos[0], ploldpos[1] - 12, 12, 12, objectData[2], objectData[3], objectData[6], objectData[7], b1, b2);
    10.       if (i >= 0)
    11.         if (i == 0) {
    12.           PlayerParam[1] = objectData[3] - b2 << 8;
    13.           setRaidOnSize(objectData[2], b1);
    14.           playerRaidOn(objectData[22]);
    15.         } else if (i == 1) {
    16.           PlayerParam[0] = objectData[2] - b1 - 12 << 8;
    17.           PlayerParam[10] = 0;
    18.           if (objectData[19] == 0) {
    19.             objectData[5] = 1;
    20.             objectData[10] = 0;
    21.           } else if (KeyPress[4]) {
    22.             playerPushSet();
    23.           }
    24.         } else if (i == 2) {
    25.           PlayerParam[0] = objectData[2] + b1 + 12 + 1 << 8;
    26.           PlayerParam[10] = 0;
    27.           if (objectData[19] != 0) {
    28.             objectData[5] = 1;
    29.             objectData[10] = 0;
    30.           } else if (KeyPress[3]) {
    31.             playerPushSet();
    32.           }
    33.         } else if (i == 3) {
    34.           PlayerParam[1] = objectData[3] + b2 + 12 + 12 + 1 << 8;
    35.           setHeadHit();
    36.         }
    37.     }
    38.     if (objectData[5] == 1) {
    39.       PlayerJump = true;
    40.       PlayerDamage = false;
    41.       PlayerBall = true;
    42.       PlayerNoCol = true;
    43.       PlayerNoCtrl = true;
    44.       PlayerParam[11] = PlayerParam[11] + plmaxspd;
    45.       objectData[10] = objectData[10] + 1;
    46.       PlayerParam[0] = objectData[2] << 8;
    47.       PlayerParam[1] = objectData[3] + 12 - this.shooter_nflag_ike_pos[objectData[10] / 5 % 12] << 8;
    48.       if (objectData[10] / 5 % 12 == 11) {
    49.         objectData[5] = 2;
    50.         if (objectData[4] == 0 || objectData[4] == 6)
    51.           objectData[5] = 4;
    52.         objectData[10] = 0;
    53.         objectData[11] = 0;
    54.         objectData[12] = 0;
    55.         PlayerParam[3] = 0;
    56.         PlayerParam[5] = 0;
    57.         PlayerParam[10] = 0;
    58.       }
    59.     }
    60.     if (objectData[5] == 4)
    61.       if (objectData[4] == 0) {
    62.         PlayerParam[1] = PlayerPosY() + 10 << 8;
    63.         if (objectData[3] > PlayerPosY())
    64.           objectData[5] = 2;
    65.       } else {
    66.         PlayerParam[1] = PlayerPosY() - 10 << 8;
    67.         if (158 < PlayerPosY())
    68.           objectData[5] = 2;
    69.       }
    70.     if (objectData[5] == 2) {
    71.       PlayerJump = true;
    72.       PlayerDamage = false;
    73.       PlayerBall = true;
    74.       PlayerNoCol = true;
    75.       PlayerNoCtrl = true;
    76.       PlayerParam[11] = PlayerParam[11] + plmaxspd;
    77.       objectData[11] = 0;
    78.       objectData[12] = 0;
    79.       if (objectData[10] * 2 + 1 < (this.shooter_nflag_ike_objectPos[objectData[4]]).length) {
    80.         if (PlayerPosX() > this.shooter_nflag_ike_objectPos[objectData[4]][objectData[10] * 2]) {
    81.           objectData[11] = -1;
    82.         } else if (PlayerPosX() < this.shooter_nflag_ike_objectPos[objectData[4]][objectData[10] * 2]) {
    83.           objectData[11] = 1;
    84.         }
    85.         if (PlayerPosY() > this.shooter_nflag_ike_objectPos[objectData[4]][objectData[10] * 2 + 1]) {
    86.           objectData[12] = -1;
    87.         } else if (PlayerPosY() < this.shooter_nflag_ike_objectPos[objectData[4]][objectData[10] * 2 + 1]) {
    88.           objectData[12] = 1;
    89.         }
    90.         objectData[10] = objectData[10] + 1;
    91.         objectData[5] = 3;
    92.       } else {
    93.         objectData[5] = 0;
    94.         PlayerNoCol = false;
    95.         PlayerNoCtrl = false;
    96.       }
    97.     }
    98.     if (objectData[5] == 3) {
    99.       PlayerParam[11] = PlayerParam[11] + plmaxspd;
    100.       PlayerJump = true;
    101.       PlayerDamage = false;
    102.       PlayerBall = true;
    103.       PlayerNoCol = true;
    104.       PlayerNoCtrl = true;
    105.       if (objectData[11] != 0) {
    106.         PlayerParam[0] = PlayerPosX() + objectData[11] * 10 << 8;
    107.         if (objectData[11] == -1 && PlayerPosX() < this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2]) {
    108.           PlayerParam[0] = this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2] << 8;
    109.           objectData[11] = 0;
    110.         }
    111.         if (objectData[11] == 1 && PlayerPosX() > this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2]) {
    112.           PlayerParam[0] = this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2] << 8;
    113.           objectData[11] = 0;
    114.         }
    115.       }
    116.       if (objectData[12] != 0) {
    117.         PlayerParam[1] = PlayerPosY() + objectData[12] * 10 << 8;
    118.         if (objectData[12] == -1 && PlayerPosY() < this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2 + 1]) {
    119.           PlayerParam[1] = this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2 + 1] << 8;
    120.           objectData[12] = 0;
    121.         }
    122.         if (objectData[12] == 1 && PlayerPosY() > this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2 + 1]) {
    123.           PlayerParam[1] = this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2 + 1] << 8;
    124.           objectData[12] = 0;
    125.         }
    126.       }
    127.       if (objectData[11] == 0 && objectData[12] == 0) {
    128.         PlayerParam[0] = this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2] << 8;
    129.         PlayerParam[1] = this.shooter_nflag_ike_objectPos[objectData[4]][(objectData[10] - 1) * 2 + 1] << 8;
    130.         objectData[5] = 2;
    131.       }
    132.     }
    133.     if (raidOn && raidObjectNum == objectData[20] && i != 0)
    134.       raidOn = false;
    135.   }
    Also turns out the absurd amount of draw functions was not an obfuscation thing.
    Every single actor has it's own drawing function.

    And there's still a chance now that met isn't the special stage walls:
    upload_2025-1-10_9-59-13.png
     
    Last edited: Jan 10, 2025 at 3:59 PM
    • Informative Informative x 2
    • List
  7. TwoSpaces

    TwoSpaces

    Member
    Cool stuff, though it's not Part 2 (the version of Part 2 with debug prints was another thing). Basically someone I know went digging on old forums and found a firmware of the Chinese release of the Panasonic VS3, which is one of the phones that had Sonic 1 for the J2ME preinstalled in it - not Part 1 (or 2), but seemingly a different port of the DoJa version produced specifically for these Panasonic preinstalls, with key differences being that all content is in one app (as opposed to being split into Part 1 and Part 2), that the music is in Yamaha SMAF (.MMF) format (most versions of Part 1 and 2 have MIDI music), and now, after the Japanese phone preservationists managed to extract this version out of the firmware dump, it turned out that there's no obfuscation on the Java classes. Also, there's music and graphics for the special stages, but you can't actually enter the giant rings in this Panasonic version (apparently their graphics aren't present), so I'm guessing all versions aside from DoJa had those cut because of tech limitations.
    Screenshot from 2025-01-11 14-30-10.png
     
    • Informative Informative x 3
    • Like Like x 2
    • List
  8. Kilo

    Kilo

    Starting new projects every week Tech Member
    1,209
    1,159
    93
    Canada
    Changes with the weather
    The well's running pretty dry on things we can get out of Sonic 1 at this point, so I've switched over to investigating Sonic 2 and 3K, and pushed out a big update to the wiki. I added a bunch of actors for both games, and a decent chunk of variables and constants for 3K. If you're wondering why some of the Sonic 2 actors don't have references, it's because I pulled their names from Sonic 2 J2ME, which we don't have a thread on.
    Oh and I started uploading images to the wiki so we have more sprites to look at. Not a lot done yet in that regard, but it's something.
    I'll probably take a week off from this since I spent the whole day on it. But then I swear I'll work on functions instead of actors like I said I would. :V
    I'm also thinking at this point we should split off the resources we're referencing into their own wiki page rather than linking to a bunch of threads that are wildly disorganized.
     
    Last edited: Jan 12, 2025 at 11:10 PM