don't click here

Sonic & Knuckles Collection C port

Discussion in 'Engineering & Reverse Engineering' started by BenoitRen, Jan 11, 2024.

  1. That One Guy Josh

    That One Guy Josh

    Speaks English AND Balanese. Member
    I remember this happening to me too in Sandopolis Act 2. Kept getting lost and I just BARELY managed to beat the boss before time killed me. Let's just say... I got shocked with the time bonus.
     
  2. nineko

    nineko

    I am the Holy Cat Tech Member
    6,310
    486
    63
    italy
    Yeah, I thought it was some kind of overflow at first, I found out it was deliberate only eventually.
     
  3. saxman

    saxman

    Oldbie Tech Member
    I never knew this was a thing! I know Sonic 2's code all too well to know it's not in there. But I'm curious if this is specific to Sonic & Knuckles Collection, or if the same thing happens in Sonic 3 and Sonic & Knuckles on the Genesis.
     
  4. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    334
    339
    63
    Canada
    It does happen on the Genesis, and it was carried over to Mania.
     
  5. muteKi

    muteKi

    Fuck it Member
    7,852
    131
    43
    So I learned in Sonic Triple Trouble that you get a bonus if you finish the special stages at exactly 0:00 on the clock, and from that tried to do the same in main stages in it and at least Sonic Chaos to see if you got a bigger bonus (which may not have been true, though both gave you some extra points for doing so). From that I decided to see if I could also hit 9:59 in Sonic 3 and get a bonus, and did there too.
     
    • Informative Informative x 1
    • List
  6. That One Guy Josh

    That One Guy Josh

    Speaks English AND Balanese. Member
    Just to show that it's actually possible:
    S3K-240409-115958.png
     
  7. BenoitRen

    BenoitRen

    Tech Member
    420
    186
    43
    I added a file to keep external resources that don't seem to be placed with object code. The most interesting piece of data is the following table that stores which animals can pop out of enemies and the end-of-level capsule per zone:
    Code (C):
    1. #define POCKY_RABBIT 0
    2. #define CUCKY_CHICKEN 1
    3. #define PECKY_PINGUIN 2
    4. #define ROCKY_SEAL 3
    5. #define FLICKY_FLICKY 5
    6. #define RICKY_SQUIRREL 6
    7. unsigned char zone_friend_data[24][2] = {
    8.   { FLICKY_FLICKY,  CUCKY_CHICKEN }, // Angel Island
    9.   { POCKY_RABBIT,   ROCKY_SEAL    }, // Hydrocity
    10.   { FLICKY_FLICKY,  CUCKY_CHICKEN }, // Marble Garden
    11.   { POCKY_RABBIT,   FLICKY_FLICKY }, // Carnival Night
    12.   { RICKY_SQUIRREL, FLICKY_FLICKY }, // Flying Battery
    13.   { PECKY_PINGUIN,  ROCKY_SEAL    }, // Icecap
    14.   { FLICKY_FLICKY,  CUCKY_CHICKEN }, // Launch Base
    15.   { RICKY_SQUIRREL, CUCKY_CHICKEN }, // Mushroom Hill
    16.   { POCKY_RABBIT,   CUCKY_CHICKEN }, // Sandopolis
    17.   { FLICKY_FLICKY,  CUCKY_CHICKEN }, // Lava Reef
    18.   { POCKY_RABBIT,   FLICKY_FLICKY }, // Sky Sanctuary
    19.   { RICKY_SQUIRREL, CUCKY_CHICKEN }, // Death Egg
    20.   { RICKY_SQUIRREL, FLICKY_FLICKY }, // Doomsdag
    21.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    22.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    23.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    24.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    25.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    26.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    27.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    28.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    29.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    30.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    31.   { FLICKY_FLICKY,  CUCKY_CHICKEN },
    32. };
    For fun, let's see how often each animal is represented:
    • Pocky the rabbit: 4
    • Cucky the chicken: 7
    • Pecky the pinguin: 1
    • Rocky the seal: 2
    • Flicky the flicky: 7
    • Ricky the squirrel: 3
    Cucky and Flicky are clearly overrepresented. And that's without counting their entries in zones after Doomsday Zone!
     
  8. BenoitRen

    BenoitRen

    Tech Member
    420
    186
    43
    I've been focusing on porting code related to Angel Island Zone. The code for its four enemies have been ported! Those being Cyclone/Rhinobot, Tullipon/Bloominator, Saruder/Monkey Dude, and Meramora/Catakiller Jr.

    Tullipon might be the simplest enemy in the game. It doesn't move. All it does is wait to appear on the screen, start a timer, then once that reaches -1 it'll shoot on frame 6 and 14. When it has finished animating, it waits once more. If you want to get an idea of how Sonic 3 works internally, this is a good place to start.

    There are two interesting things about Saruder.

    First, we all know it throws a coconut, right? Well, the game's labels don't refer to a coconut, but a banana. Maybe it was meant to throw that instead at some earlier point in development?

    Possibly related to the banana, the enemy's code has two data structures that seem to go unused. The first is called saru00_arm_set_tbl2, and it's meant to be used with function set_act00. Its data does nothing more than assign saru00_banana as the routine pointer. The second is saru00_arm_set_tbl2. I don't know what it's supposed to be used with yet. All I can see is that it has a pointer to saru00_arm. But each arm already has a structure with initialisation data.

    Then again, I can't determine where the coconut or banana is instantiated or even thrown (though there's plenty of code to move the arm when it takes a shot), so maybe that's done somewhere else and I have yet to uncover that reference.
     
  9. Mr. Cornholio

    Mr. Cornholio

    Member
    95
    64
    18
    That's interesting! If anything, I kinda figured Saruder was built on top of/heavy referenced Coconuts' code from Sonic 2 where that character does throw a coconut. All the stuff we have for Sonic 2 seems to suggest that's how that character was always intended to attack and Sonic 3 seems to have different naming conventions altogether skimming this thread. So...that's something.

    I kinda wonder if it was changed because the coconut just seemed more harmful to Sonic or it was easier to see in a busy environment.

    Nothing I'm saying here is terribly handy for your C port, but I did want to at least stop by and say thanks for your efforts. Your finds have been fun reads.
     
  10. BenoitRen

    BenoitRen

    Tech Member
    420
    186
    43
    I've been looking at the code for the zone title cards, and am now wondering if the zone order I have for the 2P zones is correct.

    This is the enum for the zone order I have at the moment:
    Code (C):
    1. typedef enum zone_id {
    2.   ANGEL_ISLAND = 0x00,
    3.   HYDROCITY = 0x01,
    4.   MARBLE_GARDEN = 0x02,
    5.   CARNIVAL_NIGHT = 0x03,
    6.   FLYING_BATTERY = 0x04,
    7.   ICECAP = 0x05,
    8.   LAUNCH_BASE = 0x06,
    9.   MUSHROOM_HILL = 0x07,
    10.   SANDOPOLIS = 0x08,
    11.   LAVA_REEF = 0x09,
    12.   SKY_SANCTUARY = 0x0A,
    13.   DEATH_EGG = 0x0B,
    14.   DOOMSDAY = 0x0C,
    15.   ANGEL_ISLAND_DUMMY_AND_ENDING = 0x0D,
    16.   AZURE_LAKE = 0x0E,
    17.   BALLOON_PARK = 0x0F,
    18.   DESERT_PALACE = 0x10,
    19.   CHROME_GADGET = 0x11,
    20.   ENDLESS_MINE = 0x12,
    21.   ZONE_GUMBALL_MACHINE = 0x13,
    22.   ZONE_SLOT_MACHINE = 0x14,
    23.   ZONE_ROLLING_JUMP = 0x15,
    24.   LAVA_REEF_BOSS_AND_HIDDEN_PALACE = 0x16,
    25.   DEATH_EGG_BOSS_AND_MASTER_EMERALD_SHRINE = 0x17
    26. }
    27. zone_id;
    What confuses me is that in the disassembly, Balloon Park is followed by Chrome Gadget, whereas in the list on Sonic the Hedgehog 3/Hidden content, it's followed by Desert Palace.

    Which one is right?
     
  11. Brainulator

    Brainulator

    Regular garden-variety member Member
    It's ABDCE in the internal order, but ABCDE in gameplay, if it makes any sense.
     
    • Informative Informative x 1
    • List
  12. BenoitRen

    BenoitRen

    Tech Member
    420
    186
    43
    Now the code for the title cards has been committed!

    This is the second unlabelled object I've ported. The disassembly wasn't as documented for this one, resulting in lots of unknown values, which frustrated me. However, when I sat down to study them, I noticed similarities with actclear (end-of-act results tallying), and in the end they've all been documented. Phew!
     
  13. BenoitRen

    BenoitRen

    Tech Member
    420
    186
    43
    I've been porting the code for springs, which more than once calls collision checking code. So I figured I'd also look at that to get a better understanding of what parameters to send and what to expect back.

    Almost 500 lines of code later: it's a mess, and I don't get it (which should be obvious by how much I just plainly transcribed the ASM to C). That portion was not labelled, after all, and documentation in the disassemblies is sparse.

    Can anyone familiar with how Sonic 2 or Sonic 3 handle collision lend me a hand?

    EDIT: Oh, I didn't see that Sonic 2's disassembly has loads of notes at
    SolidObject_OnScreenTest. Will have to take a closer look.
     
    Last edited: May 1, 2024 at 11:39 PM
  14. nineko

    nineko

    I am the Holy Cat Tech Member
    6,310
    486
    63
    italy