Help Getting the Unused Idle Frame Working for Super Sonic

Discussion in 'Engineering & Reverse Engineering' started by DeadSkullzJr, Apr 14, 2020.

  1. DeadSkullzJr


    Hello everyone, did some extensive research on the unused content in relation to Sonic 3 and a little bit for Sonic 3 & Knuckles. A few things got my interest, and for the most part I was able to mess with the disassembly for the games respectively to get those pieces of unused content working again. One thing stuck out to me though, and that was the idle Sonic frame that ended up unused for Super Sonic. I already looked into the unused palette cycle and managed to get that working myself. However I am at a stump trying to get the idle frame itself working, I looked on this site here for some information regarding the matter:

    TCRF doesn't mention much on it other than the fact that it was unused (ended up editing that page because whoever posted the information made a mistake and put down the wrong value for the palette frame, all fixed of course). I looked into the list of tools to find anything in relation to DPLC entries and generally anything about what Fred Bronze did to fix the frame (sadly he didn't list the tools he used and the comments didn't have questions regarding the matter). Normally I would have asked right in the source page but considering the last comment was made back in 2017, who knows if the author is active, plus I am not sure if bumping is allowed on the blogs (I never blogged before so I haven't a clue on the matter). I tried the Sonic Retro Discord server in the appropriate channel, sadly my help request fell into the chat abyss (this does get annoying at times, but oh well I guess), I even went on YouTube to see how people did tweaks to the sprites/frames, unfortunately it seems most if not all of the videos are extremely dated and practically none of them show any utilization of most or if any of the modern tools that current hackers obviously use (some videos even crop the name of the software out for whatever reason, making it difficult to know what these individuals used, comments there aren't helpful either). I tried Flex 2 at least to give that a shot and right away I was confused on many of the ways it went about handling things. It's evident though that I am trying to figure things out one way or another, however the results require me to have some assistance or a guide to pull me through for a better understanding of things.

    One thing I will mention, I couldn't seem to find anything about Super Sonic in the sprite section of the S3/SK disassembly, though I might be looking in the wrong place. I did assume that maybe it was bunched in with one of the Sonic ASM, map, etc files and wasn't able to get anything about them to show up with Flex 2 (my inability to use Flex 2 might be the reason I couldn't though).

    Thank you in advance for providing the time to read and for helping if you can, if you can't, still thank you for at least giving a look at this!

    Side Note:
    Part of me feels kind of dumb by the fact that I've done work with games before, though more so for things like the Nintendo DS. Considering newer systems are generally supposed to be more complicated to work with compared to older systems, you'd think stuff like this would be easier to understand (though these are two different systems, I guess I looked at it too blindly to really look at it correctly). Not to say what's here is complicated, I guess it's just more so because I wasn't expecting this level of detail, especially on a source code level, which isn't really common for the newer systems by the way (at times I SOOOO wish we had source code for many of the games for systems like the Nintendo DS....ROM hacking would benefit greatly, as it's one crippled scene).
  2. Fred


    Formerly known as 'Neo' Oldbie
    Sonic 3 Unlocked

    My advice to you is not to be afraid of opening the ASM files and seeing what's inside. Your average sprite mappings file is composed of two things:
    1. An array of word offsets, containing one entry per mapping frame
    2. The actual sprite mapping definitions, which are addressed by the preceding offset array
    Code (ASM):
    1.                 dc.w word_1C394-Map_Explosion
    2.                 dc.w word_1C39C-Map_Explosion
    3.                 dc.w word_1C3A4-Map_Explosion
    4.                 dc.w word_1C3AC-Map_Explosion
    5.                 dc.w word_1C3B4-Map_Explosion
    6. word_1C394:     dc.w 1
    7.                 dc.b  $F8,   5,   0,   0, $FF, $F8
    8. word_1C39C:     dc.w 1
    9.                 dc.b  $F0,  $F, $20,   4, $FF, $F0
    10. word_1C3A4:     dc.w 1
    11.                 dc.b  $F0,  $F, $20, $14, $FF, $F0
    12. word_1C3AC:     dc.w 1
    13.                 dc.b  $F0,  $F, $20, $24, $FF, $F0
    14. word_1C3B4:     dc.w 1
    15.                 dc.b  $F0,  $F, $20, $34, $FF, $F0
    Now, if you open up the mappings file for Sonic, you should be able to figure out what's up: there are two offset arrays, one for Sonic and another for Super Sonic. The reason for this is that Super Sonic reuses most of regular Sonic's sprites, so a lot of the sprite definitions are shared between the two.

    Sonic is not the only object which does this, the same happens with springs for example:
    Code (ASM):
    1. Map_Spring_:    dc.w word_23788-Map_Spring_
    2.                 dc.w word_23796-Map_Spring_
    3.                 dc.w word_2379E-Map_Spring_
    4.                 dc.w word_237D0-Map_Spring_
    5.                 dc.w word_237DE-Map_Spring_
    6.                 dc.w word_237E6-Map_Spring_
    7.                 dc.w word_23818-Map_Spring_
    8.                 dc.w word_23834-Map_Spring_
    9.                 dc.w word_2384E-Map_Spring_
    10.                 dc.w word_23862-Map_Spring_
    11.                 dc.w word_23882-Map_Spring_
    12. Map_Spring2:
    13. Map_Spring2_:   dc.w word_237AC-Map_Spring2_
    14.                 dc.w word_237BA-Map_Spring2_
    15.                 dc.w word_237C2-Map_Spring2_
    16.                 dc.w word_237F4-Map_Spring2_
    17.                 dc.w word_23802-Map_Spring2_
    18.                 dc.w word_2380A-Map_Spring2_
    19.                 dc.w word_23826-Map_Spring2_
    20.                 dc.w word_2389C-Map_Spring2_
    21.                 dc.w word_238B6-Map_Spring2_
    22.                 dc.w word_238CA-Map_Spring2_
    23.                 dc.w word_238EA-Map_Spring2_
    24. word_23788:     dc.w 2
    25.                 dc.b  $F8,  $C,   0,   0, $FF, $F0
    26.                 dc.b    0,   4,   0,   8, $FF, $F8
    27. word_23796:     dc.w 1
    28.                 dc.b    0,  $C,   0,   0, $FF, $F0
    29. word_2379E:     dc.w 2
    30.                 dc.b  $E8,  $C,   0,   0, $FF, $F0
    31.                 dc.b  $F0,   6,   0,  $A, $FF, $F8
    32. word_237AC:     dc.w 2
    33.                 dc.b  $F8,  $C, $20,   4, $FF, $F0
    34.                 dc.b    0,   4,   0,   8, $FF, $F8
    35. word_237BA:     dc.w 1
    36.                 dc.b    0,  $C, $20,   4, $FF, $F0
    37. word_237C2:     dc.w 2
    38.                 dc.b  $E8,  $C, $20,   4, $FF, $F0
    39.                 dc.b  $F0,   6,   0,  $A, $FF, $F8
    40. word_237D0:     dc.w 2
    41.                 dc.b  $F0,   3,   0,   0,   0,   0
    42.                 dc.b  $F8,   1,   0,   8, $FF, $F8
    43. word_237DE:     dc.w 1
    44.                 dc.b  $F0,   3,   0,   0, $FF, $F8
    45. word_237E6:     dc.w 2
    46.                 dc.b  $F0,   3,   0,   0,   0, $10
    47.                 dc.b  $F8,   9,   0,  $A, $FF, $F8
    48. word_237F4:     dc.w 2
    49.                 dc.b  $F0,   3, $20,   4,   0,   0
    50.                 dc.b  $F8,   1,   0,   8, $FF, $F8
    51. word_23802:     dc.w 1
    52.                 dc.b  $F0,   3, $20,   4, $FF, $F8
    53. word_2380A:     dc.w 2
    54.                 dc.b  $F0,   3, $20,   4,   0, $10
    55.                 dc.b  $F8,   9,   0,  $A, $FF, $F8
    56. word_23818:     dc.w 2
    57.                 dc.b    0,  $C, $10,   0, $FF, $F0
    58.                 dc.b  $F8,   4, $10,   8, $FF, $F8
    59. word_23826:     dc.w 2
    60.                 dc.b    0,  $C, $30,   4, $FF, $F0
    61.                 dc.b  $F8,   4, $10,   8, $FF, $F8
    62. word_23834:     dc.w 4
    63.                 dc.b  $F1,   8,   0,   0, $FF, $EB
    64.                 dc.b  $F9,   8,   0,   3, $FF, $F3
    65.                 dc.b    1,   5,   0,   6, $FF, $FB
    66.                 dc.b  $FB,   5,   0, $14, $FF, $F1
    67. word_2384E:     dc.w 3
    68.                 dc.b  $F7,   8,   0,   0, $FF, $E6
    69.                 dc.b  $FF,   8,   0,   3, $FF, $EE
    70.                 dc.b    7,   5,   0,   6, $FF, $F6
    71. word_23862:     dc.w 5
    72.                 dc.b  $E6,   8,   0,   0, $FF, $F6
    73.                 dc.b  $EE,   8,   0,   3, $FF, $FE
    74.                 dc.b  $F6,   5,   0,   6,   0,   6
    75.                 dc.b  $F5,   4,   0, $18, $FF, $FA
    76.                 dc.b  $FD,   4,   0, $1A, $FF, $F2
    77. word_23882:     dc.w 4
    78.                 dc.b    7,   8, $10,   0, $FF, $EB
    79.                 dc.b  $FF,   8, $10,   3, $FF, $F3
    80.                 dc.b  $EF,   5, $10,   6, $FF, $FB
    81.                 dc.b  $F5,   5, $10, $14, $FF, $F1
    82. word_2389C:     dc.w 4
    83.                 dc.b  $F1,   8, $20,  $A, $FF, $EB
    84.                 dc.b  $F9,   8, $20,  $D, $FF, $F3
    85.                 dc.b    1,   5, $20, $10, $FF, $FB
    86.                 dc.b  $FB,   5,   0, $14, $FF, $F1
    87. word_238B6:     dc.w 3
    88.                 dc.b  $F7,   8, $20,  $A, $FF, $E6
    89.                 dc.b  $FF,   8, $20,  $D, $FF, $EE
    90.                 dc.b    7,   5, $20, $10, $FF, $F6
    91. word_238CA:     dc.w 5
    92.                 dc.b  $E6,   8, $20,  $A, $FF, $F6
    93.                 dc.b  $EE,   8, $20,  $D, $FF, $FE
    94.                 dc.b  $F6,   5, $20, $10,   0,   6
    95.                 dc.b  $F5,   4,   0, $18, $FF, $FA
    96.                 dc.b  $FD,   4,   0, $1A, $FF, $F2
    97. word_238EA:     dc.w 4
    98.                 dc.b    7,   8, $30,  $A, $FF, $EB
    99.                 dc.b  $FF,   8, $30,  $D, $FF, $F3
    100.                 dc.b  $EF,   5, $30, $10, $FF, $FB
    101.                 dc.b  $F5,   5, $10, $14, $FF, $F1

    Support for these mappings is pretty slim due to how non-standard they are, so you'll probably just have to make a copy of the file and remove the extraneous offset table before attempting to open it in an editor.

    You can then inject your changes to that specific sprite definition back into the original file by hand, or if you don't care about reusing regular Sonic's sprites, you can just keep two separate sets of mappings with a single offset array each, and then include both of them in the main disassembly.
  3. DeadSkullzJr


    Quite unexpected with a response from you lol. Do you have any suggestions on the tools to use specifically? Thanks for the information by the way, my idea is to try and maintain everything as is, just tweak the Super Sonic frame, so I'll likely have to do as you suggested and tweak by hand (which is fine). I'll have to really read into it again because I did look at the ASM before, I just wasn't sure how to really tweak it without messing anything up, hence why I went straight for an editor.

    My ASM knowledge I'll admit is a tad bit rough considering I've been learning off of ARM based systems that don't exactly have a lot of information to look at. Basically I had to throw myself blindly into it just to try and learn. So this is new but not new territory for me considering some of the aspects I understand, while others it's new to me entirely. Hopefully that makes sense, if not then I apologize.
  4. Wafer


    Find me on Twitter instead Member
    You've already got a mapping editor in Flex 2, so the only other "tool" you need is a text editor. Notepad++ will do the trick.

    It will probably also help you to understand the sprite map format for S3, which you'll find here.

    In terms of ASM knowledge needed to read the sprite maps, it may help you to know that dc.b is used for defining data in a byte-aligned fashion, so each comma separate value represents a single byte. Where you see dc.w (which defines word aligned data) followed by a number in the examples that Fred posted, it's telling you how many "pieces" (SonMapEd terminology, not sure what Flex 2 calls them) a sprite frame is made up of. Each piece is a rectangle of dimensions 1x1 to 4x4 tiles. Each line with a dc.b entry is defining one piece. It might help your understanding of how Flex 2 works to know that each sprite frame is made up of one or more of these rectangles.

    The tldr version is: if you want to split the sprite map file into the parts just used by Super Sonic:
    - Make a copy of the file
    - In that copy, delete the word array that's for regular Sonic (as in, not Super)
    - Open it in Flex, make the changes to fix the broken frame
    - Save the changes
    - Open up the original and the copy that you've made changes to, and reintegrate the changes into the original

    Beyond that, you'll also need to fix up the animation scripts and DPLC.
    Last edited: Apr 14, 2020
  5. Fred


    Formerly known as 'Neo' Oldbie
    Sonic 3 Unlocked
    Well I'm an old fogie so I'm still using SonMapEd, but people swear by Flex and I imagine it is at least as functional, so I'd keep using that. If you're afraid of messing around with mapping definitions in a text editor then rid yourself of your fears by reading the SCHG page on sprite mappings so you understand what you're doing.

    Though in this case, knowing the mappings format by heart (spoiler: I don't) is probably not even necessary, since you can just use the editor to fix up the one definition you're interested in, then slide it back in the original file in the right place. Just write down the sprite frame number, then go down the offset array until you get to the right entry (note that frame numbers start at 0 so you'll have to go down an extra line), then find the label that's referenced there and replace that definition with the one you changed in the editor.

    Reminder that the Sonic object uses DPLC, so you'll have to do the same process with the "pattern load cue" file in the same directory. Again, SCHG is your friend.