Actions

SCHG

Difference between revisions of "Nem s3"

From Sonic Retro

Line 526: Line 526:
 
:::5AF84: AIZ act 1 128x128 block mappings (1ABC40) [00]
 
:::5AF84: AIZ act 1 128x128 block mappings (1ABC40) [00]
 
:::5AF88: AIZ act 1 128x128 block mappings (1ABC40) [00]
 
:::5AF88: AIZ act 1 128x128 block mappings (1ABC40) [00]
 +
 +
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 [[#Palletes|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 [[#Pattern_load_cue's|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:
 +
 +
{| border="1" align="center"
 +
| Index
 +
| Location
 +
| Name
 +
| Contents
 +
| Rom
 +
| Vram
 +
| Number
 +
|-
 +
| 00
 +
| 5B084
 +
| Unknown
 +
| -Sonic lives counter<br />-Ring and score/time/rings<br />-Points and starpoll<br />-Monitor
 +
| 15CEE6<br />15F2EC<br />15F528<br />15D2DE
 +
| FA80<br />D780<br />BC80<br />9880
 +
| (3)
 +
|-
 +
| 01
 +
| 5B09E
 +
| Unknown
 +
| -Sonic lives counter<br />-Monitor<br />-Ring and score/time/rings<br />-Points and starpoll
 +
| 15CEE6<br />15D2DE<br />15F2EC<br />15F528
 +
| FA80<br />9880<br />D780<br />BC80
 +
| (3)
 +
|-
 +
| 02
 +
| 5B0B8
 +
| Unknown
 +
| -Explosion<br />-Squirrel<br />-Bluebird
 +
| 15E6C0<br />15FDA6<br />15F9D4
 +
| B400<br />B000<br />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<br />-Mini spring and button<br />-Competition mode powerups
 +
| 196D10<br />196B9C<br />196F02
 +
| 7220<br />75A0<br />78C0
 +
| (2)
 +
|-
 +
| 07
 +
| 5B0F8
 +
| Unknown
 +
| -Tails lives counter<br />-Monitor<br />-Ring and score/time/rings<br />-Points and starpoll
 +
| 15CFFE<br />15D2DE<br />15F2EC<br />15F528
 +
| FA80<br />9880<br />D780<br />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<br />-Unknown<br />-Unknown<br />-Impact splash on water<br />-Bubbles from underwater<br />-Grass tiles
 +
| 18D8BC<br />18DA22<br />18DC90<br />18E4D8<br />15E1FC<br />18D586
 +
| 8360<br />6480<br />6660<br />79E0<br />8B80<br />7EE0
 +
| (5)
 +
|-
 +
| 0C-0D
 +
| 5B150
 +
| AIZ 2nd load cue
 +
| -Misc AIZ blocks<br />-Rope on flying fox<br />-Unknown<br />-Bubbles<br />-Button<br />-Unknown
 +
| 18E760<br />18D8BC<br />18DB46<br />15E1FC<br />15C900<br />18D72A
 +
| 5D20<br />8360<br />8700<br />8B80<br />8AC0<br />8800
 +
| (5)
 +
|-
 +
| 0E
 +
| 5B176
 +
| HCZ 1st load cue
 +
| -Bubbles<br />-Misc HCZ blocks<br />-Unknown<br />-Misc MCZ blocks<br />-Unknown<br />-Metal spikeball
 +
| 15E1FC<br />18FD88<br />18FCD4<br />190348<br />18FBB4<br />18FAEC
 +
| 8B80<br />7940<br />84C0<br />6F40<br />85C0<br />87C0
 +
| (5)
 +
|-
 +
| 0F
 +
| 5B19C
 +
| HCZ 2nd load cue
 +
| -Blowfly
 +
| 16A3E0
 +
| 8980
 +
| (0)
 +
|-
 +
| 10
 +
| 5B1A4
 +
| Unknown
 +
| -Bubbles<br />-Misc HCZ blocks<br />-Unknown<br />-Unknown<br />-Metal spikeball<br />-Sliding tube
 +
| 15E1FC<br />18FD88<br />18FCD4<br />18FBB4<br />18FAEC<br />191B36
 +
| 8B80<br />7940<br />84C0<br />85C0<br />87C0<br />6B80
 +
| (5)
 +
|-
 +
| 11
 +
| 5B1CA
 +
| Unknown
 +
| -Unknown<br />-HCZ bridge<br />-Blowfly
 +
| 193714<br />19204C<br />16A3E0
 +
| 6A00<br />0500<br />8980
 +
| (2)
 +
|-
 +
| 12-13
 +
| 5B1DE
 +
| MGZ 1st load cue
 +
| -Unknown<br />-Unknown<br />-MGZ signs<br />-Diagonal spring
 +
| 19382E<br />19426C<br />19487C<br />15CBD2
 +
| 6BE0<br />7FE0<br />8A20<br />8F00
 +
| (3)
 +
|-
 +
| 14-15
 +
| 5B1F8
 +
| MGZ 2nd load cue
 +
| -Unknown<br />-Unknown<br />-MGZ signs<br />-Diagonal spring
 +
| 19382E<br />19426C<br />19487C<br />15CBD2
 +
| 6BE0<br />7FE0<br />8A20<br />8F00
 +
| (3)
 +
|-
 +
| 16-19
 +
| 5B212
 +
| CNZ 1st load cue
 +
| -Misc CNZ blocks<br />-Bubbles<br />-Lightbulb
 +
| 194AB6<br />15E1FC<br />195874
 +
| 6A20<br />8B80<br />8600
 +
| (2)
 +
|-
 +
| 1A-1D
 +
| 5B226
 +
| CNZ 2nd load cue
 +
| -Diagonal spring
 +
| 15CBD2
 +
| 8740
 +
| (0)
 +
|-
 +
| 1E-1F
 +
| 5B22E
 +
| ICZ 1st load cue
 +
| -Unknown<br />-Diagonal spring<br />-Button<br />-Ice blocks<br />-Unknown
 +
| 38FFE<br />15CBD2<br />15C900<br />171B0E<br />172732
 +
| D700<br />8740<br />8AC0<br />76C0<br />68C0
 +
| (4)
 +
|-
 +
| 20-21
 +
| 5B24E
 +
| ICZ 2nd load cue
 +
| -Diagonal spring<br />-Button<br />-Ice blocks<br />-Unknown<br />-Bubbles
 +
| 15CBD2<br />15C900<br />171B0E<br />172BB4<br />15E1FC
 +
| 8740<br />8AC0<br />76C0<br />6EE0<br />8B80
 +
| (4)
 +
|-
 +
| 22-23
 +
| 5B26E
 +
| LBZ 1st load cue
 +
| -Unknown<br />-Unknown
 +
| 1959DE<br />1964FC
 +
| 7860<br />8AA0
 +
| (1)
 +
|-
 +
| 24
 +
| 5B27C
 +
| LBZ 2nd load cue
 +
| -Unknown<br />-Bubbles
 +
| 1959DE<br />15E1FC
 +
| 7860<br />8B80
 +
| (1)
 +
|-
 +
| 25
 +
| 5B28A
 +
| Unknown
 +
| -Unknown
 +
| 196760
 +
| 5D40
 +
| (0)
 +
|-
 +
| 26-2D
 +
| 5B292
 +
| Unknown
 +
| -Diagonal spring<br />-Horizontal and vertical spikes
 +
| 15CBD2<br />15EFFC
 +
| 8740<br />9280
 +
| (1)
 +
|-
 +
| 2E-41
 +
| 5B2A0
 +
| Unknown
 +
| -Diagonal spring<br />-Horizontal and vertical spikes
 +
| 15CBD2<br />15EFFC
 +
| 8740<br />9280
 +
| (1)
 +
|-
 +
| 42
 +
| 5B2AE
 +
| Azure lake
 +
| -Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Mini spring and spikes<br />-Mini spring and button<br />-Competition mode powerups
 +
| 14F5E2<br />1973F8<br />197BCA<br />197570<br />1980C4<br />196D10<br />196B9C<br />196F02
 +
| FC00<br />D780<br />E000<br />C000<br />EBC0<br />7220<br />75A0<br />78C0
 +
| (7)
 +
|-
 +
| 43
 +
| 5B2E0
 +
| Baloon park
 +
| -Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Mini spring and spikes<br />-Mini spring and button<br />-Competition mode powerups
 +
| 19815E<br />14F5E2<br />1973F8<br />197BCA<br />197570<br />1980C4<br />196D10<br />196B9C<br />196F02
 +
| 6000<br />FC00<br />D780<br />E000<br />C000<br />EBC0<br />7220<br />75A0<br />78C0
 +
| (8)
 +
|-
 +
| 44
 +
| 5B318
 +
| Chrome gadget
 +
| -Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Mini spring and spikes<br />-Mini spring and button<br />-Competition mode powerups
 +
| 1989A8<br />14F5E2<br />1973F8<br />197BCA<br />197570<br />1980C4<br />196D10<br />196B9C<br />196F02
 +
| 5000<br />FC00<br />D780<br />E000<br />C000<br />EBC0<br />7220<br />75A0<br />78C0
 +
| (8)
 +
|-
 +
| 45
 +
| 5B350
 +
| Desert palace
 +
| -Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Mini spring and spikes<br />-Mini spring and button<br />-Competition mode powerups
 +
| 1989A8<br />14F5E2<br />1973F8<br />197BCA<br />197570<br />1980C4<br />196D10<br />196B9C<br />196F02
 +
| 5000<br />FC00<br />D780<br />E000<br />C000<br />EBC0<br />7220<br />75A0<br />78C0
 +
| (8)
 +
|-
 +
| 46
 +
| 5B388
 +
| Endless mine
 +
| -Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Unknown<br />-Mini spring and spikes<br />-Mini spring and button<br />-Competition mode powerups
 +
| 1989A8<br />14F5E2<br />1973F8<br />197BCA<br />197570<br />1980C4<br />196D10<br />196B9C<br />196F02
 +
| 5000<br />FC00<br />D780<br />E000<br />C000<br />EBC0<br />7220<br />75A0<br />78C0
 +
| (8)
 +
|-
 +
| 47
 +
| 5B3C0
 +
| Dispencer bonus stage
 +
| -Dispencer<br />-Horizontal springs and vertical spikes
 +
| 18AE2A<br />15EFFC
 +
| 2B60<br />9280
 +
| (1)
 +
|-
 +
| 48-5A
 +
| 5B3CE
 +
| AIZ act 1 boss
 +
| -Firebomber from AIZ<br />-Bombs launched by firebomber<br />-Explosion<br />-Small explosion
 +
| 164BF2<br />1671A2<br />17FB50<br />17F800
 +
| 8340<br />8E80<br />9040<br />9A40
 +
| (3)
 +
|-
 +
| 5B
 +
| 5B3E8
 +
| Unknown
 +
| -Unknown<br />-Small explosion
 +
| 168400<br />17F800
 +
| 6080<br />A000
 +
| (1)
 +
|-
 +
| 5C-5D
 +
| 5B3F6
 +
| Unknown
 +
| -Unknown<br />-Small explosion
 +
| 16E548<br />17F800
 +
| A5C0<br />A000
 +
| (1)
 +
|-
 +
| 5E
 +
| 5B404
 +
| Unknown
 +
| -Unknown<br />-Egg prison<br />-Small explosion<br />-Squirrel<br />-Bluebird
 +
| 1706B0<br />182180<br />17F800<br />15FDA6<br />15F9D4
 +
| A5C0<br />89C0<br />A000<br />85C0<br />8800
 +
| (4)
 +
|-
 +
| 5F
 +
| 5B424
 +
| Unknown
 +
| -Unknown<br />-Small explosion
 +
| 173CCC<br />17F800
 +
| 9520<br />A000
 +
| (1)
 +
|-
 +
| 60
 +
| 5B432
 +
| Unknown
 +
| -Robotnic in main ship<br />-Unknown
 +
| 18041E<br />1791DE
 +
| A5C0<br />9AC0
 +
| (1)
 +
|-
 +
| 61-6A
 +
| 5B440
 +
| FBZ act 2 mini boss
 +
| -Lazer boss from FBZ<br />-Robotnic<br />-More Robotnic stuff<br />-Small explosion
 +
| 170C76<br />180BEC<br />181002<br />17F800
 +
| A5C0<br />8CC0<br />9520<br />A000
 +
| (3)
 +
|-
 +
| 6B
 +
| 5B45A
 +
| Unknown
 +
| -Robotnic in main ship<br />-Small explosion
 +
| 18041E<br />17F800
 +
| A5C0<br />9A40
 +
| (1)
 +
|-
 +
| 6C
 +
| 5B468
 +
| HCZ act 2 boss
 +
| -Water sprial<br />-Robotnic in main ship<br />-Small explosion<br />-Egg prison
 +
| 16929E<br />18041E<br />17F800<br />182180
 +
| 6400<br />A5C0<br />A000<br />9280
 +
| (3)
 +
|-
 +
| 6D
 +
| 5B482
 +
| Unknown
 +
| -Robotnic in main ship<br />-Small explosion<br />-Egg prison
 +
| 18041E<br />17F800<br />182180
 +
| A5C0<br />A000<br />9280
 +
| (2)
 +
|-
 +
| 6E
 +
| 5B496
 +
| Unknown
 +
| -Unknown<br />-Robotnic in main ship<br />-Small explosion<br />-Egg prison
 +
| 16EA04<br />18041E<br />17F800<br />182180
 +
| 8600<br />A5C0<br />A000<br />9280
 +
| (3)
 +
|-
 +
| 6F
 +
| 5B4B0
 +
| FBZ act 2 boss
 +
| -FBZ act 2 boss<br />-Robotnic's head<br />-Other explosion<br />-Robotnic in main ship<br />-Small explosion<br />-Egg prison
 +
| 171178<br />18097A<br />1800A2<br />18041E<br />17F800<br />182180
 +
| 7C00<br />8200<br />8A80<br />A5C0<br />A000<br />9280
 +
| (5)
 +
|-
 +
| 70
 +
| 5B4D6
 +
| Unknown
 +
| -Unknown<br />-Robotnic in main ship<br />-Small explosion<br />-Egg prison
 +
| 172F1E<br />18041E<br />17F800<br />182180
 +
| 54C0<br />A5C0<br />A000<br />9280
 +
| (3)
 +
|-
 +
| 71
 +
| 5B4F0
 +
| Unknown
 +
| -Unknown<br />-Small explosion
 +
| 17599C<br />17F800
 +
| 7540<br />A000
 +
| (1)
 +
|-
 +
| 72-77
 +
| 5B4FE
 +
| Unknown
 +
| -Robotnic in main ship<br />-More Robotnic stuff<br />-Small explosion
 +
| 18041E<br />181002<br />17F800
 +
| A5C0<br />9520<br />A000
 +
| (2)
 +
|-
 +
| 78-7B
 +
| 5B512
 +
| Unknown
 +
| -Robotnic in main ship<br />-Small explosion
 +
| 18041E<br />17F800
 +
| A5C0<br />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:

Revision as of 15:57, 4 September 2006

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]


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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]

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: