Nem s3
From Sonic Retro
Revision as of 15:57, 4 September 2006 by Scarred Sun (talk | contribs)
Contents
Introduction
Here are my hacking notes on the Sonic 3 rom. If you use these notes I'd appreciate it if you would mention it with your hack or your utility, so that other people can find their way here. For hex editing I recommend you use a hex utility called Hex Workshop, and for emulators I recommend you get both Gens and Genecyst. Genecyst may be old and kinda crap, but it has a whole heap of debug outputs that really help when it comes to seeing exactly what it's doing and when.
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 doesn'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 it deals 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 their 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 for 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 recognisable 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 necessary 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 value, you will in fact end up with 80, because that value you are entering is actually a hex value, but if you use the base converter 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.
Another thing you need to know is that each level in Sonic 2 has a value assigned 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 in Sonic 3:
00 | Angel island zone |
01 | Hydrocity zone |
02 | Marble garden zone |
03 | Carnival Night zone |
04 | Flying Battery zone |
05 | Ice cap zone |
06 | launch base zone |
07 | Empty |
08 | Empty |
09 | Empty |
0A | Empty |
0B | Empty |
0C | Empty |
0D | Empty |
0E | Azure Lake |
0F | Balloon Park |
10 | Chrome Gadget |
11 | Desert Palace |
12 | Endless Mine |
13 | Bonus Stage |
14 | Empty |
15 | Empty |
16 | Empty |
17 | Empty |
One other thing you need to know is the way that the Mega Drive stores all the art. 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 palette line the pixel will get its colour from. The palette has 4 lines, each with 16 colours on them. Now the colours on the palette can be changed at any point during play, and some palette 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 make up the level directly. 4 8x8 blocks are grouped together to form a 16x16 block, and it is at this point that the palette line to use for that 16x16 block is specified. The 8x8 patterns can also have their x, y, or x and y values reversed when placing them in a 16x16 block. Also it's at the 16x16 level that the collision definitions are specified. Now finally we get to a 128x128 block, and these are the things that the actual level info loads. It is made up of 64 16x16 blocks, and each block inside them can use a different palette line. You cannot place anything except a sprite or a 128x128 block directly into a level.
Now that you know all the basics, here's my breakdown:
Address Listing
For the most part, there are no breaks in this list. If one address follows on directly from another on this list, it does so in the rom, with the exception of data that comes before 50000. All the compiled code that is used in the game is stored in this section, and that's a pain in the ass to sort through, so there will be many breaks there. The column on the left lists it's file location, the column in the middle contains it's name and description, and the column on the right will contain any special notes about it, such as compression format used if applicable, and number of blocks an art tile uses. The right column will also contain a link with the text further info, if that particular block requires it. That link will jump to a detailed explanation of that thing. Anything linked like that will also be listed in the contents at the top of the page. Any patterns that are not used anywhere in the game will be preceeded by this red dot File:Reddot.gif .
See SCHG:Nem s3/Address listing.
Offset indexes
An offset index is a handy way of keeping a block of data grouped together, and also replacing a whole heap of pointers. The way it works is there is a list of two byte vaues, and depending on the block of data the game wants to load, it will take one of those values and add it to the starting address of the offset index. The most common usage is for every act of every level value, there is an offset that acts as the pointer to the block of data to use for it. Lets look at an example:
5AF8C: | 00F8 | 0112 | 012C | 0140 | 0148 | 0150 | 0158 | 016C |
This is the beginning of the offset index for the pattern load cue's. If the game was trying to access the second pattern load cue, it would take the pointer to the offset index which is 5AF8C, and it would jump to the second offset, which in this case is 0112. It would then add that value to the location of the offset index, and that gives the location of the data.
5AF8C + 0112 = 5B09E |
So in this case the data is located at 5B09E in the rom. This type of system is used for many things in the rom such as pattern load cue's, sprite mappings, etc.
Pointer list
A pointer list is simply a block of pointers. Pointers are a 4 byte number that gives the location of data. This location is listed on the lefthand side of a hex editor. The most common use of a pointer list in the game is to specify a block of data to be used in conjunction with each level or act. Simply count across to the pointer you wish to modify. For example, if you want to change the pointer to the data for HCZ act 1, and it's done on an act by act basis, you'll want to modify the third pointer in the list, which would be 8 bytes along.
Main level load block
This pointer table is what is used to load up the block mappings and main level patterns for every level in the game. Here's a breakdown of the pointer table in the S3 rom:
5AB0C-5AF8B: Main level load blocks (Bpatterns/Epatterns/B16x16/E16x16/B128x128/E128x128)
- 5AB0C-5AB3B: Angel Island zone (00)
- 5AB0C-5AB23: Act 1
- 5AB0C: AIZ act 1 base tiles (1A566A) [0B]
- 5AB10: AIZ act 1 extended tiles (1A647C) [0B]
- 5AB14: AIZ act 1 base 16x16 block mappings (1A374A) [0A]
- 5AB18: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AB1C: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AB20: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AB0C-5AB23: Act 1
- 5AB24-5AB3B: Act 2
- 5AB24: AIZ act 2 base tiles (1B15D2) [0C]
- 5AB28: AIZ act 2 extended tiles (1B3784) [0C]
- 5AB2C: AIZ act 2 base 16x16 block mappings (1B0052) [0B]
- 5AB30: AIZ act 2 extended 16x16 block mappings (1B08F2) [0B]
- 5AB34: AIZ act 2 128x128 block mappings (1B51E8) [00]
- 5AB38: AIZ act 2 128x128 block mappings (1B51E8) [00]
- 5AB24-5AB3B: Act 2
- 5AB3C-5AB6B: Hydrocity zone (01)
- 5AB3C-5AB53: Act 1
- 5AB3C: HCZ base tiles (1B9668) [0E]
- 5AB40: HCZ act 1 extended tiles (1BAE7A) [0F]
- 5AB44: HCZ base 16x16 block mappings (1B91F8) [0C]
- 5AB48: HCZ act 1 extended 16x16 block mappings (1BA5EA) [0C]
- 5AB4C: HCZ base 128x128 block mappings (1BA2AA) [00]
- 5AB50: HCZ act 1 extended 128x128 block mappings (1BD0CC) [00]
- 5AB3C-5AB53: Act 1
- 5AB54-5AB6B: Act 2
- 5AB54: HCZ base tiles (1B9668) [10]
- 5AB58: HCZ act 2 extended tiles (1BFA6C) [11]
- 5AB5C: HCZ base 16x16 block mappings (1B91F8) [0D]
- 5AB60: HCZ act 2 extended 16x16 block mappings (1BF17C) [0D]
- 5AB64: HCZ base 128x128 block mappings (1BA2AA) [00]
- 5AB68: HCZ act 2 extended 128x128 block mappings (1C18EE) [00]
- 5AB54-5AB6B: Act 2
- 5AB6C-5AB9B: Marble Garden zone (02)
- 5AB6C-5AB83: Act 1
- 5AB6C: MGZ base tiles (1C3EBE) [12]
- 5AB70: MGZ act 1 extended tiles (1C8A70) [12]
- 5AB74: MGZ base 16x16 block mappings (1C356E) [0E]
- 5AB78: MGZ act 1 extended 16x16 block mappings (1C8760) [0E]
- 5AB7C: MGZ base 128x128 block mappings (1C6460) [00]
- 5AB80: MGZ act 1 extended 128x128 block mappings (1C9452) [00]
- 5AB6C-5AB83: Act 1
- 5AB84-5AB9B: Act 2
- 5AB84: MGZ base tiles (1C3EBE) [14]
- 5AB88: MGZ act 2 extended tiles (1CA132) [14]
- 5AB8C: MGZ base 16x16 block mappings (1C356E) [0F]
- 5AB90: MGZ act 2 extended 16x16 block mappings (1C9CD2) [0F]
- 5AB94: MGZ base 128x128 block mappings (1C6460) [00]
- 5AB98: MGZ act 2 extended 128x128 block mappings (1CB1C4) [00]
- 5AB84-5AB9B: Act 2
- 5AB9C-5ABCB: Carnival Night zone
- 5AB9C-5ABB3: Act 1
- 5AB9C: CNZ tiles (1CDC74) [16]
- 5ABA0: CNZ tiles (1CDC74) [17]
- 5ABA4: CNZ 16x16 block mappings (1CCC34) [10]
- 5ABA8: CNZ 16x16 block mappings (1CCC34) [10]
- 5ABAC: CNZ 128x128 block mappings (1D0E96) [00]
- 5ABB0: CNZ 128x128 block mappings (1D0E96) [00]
- 5AB9C-5ABB3: Act 1
- 5ABB4-5ABCB: Act 2
- 5ABB4: CNZ tiles (1CDC74) [18]
- 5ABB8: CNZ tiles (1CDC74) [19]
- 5ABBC: CNZ 16x16 block mappings (1CCC34) [11]
- 5ABC0: CNZ 16x16 block mappings (1CCC34) [11]
- 5ABC4: CNZ 128x128 block mappings (1D0E96) [00]
- 5ABC8: CNZ 128x128 block mappings (1D0E96) [00]
- 5ABB4-5ABCB: Act 2
- 5ABCC-5ABFB: Flying battery zone (04)
MEDIAWIKI WON'T ACCEPT THIS BLOCK?
- 5ABE4-5ABFB: Act 2
- 5ABE4: ICZ base 16x16 block mappings (1D3FB6) [1C]
- 5ABE8: ICZ base 16x16 block mappings (1D3FB6) [1C]
- 5ABEC: ICZ base 16x16 block mappings (1D3FB6) [13]
- 5ABF0: ICZ base 16x16 block mappings (1D3FB6) [13]
- 5ABF4: ICZ base 16x16 block mappings (1D3FB6) [00]
- 5ABF8: ICZ base 16x16 block mappings (1D3FB6) [00]
- 5ABE4-5ABFB: Act 2
- 5ABFC-5AC2B: Ice Cap zone (05)
- 5ABFC-5AC13: Act 1
- 5ABFC: ICZ base tiles (1D4296) [1E]
- 5AC00: ICZ act 1 extended tiles (1D64C8) [1E]
- 5AC04: ICZ base 16x16 block mappings (1D3FB6) [14]
- 5AC08: ICZ act 1 extended 16x16 block mappings (1D5958) [14]
- 5AC0C: ICZ base 128x128 block mappings (1D56A8) [00]
- 5AC10: ICZ act 1 extended 128x128 block mappings (1D844A) [00]
- 5ABFC-5AC13: Act 1
- 5AC14-5AC2C: Act 2
- 5AC14: ICZ base tiles (1D4296) [20]
- 5AC18: ICZ act 2 extended tiles (1DAF0A) [20]
- 5AC1C: ICZ base 16x16 block mappings (1D3FB6) [15]
- 5AC20: ICZ act 2 extended 16x16 block mappings (1DA26A) [15]
- 5AC24: ICZ base 128x128 block mappings (1D56A8) [00]
- 5AC28: ICZ act 2 extended 128x128 block mappings (1DCFBC) [00]
- 5AC14-5AC2C: Act 2
- 5AC2C-5AC5B: Launch base zone (06)
- 5AC2C-5AC43: Act 1
- 5AC2C: LBZ base tiles (1DFABC) [22]
- 5AC30: LBZ act 1 extended tiles (1E120E) [22]
- 5AC34: LBZ base 16x16 block mappings (1DEA8C) [16]
- 5AC38: LBZ act 1 extended 16x16 block mappings (1DEFCC) [16]
- 5AC3C: LBZ act 1 128x128 block mappings (1E2FA0) [00]
- 5AC40: LBZ act 1 128x128 block mappings (1E2FA0) [00]
- 5AC2C-5AC43: Act 1
- 5AC44-5AC5B: Act 2
- 5AC44: LBZ base tiles (1DFABC) [24]
- 5AC48: LBZ act 2 extended tiles (1E77D0) [25]
- 5AC4C: LBZ base 16x16 block mappings (1DEA8C) [17]
- 5AC50: LBZ act 2 extended 16x16 block mappings (1E5F70) [17]
- 5AC54: LBZ act 2 128x128 block mappings (1EAF04) [00]
- 5AC58: LBZ act 2 128x128 block mappings (1EAF04) [00]
- 5AC44-5AC5B: Act 2
- 5AC5C-5AC8B: Empty (07)
- 5AC5C-5AC73: Act 1
- 5AC5C: AL 16x16 block mappings (1EE0C4) [26]
- 5AC60: AL 16x16 block mappings (1EE0C4) [26]
- 5AC64: AL 16x16 block mappings (1EE0C4) [18]
- 5AC68: AL 16x16 block mappings (1EE0C4) [18]
- 5AC6C: AL 16x16 block mappings (1EE0C4) [00]
- 5AC70: AL 16x16 block mappings (1EE0C4) [00]
- 5AC5C-5AC73: Act 1
- 5AC74-5AC8B: Act 2
- 5AC74: AL 16x16 block mappings (1EE0C4) [28]
- 5AC78: AL 16x16 block mappings (1EE0C4) [28]
- 5AC7C: AL 16x16 block mappings (1EE0C4) [19]
- 5AC80: AL 16x16 block mappings (1EE0C4) [19]
- 5AC84: AL 16x16 block mappings (1EE0C4) [00]
- 5AC88: AL 16x16 block mappings (1EE0C4) [00]
- 5AC74-5AC8B: Act 2
- 5AC8C-5ACBB: Empty (08)
- 5AC8C-5ACA3: Act 1
- 5AC8C: AIZ act 1 base tiles (1A566A) [0B]
- 5AC90: AIZ act 1 extended tiles (1A647C) [0B]
- 5AC94: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AC98: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AC9C: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5ACA0: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AC8C-5ACA3: Act 1
- 5ACA4-5ACBB: Act 2
- 5ACA4: AIZ act 1 base tiles (1A566A) [0C]
- 5ACA8: AIZ act 1 extended tiles (1A647C) [0C]
- 5ACAC: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5ACB0: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5ACB4: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5ACB8: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5ACA4-5ACBB: Act 2
- 5ACBC-5ACEB: Empty (09)
- 5ACBC-5ACD3: Act 1
- 5ACBC: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACC0: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACC4: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACC8: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACCC: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACD0: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACBC-5ACD3: Act 1
- 5ACD4-5ACEB: Act 2
- 5ACD4: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACD8: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACDC: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACE0: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACE4: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACE8: AL 16x16 block mappings (1EE0C4) [2E]
- 5ACD4-5ACEB: Act 2
- 5ACEC-5AD04: Empty (0A)
- 5ACEC-5AD03: Act 1
- 5ACEC: AIZ act 1 base tiles (1A566A) [0B]
- 5ACF0: AIZ act 1 extended tiles (1A647C) [0B]
- 5ACF4: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5ACF8: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5ACFC: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD00: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5ACEC-5AD03: Act 1
- 5AD04-5AD1B: Act 2
- 5AD04: AIZ act 1 base tiles (1A566A) [0C]
- 5AD08: AIZ act 1 extended tiles (1A647C) [0C]
- 5AD0C: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AD10: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AD14: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD18: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD04-5AD1B: Act 2
- 5AD1C-5AD4C: Empty (0B)
- 5AD1C-5AD33: Act 1
- 5AD1C: AIZ act 1 base tiles (1A566A) [0B]
- 5AD20: AIZ act 1 extended tiles (1A647C) [0B]
- 5AD24: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AD28: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AD2C: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD30: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD1C-5AD33: Act 1
- 5AD34-5AD4B: Act 2
- 5AD34: AIZ act 1 base tiles (1A566A) [0C]
- 5AD38: AIZ act 1 extended tiles (1A647C) [0C]
- 5AD3C: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AD40: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AD44: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD48: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD34-5AD4B: Act 2
- 5AD4C-5AD7B: Empty (0C)
- 5AD4C-5AD63: Act 1
- 5AD4C: AIZ act 1 base tiles (1A566A) [0B]
- 5AD50: AIZ act 1 extended tiles (1A647C) [0B]
- 5AD54: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AD58: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AD5C: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD60: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD4C-5AD63: Act 1
- 5AD64-5AD7C: Act 2
- 5AD64: AIZ act 1 base tiles (1A566A) [0C]
- 5AD68: AIZ act 1 extended tiles (1A647C) [0C]
- 5AD6C: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AD70: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AD74: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD78: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD64-5AD7C: Act 2
- 5AD7C-5AD93: Empty (0D)
- 5AD7C-5AD93: Act 1
- 5AD7C: AIZ act 1 base tiles (1A566A) [0B]
- 5AD80: Unknown patterns (1A944E) [0B]
- 5AD84: AIZ act 1 base 16x16 block mappings (1A374A) [2A]
- 5AD88: Unknown extended 16x16 block mappings (1A458A) [2A]
- 5AD8C: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD90: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD7C-5AD93: Act 1
- 5AD94-5ADAB: Act 2
- 5AD94: AIZ act 1 base tiles (1A566A) [0C]
- 5AD98: AIZ act 1 extended tiles (1A647C) [0C]
- 5AD9C: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5ADA0: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5ADA4: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5ADA8: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AD94-5ADAB: Act 2
- 5ADAC-5ADDB: Azure lake (0E)
- 5ADAC-5ADC4: Act 1
- 5ADAC: AL tiles (1EEB84) [42]
- 5ADB0: AL tiles (1EEB84) [42]
- 5ADB4: AL 16x16 block mappings (1EE0C4) [26]
- 5ADB8: AL 16x16 block mappings (1EE0C4) [26]
- 5ADBC: AL 128x128 block mappings (1F1936) [00]
- 5ADC0: AL 128x128 block mappings (1F1936) [00]
- 5ADAC-5ADC4: Act 1
- 5ADC4-5ADDC: Act 2
- 5ADC4: AL tiles (1EEB84) [42]
- 5ADC8: AL tiles (1EEB84) [42]
- 5ADCC: AL 16x16 block mappings (1EE0C4) [27]
- 5ADD0: AL 16x16 block mappings (1EE0C4) [27]
- 5ADD4: AL 128x128 block mappings (1F1936) [00]
- 5ADD8: AL 128x128 block mappings (1F1936) [00]
- 5ADC4-5ADDC: Act 2
- 5ADDC-5AE0B: Ballon Park (0F)
- 5ADDC-5ADF3: Act 1
- 5ADDC: BP tiles (1F2896) [43]
- 5ADE0: BP tiles (1F2896) [43]
- 5ADE4: BP 16x16 block mappings (1F1FC6) [28]
- 5ADE8: BP 16x16 block mappings (1F1FC6) [28]
- 5ADEC: BP 128x128 block mappings (1F4878) [00]
- 5ADF0: BP 128x128 block mappings (1F4878) [00]
- 5ADDC-5ADF3: Act 1
- 5ADF4-5AE0B: Act 2
- 5ADF4: BP tiles (1F2896) [43]
- 5ADF8: BP tiles (1F2896) [43]
- 5ADFC: BP 16x16 block mappings (1F1FC6) [29]
- 5AE00: BP 16x16 block mappings (1F1FC6) [29]
- 5AE04: BP 128x128 block mappings (1F4878) [00]
- 5AE08: BP 128x128 block mappings (1F4878) [00]
- 5ADF4-5AE0B: Act 2
- 5AE0C-5AE3B: Chrome Gadget (10)
- 5AE0C-5AE23: Act 1
- 5AE0C: CG tiles (1F5948) [44]
- 5AE10: CG tiles (1F5948) [44]
- 5AE14: GC 16x16 block mappings (1F4F68) [34]
- 5AE18: GC 16x16 block mappings (1F4F68) [34]
- 5AE1C: GC 128x128 block mappings (1F743A) [00]
- 5AE20: GC 128x128 block mappings (1F743A) [00]
- 5AE0C-5AE23: Act 1
- 5AE24-5AE3B: Act 2
- 5AE24: CG tiles (1F5948) [44]
- 5AE28: CG tiles (1F5948) [44]
- 5AE2C: GC 16x16 block mappings (1F4F68) [34]
- 5AE30: GC 16x16 block mappings (1F4F68) [34]
- 5AE34: GC 128x128 block mappings (1F743A) [00]
- 5AE38: GC 128x128 block mappings (1F743A) [00]
- 5AE24-5AE3B: Act 2
- 5AE3C-5AE6B: Desert Palace (11)
- 5AE3C-5AE53: Act 1
- 5AE3C: DP tiles (1F81BA) [45]
- 5AE40: DP tiles (1F81BA) [45]
- 5AE44: DP 16x16 block mappings (1F7A6A) [35]
- 5AE48: DP 16x16 block mappings (1F7A6A) [35]
- 5AE4C: DP 128x128 block mappings (1FA75C) [00]
- 5AE50: DP 128x128 block mappings (1FA75C) [00]
- 5AE3C-5AE53: Act 1
- 5AE54-5AE6B: Act 2
- 5AE54: DP tiles (1F81BA) [45]
- 5AE58: DP tiles (1F81BA) [45]
- 5AE5C: DP 16x16 block mappings (1F7A6A) [35]
- 5AE60: DP 16x16 block mappings (1F7A6A) [35]
- 5AE64: DP 128x128 block mappings (1FA75C) [00]
- 5AE68: DP 128x128 block mappings (1FA75C) [00]
- 5AE54-5AE6B: Act 2
- 5AE6C-5AE9B: Endless Mine (12)
- 5AE6C-5AE83: Act 1
- 5AE6C: EM tiles (1FB6CC) [46]
- 5AE70: EM tiles (1FB6CC) [46]
- 5AE74: EM 16x16 block mappings (1FAC1C) [36]
- 5AE78: EM 16x16 block mappings (1FAC1C) [36]
- 5AE7C: EM 128x128 block mappings (1FE2FE) [00]
- 5AE80: EM 128x128 block mappings (1FE2FE) [00]
- 5AE6C-5AE83: Act 1
- 5AE84-5AE9B: Act 2
- 5AE84: EM tiles (1FB6CC) [46]
- 5AE88: EM tiles (1FB6CC) [46]
- 5AE8C: EM 16x16 block mappings (1FAC1C) [36]
- 5AE90: EM 16x16 block mappings (1FAC1C) [36]
- 5AE94: EM 128x128 block mappings (1FE2FE) [00]
- 5AE98: EM 128x128 block mappings (1FE2FE) [00]
- 5AE84-5AE9B: Act 2
- 5AE9C-5AECB: Bonus stage (13)
- 5AE9C-5AEB3: Act 1
- 5AE9C: Bonus stage 1 base tiles (1FEE2E) [47]
- 5AEA0: Bonus stage 1 base tiles (1FEE2E) [47]
- 5AEA4: Bonus stage 16x16 block mapings (1FEA0E) [33]
- 5AEA8: Bonus stage 16x16 block mapings (1FEA0E) [33]
- 5AEAC: Bonus stage 128x128 block mappings (1FFB80) [00]
- 5AEB0: Bonus stage 128x128 block mappings (1FFB80) [00]
- 5AE9C-5AEB3: Act 1
- 5AEB4-5AECB: Act 2
- 5AEB4: Bonus stage 1 base tiles (1FEE2E) [47]
- 5AEB8: Bonus stage 1 base tiles (1FEE2E) [47]
- 5AEBC: Bonus stage 16x16 block mapings (1FEA0E) [33]
- 5AEC0: Bonus stage 16x16 block mapings (1FEA0E) [33]
- 5AEC4: Bonus stage 128x128 block mappings (1FFB80) [00]
- 5AEC8: Bonus stage 128x128 block mappings (1FFB80) [00]
- 5AEB4-5AECB: Act 2
- 5AECC-5AEFB: Empty (14)
- 5AECC-5AEE3: Act 1
- 5AECC: Nothing (1FFF20) [47]
- 5AED0: Nothing (1FFF20) [47]
- 5AED4: Nothing (1FFF20) [37]
- 5AED8: Nothing (1FFF20) [37]
- 5AEDC: Nothing (1FFF20) [00]
- 5AEE0: Nothing (1FFF20) [00]
- 5AECC-5AEE3: Act 1
- 5AEE4-5AEFB: Act 2
- 5AEE4: Nothing (1FFF20) [47]
- 5AEE8: Nothing (1FFF20) [47]
- 5AEEC: Nothing (1FFF20) [37]
- 5AEF0: Nothing (1FFF20) [37]
- 5AEF4: Nothing (1FFF20) [00]
- 5AEF8: Nothing (1FFF20) [00]
- 5AEE4-5AEFB: Act 2
- 5AEFC-5AF2B: Empty (15)
- 5AEFC-5AF13: Act 1
- 5AEFC: Nothing (1FFF20) [47]
- 5AF00: Nothing (1FFF20) [47]
- 5AF04: Nothing (1FFF20) [38]
- 5AF08: Nothing (1FFF20) [38]
- 5AF0C: Nothing (1FFF20) [00]
- 5AF10: Nothing (1FFF20) [00]
- 5AEFC-5AF13: Act 1
- 5AF14-5AF2C: Act 2
- 5AF14: Nothing (1FFF20) [47]
- 5AF18: Nothing (1FFF20) [47]
- 5AF1C: Nothing (1FFF20) [38]
- 5AF20: Nothing (1FFF20) [38]
- 5AF24: Nothing (1FFF20) [00]
- 5AF28: Nothing (1FFF20) [00]
- 5AF14-5AF2C: Act 2
- 5AF2C-5AF5B: Empty (16)
- 5AF2C-5AF43: Act 1
- 5AF2C: AIZ act 1 base tiles (1A566A) [0B]
- 5AF30: AIZ act 1 extended tiles (1A647C) [0B]
- 5AF34: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AF38: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AF3C: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF40: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF2C-5AF43: Act 1
- 5AF44-5AF5B: Act 2
- 5AF44: AIZ act 1 base tiles (1A566A) [0C]
- 5AF48: AIZ act 1 extended tiles (1A647C) [0C]
- 5AF4C: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AF50: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AF54: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF58: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF44-5AF5B: Act 2
- 5AF5C-5AF73: Empty (17)
- 5AF5C-5AF73: Act 1
- 5AF5C: AIZ act 1 base tiles (1A566A) [0B]
- 5AF60: AIZ act 1 extended tiles (1A647C) [0B]
- 5AF64: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AF68: AIZ act 1 extended 16x16 block mappings (1A394A) [0A]
- 5AF6C: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF70: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF5C-5AF73: Act 1
- 5AF74-5AF8B: Act 2
- 5AF74: AIZ act 1 base tiles (1A566A) [0C]
- 5AF78: AIZ act 1 extended tiles (1A647C) [0C]
- 5AF7C: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AF80: AIZ act 1 extended 16x16 block mappings (1A394A) [0B]
- 5AF84: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF88: AIZ act 1 128x128 block mappings (1ABC40) [00]
- 5AF74-5AF8B: Act 2
Sonic 3 is quite different from the previous sonic games in the way that the core of S3 allows the programmers to change virtually anything about the level during game easily, making things such as smooth transition betwen acts and intro sequences possible. The data itself is often cut into sections, allowing the programmers to load just the modules that need updating. For each level, there may be a base block of data and an extended block of data for each thing. The way this works is the base block of data is the first section of that data block, and the extended one is the second. If you decompress both of them and chuck the extended one on the end of the base one, you get the full block of data. It is seperated like this to allow programmers to duplicate as little data as possible in any patches they may want to apply to that data while the level is running, and thus save rom space and cut down on the power required to make the transition. Now as you can see, these pointers specify the loading addresses in the rom for the 16x16 and 128x128 block mappings, as well as the main pattern block for that level. The main pattern block will always be loaded into the VRAM at address 0000. These loading addresses are all preceeded by a one byte value, so the address pointer only uses three bytes rather than the standard four. The value that proceeds the 128x128 block mappings specifies a value on the palette index to load for that level. For more information on the palette system, go here. The values preceeding the main level pattern and 16x16 block mapping pointers give the index numbers of the pattern load cue's to use for that level. For more information on that go here.
Pattern load cue's
The pattern load cue's are what loads all the peices of art into the VRAM that are not in the main level load block. Here's a breakdown of the pattern load cue's in the S3 rom:
Index | Location | Name | Contents | Rom | Vram | Number |
00 | 5B084 | Unknown | -Sonic lives counter -Ring and score/time/rings -Points and starpoll -Monitor |
15CEE6 15F2EC 15F528 15D2DE |
FA80 D780 BC80 9880 |
(3) |
01 | 5B09E | Unknown | -Sonic lives counter -Monitor -Ring and score/time/rings -Points and starpoll |
15CEE6 15D2DE 15F2EC 15F528 |
FA80 9880 D780 BC80 |
(3) |
02 | 5B0B8 | Unknown | -Explosion -Squirrel -Bluebird |
15E6C0 15FDA6 15F9D4 |
B400 B000 B240 |
(2) |
03 | 5B0CC | Game/Time over | -Game/Time over text | 15E49A | F380 | (0) |
04 | 5B0D4 | Signpost | -End of level signpost | 15DA5A | A000 | (0) |
05 | 5B0DC | Springs and spikes | -Horizontal springs and vertical spikes | 15EFFC | 9280 | (0) |
06 | 5B0E4 | Competition mode | -Mini spring and spikes -Mini spring and button -Competition mode powerups |
196D10 196B9C 196F02 |
7220 75A0 78C0 |
(2) |
07 | 5B0F8 | Unknown | -Tails lives counter -Monitor -Ring and score/time/rings -Points and starpoll |
15CFFE 15D2DE 15F2EC 15F528 |
FA80 9880 D780 BC80 |
(3) |
08 | 5B112 | Monitor | -Monitor | 15D2DE | 9880 | (0) |
09 | 5B11A | Special stage platform test | -Special stage sphere | 911CE | 9C00 | (0) |
0A | 5B122 | AIZ intro | -Waves from AIZ intro | 1481A0 | 7A20 | (0) |
0B | 5B12A | AIZ 1st load cue | -Rope on flying fox -Unknown -Unknown -Impact splash on water -Bubbles from underwater -Grass tiles |
18D8BC 18DA22 18DC90 18E4D8 15E1FC 18D586 |
8360 6480 6660 79E0 8B80 7EE0 |
(5) |
0C-0D | 5B150 | AIZ 2nd load cue | -Misc AIZ blocks -Rope on flying fox -Unknown -Bubbles -Button -Unknown |
18E760 18D8BC 18DB46 15E1FC 15C900 18D72A |
5D20 8360 8700 8B80 8AC0 8800 |
(5) |
0E | 5B176 | HCZ 1st load cue | -Bubbles -Misc HCZ blocks -Unknown -Misc MCZ blocks -Unknown -Metal spikeball |
15E1FC 18FD88 18FCD4 190348 18FBB4 18FAEC |
8B80 7940 84C0 6F40 85C0 87C0 |
(5) |
0F | 5B19C | HCZ 2nd load cue | -Blowfly | 16A3E0 | 8980 | (0) |
10 | 5B1A4 | Unknown | -Bubbles -Misc HCZ blocks -Unknown -Unknown -Metal spikeball -Sliding tube |
15E1FC 18FD88 18FCD4 18FBB4 18FAEC 191B36 |
8B80 7940 84C0 85C0 87C0 6B80 |
(5) |
11 | 5B1CA | Unknown | -Unknown -HCZ bridge -Blowfly |
193714 19204C 16A3E0 |
6A00 0500 8980 |
(2) |
12-13 | 5B1DE | MGZ 1st load cue | -Unknown -Unknown -MGZ signs -Diagonal spring |
19382E 19426C 19487C 15CBD2 |
6BE0 7FE0 8A20 8F00 |
(3) |
14-15 | 5B1F8 | MGZ 2nd load cue | -Unknown -Unknown -MGZ signs -Diagonal spring |
19382E 19426C 19487C 15CBD2 |
6BE0 7FE0 8A20 8F00 |
(3) |
16-19 | 5B212 | CNZ 1st load cue | -Misc CNZ blocks -Bubbles -Lightbulb |
194AB6 15E1FC 195874 |
6A20 8B80 8600 |
(2) |
1A-1D | 5B226 | CNZ 2nd load cue | -Diagonal spring | 15CBD2 | 8740 | (0) |
1E-1F | 5B22E | ICZ 1st load cue | -Unknown -Diagonal spring -Button -Ice blocks -Unknown |
38FFE 15CBD2 15C900 171B0E 172732 |
D700 8740 8AC0 76C0 68C0 |
(4) |
20-21 | 5B24E | ICZ 2nd load cue | -Diagonal spring -Button -Ice blocks -Unknown -Bubbles |
15CBD2 15C900 171B0E 172BB4 15E1FC |
8740 8AC0 76C0 6EE0 8B80 |
(4) |
22-23 | 5B26E | LBZ 1st load cue | -Unknown -Unknown |
1959DE 1964FC |
7860 8AA0 |
(1) |
24 | 5B27C | LBZ 2nd load cue | -Unknown -Bubbles |
1959DE 15E1FC |
7860 8B80 |
(1) |
25 | 5B28A | Unknown | -Unknown | 196760 | 5D40 | (0) |
26-2D | 5B292 | Unknown | -Diagonal spring -Horizontal and vertical spikes |
15CBD2 15EFFC |
8740 9280 |
(1) |
2E-41 | 5B2A0 | Unknown | -Diagonal spring -Horizontal and vertical spikes |
15CBD2 15EFFC |
8740 9280 |
(1) |
42 | 5B2AE | Azure lake | -Unknown -Unknown -Unknown -Unknown -Unknown -Mini spring and spikes -Mini spring and button -Competition mode powerups |
14F5E2 1973F8 197BCA 197570 1980C4 196D10 196B9C 196F02 |
FC00 D780 E000 C000 EBC0 7220 75A0 78C0 |
(7) |
43 | 5B2E0 | Baloon park | -Unknown -Unknown -Unknown -Unknown -Unknown -Unknown -Mini spring and spikes -Mini spring and button -Competition mode powerups |
19815E 14F5E2 1973F8 197BCA 197570 1980C4 196D10 196B9C 196F02 |
6000 FC00 D780 E000 C000 EBC0 7220 75A0 78C0 |
(8) |
44 | 5B318 | Chrome gadget | -Unknown -Unknown -Unknown -Unknown -Unknown -Unknown -Mini spring and spikes -Mini spring and button -Competition mode powerups |
1989A8 14F5E2 1973F8 197BCA 197570 1980C4 196D10 196B9C 196F02 |
5000 FC00 D780 E000 C000 EBC0 7220 75A0 78C0 |
(8) |
45 | 5B350 | Desert palace | -Unknown -Unknown -Unknown -Unknown -Unknown -Unknown -Mini spring and spikes -Mini spring and button -Competition mode powerups |
1989A8 14F5E2 1973F8 197BCA 197570 1980C4 196D10 196B9C 196F02 |
5000 FC00 D780 E000 C000 EBC0 7220 75A0 78C0 |
(8) |
46 | 5B388 | Endless mine | -Unknown -Unknown -Unknown -Unknown -Unknown -Unknown -Mini spring and spikes -Mini spring and button -Competition mode powerups |
1989A8 14F5E2 1973F8 197BCA 197570 1980C4 196D10 196B9C 196F02 |
5000 FC00 D780 E000 C000 EBC0 7220 75A0 78C0 |
(8) |
47 | 5B3C0 | Dispencer bonus stage | -Dispencer -Horizontal springs and vertical spikes |
18AE2A 15EFFC |
2B60 9280 |
(1) |
48-5A | 5B3CE | AIZ act 1 boss | -Firebomber from AIZ -Bombs launched by firebomber -Explosion -Small explosion |
164BF2 1671A2 17FB50 17F800 |
8340 8E80 9040 9A40 |
(3) |
5B | 5B3E8 | Unknown | -Unknown -Small explosion |
168400 17F800 |
6080 A000 |
(1) |
5C-5D | 5B3F6 | Unknown | -Unknown -Small explosion |
16E548 17F800 |
A5C0 A000 |
(1) |
5E | 5B404 | Unknown | -Unknown -Egg prison -Small explosion -Squirrel -Bluebird |
1706B0 182180 17F800 15FDA6 15F9D4 |
A5C0 89C0 A000 85C0 8800 |
(4) |
5F | 5B424 | Unknown | -Unknown -Small explosion |
173CCC 17F800 |
9520 A000 |
(1) |
60 | 5B432 | Unknown | -Robotnic in main ship -Unknown |
18041E 1791DE |
A5C0 9AC0 |
(1) |
61-6A | 5B440 | FBZ act 2 mini boss | -Lazer boss from FBZ -Robotnic -More Robotnic stuff -Small explosion |
170C76 180BEC 181002 17F800 |
A5C0 8CC0 9520 A000 |
(3) |
6B | 5B45A | Unknown | -Robotnic in main ship -Small explosion |
18041E 17F800 |
A5C0 9A40 |
(1) |
6C | 5B468 | HCZ act 2 boss | -Water sprial -Robotnic in main ship -Small explosion -Egg prison |
16929E 18041E 17F800 182180 |
6400 A5C0 A000 9280 |
(3) |
6D | 5B482 | Unknown | -Robotnic in main ship -Small explosion -Egg prison |
18041E 17F800 182180 |
A5C0 A000 9280 |
(2) |
6E | 5B496 | Unknown | -Unknown -Robotnic in main ship -Small explosion -Egg prison |
16EA04 18041E 17F800 182180 |
8600 A5C0 A000 9280 |
(3) |
6F | 5B4B0 | FBZ act 2 boss | -FBZ act 2 boss -Robotnic's head -Other explosion -Robotnic in main ship -Small explosion -Egg prison |
171178 18097A 1800A2 18041E 17F800 182180 |
7C00 8200 8A80 A5C0 A000 9280 |
(5) |
70 | 5B4D6 | Unknown | -Unknown -Robotnic in main ship -Small explosion -Egg prison |
172F1E 18041E 17F800 182180 |
54C0 A5C0 A000 9280 |
(3) |
71 | 5B4F0 | Unknown | -Unknown -Small explosion |
17599C 17F800 |
7540 A000 |
(1) |
72-77 | 5B4FE | Unknown | -Robotnic in main ship -More Robotnic stuff -Small explosion |
18041E 181002 17F800 |
A5C0 9520 A000 |
(2) |
78-7B | 5B512 | Unknown | -Robotnic in main ship -Small explosion |
18041E 17F800 |
A5C0 A000 |
(1) |
his pointer list has an offset index to locate the correct cue. Go here for an explanation of how this works. Note that the number in parenthesis is the recorded number of requests in the cue. If a number follows it in brackets, it means the actual number that exists differs from the recorded one. This means any load requests past the recorded number were not being loaded, but still exist in the rom. Now, each load cue has a two byte value before it that specifies how many addresses are in the cue, to avoid it reading too far, and going into the next cue. This value is dead simple, just enter the number of patterns on the cue in hex between the first two bytes, but you have to count 00 as 1, so if there was 16 loading addresses in the cue, you'd have 000F preceding it. After that, there are 6 bytes per load request. The first four bytes are a pointer to the art block to use, and the two bytes after that are the location in the VRAM to load them into. To change the pattern load cue's being loaded for a level, you need to change the values in the main level load block. For more information on that go here.
Collision definitions
Ok, I'm going to explain how collision works on objects that are not sprites in the sonic games. First of all forget the image that the block contains. The image has absolutely nothing to do with the collision. There's basically in invisible collision box on top of every 16x16 block that sets what's solid and what's not. This collision box has two parts to it. The main part of it is the collision array (an array is basically a table of values). The collision array stores the actual data that says that is a block is solid in certain places. It does that through 16 bytes per collision box. To understand how those 16 bytes set what's solid, imagine a 16x16 block. Now imagine that 16x16 block with the numbers 1-10 (hex) down the side starting from the bottom and going up to the top, and starting from the left and going up as it moves right along the top, so that you can give an exact location of each pixel. (eg, the top left pixel would be 10,00) Now, in this array the first two bytes define what's solid for the row of pixels on the left side of that 16x16 block. Basically the first of those two bytes says where to start making things solid, and the second byte says where to stop making them solid. So if you entered the value 0010, the first row would be solid from the very bottom of the block all the way up to the top. If you were to enter the value 020E, there would be two pixels on either side of the block that are not solid, and everything in the middle would be. The next two bytes after that are for the next row, etc. After 16 bytes the definitions for the next collision box begin.
Now, to specify which blocks use which collision boxes, there are collision indexes, which give an array location for each 16x16 block. If you look at the space used by the collision array, you can divide that by 16 (the number of bytes used by each entry into the array) to give a one byte value, which represents the maximum number of collision boxes that the array can hold in the S3 platform, which is FF. Now, for each level there is at least one 16x16 collision index, and that index consists of a whole heap of array locations, one for each 16x16 block. If for example you wanted the 9th 16x16 block to use the collision box with an array location of 3E, you would give the 9th byte of the collision index for that level a value of 3E.
It is through collision indexes that the loops work in the game. It's commonly believed that there are layers, and that the sprite represented by 4 rings changes between them. This is partly true. For any levels that use multiple layers like that, there is a secondary 16x16 collision index. That object switches the 16x16 collision index in use. The pointers to these 16x16 collision indexes are stored at 4ADC-4B63. The first set of pointers in this group specify the location of the primary collision index to use for each level, and the second set specify the location of the secondary collision index to use for each level.
Now just setting something as solid, doesn't give it the effect of having a slope. There's an index in the rom, which has one byte in it for each collision array location. To understand how this value works, think of two lines running parallel to each other, both with the value 0-F along them. Now, the first value of the byte gives a point on the right line, and the second value gives a point on the left line. Now imagine drawing a line between these to points. If the points are different, the resulting gradient will be taken to create the effect of a slope and the resistance going up it on the box in the corresponding collision array location.
Level layout
In the S3 rom none of the level leyout's are compressed as such, but due to the nature of the way they're stored editing them is not nessicarily straightforward. Check the savestate hackng guide for information on how to edit the level layout.
Ring placement
The data for ring placement has an offset index to locate the correct group. Go here for an explanation of how this works. Now, in the rom each ring does not have to be stored individually. Instead you can place one ring, and specify that a certain number of rings come after it. The definitions for one ring takes up 4 bytes in the rom. Let's look at an example: 1234 5678 Now, in this example the ring will be placed at an x location of 1234, and a y location of 678. With that value where the 5 was entered, if the value entered is below 8, an additional ring will be placed next to the one before it for every unit that the value entered is above 0. Entering a value above 8 will place an additional ring below the one before it for each unit that the value entered is above 8. When specifying a position as the start of a group of rings, if the group is horizontal, the rings will go across to the right of that point, and if the group is vertical the rings will go down from that point. The value FFFF closes the group of ring locations, and it is essential that this is at the end of the ring locations list, or else the game will keep on reading past that point until it hits that value.
Sprite placement
Sprites are quite simple to define. It takes six bytes to define one sprite. The first two bytes are the x location of the sprite, and the next two bytes are the y location of the sprite. The 5th byte is the number on the sprite array to lookup to get the location for the function to use for the programming of that sprite, and the 6th byte is an optional declaration to use with the function for that sprite. Go here for more info on what exactly that means, and a list of all the sprites in the S3 rom.
Main level Block mappings
For information on exactly what the block mappings do, read the introduction. In the S3 rom, the 128x128 and 16x16 block mappings are compressed. Editing compressd data is extremely impractical, so in order to edit this data you will need to extract them first. Chaosax-extract is capable of decompressing this data.Once it's decompressed you can dit it just like in the savestate, so check the savestate section for further info on editing them. Once you've made the appropriate changes, you can use chaos-pack to recompress the data.
Uncompressed art
Any art that needs to be updated on the fly will not be compressed in the rom. This is because the game can't work with compressed data, and needs to extract any data it wants to use to the ram. This decompression process takes a fair bit of computation, and because of that it wouldn't be possible to create the appearance of a smooth animation using compressed data. The same reason is true as to why any data that is not loaded into the ram will always be uncompressed, because otherwise they would have to load it into the ram just to read it.
Now, for example all of the blocks for Sonic and Tails are uncompressed, because they of course need to be updated quickly. You can use basically any editing utility to edit them, but you can only change what each block looks like through this. In order to edit what blocks are placed where in each of Sonic's animation frames, you need to edit the mappings for them, and for more information on that go here. Now in their uncompressed form, you can edit them just like you would in the VRAM, so for more information on that check the sonic 2 savestate breakdown.
Sprite mapping format
Sprite mappings are what construct an image for a sprite out of the 8x8 blocks. This format has two parts to it, the image layout and the pattern reloading. The patern reloading is only applicable to sprites that are animated and have to reload uncompressed patterns from the rom, such as the playable characters. It is important to understand when dealing with sprite mappings that a single sprite may be made up of several sections. When dealing with mappings you can freely create, move, and resize these sections. Each one is independent of each other, and as such each on is defined seperately.
Each section has a maximum size of 4x4 units, each one capable of holding an 8x8 block. You cannot actually specify what block goes where within that box. You give it a VRAM location, and starting at the top and working it's way down the first vertical column, then moving across one and working it's way down again, it loads as many blocks from that point in the VRAM as it needs. Here's an explination of the two parts of the sprite mapping format: