If you’re interested in hacking Sonic Adventure, you’ve probably seen 60 FPS and widescreen codes for the Dreamcast version floating around. The problem with 60 FPS codes for SA1 is that they make cutscenes run at double speed. Here’s my understanding of why it happens and a solution for version 1.005 (US, animated title screen).
The game uses two values to control framerate and speed: the frame increment (8C754EBC) and the multiplier (8C754EC4) used in physics and other things. The frame increment controls the actual framerate (1 for 60 FPS, 2 for 30 FPS), and the multiplier speeds up or slows down the physics to match it (1 is original speed). The Dreamcast version runs at 30 FPS everywhere except menus and Twinkle Circuit. In 30 FPS mode the frame increment is set to 2, and the multiplier is also set to 2 to speed up the physics to match the reduced framerate. In menus and Twinkle Circuit both values are set to 1, so the game runs at its original speed at full framerate.
This would be all fine, but the problem is the cutscenes. They are programmed in double speed, so the game sets the frame increment to 2 and leaves the multiplier at 1 to get them to work at half speed. This is also the real reason SADX cutscenes are still capped at 30 FPS – updating them would require fixing the timings in all functions used by cutscenes to work properly at 60 FPS, which is a lot more work than simply unlocking the 60 FPS mode in levels like the developers did.
The problem with existing codes is that they don’t account for the above and simply force both values to 1, which causes cutscenes to run at double speed. To fix this, instead of changing the values directly we can do the same thing SADX developers did, and change them depending on what happens in the game. Like in SADX, there is a function that is called to set the required frame increment and multiplier. All we have to do is patch the arguments that are passed for this function when the game loads levels, and leave cutscenes alone. Here are the addresses for version 1.005 (US, animated title screen). Just change the bytes at these addresses from 2 to 1, and the game will set framerate modes like SADX. If you use Demul with Cheat Engine, replace the starting 8C with 2C.
8C04956E 8C04E662 8C054736 8C082AAE 8C09A1D2
Here’s also a code that you can add as a custom cheat for redream. It’s a regular CodeBreaker code so you could use it on other emulators or on real hardware.
cheat=0204956E 420BE501 0204E662 4F22E501 02054736 430BE501 02082AAE 420BE501 0209A1D2 D252E501
There are still two problems remaining with the 60 FPS code:
- The hardware cannot handle the game at 60 FPS most of the time (sometimes it struggles even at 30 FPS), so you will get a slow motion effect like in older SA1 preview videos. Unfortunately this also affects emulators – for example, at the moment the game does not reach full framerate in redream. There was a similar problem with Sonic Colors, which the Wii can’t handle at 60 FPS, but that was resolved with Dolphin’s overclock feature. Maybe we’ll get that in Dreamcast emulators someday?
UPDATE: It seems to be perfect on flycast, no slowdown at all.
- There are glitches that happen when the game runs at 60 FPS. It’s possible that some things in the game were added after the decision to switch to 30 FPS was made, and perhaps they were only tested at 30 FPS. A lot of such glitches appear in SADX. For example, the Leon badnik almost never attacks the player and disappears too fast. There are visual glitches too, for example Tails’ tails are too fast, and the background in the tornado section in Windy Valley loses the multi-layered effect for one layer. A lot of these glitches are fixed in the Dreamcast Conversion mod for the PC version, and it’s also possible to fix them in the Dreamcast version if we really want it. Interestingly some issues that affected DX at 60 FPS don’t affect SA1 at 60 FPS – for example, the Egg Hornet engine sound glitch.
There’s another issue with SA1 on emulators related to not being able to run in a straight line with the keyboard and some controllers. You can fix this by disabling analog interpolation by writing 00 00 00 00 to 8C051278 and 8C051430. CodeBreaker code:
02051278 00000000 02051430 00000000
It’s not an ideal solution but that will do for now. A better fix may show up very soon.