Sonic 1 objects and their memory usage

Discussion in 'Engineering & Reverse Engineering' started by Hivebrain, Aug 15, 2021.

  1. Hivebrain

    Hivebrain

    Administrator
    2,917
    57
    28
    53.4N, 1.5W
    HiveView
    As you know, objects in Sonic 1 are each assigned $40 bytes of memory in the object status table (OST) when they're loaded. Bytes 0-$28 have fixed uses (as described here), although not every object sticks to it. The remaining bytes $29-$3f are free for the object to use in any way.

    I wanted to rearrange how the OST is used, in particular to expand the number of fixed bytes, so I thought it would be helpful to know exactly which bytes are used by every object. This is a diagram showing that information:

    Sonic 1 objects and memory usage - Sheet1.png

    Bytes $29-$2f are only used by a handful of objects, so if you want more fixed bytes that's where I'd start. Teal bytes represent child object addresses, which vary in number in some cases (bridges, swinging platforms) but not in others (caterkiller segments). The diagram may not be 100% accurate as I probably made 1 or 2 mistakes.

    EDIT: Out of date. Use this instead: https://github.com/cvghivebrain/s1disasm/blob/main/Objects and memory usage.pdf
     
    Last edited: Sep 4, 2021
    • Like Like x 5
    • Informative Informative x 1
    • List
  2. Sonic Hachelle-Bee

    Sonic Hachelle-Bee

    Taking a Sand Shower Tech Member
    748
    70
    28
    Lyon, France
    Sonic 2 Long Version
    This is very useful information. It is often hard to tell which object uses which bytes in a safe and fast manner.
    We should have a diagram like this for S2 and S3K.

    Thank you Hivebrain.
     
  3. Quickman

    Quickman

    Tech Member
    5,590
    4
    18
    :x
    omg porjcet
    It seems like the bytes with documented uses are broken down into two groups: those whose purpose is fixed due to being used by the object system itself, and those whose purpose is conveyed by using particular subroutines (e.g. objects which never call the collision routines can use the collision bytes as scratch space; likewise for objects which don't animate and the animation bytes). Documenting which is which would be helpful as an extension of this already impressive work.
     
  4. Techokami

    Techokami

    For use only on NTSC Genesis systems Researcher
    1,349
    42
    28
    HoleNet!
    Sonic Worlds Next
    If what I am seeing in this chart is correct... there is a word-sized entry ($0E and $0F) that is only used by the SonicPlayer object, which isn't using $2A or $2B. So if that word-sized entry gets moved... that frees up an entire global word-sized entry in the OST, which would be needed for things like porting the Sonic 3K object manager over... HMMMMMM...
     
  5. Hivebrain

    Hivebrain

    Administrator
    2,917
    57
    28
    53.4N, 1.5W
    HiveView
    I can use a different colour for bytes which are used for something other than their intended purpose. I think there might be a couple of objects that use animation bytes as general timers.

    That's true, but $e-$f are the y subpixel value, which is probably assumed to be next to the y value. Moving it may require more work than changing a single equ. A better option would be bytes $14-$15 (inertia), which are used by 5 objects, but relocating them would be pretty straightforward.

    Also I'm thinking animations only really need three bytes: animation number, animation frame and time until next frame. Optimising the code would save another 2 bytes.
     
  6. Hivebrain

    Hivebrain

    Administrator
    2,917
    57
    28
    53.4N, 1.5W
    HiveView
    I combed through all the objects again, and I'd actually made a lot of mistakes, so here's an up to date chart:

    https://github.com/cvghivebrain/s1disasm/blob/main/Objects and memory usage.pdf

    I added more colours along with a key at the bottom of the page. Again, I can't guarantee this is 100% accurate. The Final Zone boss appears to have variables that aren't functional, meaning when I disabled them it continued to behave normally. It's a rather complicated object that I found somewhat incomprehensible, so I haven't marked any of it as orange yet.
     
    • Informative Informative x 4
    • Like Like x 3
    • List
  7. Brainulator

    Brainulator

    Regular garden-variety member Member
    I was actually thinking of working on something like this, only making the actual cell contents list out how each byte is used (which would result in some redundancy with common variables, given their descriptions in a U.S. patent). Interesting how there's no object that makes use of all $40 bytes...
     
  8. Hivebrain

    Hivebrain

    Administrator
    2,917
    57
    28
    53.4N, 1.5W
    HiveView
    OSTs are located in $D000-$EFFF in RAM, but only those in $D800+ are used by the usual object loading routine and can interact with Sonic. The first $20 OST spots are used by Sonic, shields, the HUD and so on. I wanted to know exactly which ones are used so I can safely add things like spindash dust without worrying about conflicts.

    Code (Text):
    1.  
    2. v_ost_all:       equ $FFFFD000 ; object variable space ($40 bytes per object) ($2000 bytes)
    3.    v_ost_player:       equ v_ost_all ; object variable space for Sonic ($40 bytes)
    4.    ; Title screen and intro
    5.    v_ost_titlesonic:   equ v_ost_all+(sizeof_ost*1) ; title screen Sonic
    6.    v_ost_psb:       equ v_ost_all+(sizeof_ost*2) ; title screen "Press Start Button"
    7.    v_ost_tm:       equ v_ost_all+(sizeof_ost*3) ; title screen "TM"
    8.    v_ost_titlemask:   equ v_ost_all+(sizeof_ost*4) ; title screen sprite mask
    9.    ; Intro/credits
    10.    v_ost_credits:       equ v_ost_all+(sizeof_ost*2) ; "Sonic Team Presents" and credits text
    11.    ; Try again
    12.    v_ost_endeggman:   equ v_ost_all+(sizeof_ost*2) ; ending/"Try Again" Eggman
    13.    v_ost_tryagain:       equ v_ost_all+(sizeof_ost*3) ; "Try Again" text
    14.    v_ost_tryag_emeralds:   equ v_ost_all+(sizeof_ost*$20) ; "Try Again" chaos emeralds
    15.    ; Continue
    16.    v_ost_cont_text:   equ v_ost_all+(sizeof_ost*1) ; continue screen text
    17.    v_ost_cont_oval:   equ v_ost_all+(sizeof_ost*2) ; continue screen oval
    18.    v_ost_cont_minisonic:   equ v_ost_all+(sizeof_ost*3) ; continue screen mini Sonics
    19.    ; Level - no interaction with Sonic
    20.    v_ost_hud:       equ v_ost_all+(sizeof_ost*1) ; HUD
    21.    v_ost_titlecard1:   equ v_ost_all+(sizeof_ost*2) ; title card - zone name
    22.    v_ost_titlecard2:   equ v_ost_all+(sizeof_ost*3) ; title card - "zone"
    23.    v_ost_titlecard3:   equ v_ost_all+(sizeof_ost*4) ; title card - "act" 1/2/3
    24.    v_ost_titlecard4:   equ v_ost_all+(sizeof_ost*5) ; title card - oval
    25.    v_ost_shield:       equ v_ost_all+(sizeof_ost*6) ; shield
    26.    v_ost_stars1:       equ v_ost_all+(sizeof_ost*8) ; invincibility stars
    27.    v_ost_stars2:       equ v_ost_all+(sizeof_ost*9) ; invincibility stars
    28.    v_ost_stars3:       equ v_ost_all+(sizeof_ost*$A) ; invincibility stars
    29.    v_ost_stars4:       equ v_ost_all+(sizeof_ost*$B) ; invincibility stars
    30.    v_ost_end_emeralds:   equ v_ost_all+(sizeof_ost*$10) ; ending chaos emeralds
    31.    v_ost_gotthrough1:   equ v_ost_all+(sizeof_ost*$17) ; got through act - "Sonic has"
    32.    v_ost_gotthrough2:   equ v_ost_all+(sizeof_ost*$18) ; got through act - "passed"
    33.    v_ost_gotthrough3:   equ v_ost_all+(sizeof_ost*$19) ; got through act - "act" 1/2/3
    34.    v_ost_gotthrough4:   equ v_ost_all+(sizeof_ost*$1A) ; got through act - score
    35.    v_ost_gotthrough5:   equ v_ost_all+(sizeof_ost*$1B) ; got through act - time bonus
    36.    v_ost_gotthrough6:   equ v_ost_all+(sizeof_ost*$1C) ; got through act - ring bonus
    37.    v_ost_gotthrough7:   equ v_ost_all+(sizeof_ost*$1D) ; got through act - oval
    38.    v_ost_watersurface1:   equ v_ost_all+(sizeof_ost*$1E) ; LZ water surface
    39.    v_ost_watersurface2:   equ v_ost_all+(sizeof_ost*$1F) ; LZ water surface
    40.    ; Special stage results
    41.    v_ost_ssresult1:   equ v_ost_all+(sizeof_ost*$17) ; special stage results screen
    42.    v_ost_ssresult2:   equ v_ost_all+(sizeof_ost*$18) ; special stage results screen
    43.    v_ost_ssresult3:   equ v_ost_all+(sizeof_ost*$19) ; special stage results screen
    44.    v_ost_ssresult4:   equ v_ost_all+(sizeof_ost*$1A) ; special stage results screen
    45.    v_ost_ssresult5:   equ v_ost_all+(sizeof_ost*$1B) ; special stage results screen
    46.    v_ost_ssres_emeralds:   equ v_ost_all+(sizeof_ost*$20) ; special stage results screen chaos emeralds
    47.    ; Level - can interact with Sonic
    48.    v_ost_level_obj:   equ v_ost_all+(sizeof_ost*$20) ; level object variable space ($1800 bytes)
    49.  
    The ones that seem to be completely unused are 7, $C-$F and $16. $10-$15 are only used in the ending so those are pretty safe too.
     
    • Informative Informative x 2
    • List
  9. Alex Field

    Alex Field

    シュート! カオス・エメラルド・ザが消えようとしている! Member
    129
    73
    28
    Downunda, Mobius
    Sonic the Hedgehog 2+, Sonic the Hedgehog 3+
    Minor correction:
    Those "unused" values for the wrecking ball are used; $38-$3B are used for spawning, while $3E-$3F are used for its motion.
     
    • Informative Informative x 1
    • List
  10. Hivebrain

    Hivebrain

    Administrator
    2,917
    57
    28
    53.4N, 1.5W
    HiveView
    They're being written to, but I can't see where $38-$3B are being read. You're right though, I tried disabling those bytes and it did break the object. $3E-$3F is handled by a separate routine which is why I missed that.
     
    • Informative Informative x 1
    • List