Nem s1ss
From Sonic Retro
Contents
- 1 Introduction
- 2 Internal Groups
- 3 Single Variables
- 4 Pattern breakdown
- 5 Sprite loading addresses (11BE8-11BEF)
- 6 Title card breakdown (11BE8-11BEF)
- 7 Buffered sprite breakdown
- 8 Palette breakdown
- 9 Pattern load cue (11AF8-?????)
- 10 Master level trigger (11A78)
- 11 Level design breakdown (C878-????)
Introduction
I've spent a great deal of time
tearing the Sonic savestate files to shreds, and here are my notes. In order to
edit these files I recommend a hex utility called Hex Workshop, and I recommend
getting the emulators gens and genecyst. Gens is the one I use most of the time,
but genecyst has a lot of features that are extremely useful that gens dosen't
have.
First of all it's very important that you understand the basics. All data
stored on a computer is in the form of 1's and 0's. On a CD for example, a laser
hits the surface, and if the laser bounces back and hits the lens it's a 1, and
if it dosen't it's a zero. Each 1 or 0 is called a bit, and a bit cannot have
any other characters in it other that a 1 or a 0. Now the computer deals with
bits in groups of 4. There are 16 possible combinations for a group of four 1's
and 0's, so to make it simpler to deal with it as one value, rather than 4 (Eg.
0110 becomes 6). Now as there are 16 possible combinations for a group of 4
bits, this value to represent thier values must have 16 values itself, so rather
than a simple 0-9, this value is 0-F (0123456789ABCDEF). This value is called a
hexadecimal value (hex value fo short). Each hex value is dealt with in groups
of 2, called a byte, each byte having 128 possible combinations. Now on a final
output level the byte may be looked up on an ASCII table, which will convert
that value into a recogniseable character (Eg. a byte value of 73 becomes a
lowercase s on an english ASCII table). You will practically never touch the
ASCII version of the code in hacking though.
Now one important thing to realise is that as one character of hex has 16
values and a decimal (real) value only has 10, it may be nessicary to convert
the numbers between them from time to time. This is done with the use of a base
converter (included in hex workshop). Let's say you wanted to give Sonic 50
rings. If you enter 50 as the vaue, you will in fact end up with 80, becuase
that value you are entering is actually a hex value, but if you use the base
converer to convert it first, you merely enter the value of 50 into the decimal
box, and it will spit out a hex value of 32, which will in fact give you 50
rings in the game. Another useful utility that you will need is a hex calculator
(also included in hex workshop). A hex calculator is the same as a normal
calculator, but it deals with hex values rather than decimal values.
Now onto exactly what a savestate consists of. A savestate is a dump of all
the ram that is allocated to the system, but that's not just main system ram,
it's sound ram, CPU cache, etc. In a savestate all of this is mashed together in
one file. Here's what's where in a genecyst savestate:
0-111 | Unknown |
112-191 | C ram (byteswapped) |
192-1E1 | VS ram |
1E2 and 1E3 | A 2 byte break. |
1E4-3E3 | YM2612 registers |
3E4-473 | Some kind of sound ram (Z80 internal cache?)(93) |
474-2473 | Z80 ram (sound ram) |
2474-2477 | A 4 byte break |
2478-12477 | System ram |
12478-22477 | Video ram |
And here's what's where in a Kgen savestate:
0-97 | File header |
98-2097 | Z80 ram |
2098-12097 | System ram |
12098-22097 | Video ram |
22098-22117 | C ram |
22118-223A5 | Unknown (D72) |
223A6-225A5 | YM2612 registers |
225A6-2275B | Unknown (1B6) |
All the address values listed here are based on a genecyst savestate file, so
if you wish to edit one of another type you'll have to convert them yourself.
Now any single value that is stored in the system ram can be altered in game by
use of a pro action replay code. First of all, here's an example of a Pro action
replay code: FFFE10:0800 Now, the first byte in this code is FF, and a value of
FF in the first two characters indicates that the code is altering data in the
system ram. The next four character after it are the actual memory location in
the ram, and the last four are the two byte value to write into that memory
address. The pro action replay will always alter two memory addreses at a time
by the way, because the Mega Drive (Genesis) is a 16 bit system. It dosen't
matter though because you will find that a value will have two bytes assigned to
it anyway, or the second byte will be related. In the case of the example, the
first byte being altered is the current level, and the second is the current act
within that level. The actual address of these values in the savestate are 12288
and 12289. An explination of why lies in the locations of the ram data that is
stored in the savestate. If you look at the above table, there are 2478 lines
worth of data before the system ram in the savestate, so for any action replay
code you want to convert into a file location, you will need to add 2478 to the
line number, and for any line number you want to convert into a pro action
replay code you will need to minus 2478. Remember that these line numbers are
hex values though, so you will need to do this in a hex calculator. (NOTE:
Genecyst dosen't do pro action replay codes properly, use gens instead for that
function).
Another thing you need to know is that each level in Sonic has a value
asigned to it, but this value does not correspond with each level's final
position in the game. Here is a list of the level values:
00 | Green Hill zone |
01 | Labyrinth zone (act 4 is scrap brain zone 3) |
02 | Marble zone |
03 | Star Light zone |
04 | Spring Yard zone |
05 | Scrap Brain zone (act 3 is Final zone) |
And one last thing you need to know is the way that the art is stored in the
rom. All the art that is used in the game is stored in the form of 8x8 pixel
blocks. These blocks do not actually store colours at all, they actually only
have one hex value per pixel. That value specifies what point on the pallette
line the pixel will get it's colour from. The pallette has 4 lines, each with 16
colurs on them. Now the colours on the pallette can be changed at any point
during play, and some pallette colours may even automatically change colour each
couple of frames to make it look like the colour is flashing.
Now these 8x8 blocks are not what makes up the level directly, 4 8x8 blocks
are grouped together to form a 16x16 block, and it is at this point that the
pallette line to use for that 16x16 block is specified. The 8x8 patterns can
also have thier x, y, or x and y values reversed when placing them in a 16x16
block. Now finally we get to a 256x256 block, and these are the things that the
actual level info loads. It is made up of 256 16x16 blocks,and each block inside
them can use a different pallette line. You cannot place anything except a
sprite or a 256x256 block directly into a level.
Now that you know all the basics, here's my breakdown:
System ram | ||
2478-B477 | 256x256 block mappings | |
C878-CC77 | Level design | |
D478-E477 | 16x16 block mappings | |
11AF8-????? | Pattern load cue | |
11EF8-11F77 | Above water pallette | |
11F78-11FF7 | Below water pallette | |
Video ram | ||
12478-1E477 | Main Pattern info | |
1E478-1F477 | Makeup of buffered foreground | |
1F478-20477 | Patterns for text/computers/rings | |
20478-21477 | Makeup of buffered background | |
21478-21C77 | Patterns for sonic and tails (reloaded from rom each time they change) | |
21C78-21EF7 | Makeup of buffered active objects? | |
21EF8-22077 | Lives counter patterns | |
22078-223F7 | Current state of background tiles | |
223F8-22477 | 4 empty blocks |
F47A and F47B | Patterns for Sonic. First value specifies pallette line to use and
mirroring/flipping of sprite. refer to table in 16x16 mappings section. Next three values specify the number of the pattern that Sonic's 8x8 blocks start at. |
F480 and F481 | Sonic's x position |
F484 and F485 | Sonic's y position |
F48C and F48D | Sonic's horizontal speed (8000 is max forward, 7FFF is max back and working back to either 0000 or FFFF accordingly) |
F493 | Sonic's current animation frame |
F4A8 and F4A9 | Sonic flashing (Enter how many frames to flash for. There are 60 frames per second on an NTSC system.) |
F500 and F501 | x position of level name on screen |
F502 and F503 | y position of level name on screen |
F512 | Image for level name |
F516 and F517 | Time until level name moves off screen |
F51C | "Press start button" text enabled/disabled (set to 00 to enable) |
F540 and F541 | x position of "zone" on screen |
F542 and F543 | y position of "zone" on screen |
F552 | Image for "zone" |
F556 and F557 | Time until "zone" moves off screen |
F580 and F581 | x position of act number on screen |
F582 and F583 | y position of act number on screen |
F592 | Image for act number |
F596 and D597 | Time until act number moves off screen |
F5C0 and F5C1 | x position of sonic thingy on screen |
F5C2 and F5C3 | y position of sonic thingy on screen |
F5D2 | Image for sonic thingy |
F5D6 and D5D7 | Time until sonic thingy moves off screen |
11A78 | Master level trigger (This trigger tells the game what you're in, be
it a level, special stage, or a menu. View breakdown for table of values.) |
11AC0 and 11AC1 | Current Water level (specify a y axis value. Note that the y axis
values work as 0 being the top of the level and increase as the character moves further down the level. If this value differs to what it should be, the water level will rise/lower as is neccisary to end up where it should be.) |
11AC4 | The speed at which the water moves (If this is set to 00 the water will not move if the set water level changes) |
11BD8 and 11BD9 | Sonic's Top speed |
11BDA and 11BDB | Sonic's Acceleration |
11BDC and 11BDD | Sonic's Deceleration |
11BE8-11BEF | Sprites (includes map triggers. NOTE: this is not the actual data on the sprite locations. Read breakdown for details). |
1227E | Sprite currently selected in sprite placement mode |
12281 | Sprite placement mode (00=off 01 up=on) |
12288 | Level (hex vaue assigned to level, not level position on list. NOTE:
Changing this value in level will also switch info for background movement, animated sprites, and animated pallette sections.) |
12289 | Act |
1228A | Lives (convert from decimal to hex for desired number) |
12290 | Continues (convert from decimal to hex for desired number) |
12298 and 12299 | Rings (convert from decimal to hex for desired number) |
1229B | Minutes on clock (beyond 09 it loads images beyond it's range, hence screwup) |
1229C | Seconds |
1229D | Milliseconds |
1229E-122A1 | Score (convert from decimal to hex for desired score) |
122A8 | Number of star polls that have been hit (based thier positions on the x axis) |
122CF | Number of emeralds you have |
12388 and 12389 | Camera x position |
1238C and 1238D | Camera y position |
123FA and 123FB | Item in level select menu that is selected |
123FD | Sound that is selected in options menu (minus (80) of any value you
enter, becuase for some weird reason they have the counter starting at 80) |
12404 | Box that is selected in options menu |
12429 | Number of emeralds you have |
12468 and 12469 | Demo mode (00=off 01 up=on) |
12472 | Debug mode (00=off 01 up=on) |
Pattern breakdown
8x8 blocks (12478-1C477)
All 8x8 patterns are stored sequentially,
each one taking up 32(20) bytes. One pixel takes up one hex value, not one byte.
The value of this hex value being 0-16 represents the colour that pixel is on
the pallette, 0 being the start, and F being the end (NOTE: specifying a value
of 0 will not load up the first colour on the pallette line, but instead make
that pixel transparent).
16x16 block mappings: (D478-????)
Each 16x16 block is made up of
four 8x8 blocks. Delt with in blocks of 8 bytes, 2 bytes per pattern to be used
in block. First value determins which pallette line to use, and which
orientation the pattern is at. Refer to table for explination:
Value | pallette line | flipped horizntally | flipped vertically |
0 | 1 | n | n |
1 | 1 | n | y |
2 | 2 | n | n |
3 | 2 | n | y |
4 | 3 | n | n |
5 | 3 | n | y |
6 | 4 | n | n |
7 | 4 | n | y |
8 | 1 | n | n |
9 | 1 | y | n |
A | 2 | n | n |
B | 2 | y | n |
C | 3 | n | n |
D | 3 | y | n |
E | 4 | n | n |
F | 4 | y | n |
The next three values represent the pattern number to use. Specify the number
that the pattern is in the list (EFF is the last of the useable patterns). The
block mappings use the standard method of layout, start at x0 y0 and move across
x values until end of line is reached, then repeating on next y value. If a
space is blank in the 16x16 mappings, it will have the values 4000 in every box.
256x256 block mappings: (2478-B477)
Delt with in blocks of 512
(200) bytes. Each 256x256 block is made up of 256 16x16 blocks, hence two bytes
per 16x16 block are used. The first value is to do with the flipping of the
block. An odd number will flip it vertically, while an even number will load it
normally. The next 3 values are the number of the 16x16 block to use.
Sprite loading addresses (11BE8-11BEF)
The sprite information is discarded when screen moves too far away, and
information is then reloaded from rom when character reenters area. These values
specify a location in the rom to load the information from. The first four bytes
are the address to load the sprites from when approaching from the left. The
four bytes after that is the address to load the sprite info when approaching
from the right. There is also another block of 8 bytes after this one that
appears to be the same, but it dosen't seem to do anything. And no, it's not
where to load the sprites from when approaching from the top and bottom.
NOTE: Altering these values to those of another level will transfer the
information for the location of sprites, and the key files (definitions about
movement/reactions) for the sprites, but unless the correct patterns for them
are loaded into the ram, it will look like a jumbled peice of crap.
Title card breakdown (11BE8-11BEF)
The title card is quite a simple thing. It's really just 4 sprites on different levels that are bound to the screen. There's 64 (40) bytes of data that defines each one of these sprites. Look in the single variables section for these values. WIth the Image variable, these values will load up these images:
Value | Image |
00 | Green Hill |
01 | Labyrinth |
02 | Marble |
03 | Star Light |
04 | Spring Yard |
05 | Scrap Brain |
06 | Zone |
07 | Act 1 |
08 | Act 2 |
09 | Act 3 |
0A | Blue circle thingy |
0B | Final |
We can really see from this just how much of a last minute thing adding a
final zone rather than having it as part of Scrap Brain zone 3 was.
Buffered sprite breakdown
Final: (D878-F477)
Stored in blocks of 64 bytes (40) per sprite.
The sprites are listed in the order that they appear starting from the top left
and scrolling across x values, then beginning on next line. The following
example uses address locations for the first sprite on the list as a referance.
You will need to increase the line values on this list by 40(hex) for every
sprite that comes before the one you want to modify.
FB78 | Key file to use for defining the actions/movements of sprite. 94 is
lava snake, 26 is monitor, A4 is exploding star, just to name a few. I have compiled an early list of values for it in the final version of Sonic 2 here |
FBFA and FBFB | Patterns to use for sprite. Specify number of 8x8 block to start from, not address value. |
FC00 and FC01 | x position of sprite |
FC04 and FC05 | y position of sprite |
FC18 | Collision response (this value determines what happens when your
character's sprite hits this one. A long list of different values so one will have to be compiled). |
FC19 | Special flag for collision (Setting this value to 01 or above will set
a special thing about the sprite for the collision group it belongs to. If it's set as an enemy this trigger will make you bounce off the sprite like the enemy in Casino night. If it's a computer it will turn off collision responces all together. The other two do nothing.) |
Palette breakdown
(Above water: 11EF8-11F77, Below water: 11F78-11FF7)
A simple 12 bit
RGB value. One colour on pallette is represented by two bytes, and working back
from the last value forward an RGB value is specified like this: 0BGR. So if you
wanted that colour on the pallette to be completely red, you would enter a value
of 000F. The first colour on the pallette is the default colour of the stage. If
you had a value of 0 in one of the background tiles, this colour will be
substituted in instead of making it transparent.
Pattern load cue (11AF8-?????)
Requests are processed in the order they are listed. If you try to load
multiple patterns to the same area, the last one will overwrite the first. A six
byte value per request. First four bytes are the address to load the patterns
from the rom (eg, 0008 30D2). The last two bytes are the address to load the
patterns into in the video ram. The pattern view window in genecyst is the
easiest way to determine this. Note than whenever clearing out the pattern cue
you must also set 11B71 to 00, or else some crap will be written over the first
few patterns in the video ram. I have yet to narrow down the exact relationship
this variable has with the load cue.
Master level trigger (11A78)
This trigger is the main trigger that specifies the current "mode" if you
will that the game is in. Changing this will make the game switch to the mode
you specify once it finishes it's current process.
00 | SEGA logo |
04 | Title screen |
08 | Demo (will make the screen fade out and return to title when time reaches 27 seconds) |
0C | Normal level |
10 | Special stage |
14 | Continue screen |
18 | End of game sequence |
1C | Credits |
Values above 1C have not been used, so you get some strange results. If you
change this value in level the screen will fade out and the data for the thing
you have selected will be loaded instead. If you specify a value betwen the
values I have listed, you will get some strange results most of the time.
Level design breakdown (C878-????)
Level is delt with as a grid, starting with first tile in top left and working across to the right doing one x value at a time. One byte represents one tile in one grid location. A value of 00 will not load up the first large tile, but instead will simply display no block. A value of 01 will load up the first block, 02 the second, etc. The maximum possible number of large tiles on the x-axis is 127 (80). One x line is stored in the form of 128 (40) lines for foreground tiles, then another 128 (40) lines for background tiles per y value. That totals an increase of 0100 per line, so if level data started at 0300 (not possible), 0300-03FF would be all the data for the top row of 128x128 tiles, 0400-04FF would be all the data for the second row of 256x256 tiles, etc.