Actions

SCHG

Difference between revisions of "Sonic the Hedgehog 2 (16-bit)"

From Sonic Retro

(I did a mistake here. Fixed now.)
m (Text replacement - "{|cellpadding="5"" to "{| class="prettytable" style="width:auto;"")
 
(39 intermediate revisions by 9 users not shown)
Line 1: Line 1:
This is the [[Sonic Community Hacking Guide]] for [[Sonic the Hedgehog 2]]. It's still mostly trying to copy and correct [[Nemesis]]'s guide, but it's still useful.
+
__NOTOC__
 +
{{SCHG S2}}
 +
This is the '''[[Sonic Community Hacking Guide]] for ''[[Sonic the Hedgehog 2]]'''''. Originally based on [[User:Nemesis|Nemesis]] and [[User:Saxman|saxman]]'s guides, this document has grown to outclass those two documents in most ways, and is now preferred over the original guides (which were written three or four years ago with limited knowledge of the game's code). This is due to the updating of those documents to give them a living, breathing nature.  
  
==ROM Hacking==
+
==Miscellaneous==
===Art Editing===
+
Pieces of the guide not big enough for their own page should be left here.
There are several different tools that can be used to edit art besides the hex editor. [[SonED]] is probably the best tool to use for editing level art, and can also be used on palettes. [[HivePal]] is also a great tool for editing palettes. [[Sonik Sprite]] is useful for editing uncompressed art; it gets its name from its ability to edit Sonic's sprites. [[LOst Library]] is most likely the best choice for editing compressed art in the [[Nemesis compression|Nemesis format]].
 
  
If, however, you still want to do it yourself, your best bet is to download the Sonic 2 Split disassembly [http://www.hacking-cult.org/download/s2split.rar here]. Decompress the archive into a new folder, and place your S2 ROM, ''in binary format and named "S2.bin"'', in that folder. Run the batch file "split.bat". This will split up all the art into its own binary files, which you can then decompress and edit. When you're done, run "combine.bat".
+
===Game Configuration===
  
====Uncompressed Art Locations====
+
{|class="prettytable" style="width:auto;"
Most of this information was taken from [[Sonic_Community_Hacking_Guide/Nem_s2|Nemesis's guide]]. Please excuse any mistakes or misunderstandings, as that guide wasn't exactly well-written. A description is written in parentheses after the original name if I deem it necessary; if I don't know what it is, "Unknown" appears in that place. Please correct this if you know. It doesn't list the number of blocks taken up, so if you know, put it in. Otherwise, I'll find out eventually.
+
!Offset||Description
 
 
{| border="1"
 
! Offset||Description||# of blocks
 
|-
 
! colspan="3" | Zone Independent
 
|-
 
| $50000
 
| Sonic
 
| ?
 
|-
 
| $64180
 
| Tails
 
| ?
 
|-
 
| $71FFC
 
| Splash
 
| ?
 
|-
 
| $7287C
 
| Spindash smoke
 
| ?
 
|-
 
| $7A1A0
 
| Signpost
 
| ?
 
|-
 
| $7AF82
 
| Drowning countdown
 
| ?
 
|-
 
| $7CD30
 
| Option and level select menu background
 
| ?
 
|-
 
! colspan="3" | Emerald Hill Zone
 
|-
 
| $49714
 
| Animated flowers
 
| ?
 
|-
 
| $49914
 
| Pulsing orb on walls
 
| ?
 
|-
 
! colspan="3" | Chemical Plant Zone
 
|-
 
| $4FAFE
 
| Part of background
 
| ?
 
|-
 
! colspan="3" | Aquatic Ruin Zone
 
|-
 
| $4FCFE
 
| Waterfall
 
| ?
 
|-
 
! colspan="3" | Casino Night Zone
 
|-
 
| $4D4FE
 
| Flipping square in foreground
 
| ?
 
|-
 
| $4EEFE
 
| Slot machine pictures
 
| ?
 
|-
 
! colspan="3" | Hill Top Zone
 
|-
 
| $49714
 
| Animated flowers
 
| ?
 
|-
 
| $4A33E
 
| Clouds from background
 
| ?
 
|-
 
| $4B73E
 
| Lava
 
| ?
 
|-
 
! colspan="3" | Mystic Cave Zone
 
 
|-
 
|-
| $894E4
+
|$3CD2
| Rocks that fall from ceiling during boss fight
+
|Enable level select
| ?
 
 
|-
 
|-
! colspan="3" | Oil Ocean Zone
+
|$3C79
 +
|Starting lives for player 1
 
|-
 
|-
| $49914
+
|$41CC
| Pulsing orb on walls
+
|How to determine how many rings to start with
| ?
 
 
|-
 
|-
| $4BF7E
+
|$41D0
| Pulsing ball
+
|How to determine how much time starts on the timer
| ?
 
 
|-
 
|-
| $4C0FE
+
|$142F8
| Square rotating around ball (Unknown)
+
|Order that the levels come in
| ?
 
 
|-
 
|-
| $4C4FE
+
|$1600C
| Oil
+
|Object code pointers
| ?
 
|-
 
! colspan="3" | Metropolis Zone
 
|-
 
| $4A73E
 
| Rotating net
 
| ?
 
|-
 
| $4B73E
 
| Lava
 
| ?
 
|-
 
| $4BD3E
 
| Parts of background
 
| ?
 
|-
 
! colspan="3" | Death Egg Zone
 
|-
 
| $4FAFE
 
| Part of background
 
| ?
 
 
|}
 
|}
  
====Compressed Art Locations - [[Nemesis compression|Nemesis format]]====
 
See [[SCHG:Sonic 2/Nemesis Compressed Art]].
 
  
====Compressed Art Locations - [[Kosinski compression|Kosinski format]]====
+
Each of the object code pointers are in 32-bits. They locate where the code for the object starts in the ROM. It starts with object 01 (Sonic) and goes in order from there. You will find a total of 220 pointers. These are useful if you want to create your own object code, or if you want to make one object into another. Check out the object list to see what each object is.
*'''$95C24''' - EHZ/HTZ main level patterns
 
*'''$9DB64''' - MTZ main level patterns
 
*'''$A4204''' - OOZ main level patterns
 
*'''$A9D74''' - MCZ main level patterns
 
*'''$B0894''' - CNZ main level patterns
 
*'''$B6174''' - CPZ/DEZ main level patterns
 
*'''$BCC24''' - ARZ main level patterns
 
*'''$C5004''' - SCZ/WFZ main level patterns
 
*'''$DCA38''' - Special stage floor patterns
 
  
====Palette Editing====
+
{|class="prettytable" style="width:auto;"
Usually, it's not really necessary to edit a palette in hex. Palette editors give you instant feedback for each RGB value, and the palette can be easily saved as a separate binary and reimported into the ROM. However, it is sometimes desireable or necessary to do it in hex, and it can't hurt to know how it's done.
+
!Offset||Description
 
 
These are the ROM offsets of the palettes in Sonic 2, as listed by [[HivePal]]:
 
{| border="1"
 
! Name||Offset
 
 
|-
 
|-
| Sega Sonic
+
|$16398
| $2902
+
|Amount of gravity player has (16-bit)
 
|-
 
|-
| Title Screen (Sonic)
+
|$19FA2
| $133EC
+
|Max speed (16-bit)
 
|-
 
|-
| Title Screen (Tails)
+
|$19FA8
| $2942
+
|Acceleration (16-bit)
 
|-
 
|-
| Title Screen (Main)
+
|$19FAE
| $1340C
+
|Slow down speed (16-bit)
 
|-
 
|-
| Title Screen Water
+
|$1A0E8
| $1E5A
+
|Invincibility time (16-bit)
 
|-
 
|-
| Sonic and Tails
+
|$1A122
| $29E2
+
|Max speed after super sneakers wear off (16-bit)
 
|-
 
|-
| Sonic to Super Sonic
+
|$1A122
| $2246
+
|Acceleration after super sneakers wear off (16-bit)
 
|-
 
|-
| Super Sonic
+
|$1A12E
| $2276
+
|Slow down speed after super sneakers wear off (16-bit)
 
|-
 
|-
| Title Cards
+
|$1A1B8
| $2A02
+
|Max speed under water (16-bit)
 
|-
 
|-
| Emerald Hill
+
|$1A1BE
| $2A22
+
|Acceleration under water (16-bit)
 
|-
 
|-
| Emerald Hill/Aquatic Ruin Rotating Water
+
|$1A1C4
| $1E7A
+
|Slow down speed under water (16-bit)
 
|-
 
|-
| Wood
+
|$1A5BD
| $2A82
+
|Use this animation when looking down
 
|-
 
|-
| Wood Conveyor Belts
+
|$1A5D5
| $1F1A
+
|How far to look down (player Y - input value) (16-bit)
 
|-
 
|-
| Metropolis
+
|$1AA5C
| $2AE2
+
|Jump height (16-bit)
 
|-
 
|-
| Metropolis Cycle #1
+
|$1AC47
| $1F2A
+
|Do Spin Dash if this frame is shown
 
|-
 
|-
| Metropolis Cycle #2
+
|$1B1BE
| $1F36
+
|Flash time after hit (16-bit)
 
|-
 
|-
| Metropolis Cycle #3
+
|$1B8A4
| $1F42
+
|Stop Tails from going to the left when end level sign is active (16-bit)
 
|-
 
|-
| Wing Fortress
+
|$1F1FC
| $2B42
+
|Rings needed for special stage (16-bit)
 
|-
 
|-
| Wing Fortress Fire Cycle
+
|$4082F
| $20A2
+
|Specify the minute that causes "TIME" to flash red
 
|-
 
|-
| Hill Top
+
|$40DED
| $2BA2
+
|Max minutes of timer
 
|-
 
|-
| Hill Top Lava
+
|$40DF9
| $1E9A
+
|Max middle seconds of timer
 
|-
 
|-
| Hidden Palace
+
|$42594
| $2C02
+
|Art/mapping pointers for levels
|-
 
| Hidden Palace (Sonic & Tails Under Water)
 
| $2C62
 
|-
 
| Hidden Palace Underwater Tiles Pallete
 
| $2C82
 
|-
 
| Hidden Palace Water Cycle
 
| $1F56
 
|-
 
| Hidden Palace Underwater Cycle
 
| $1F66
 
|-
 
| Oil Ocean (Do not edit or you'll get a huge mess unless you know how to fix it!)
 
| $2CE2
 
|-
 
| Oil Ocean Oil
 
| $1F76
 
|-
 
| Mystic Cave
 
| $2D42
 
|-
 
| Mystic Cave Lanterns
 
| $1F86
 
|-
 
| Casino Night
 
| $2DA2
 
|-
 
| Casino Night Cycle 1
 
| $1F8E
 
|-
 
| Casino Night Cycle 2
 
| $1FA0
 
|-
 
| Casino Night Cycle 3
 
| $1FB2
 
|-
 
| Casino Night Cycle 4
 
| $1FC4
 
|-
 
| Chemical Plant
 
| $2E02
 
|-
 
| Chemical Plant Sonic & Tails Underwater
 
| $2E62
 
|-
 
| Chemical Plant Underwater
 
| $2E82
 
|-
 
| Chemical Plant Underwater Sonic to Super Sonic
 
| $22C6
 
|-
 
| Chemical Plant Underwater Super Sonic
 
| $22F6
 
|-
 
| Chemical Plant Cycle 1
 
| $2022
 
|-
 
| Chemical Plant Cycle 2
 
| $2058
 
|-
 
| Chemical Plant Cycle 3
 
| $2082
 
|-
 
| Chemical Plant Cycle 4
 
| $20E2
 
|-
 
| Death Egg
 
| $2EE2
 
|-
 
| Aquatic Ruin
 
| $2F42
 
|-
 
| Sonic & Tails Underwater (Aquatic Ruin)
 
| $2FA2
 
|-
 
| Aquatic Ruin Underwater
 
| $2FC2
 
|-
 
| Sonic to Super Sonic Underwater (Aquatic Ruin)
 
| $2346
 
|-
 
| Aquatic Ruin Underwater Super Sonic
 
| $2376
 
|-
 
| Sky Chase
 
| $3022
 
|-
 
| Menus
 
| $30E2
 
|-
 
| Special Stage Main
 
| $3162
 
|-
 
| Special Stage Sonic
 
| $3182
 
|-
 
| Special Stage Tails
 
| $31A2
 
|-
 
| Special Stage 1
 
| $31C2
 
|-
 
| Special Stage 2
 
| $31E2
 
|-
 
| Special Stage 3
 
| $3202
 
|-
 
| Special Stage 4
 
| $3222
 
|-
 
| Special Stage 5
 
| $3242
 
|-
 
| Special Stage 6
 
| $3262
 
|-
 
| Special Stage 7
 
| $3282
 
|-
 
| Special Stag 1 2p
 
| $32A2
 
|-
 
| Special Stage 2 2p
 
| $32C2
 
|-
 
| Special Stage 3 2p
 
| $32E2
 
|-
 
| Special Stage Chaos Emerald
 
| $35F92
 
|-
 
| Special Stage Results Screen
 
| $3302
 
|-
 
| Emerald Hill Icon
 
| $9880
 
|-
 
| Metropolis Icon
 
| $98A0
 
|-
 
| Hill Top Icon
 
| $98C0
 
|-
 
| Hidden Palace Icon
 
| $98E0
 
|-
 
| Oil Ocean Icon
 
| $9900
 
|-
 
| Mystic Cave Icon
 
| $9920
 
|-
 
| Casino Night Icon
 
| $9940
 
|-
 
| Chemical Plant Icon
 
| $9960
 
|-
 
| Aquatic Ruin Icon
 
| $9980
 
|-
 
| Sky Chase Icon
 
| $99A0
 
|-
 
| Wing Fortress Icon
 
| $99C0
 
|-
 
| Death Egg Icon
 
| $99E0
 
|-
 
| Special Stage Icon
 
| $9A00
 
|-
 
| X 2 Player Versus Icon
 
| $9A20
 
|-
 
| Sound Test Icon
 
| $9A40
 
|-
 
| Ending Grey Cutscenes
 
| $AD1E
 
|-
 
| Ending Main
 
| $ACBE
 
|-
 
| Ending Sonic
 
| $AC7E
 
|-
 
| Ending Tails
 
| $AC9E
 
|-
 
| Ending Super Sonic
 
| $AD3E
 
|-
 
| Unknown 1
 
| $3082
 
|-
 
| Unknown 2
 
| $30A2
 
|-
 
| Oil Ocean Zone Boss (Pallete line 1)
 
| $30C2
 
 
|}
 
|}
  
For details of the palette data format, see [[Palette#Megadrive_Palette|Megadrive Palettes]].
 
  
====Pattern Load Requests====
+
Each full level has 3 pointers. However, the pointers are 24-bits in size. The extra 8-bits in each pointer has a unique function. These are known as 'flags'. The pointers will define mapping sets, as well as art for a specific level. In total, 12 bytes are used per level. Here is what each flag/pointer does.
Nemesis named this structure the "pattern load queue". However, this name tends to confuse the RAM structure (which is actually a queue) with the ROM structure (which is a set of data to be loaded into the queue).
 
  
PLRs tell the game engine where to get Nemesis-compressed art data and where to put it. The format is rather simple, and can be described with this pseudocode:
+
Flag 1 - Primary level PLC number<br/>
 +
Pointer 1 - Level 8x8 art<br/>
 +
Flag 2 - Secondary level PLC number<br/>
 +
Pointer 2 - 16x16 mappings<br/>
 +
Flag 3 - Palette number<br/>
 +
Pointer 3 - 128x128 mappings.<br/>
  
<pre>
+
===Cheats editing===
struct plr{
+
In this section, you can change any of the cheat codes to whatever you want them to be.
  long *compPattern;
 
  word vramStartLoc;
 
};
 
  
struct plrList03{
+
{|class="prettytable" style="width:auto;"
  const word plrCount == 3;
+
!Offset||Description
  plr plrArray[3]
 
} plr000;
 
</pre>
 
 
 
<tt>plrCount</tt> is the length of <tt>plrArray</tt>. <tt>compPattern</tt> is a pointer to Nemesis-compressed patterns, and <tt>vramStartLoc</tt> is the VRAM address where the patterns are to be decompressed to.
 
 
 
The RAM queue has space for 20 PLRs. Note that the routines that load PLRs into the queue do not do any bounds checking, and it is quite easy to create a buffer overrun condition. Further, both lists seem to be moved into the queue at the same time, so even if neither one is longer than 20 requests, they can still overrun the queue and destroy the variables that are stored just beyond it. ''''Make sure that the primary and secondary PLR lists are no more than 20 requests long.''''
 
 
 
===Object Editing===
 
====Sounds====
 
<!--Original submission by Weird Person-->
 
If you change the "ring" sound effect, ''all'' objects using that sound will have the new sound. This may not be desired, however - you may have only wanted the Super Ring powerup to play the new sound. With this list, you can edit the sound effect that an object plays. If you change the sound for the Super Ring power-up, '''only''' the Super Ring will have the new sound. Note that you are not changing any sound effects - you are only changing which effect will play.
 
 
 
These notes are for those who don't want see the programming stuff of the objects to change its sounds.
 
 
 
To change the sound, first, take a value from the sound test (Ex: 1-up sound is $18) , add $80 to it and you get $98. This is the way you have to replace sounds (take a value from sound test, add $80 to it, and after that, insert the byte in the offset where you wish change the sound.)
 
 
 
=====Offset List=====
 
The following list is the offset where you will place the new sound. I not will make a list with the values and its respective sounds. Use the trick (explained above) and Sound Test. Of course you can place the objects in any level you want (see Object Placement below), I'm just saying the level the object is used in for a better description.
 
 
 
{| border="1"
 
! Level||Description||Offset
 
|-
 
| ALL
 
| Invincibility power-up
 
| $12A81
 
|-
 
| ALL
 
| Shield power-up
 
| $12A37
 
|-
 
| ALL
 
| Super Ring
 
| $129CD
 
|-
 
| ALL
 
| Lamp Post:
 
| $1F191
 
|-
 
| Casino Night
 
| Bumper
 
| $1F7F5
 
|-
 
| ALL
 
| Red and Yellow Springs Facing Up
 
| $18A69
 
|-
 
| ALL
 
| Red and Yellow Springs Facing Right
 
| $18BBF
 
|-
 
| ALL
 
| Red Spring Facing Down
 
| $18D63
 
|-
 
| Chemical Plant
 
| Speed booster
 
| $223DB
 
 
|-
 
|-
| Chemical Plant
+
|$3DEE
| Blue worm (The sound is repeated 3 Times.)
+
|Tails / Miles switch
| $224EA
 
 
|-
 
|-
| Aquatic Ruin
+
|$97B2
| Arrow launcher
+
|Level select / slow motion (example)
| $257B7
 
 
|-
 
|-
| Casino Night
+
|$97B7
| Slot machine cage
+
|14 continues (example)
| $2BE1F
 
 
|-
 
|-
| Casino Night
+
|$97BC
| Point cage
+
|Debug mode (example)
| $2BE6B
 
 
|-
 
|-
| Hill Top
+
|$97C5
| Zip line
+
|Super Sonic (example)
| $21E75
 
|-
 
| Casino Night
 
| Blue Bumper
 
| $2C577
 
|-
 
| Casino Night
 
| Green flipper
 
| $2B30B
 
|-
 
| Casino Night
 
| Orange flipper
 
| $2B3BF
 
|-
 
| Casino Night
 
| Impulse spring facing up
 
| $2AE4F
 
|-
 
| Wing Fortress
 
| Propellor (repeat infinitely)
 
| $3B3A3
 
 
|}
 
|}
  
====Object Pointer List====
 
See [[SCHG:Sonic 2/Object Pointers]].
 
  
====Sprite table (aka mappings)====
+
These codes (except for the first one listed) use the regular sound 00-7F format, not the 80-FF format that the regular sound pointers use. Also, you can make these codes as long as you want. Simply use '00' to tell the game that the code ends there. If you make the very first sound to play in the code sequence a '00', it will then require you to play that sound along with the rest of the code.
[http://sonicology.fateback.com/hacks/mappings/sonic2_format.htm Reference]<br>
 
The sprite table data can be expressed with this pseudocode:
 
  
<pre>
+
The first code (Tails / Miles switch) is based on the output of Sega's standard 3-button controller input routine:
struct spriteTablePiece{
+
{| class="prettytable" style="width:auto;"
  byte yPosition;
 
  byte shape;
 
  byte attributes1P;
 
  byte artOffset1P;
 
  byte attributes2P;
 
  byte artOffset2P;
 
  word xPosition;
 
};
 
 
 
struct spriteTableLenghth03{
 
  const word length == 3;
 
  spriteTablePiece table[3];
 
} spriteTable01;
 
</pre>
 
 
 
* The value of <tt>shape</tt> can range from $00 (1x1) to $0F (4x4). $01 is a 1x2 sprite, $02 is a 1x3 sprite, $04 is a 2x1 sprite, and so on.
 
* <tt>attributes1P</tt> and <tt>attributes2P</tt> are bitfields that controls various sprite attributes:
 
:{|border="1"
 
!Bit||Attribute
 
 
|-
 
|-
| 3
+
|7||6||5||4||3||2||1||0||(this is a byte represented in bits)
| Flip sprite horizontally
 
 
|-
 
|-
| 4
+
|S||A||C||B||R||L||D||U||(these are the bits translated to show what each key is)
| Flip sprite vertically
 
|-
 
| 5
 
| Palette line +1
 
|-
 
| 6
 
| Palette line +2
 
|-
 
| 7
 
| Keep sprite in forground
 
 
|}
 
|}
* <tt>artOffset1P</tt> and <tt>artOffset2P</tt> control the offset from the object's base tile that the sprite should start reading from. For example, if the object's art started a tile $3F0, and <tt>artOffset1P</tt> was $06, then the sprite would start reading its art at $3F6.
 
  
<font color="red">Question: Are <tt>xPosition</tt> and <tt>yPosition</tt> offsets from the object's current position?</font>
+
If you want to relocate some of these cheat codes to another area of the ROM, just change these address pointers.
  
====Object Placement====
+
{|class="prettytable" style="width:auto;"
There are six bites in one object definition. The first two bytes are the X position of the object, and the next two bytes are the Y position. The 5th byte is the reference number on the object pointer list (see above), and the 6th byte is an optional declaration to use for defining that object's behavior and/or animation. This will depend on the object. See the [[Sonic Community Hacking Guide/Sonic 2/Level Specific|level specific hacking info]] for the locations of the object lists.
+
!Offset||Description
 
 
The 6th byte, the object subtype, is loaded in the 28th byte of the SST of that object (see below).
 
 
 
===Ring Placement===
 
There are four bytes for every ring object. The first 2 bytes are X coordinates, after that there is one nibble to determine how many rings, then three nibbles (or one nibble and one byte) for the Y coordinates. After you are done adding all your rings for the level, "FF FF" will end the ring data. A format would look like this:
 
XX XX TY YY
 
Where X represents X position, Y represents Y position, and T represents type, as per the table below.
 
 
 
'''Example:'''
 
03 46 10 2B
 
 
 
If you see this, then you will get two horizontal rings at X = 0346 Y = 02B. The "1" determines how many rings there are, and what direction they go. (horizontal or vertical) Here is what you get for each value:
 
 
 
{| border="1"
 
!Value||Rings
 
|-
 
|0
 
|1 Horizontal
 
|-
 
|1
 
|2 Horizontal
 
|-
 
|2
 
|3 Horizontal
 
|-
 
|3
 
|4 Horizontal
 
|-
 
|4
 
|5 Horizontal
 
|-
 
|5
 
|6 Horizontal
 
|-
 
|6
 
|7 Horizontal
 
 
|-
 
|-
|7
+
|$3DB6
|8 Horizontal
+
|Tails / Miles switch cheat pointer
 
|-
 
|-
|8
+
|$9164
|1 Vertical
+
|Level select / slow motion cheat pointer
 
|-
 
|-
|9
+
|$916A
|2 Vertical
+
|14 continues cheat pointer
 
|-
 
|-
|A
+
|$9574
|3 Vertical
+
|Debug mode cheat pointer
|-
 
|B
 
|4 Vertical
 
|-
 
|C
 
|5 Vertical
 
|-
 
|D
 
|6 Vertical
 
|-
 
|E
 
|7 Vertical
 
|-
 
|F
 
|8 Vertical
 
 
|-
 
|-
 +
|$957A
 +
|Super Sonic cheat pointer
 
|}
 
|}
  
See the [[Sonic Community Hacking Guide/Sonic 2/Level Specific|level specific hacking info]] for the locations of the ring data.
+
===Debug Mode===
 +
This will allow you to change the objects available in each of level when using debug mode. Each object uses 8 bytes to reference it in debug mode. Here are the notes you need to modify these references.
  
===Level Layout===
+
FORMAT:<br/>
Level layouts are compressed in [[Kosinski compression|Kosinski format]], so to edit them you will need to decompress them first. (I recommend using TSDC for this)
+
<nowiki>#1 #2 #3 #4 #5 #6 #7 #8</nowiki><br/>
 +
<br/>
 +
1 - Object value<br/>
 +
2 - ??? (usually 01)<br/>
 +
3 + 4 - Size of selection<br/>
 +
5 - Object type<br/>
 +
7 +8 - Sprites for selection<br/>
  
Level layouts are pretty simple. There is one byte per 128x128 tile to place on the map. The blocks are put together from left to right, top to bottom. Each horizontal row is 60 bytes long. The rows are interlaced between the foreground and the background, so that there are 60 bytes for the first row of the foreground, then 60 bytes for the first row of the background, then 60 bytes for the second row of the foreground, etc.
+
You can use #3, #4, #7, and #8 for porting a selection sprite. Now, you need to know how the game understands how many sprites to read for a level. Each set of objects has a 2 byte header. Together, both bytes define how many objects should be available in debug mode. The first byte should probably stay 00 unless you want more than 255 objects! Now, you just need to know where the section is that tells what sprite set is used for what level.
  
See the [[Sonic Community Hacking Guide/Sonic 2/Level Specific|level specific hacking info]] for the locations of level layout data.
+
041D0C - 16-bit address pointers for each level
  
===Block mappings===
+
Here are some of the objects that are listed and their locations
These are compressed in [[Kosinski compression|Kosinski format]], so to edit them you will need to decompress them first.
 
  
<pre>
+
Default<br/>
struct blockElement {
+
041D30 - Ring<br/>
    int cellProperties : 5;        // c
+
041D38 - Warp Monitor<br/>
    int vramCellIndex  : 11; };    // i
+
<br/>
// cccc ciii iiii iiii
+
Emerald Hill<br/>
 +
041D42 - Ring<br/>
 +
041D4A - Warp Monitor<br/>
 +
041D52 - Starpost<br/>
  
blockElement (*blockMap)[0x100][4] = 0xFFFF0000;
+
===Demo Recording===
 +
To show off a game, developers record demos. Many other people like to record their own demos too when it's possible. This is one of the fun things you can do in the Sonic 2 ROM.
  
struct metaBlockElement {
+
{|class="prettytable" style="width:auto;"
    int : 4;                      // x
+
!Offset||Description
    int blockIndex : 12; };        // I
 
// xxxx IIII IIII IIII
 
 
 
metaBlockElement (*metaBlockMap)[0x300][8] = 0xFFFF9000;
 
</pre>
 
 
 
A block is an array of four <tt>blockElement</tt>s. <tt>blockElement->cellProperties</tt> describes the palette line and orientation of the cell. The actual mapping of block elements is like this:
 
<pre>
 
0 1
 
2 3
 
</pre>
 
 
 
Metablocks are basically arrays of indeces into <tt>blockMap</tt>. <tt>metaBlockElement->blockIndex</tt> provides the first index into <tt>blockMap</tt>; the upper four bits of the element appear to be unused.
 
 
 
[[Nemesis]] provides this chart of values for the upper four bits of <tt>cellProperties</tt>. The LSB mirrors the cell.
 
 
 
{| border="1"
 
!Value||Pallet Line||Flipped<br>Horizntally|||Flipped<br>Vertically
 
|-
 
|0
 
|1
 
|n
 
|n
 
|-
 
|1
 
|1
 
|n
 
|y
 
|-
 
|2
 
|2
 
|n
 
|n
 
 
|-
 
|-
|3
+
|$3D4E
|2
+
|Number of demos to play
|n
 
|y
 
 
|-
 
|-
|4
+
|$3DAC
|3
+
|Levels that are played during demo sequence
|n
 
|n
 
 
|-
 
|-
|5
+
|$42AA
|3
+
|Number of frames that a demo plays (16-bit)
|n
 
|y
 
 
|-
 
|-
|6
+
|$4948
|4
+
|32-bit address pointers for each level
|n
 
|n
 
 
|-
 
|-
|7
+
|$4CA8
|4
+
|Demo for EHZ (Sonic)
|n
 
|y
 
 
|-
 
|-
|8
+
|$4D08
|1
+
|Demo for EHZ (Tails)
|n
 
|n
 
 
|-
 
|-
|9
+
|$4D68
|1
+
|Demo for CNZ
|y
 
|n
 
 
|-
 
|-
|A
+
|$4DD8
|2
+
|Demo for CPZ
|n
 
|n
 
|-
 
|B
 
|2
 
|y
 
|n
 
|-
 
|C
 
|3
 
|n
 
|n
 
|-
 
|D
 
|3
 
|y
 
|n
 
|-
 
|E
 
|4
 
|n
 
|n
 
|-
 
|F
 
|4
 
|y
 
|n
 
 
|-
 
|-
 +
|$4E38
 +
|Demo for ARZ
 
|}
 
|}
  
See the [[Sonic Community Hacking Guide/Sonic 2/Level Specific|level specific hacking info]] for the locations of 16x16 data.
 
  
===Text Editing===
+
FORMAT:
[to be filled later]
+
<nowiki>#1 #2</nowiki><br/>
 +
<br/>
 +
1 - Keys pressed<br/>
 +
2 - Frame count<br/>
  
===Level event scripts===
+
For keys pressed, you simply need to know the Motorola key format:
Also known as "dynamic screen resizing" or "dynamic level events", this code is used to create effects unique to a certain Zone or Act. I have no further information to contribute on the subject, as I know absolutely nothing about it.
 
  
==RAM Hacking==
+
{| class="prettytable" style="width:auto;"
===Main System Memory Locations===
 
These are significant locations in the system memory. Note that any numbers entered (for example, score or number of rings) will have to be converted to hex before putting them in.
 
 
 
These are the offsets in RAM. To convert them to Genecyst savestate offsets, add $2478.
 
{| border="1"
 
!RAM offset||Description
 
|-
 
| width="100" | $EE00-$EE01
 
| Camera's X position, as measured from the top left corner of the Act.
 
|-
 
| $EE04-$EE05
 
| Camera's Y position from the same point.
 
|-
 
| $EE06-$EE0B
 
| <font color="red">Unknown</font>
 
|-
 
| $EE0C-$EE0D
 
| Variable used by the software scroll managers. Its exact purpose is not known.
 
|-
 
| $EE0E-$EEC5
 
| <font color="red">Unknown</font>
 
|-
 
| $EEC6-$EEC7
 
| Screen Y end location; the maximum value for camera Y position.
 
|-
 
| $EEC8-$EEC9
 
| Screen X start location; minimum value for camera X position. Should be 0.
 
|-
 
| $EECA-$EECB
 
| Screen X end location; should be at least $30 less than the end of the level, otherwise, Sonic will fall off the screen.
 
|-
 
| $EECC-$EECD
 
| Screen Y start location. Note that if $FF00 is placed in both the start and the end, the screen will be Y wrapped. Y wrapping should not be used on levels with water - note what happened in the beta's Hidden Palace Zone.
 
|-
 
| $EECE-$EECF
 
| Maximum camera scroll speed
 
|-
 
| $F600
 
| Master level trigger. Tells the game what it should be doing. Values:
 
*$00 - Sega logo
 
*$04 - Title screen
 
*$08 - Demo (return to title screen at 27 seconds)
 
*$0C - Normal level (Level loop, when it has been loaded)
 
*$10 - Special stage
 
*$14 - Continue screen
 
*$18 - 2P vs. result
 
*$1C - 2P vs. level select
 
*$20 - Game end sequence
 
*$24 - Options menu
 
*$28 - Level select
 
The MSB is a loading routine flag. It only matters for some game modes. It won't have any effect when changing modes because it's filtered out, but the corresponding routine does pay attention to it...
 
|-
 
| $F604
 
| This bitfield tells which button(s) on Controller 1, if any, are being pressed. Format is:
 
*Bit 0 - Up
 
*Bit 1 - Down
 
*Bit 2 - Left
 
*Bit 3 - Right
 
*Bit 4 - B
 
*Bit 5 - C
 
*Bit 6 - A
 
*Bit 7 - Start
 
This is updated every frame.
 
|-
 
| $F605
 
| Same as $F604, but tells which buttons are being held down.
 
 
|-
 
|-
| $F606
+
|7||6||5||4||3||2||1||0||(this is a byte represented in bits)
| Same as $F604, but for Controller 2.
 
 
|-
 
|-
| $F607
+
|S||A||C||B||R||L||D||U||(these are the bits translated to show what each key is)
| Same as $F606, but tells which buttons are being held down.
 
|-
 
| $F648-$F649
 
| Current water level. Should be a valid Y-axis value. Remember, the top of the level is $0000.
 
|-
 
| $F650-$F651
 
| The level that the water should be at. If this is different than the value above, the water will move until they are the same.
 
|-
 
| $F652
 
| Water level change speed. If set to $00, the water level won't change.
 
|-
 
| $F65E
 
| Super Sonic palette counter. Decremented with every frame. How it works, exactly, is not known.
 
|-
 
| $F65F
 
| Sets the rotating palette for Super Sonic.
 
|-
 
| $F670
 
| Super Sonic ring drain counter. This is updated each frame, so the counter is set to 60 ($3C) on consoles operating in 60Hz mode, or 50 ($32) in consoles operating in 50Hz mode. After each frame, the code subtracts 1. One ring is removed when this counter reaches zero; in other words, each second.
 
|-
 
| $F730
 
| Water flag. Must be set for any of the other water variables to have any effect. Note that levels without water don't have an underwater palette; you must set one or everything below the water level will be black.
 
|-
 
| $F760-$F761
 
| Sonic's top speed
 
|-
 
| $F762-$F763
 
| Sonic's acceleration
 
|-
 
| $F764-$F765
 
| Sonic's deceleration
 
|-
 
| $F76C
 
| Routine counter for the object placement engine?
 
|-
 
| $F76E-$F76F
 
| <font color="red">Unknown</font>
 
|-
 
| $F770-$F773<br>$F774-$F777<br>$F778-$F77B<br>$F77C-$F77F
 
| Sprite loading addresses. Tells the game where in the ROM to get sprite info.
 
|-
 
| $F78C-$F78D
 
| <font color="red">Unknown</font>
 
|-
 
| $F7AA
 
| Seems to be clear during normal play, but set to some value during a boss fight. That value may be the current Zone number.
 
|-
 
| $F7DA
 
| Seems to be a count of the number of screens since the start point (which is set at FF = 0) <font color="red">What? Explain please.</font>
 
|-
 
| $F7DB
 
| <font color="red">Unknown (may be unused)</font>
 
|-
 
| $FE00
 
| Start of the system stack. Note that the stack grows '''up''' rather than '''down'''. This means that when something is pushed onto the stack, the SP is decremented, and when something is popped from it, the SP is incermented.
 
|-
 
| $FE06
 
| Object currently selected in debug mode.
 
|-
 
| $FE09
 
| Object placement mode flag.
 
|-
 
| $FE10
 
| The current Zone. This is the value assigned to the Zone, not its position in the level list.
 
|-
 
| $FE11
 
| Act number
 
|-
 
| $FE12
 
| Number of lives.
 
|-
 
| $FE16
 
| Current special stage.
 
|-
 
| $FE18
 
| Number of continues.
 
|-
 
| $FE19
 
| Super Sonic flag. Setting this will load the Super Sonic tiles, adjust Sonic's jump height, and start draining rings, but it will not load the rotating palette, change acceleration, max speed, or deceleration, or make him invincible.
 
|-
 
| $FE1D
 
| Flag determines if the rings counter needs to be updated
 
|-
 
| $FE1E
 
| Flag determines if the timer needs to be updated
 
|-
 
| $FE1F
 
| Flag determines if the score counter needs to be updated
 
|-
 
| $FE20-$FE21
 
| Ring count
 
|-
 
| $FE23
 
| Minutes on clock. Should not go above $09, or the clock will look like shit.
 
|-
 
| $FE24
 
| Seconds. This one shouldn't go above $3B, for the same reason.
 
|-
 
| $FE25
 
| Milliseconds. I don't know what'll happen if this goes out of range, but it's probably not good.
 
|-
 
| $FE26-$FE29
 
| Score
 
|-
 
| $FE30
 
| Greatest reference number of passed star poles
 
|-
 
| $FEC0-$FEC1
 
| Tails's max speed
 
|-
 
| $FEC2-$FEC3
 
| Tails's acceleration
 
|-
 
| $FEC4-$FEC5
 
| Tails's deceleration
 
|-
 
| $FEC6
 
| Tails's lives
 
|-
 
| $FF40-$FF41
 
| Number of rings to collect before a perfect is scored
 
|-
 
| $FF70-$FF71
 
| "Player in special stage"; variable tested by a lot of other routines, so it may have other meanings
 
|-
 
| $FF72-$FF73
 
| Player option (Sonic and Tails - 0, Sonic alone - 1, Tails alone - 2)
 
|-
 
| $FF74-$FF75
 
| 2P mode items (teleport only, all kinds items - which is which?)
 
|-
 
| $FF82-$FF83
 
| Item in level select menu that's selected (set to 16 to see the HPZ picture)
 
|-
 
| $FF85
 
| Sound currently selected in sound test; value retained when options menu is exited
 
|-
 
| $FF86
 
| Selection on Title Screen
 
|-
 
| $FF88
 
| Selection on 2 Player Level Select Menu
 
|-
 
| $FF90-$FF91
 
| Zone music currently playing. Used for quick access when switching music.
 
|-
 
| $FF8C
 
| Box slected in options menu
 
|-
 
| $FFB0
 
| Special stage completed flag
 
|-
 
| $FFB1
 
| Number of emeralds collected so far
 
|-
 
| $FFB2-$FFB8
 
| Array of finished special stages. Each byte represents one stage.
 
|-
 
| $FFD0
 
| Level select flag
 
|-
 
| $FFD1
 
| Slow motion flag
 
|-
 
| $FFD8-$FFD9
 
| 2P mode flag
 
|-
 
| $FFE1
 
| Play specified sound effect. Not sure how it works.
 
|-
 
| $FFE4
 
| Play specified music. These are the actual playlist values, NOT the sound test values. To convert from sound test to playlist, add $80 to the sound test value. For example, putting in $96 here will play the Super Sonic music; putting in $97 will play the invincibility music.
 
|-
 
| $FFF0-$FFF1
 
| Demo mode flag
 
|-
 
| $FFD4
 
| Unknown cheat value
 
|-
 
| $FFFA
 
| Debug mode flag
 
 
|}
 
|}
  
===Object Status Table Format===
+
With a 1, that means the button is being used (on) and with a 0, the button isn't being used.
The starting offset in RAM for this list is $B000. The first object is always Sonic; the second is always Tails. After this, there is a gap, and the list picks up again at $B400. Each object is alloted a block of $40 bytes. I will use the beginning of a block as a reference point. Note that many of these variables are object-specific - for example, some of them only make sense for Sonic, and some only work on badniks.
+
 
 +
 
 +
==References==
 +
<references />
  
{|border="1"
 
!Offset||Description
 
|-
 
|width="60"|$00||Object number. See object list above.
 
|-
 
|$01||Action flags. The bitfield looks like this:
 
*Bit 0 is the horizontal mirror flag. If set, the object will be flipped on its horizontal axis.
 
*Bit 1 is the vertical mirror flag.
 
*Bit 2 is the coordinate system flag. If clear, the object will be positioned by absolute screen coordinates. This is used for things like the HUD and menu options. If set, the object will be positioned by the playfield coordinates, i.e. where it is in a level. Sonic and Tails use both positioning systems (though I don't know how Tails uses it in a Sonic and Tails game).
 
*Bits 3, 4, and 5 are either unused, or their purpose is unknown.
 
*Bit 6 is not used in this game.
 
*Bit 7 is the draw object flag. It will be set if the object was onscreen when it came time to draw things. Otherwise, it is clear. There should be no reason to edit this flag, but it's good to know what it does.
 
|-
 
|$02-$03||Starting art block. This is an index into an array of cells; to get the actual address, multiply by $20.
 
|-
 
|$04-$07||Object's mappings offset
 
|-
 
|$08-$09
 
|If the object is Sonic or Tails, this is the X playfield coordinate. Otherwise:
 
*If in playfield positioning mode, it is the X playfield coordinate.
 
*If in screen postioning mode, it is the screen coordinate.
 
|-
 
|$0A-$0B
 
|If the object is Sonic or Tails, this is the X screen coordinate. Otherwise:
 
*If in playfield positioning mode, it is unused.
 
*If in screen positioning mode, it's the Y screen coordinate.
 
|-
 
|$0C-$0D
 
|If the object is Sonic or Tails, this is the Y playfield coordinate. Otherwise:
 
*If in playfield positioning mode, it is the Y playfield coordinate.
 
*If in screen positioning mode, it is unused.
 
|-
 
|$0E-$0F
 
|If the object is Sonic or Tails, this is the Y screen coordinate. Otherwise:
 
*It's unused.
 
|-
 
|$10-$11||X speed
 
|-
 
|$12-$13||Y speed
 
|-
 
|$14-$15||Potential speed (inertia).
 
|-
 
|$16||Height/2
 
|-
 
|$17||Width/2
 
|-
 
|$18||Sprite priority (00 = front).
 
|-
 
|$19||Width of the object, in pixels
 
|-
 
|$1A||Current animation frame to display.
 
|-
 
|$1B||Current frame in animation script.
 
|-
 
|$1C||Animation number.
 
|-
 
|$1D||Restart animation flag (when $1D is not equal to $1C, animation restarts)
 
|-
 
|$1E||Animation frame duration (time until next frame).
 
|-
 
|$20||Collision response bitfield. Tells what the object will do if hit by the character. The bitfield is in the format TTSS SSSS. TT is the type of collision - 00 is enemy, 01 is some event, 10 is harm, and 11 seems to be a special thing for the starpole. SS SSSS is the size, but the format is unknown.
 
|-
 
|$21||Custom collision property, for special interaction with Sonic. This is used by bosses, badniks, bumpers and other objects. The way in which this byte is used is different for each object. Bosses use this byte as a hit counter.
 
|-
 
|$22
 
|Object's orientation. $00 is normal, $01 is X flipped, $02 is Y flipped, and $03 is X-Y flipped. These values repeat until $FF. Note that this byte has a different meaning for Sonic and Tails (see below).
 
|-
 
|$23||Respawn index reference number, used by badniks, rings and monitors. Each destroyable object is assigned an index number (01, 02, 03 etc.) which refers to a list at $FC00 in the RAM.
 
|-
 
|$24||Routine counter.
 
|-
 
|$25||Second routine counter. This is used for some of the more complicated objects.
 
|-
 
|$26-$27||Angle.
 
|-
 
|$28||Object subtype. For example, the current monitor selected. See the Object List above for values. Has a different meaning for Sonic and Tails.
 
|-
 
!colspan="2" | Object-specific variables
 
|-
 
!Offset||Description
 
|-
 
|$22||'''Sonic and Tails''': Special bitfield. Counting from the least significant bit:
 
{|border='1'
 
!Bit||Hex||Description
 
|-
 
|0||$01||Orientation. Clear is left and set is right.
 
|-
 
|1||$02||Set if Sonic/Tails is in the air (jump counts).
 
|-
 
|2||$04||Set if jumping or rolling.
 
|-
 
|3||$08||Set if Sonic/Tails isn't on the ground but shouldn't fall. (Usually when he is on a object that should stop him falling, like a platform or a bridge.)
 
|-
 
|4||$10||Set if jumping after rolling.
 
|-
 
|5||$20||Set if pushing something.
 
|-
 
|6||$40||Set if underwater.
 
|-
 
|7||$80||Unused.
 
|}
 
You can add the hex values together to use multiple settings at once. Also notice that the first 3 bits (0-2) are used in the character object as a second routine counter.
 
|-
 
| $28
 
| '''Sonic and Tails''': Seconds of air left. Usually $1E; it decrements every second while the player is underwater. Beeps on $18, $13, and $0E. Countdown starts on $0B.
 
|-
 
|$2B
 
|'''Sonic and Tails''': Another bitfield.
 
{|border='1'
 
!Bit||Hex||Description
 
|-
 
|0||$01||Shield flag. Can be set to create the effect of having a shield, though the graphics will not be loaded.
 
|-
 
|1||$02||Sets invincibility. Behaves like you would expect. No graphics are loaded when set manually.
 
|-
 
|2||$04||Speed Shoes flag. (Doesn't have visible effect in game)
 
|-
 
|3||$08||Unused
 
|-
 
|4||$10||Unused
 
|-
 
|5||$20||Unused
 
|-
 
|6||$40||Unused
 
|-
 
|7||$80||Sets infinite inertia. While Sonic is in collision with the ground, he will continue moving in the same direction and at the same speed that he was moving before (even if that speed was zero). You can still jump and control him in midair. (A few movement routines are skipped if it's set, which produces this effect.)
 
|}
 
|-
 
| $30-$31
 
| '''Sonic and Tails''': Remaining invunerability time. Starts at $0078 after Sonic is hit, and seems to decrement every frame until it reaches $0000.
 
|-
 
|$32-$33||'''Sonic and Tails''': Remaining time of invincibility.
 
|-
 
|$34-$35||'''Sonic and Tails''': Remaining time of Speed Shoes.
 
|-
 
|$36||'''Sonic and Tails''': Seems to be related with the collision block boundaries (this isn't a flag)
 
|-
 
|$37||'''Sonic and Tails''': Seems to be related with the collision block boundaries (the opposite side of $36) (this isn't a flag)
 
|-
 
|$39||'''Sonic and Tails''': Set if charging a spindash.
 
|-
 
|$3A-$3B
 
|'''Sonic and Tails''': Spindash counter. Cleared when the spindash is started. After each subsequent "rev", $200 is added to the counter, which then rapidly decreases (the algorithm is to logically shift the value right by five bits and subtract the results from the original). It maxes out at $800. The game looks at the high-order byte to determine how fast the character should move after the dash is released.
 
|-
 
|$3C||'''Sonic and Tails''': Set if jumping.
 
|}
 
 
{{SCHGuides}}
 
{{SCHGuides}}
 +
[[Category:Sonic Community Hacking Guide]]

Latest revision as of 12:51, 25 March 2020


Sonic Community Hacking Guide
Sonic the Hedgehog 2 (16-bit)
Art
Objects
Levels
Text
Music
RAM
Miscellaneous

This is the Sonic Community Hacking Guide for Sonic the Hedgehog 2. Originally based on Nemesis and saxman's guides, this document has grown to outclass those two documents in most ways, and is now preferred over the original guides (which were written three or four years ago with limited knowledge of the game's code). This is due to the updating of those documents to give them a living, breathing nature.

Miscellaneous

Pieces of the guide not big enough for their own page should be left here.

Game Configuration

Offset Description
$3CD2 Enable level select
$3C79 Starting lives for player 1
$41CC How to determine how many rings to start with
$41D0 How to determine how much time starts on the timer
$142F8 Order that the levels come in
$1600C Object code pointers


Each of the object code pointers are in 32-bits. They locate where the code for the object starts in the ROM. It starts with object 01 (Sonic) and goes in order from there. You will find a total of 220 pointers. These are useful if you want to create your own object code, or if you want to make one object into another. Check out the object list to see what each object is.

Offset Description
$16398 Amount of gravity player has (16-bit)
$19FA2 Max speed (16-bit)
$19FA8 Acceleration (16-bit)
$19FAE Slow down speed (16-bit)
$1A0E8 Invincibility time (16-bit)
$1A122 Max speed after super sneakers wear off (16-bit)
$1A122 Acceleration after super sneakers wear off (16-bit)
$1A12E Slow down speed after super sneakers wear off (16-bit)
$1A1B8 Max speed under water (16-bit)
$1A1BE Acceleration under water (16-bit)
$1A1C4 Slow down speed under water (16-bit)
$1A5BD Use this animation when looking down
$1A5D5 How far to look down (player Y - input value) (16-bit)
$1AA5C Jump height (16-bit)
$1AC47 Do Spin Dash if this frame is shown
$1B1BE Flash time after hit (16-bit)
$1B8A4 Stop Tails from going to the left when end level sign is active (16-bit)
$1F1FC Rings needed for special stage (16-bit)
$4082F Specify the minute that causes "TIME" to flash red
$40DED Max minutes of timer
$40DF9 Max middle seconds of timer
$42594 Art/mapping pointers for levels


Each full level has 3 pointers. However, the pointers are 24-bits in size. The extra 8-bits in each pointer has a unique function. These are known as 'flags'. The pointers will define mapping sets, as well as art for a specific level. In total, 12 bytes are used per level. Here is what each flag/pointer does.

Flag 1 - Primary level PLC number
Pointer 1 - Level 8x8 art
Flag 2 - Secondary level PLC number
Pointer 2 - 16x16 mappings
Flag 3 - Palette number
Pointer 3 - 128x128 mappings.

Cheats editing

In this section, you can change any of the cheat codes to whatever you want them to be.

Offset Description
$3DEE Tails / Miles switch
$97B2 Level select / slow motion (example)
$97B7 14 continues (example)
$97BC Debug mode (example)
$97C5 Super Sonic (example)


These codes (except for the first one listed) use the regular sound 00-7F format, not the 80-FF format that the regular sound pointers use. Also, you can make these codes as long as you want. Simply use '00' to tell the game that the code ends there. If you make the very first sound to play in the code sequence a '00', it will then require you to play that sound along with the rest of the code.

The first code (Tails / Miles switch) is based on the output of Sega's standard 3-button controller input routine:

7 6 5 4 3 2 1 0 (this is a byte represented in bits)
S A C B R L D U (these are the bits translated to show what each key is)

If you want to relocate some of these cheat codes to another area of the ROM, just change these address pointers.

Offset Description
$3DB6 Tails / Miles switch cheat pointer
$9164 Level select / slow motion cheat pointer
$916A 14 continues cheat pointer
$9574 Debug mode cheat pointer
$957A Super Sonic cheat pointer

Debug Mode

This will allow you to change the objects available in each of level when using debug mode. Each object uses 8 bytes to reference it in debug mode. Here are the notes you need to modify these references.

FORMAT:
#1 #2 #3 #4 #5 #6 #7 #8

1 - Object value
2 - ??? (usually 01)
3 + 4 - Size of selection
5 - Object type
7 +8 - Sprites for selection

You can use #3, #4, #7, and #8 for porting a selection sprite. Now, you need to know how the game understands how many sprites to read for a level. Each set of objects has a 2 byte header. Together, both bytes define how many objects should be available in debug mode. The first byte should probably stay 00 unless you want more than 255 objects! Now, you just need to know where the section is that tells what sprite set is used for what level.

041D0C - 16-bit address pointers for each level

Here are some of the objects that are listed and their locations

Default
041D30 - Ring
041D38 - Warp Monitor

Emerald Hill
041D42 - Ring
041D4A - Warp Monitor
041D52 - Starpost

Demo Recording

To show off a game, developers record demos. Many other people like to record their own demos too when it's possible. This is one of the fun things you can do in the Sonic 2 ROM.

Offset Description
$3D4E Number of demos to play
$3DAC Levels that are played during demo sequence
$42AA Number of frames that a demo plays (16-bit)
$4948 32-bit address pointers for each level
$4CA8 Demo for EHZ (Sonic)
$4D08 Demo for EHZ (Tails)
$4D68 Demo for CNZ
$4DD8 Demo for CPZ
$4E38 Demo for ARZ


FORMAT: #1 #2

1 - Keys pressed
2 - Frame count

For keys pressed, you simply need to know the Motorola key format:

7 6 5 4 3 2 1 0 (this is a byte represented in bits)
S A C B R L D U (these are the bits translated to show what each key is)

With a 1, that means the button is being used (on) and with a 0, the button isn't being used.


References


Sonic Community Hacking Guide
General
SonED2 Manual | Subroutine Equivalency List
Game-Specific
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (Master System) | Sonic 3 | Sonic 3 & Knuckles | Chaotix | Sonic Jam | Sonic Jam 6 | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Forces
Technical information
Sonic Eraser | Sonic 2 (Nick Arcade prototype) | Sonic CD (prototype; 1992-12-04) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic & Knuckles Collection | Sonic R | Sonic Shuffle | Sonic Advance | Sonic Advance 3 | Sonic Battle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Free Riders | Sonic Lost World
Legacy Guides
The Nemesis Hacking Guides The Esrael Hacking Guides
ROM: Sonic 1 | Sonic 2 | Sonic 2 Beta | Sonic 3

Savestate: Sonic 1 | Sonic 2 Beta/Final | Sonic 3

Sonic 1 (English / Portuguese) | Sonic 2 Beta (English / Portuguese) | Sonic 2 and Knuckles (English / Portuguese)
Move to Sega Retro
Number Systems (or scrap) | Assembly Hacking Guide | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | SMPS Music Hacking Guide | Mega Drive technical information