Sonic 2 Hacking Guide
Machine Code - Tricks of the Trade

This page will provide you with tricks that you can do in the game using machine code.

 

Enabling water in other levels
This is a rather long method. However, it is very effective in the process. First, you need to go to the end of your Sonic 2 ROM and add the following lines of code:

1: 0C38 00[aa] FE10 66[bb]
2: 11FC 0001 F730
3: 31FC 0000 FFD8
4: 31FC [cccc] F648
5: 31FC [cccc] F64A
6: 4EF9 0001 3C48

In line 1, it compares the value at RAM address FE10 (Genecyst savestate equivallent - 012288) to value "aa". If the value at FE10 is not equal to "aa", it jumps "bb" bytes. Line 2 will write 01 to address F730, and line 3 will write 0000 to address FFD8. Lines 4 and 5 will tell the game the height of the water by writing the value to F648 and F64A respectively. Finally, line 6 will exit the code (I'll explain about this later).

Now, we want to substitute the values in brackets with our own values. This is what you need to fill in for each of the values:

aa - level you want to have water
bb - jump to 4EF9 (we'll deal with this later)
cccc - height of water from the top of the screen

Now, we need a way to activate the code. So, we'll use the pointer for object 34's code to activate it. So, go to address 0160D8. You'll see 00013C48 at that address (hey, we used that in our exit code!) Change that value to 00100000. That will tell the game to read the code we added to the end of the ROM, instead of the code it would normally read to start object 34 (object 34 is the level splash screen, or title card as many people call it).

We have the game reading our code now. When it gets to the end of the code, it will jump back to address 013C48 so it can begin processing the title card code. However, there's one problem. If the level condition for "aa" isn't true, it needs to jump to 4EF9. To figure out what value to put in place of "bb", you need to count how many bytes are between "bb" and 4EF9. However many you count, that's the value you need to give to "bb". That way, if the condition is false, it will ignore the code that will enable water, and simply jump back to the title card code.

If you run the ROM, you'll notice it works! However, there's another problem now. The palette used for the underwater area of the level is completely black! It's definately no fun playing the game on a screen that's completely black. So, we need to make our own palette. This is where it gets tricky.

The palette data in RAM for water is located at address F080. So, we need to begin writing our palette to that address. To do that, use this code:

31FC [0bgr] [dddd]

If you're not fermilliar with the format for palettes, it's basically shown in the code above. You put the value for blue where it has a "b". You put the value for green where it has a "g". I'm sure you can figure out where red goes. Also remember to only use even values for each color.

For "dddd", you need to start out by putting F080 there. This will tell the game to write the color at "bgr" to the RAM address at F080. Now, to write the second color, you can do the same, but put F082 in place of "dddd". Use this pattern until you've written all 64 colors to memory.

Be sure that all of this code is inserted somewhere between 4EF9 and "bb". Once you have written your palette, you then need to change "bb" since you added more bytes between "bb" and 4EF9. So, count them again and change the value. If you end up with a value larger than FF, you will need to change "bb" to 00, and then insert a place for "eeee" right after "bb". In "eeee", you will put the number of bytes between "eeee" and 4EF9. Being this number is larger than FF, you will end up with a 16-bit value. So, basically, instead of being 66[bb], it will be 6600 [eeee].

Once you have everything in, run the game and 'voila'! You've got water with a palette.