Yeah nothing much to say here, just got bored and left it sitting until now (lol commit #200). Enjoy!
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): $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. $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. :\)
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).
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
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
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:
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.
@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
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.
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.
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): $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. ;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. $FF55B3 - Message Animation Mode : $01 - Flashing, $02 - Palette Cycling, $03 - Static. Anything not $03 will cause the timer to count down $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. 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.
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.
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).
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.
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...