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

    BenoitRen

    Tech Member
    458
    199
    43
    I find it hard to believe that only the spring used the rideon routines. Surely the floating platforms do, as well?

    Anyway, I remembered Sonic Jam also having some labels for cddat, and Brainulator had this to say about them:
     
    Last edited: May 7, 2024
    • Agree Agree x 1
    • Informative Informative x 1
    • List
  2. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    395
    406
    63
    Canada
    Ohhh I see! cd_down makes sense too. It was bit 3 in Feb 90' (Although multiplied by 2 for some reason, quirk of X68k?) So that probably means that cd_up, cd_left, and cd_right were bits to detect Sonic interacting with objects from those sides! In fact if we assume that cd_left and cd_right were bits 4 and 5, because up and down were 2 and 3, then bit 5 being the push flag also makes sense. I think. With bit 4 being freed up for ballj since sideways interactions could simply be marked with 1 flag.
     
  3. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
    It's unfortunate that we don't seem to have any constants for the bits of regular objects's cddat field. I could see cd_down maybe being bit 0, but that's it.
     
  4. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
    I've been wondering if this is correct.

    From what I could find, Sonic 1 has two routines to check if something is on-screen, and they both check Sonic's X and Y position. Sonic CD's frameoutchk, which actually isn't called anywhere, only checks the X position. Sonic CD doesn't have a routine called frameoutchkd.

    However, MarkObjGone seems to a Sonic 2 disassembly label, so I checked that out. That does look more like Sonic CD's frameoutchk, but given that Sonic 2 and Sonic CD were both based on Sonic 1, and Sonic 1 doesn't have that kind of method, I'm hesitant to claim that this is the correct label.

    But maybe frameoutchk and frameoutchkd are labels coming from somewhere else? I checked out the Sonic 2 Nick Arcade symbol lists, but neither label is present there.

    Curiously, Sonic CD has some more routines that check if a sprite is on-screen, which are used:
    • frameout_s: This just calls frameout_s00 with the object's current X position.
    • frameout_s00: This is like frameoutchk, but customised for Sonic CD's time travel feature. It accepts an X position, meaning an object can give a different X position if it wants to.
    • frameout_s0: This actually doesn't do any checking, but is a more elaborate frameout. I'm mentioning it anyway because of the name similarity.
    frameout_s and frameout_s00 seems to match Sonic 2's MarkObjGone and MarkObjGone2. But, again, those don't seem to have existed in Sonic 1. Unless I'm missing something, of course.
     
    Last edited: May 8, 2024
  5. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    395
    406
    63
    Canada
    Where are you looking in Sonic 1? Because here's S1's frameoutchk.
    Code (Text):
    1. frameoutchk:
    2.         move.w    xposi(a0),d0
    3.         andi.w    #$ff80,d0
    4.         move.w    scra_h_posit,d1
    5.         subi.w    #128,d1
    6.         andi.w    #$ff80,d1
    7.         sub.w    d1,d0
    8.         cmpi.w    #640,d0
    9.         bhi.w    ?jump
    10.         bra.w    actionsub
    11.  
    12. ?jump:
    13.         lea        flagwork,a2
    14.         moveq    #0,d0
    15.         move.b    cdsts(a0),d0
    16.         beq.b    ?die
    17.         bclr    #7,2(a2,d0.w)
    18.  
    19. ?die:
    20.         bra.w    frameout
     
  6. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
  7. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    395
    406
    63
    Canada
    Yeah that's not frameoutchk, in Github it's called RememberState. ChkObjectVisible is only called by like 3 objects.
     
  8. Brainulator

    Brainulator

    Regular garden-variety member Member
    The names frameoutchk and frameoutchkd are found in the Sonic 2 Nick Arcade prototype. Deep within the ROM, there's several older versions of various obj files, which start with a list of labels, then XDEFs, then XREFs, all of which point to their locations in the (previous ROM) as well as where they are used in the file. I've worked a lot of it out and am willing to share what I've come up with so far.
     
  9. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
    Please do, o keeper of labels! :)
     
  10. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
    I had chosen CD_HOVER as the constant for bit 3 of the player's cddat field. However, I warmed up to CD_RIDE, as it seemed very likely that it was the original name. I figured I'd dig into Sonic & Knuckles Collection's labels and its related code to confirm.

    There's a shared routine called chk_ride_flg. I ported it to C for this post:
    Code (C):
    1. void chk_ride_flg(sprite_status* p_actwk) {
    2.   if ((p_actwk->cddat1 & 0x18) == 0) return;
    3.   bool plride_set = BIT_IS_SET(p_actwk->cddat1, CD_PLRIDE);
    4.   CLEAR_BIT(p_actwk->cddat1, CD_PLRIDE);
    5.   if (!plride_set) {
    6.     CLEAR_BIT(actwk[0].cddat1, CD_RIDE);
    7.     SET_BIT(actwk[0].cddat1, CD_JUMP);
    8.   }
    9.   bool pl2ride_set = BIT_IS_SET(p_actwk->cddat1, CD_PL2RIDE);
    10.   CLEAR_BIT(p_actwk->cddat1, CD_PL2RIDE);
    11.   if (!pl2ride_set) {
    12.     CLEAR_BIT(actwk[1].cddat1, CD_RIDE);
    13.     SET_BIT(actwk[1].cddat1, CD_JUMP);
    14.   }
    15. }
    If any of the object's player ride bits (3 and 4) are set, it checks the individual bits. If one is not set, it clears the ride bit on the player, and sets the jump bit.

    I think this is as much confirmation we're going to get unless we find the label itself.

    I'd also like to take this opportunity to propose names for a non-player object's cddat:
    • Bit 0: CD_RIGHT (object is looking right)
    • Bit 1: CD_DOWN (object is upside down)
    • Bit 2: CD_WRT (object has an entry in emy_wrt_flg due to performing DPLC) (not applicable to Sonic 1)
    • Bit 3: CD_PLRIDE (player is riding this object)
    • Bit 4: CD_PL2RIDE (player 2 is riding this object) (not applicable to Sonic 1)
    • Bit 5: CD_PLPUSH (player is pushing this object)
    • Bit 6: CD_PL2PUSH (player 2 is pushing this object) (not applicable to Sonic 1)
    • Bit 7: CD_DIE (object is about to be deleted) (not applicable to Sonic 1)
    According to the wiki, bit 7 is object-specific in Sonic 1. No idea what its name would be there.

    For Sonic 3, the name is based on finding that the series of chk_oya_die routines check bit 7 of the parent's cddat field.
     
    Last edited: May 12, 2024
  11. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    395
    406
    63
    Canada
    I'd say cd_die for bit 7 is accurate in Sonic 1. Bit 7 is set for every enemy when they're destroyed. However because the enemy then immediately becomes an explosion it's pretty useless. The Buzz Bomber's missile tries using it to detect when it collides with Sonic (and therefore 'dies') to spawn the beta Ball Hog projectile's explosion, but it doesn't work because it's collision type is hurt and not enemy, only enemies use cd_die. I don't necessarily agree with cd_right or cd_down though, since as I mentioned cd_left and cd_up existed in Feb 90. Along with cd_down and cd_right being bits 3 and 5 in Feb 90, so I think they're collision interactions with sprites.
     
  12. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
    cd_left and cd_up existed, but were commented out. Like you said, they were possibly deprecated. The only thing we know for sure is that cd_down survived.
     
  13. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    395
    406
    63
    Canada
    Right, but why would they deprecate most of the flags and then change the position and purpose of the others while still using their namss? That doesn't necessarily add up to me.
     
  14. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
    Where do you think cd_down and others are used in the final?
     
  15. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    395
    406
    63
    Canada
    I think cd_down is bit 3 to indicate downwards collision with a sprite, and cd_right is bit 5 to indicate right side collision with a sprite. cd_up was 2 and cd_left was 4 but got deprecated as they didn't really have a use for a top collision flag, and you could simply optimize sideways collisions with a single bit so they got rid of cd_left. This is entirely going off of Feb 90 which does give us bit positions for these things, although multiplied by 2 for some unknown reason.
    Code (Text):
    1. *cd_walk            equ 0*2
    2.  
    3. *cd_jump            equ 1*2
    4.  
    5. *cd_up              equ 2*2
    6.  
    7. *cd_down            equ 3*2
    We know at least that bit 1 is in fact cd_jump in final for Sonic. cd_walk could be the horizontal flip flag too, it'd be weird but not impossible. cd_left and cd_right aren't defined here but it can be implied they would've followed the UDLR scheme, so they'd be bits 4 and 5.
    That leaves us with the order of cd_walk(?), cd_jump, cd_ball, cd_down, cd_ballj, cd_right, cd_water, and cd_die. For Sonic.
    For every other object, bits 2 and 4 where cd_up and cd_left would've been are conveniently unused.
     
    Last edited: May 14, 2024 at 2:30 PM
  16. BenoitRen

    BenoitRen

    Tech Member
    458
    199
    43
    Hold on, why are you defining bit 7 of Sonic as cd_die? According to the wiki, it's unused, and I haven't come across it being used myself, either.
     
  17. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Tech Member
    395
    406
    63
    Canada
    Sorry, I didn't mean to imply that Sonic used it. cd_die is only used by enemies.
    Here's the full list then

    Sonic
    Bit 0 - cd_walk(?) - Horizontal flip flag.
    Bit 1 - cd_jump - In-air flag.
    Bit 2 - cd_ball - Rolling/jump flag.
    Bit 3 - cd_down - Flag when Sonic is colliding on top of an object.
    Bit 4 - cd_ballj - Roll-jump lock flag.
    Bit 5 - cd_right - Flag when Sonic is colliding with the side of an object.
    Bit 6 - cd_water - Underwater flag.
    Bit 7 - Unused

    Global
    Bit 0 - cd_walk(?) - Horizontal flip flag.
    Bit 1 - ??? - Vertical flip flag.
    Bit 2 - cd_up - Unused in final, possibly indicated when Sonic's colliding from below.
    Bit 3 - cd_down - Flag when Sonic is colliding from above.
    Bit 4 - cd_left - Unused in final, possibly indicated when Sonic's colliding from the right.
    Bit 5 - cd_right - Flag when Sonic is colliding from the sides. May have only detected if Sonic was colliding from the left in very very early versions.
    Bit 6 - ??? - Unused.
    Bit 7 - cd_die - Flag when an enemy is destroyed. Implementation is pretty wonky in Sonic 1, so most objects just end up using it as a custom flag.
     
    Last edited: May 14, 2024 at 3:59 PM
    • Like Like x 1
    • Informative Informative x 1
    • List