don't click here

ASM Spinball disassembly

Discussion in 'Engineering & Reverse Engineering' started by Andlabs, Oct 1, 2010.

  1. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    Yeah nothing much to say here, just got bored and left it sitting until now (lol commit #200). Enjoy!
     
  2. Ravenfreak

    Ravenfreak

    2 Edgy 4 U Tech Member
    3,077
    176
    43
    O'Fallon Mo
    Sonic 1 Game Gear Disassembly
    Even if it's small, I downloaded it since I've been wanting to hack Sonic Spinball, but all I could do was hack the ASCII letters used for the messages that scroll in the HUD using a Hex editor. :v: (That and I got bored looking at hex values for a long time and trying to figure out what did what, and even after switching a few bytes around I never noticed a difference. Well once I did edit Lava Powerhouse's music, but meh.) I jotted down a few notes in the past, this is what I found. (I dunno if this will help, but it may help someone. Not much is here btw.)
    Code (Text):
    1. $BE340-$BFCAF ACII Text- Unlike other Sonic games, messages on the HUD,credits, and options text are all in ASCII text and thus is easier to edit.
    2. $B7B2E-Lava Powerhouse (I'm not too sure on this one, I edited a bit and the music did change slightly. But it's been about a year since I tested it. :\)
     
  3. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    If you want to edit the music, this and this will help you (though in the disassembly I put up, the music locations are somewhat different... but they're close).
     
  4. GenesisFan64

    GenesisFan64

    The bright side of the dark side. Member
    108
    0
    16
    The sound data locations from this topic are actually wrong... (The Z80 driver is ok)

    it should be:
    Patch: $0AA0B0 - $0AB4AB
    Modulator: $0AB4AB - $0AB502
    Sequences: $0AB502 - $0B39DD
    Samples: $0B39DD - $0BDD2E

    Here's the correct data: (BIN and ASM files)
    Download
     
  5. evilhamwizard

    evilhamwizard

    Researcher
    1,392
    455
    63
    While we're on the topic of music (but not exactly related to the dissasembly of the game), just wanted to let you know that the port of the game to mobile phone seems to be using the original MIDI files for some the sound/music (OR NOT FFFFFFFFFFFFFFFFF). And since the game was ported from the original C source code, they left a lot of other files from the original game in here as well.

    Of course, you'll want to find the port for yourself, but it shouldn't be hard to find. :P
     
  6. Wafer

    Wafer

    Find me on Twitter instead Member
    255
    75
    28
    Apologies if this is necro-ing, but here's that disassembly again, only in .asm format and fixed up to build in asm68k. Thanks to Clownacy and Neo for pointing me in the right direction getting the PC-relative instructions working, and to Andlabs for providing the original .idb. I've sent a PR against the SR repo.

    Here's some more info from the readme:

     
  7. MEGAGEN

    MEGAGEN

    Level 3
    20
    0
    0
    England
    Optimizing Sonic Franchise
    Hello.

    Would be truly amazing to see Sonic Spinball running 60FPS instead of 30.

    That would be brilliant, maybe one day.

    Brilliant work on the disassembly.
     
  8. Scrambled Eggman

    Scrambled Eggman

    Worm Bagged Member
    6
    0
    1
    Picking at Sonic Spinball Disassembly
    @Wafer: I'm starting to have a poke around the disassembly and the game to begin documenting anything of interest that I can find. As there's no real home for Sonic Spinball hacking on this site yet (genuine shock).

    Are there any ground rules you have for making edits to the asm? i.e. comments/label changes. I'm branching for now locally for my own purposes, but stuff like naming conventions, comment styling etc. would be good to know... assuming you even feel you need to even take charge on that anyway. :P
     
  9. Wafer

    Wafer

    Find me on Twitter instead Member
    255
    75
    28
    I guess this thread IS the real home? :)
    The overwhelming majority of the disassembly work was by Andlabs, I just copy-pasted it out of IDA, included the align macro and a modified build script from Sonic 1, and fixed the addressing issues with some semi-automated Python brute-force. So for my sake, you should feel free to leave your mark in comments and labels. Clownacy literally commented his approval on my PR only hours before you posted, so you can hold off until a maintainer pulls it, or make PRs against me and I'll happily upstream them for you.

    The only insight I can really offer on the actual code is that ReadJoypads is only where the pads are read in the title screen. During actual gameplay the pads mainly get read in loc_D3D9E, maybe a few other places but I'm not sure what they're for.
     
  10. Scrambled Eggman

    Scrambled Eggman

    Worm Bagged Member
    6
    0
    1
    Picking at Sonic Spinball Disassembly
    Alright fair. I'll see about pushing to my own branch in your repo and we can go from there.

    I've found the player input mask gets dumped to $FF0005 at pretty much all times except for the main menu and intro cutscene. Curiously the attract mode in Toxic Caves continues to poll to this address however.

    So far I've determined where the cheat codes are stored, and where abouts in the code they are processed (labelled appropriately in the updated asm on the repo). Due to the nature of it being compiled C, for whatever reason the Level Select code uses a global location ($FF5750) for counting the number of successful entries into the cheat code, yet the credits cheat code seems to track the count via an address register (Which seems to always point to $FFEDD0 during the options menu). I should be able to follow this code backwards ultimately and learn how the options menu is managed, as well as the main menu as it should be polling input to determine which level to start when the level select byte is flagged as active.

    I'm currently in the process of dissecting the player class struct, which I have confirmed to be 76 bytes... based on that there is an array of 4 instances due to supporting 4 players (and just working out the spacing between 2 common attributes). Once I am able to determine the root offset of this array, it should be possible to track down any calling code that modifies or reads the player data which will be a useful step forward. Curiously it appears to not only keep player-specific data, but also data relevant to only the active player, such as coordinates, velocity etc... things that you would not expect to need to be instantiated.

    Anyway I will start pushing to the git from now and pop occasional digests here if I discover anything that needs shouting about. :)
     
  11. Scrambled Eggman

    Scrambled Eggman

    Worm Bagged Member
    6
    0
    1
    Picking at Sonic Spinball Disassembly
    Since I don't currently have permissions to submit to the git yet, I'll pop here what I have so far. I do have ASM notes regarding the level select, but that'll need to go into the git repo.

    EDIT: Corrected player array root address, should be 5758 not 7758.
    Player Data Struct

    I've been able to dissect a decent amount of the player struct so far. Not quite everything, that I have found, makes complete sense yet; but hopefully these initial findings might encourage some more investigation from others too.

    I've also found what appears to be a text data buffer for the HUD messages. Here's a some of the data I've poked out of it so far. It's worth noting that there seems to be multiple buffers that can be used (as you can see some of the other strings in the memory editor in the gif below). Only certain messages seem to make use of the additional buffers from what I can tell so far.

    Text Buffer #1 Attributes (tinkered with so far)
    Code (Text):
    1. $FF55AF - Message Colour : $00 - Invisible, $01 - Flat Green, $02 - Flat Red, $03 - Flat Cyan, $04 - Flat Yellow, $05 - Rainbow,  $06 - Red/Yellow Gradient, $07 - Green Yellow Gradient.
    2. ;Values above $07 tend to create weird and wonderful colour combinations, including black text and partially filled versions of these colours; and even colour combos not seen in game normally.
    3. $FF55B3 - Message Animation Mode : $01 - Flashing, $02 - Palette Cycling, $03 - Static. Anything not $03 will cause the timer to count down
    4. $FF55B8 - word - Countdown for hud text animations. Once it reaches 0, the text buffer always resets to colour setting $04 and plays a vertical "uncover" animation.  
    [​IMG]

    I specifically called this out as a buffer, as I'm pretty sure this is used temporarily to generate the text glyphs that are actually sent to the VDP. The proof of this is that this buffer is also used for the Options screen. Whenever you change an options, the last option that you change always appears in the buffer in the memory viewer. If you change the control config, it usually shows the bottom bit of text (as it will have been processed last). It appears that it uses all the same parameters too (Note that the colour below is $06 which is the gradient red/yellow) so theoretically you could change the colour styling of the options menu by tinkering with this buffer, and potentially animate things.

    This buffer seems to be polled in-game, but in the options menu it seems to be event-driven as to when it is read in and the glyphs rendered.

    [​IMG]
     
  12. Wafer

    Wafer

    Find me on Twitter instead Member
    255
    75
    28
    Nice find! By coincidence, I found myself building a very similar system only last week for my current project. With non-baked text that can move or animate, keeping it in a buffer and then changing the parameters as you play it back out to the VDP seems much faster than rendering it all again.

    If some hypothetical future hacker was going to try and optimize the engine, they'd probably go ahead and bake the strings into something closer to the VDP format at the build stage, IIRC Sonic Team did it this way for eg. zone title cards.
     
  13. Scrambled Eggman

    Scrambled Eggman

    Worm Bagged Member
    6
    0
    1
    Picking at Sonic Spinball Disassembly
    Yeah this seems quite plausible, although it depends on how the data is submitted. In-game the buffer polls the text for data such as the timer and animation mode; as well as updated text that comes in from events such as Bagged-Worms etc. One to follow up for sure.

    Also I can confirm my suspicions for the options menu text by messing around with patch codes in Gens. The interesting thing however is that the colour code affects ALL the text on screen even though the buffer seemingly appears to only deal with the modified text. This leads me to believe that all of the text rendered using this method either uses only a single shared memory location for text attributes, or all of the text gets refreshed with the buffer data (seems unlikely based on the text that is seen in the buffer).

    [​IMG]
     
  14. kazblox

    kazblox

    Member
    178
    27
    28
    Diassemblies and decompilations.
    Ghidra shows that this is a combination of assembly and C. The game was likely built with an early version of Sierra C; NOT the one on the Sega Channel disc from Hidden Palace, for sure.
     
  15. kazblox

    kazblox

    Member
    178
    27
    28
    Diassemblies and decompilations.
    I solved the memory/address/IO access problem. Sonic Spinball used structs for a variety of accesses, like every sane C program. However, the only known version of Sierra C that I have likes to optimally avoid clashing the first scratch register, d0, with the return register.... which is also d0.

    With my version of Sierra C, this decompilation of function $D6796 is exactly equivalent to the original, but the recompiled function d0 has strictly reserved for returns. Thus, scratch register use is strictly allocated to d1 and d2 and the recompiled function does not match. The original function allocates the return register to d0 while also allocating scratch register use to d0 and d1. Therefore, I still need an early version of Sierra C...
     
  16. CrazyTerabyte

    CrazyTerabyte

    Member
    9
    0
    1
    I just wanted to mention a little known fact… Sonic Spinball was ported to J2ME and was available to Java-capable phones. Thus, a decompilation of the J2ME Spinball game may help with the 16-bit disassembly. Or may help in producing an equivalent high-level code (e.g. in C) for the game logic.

    I couldn't find any mention of the J2ME version on the wiki, and there aren't many threads here for J2ME games (this one about Sonic 1 Java is relevant). Thus, I'm commenting here just to raise awareness, and as a hint to anyone who wants to decompile/disassemble Sonic Spinball any further.
     
    • Informative Informative x 1
    • List