IPB

Welcome Guest ( Log In | Register )


 

Recent Changes | Random | Help | Special Pages | Upload
home | info | forums | svn | irc | podcast | about

SCHG:Nem s2b

From Sonic Retro

Contents

Introduction

Here are my hacking notes on the Sonic 2 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 2 beta:

00Emerald Hill zone
02Wood zone
04Metropolis zone
05Metropolis zone act 3
07Hill Top zone
08Hidden Palace zone
0AOil Ocean zone
0BDust Hill zone
0CCasino Night zone
0DChemical Plant zone
0EGenocide City zone
0FNeo Green Hill zone
10Death Egg zone


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 20000. 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.

To indicate sections containing leftover data from previous builds, a colour coding system is in place. The address value for a block of data will be coloured if that block of data is from a previous build. Different colours are used to indicate layering of this data. Red is the first layer, green is the second, blue is the third, yellow is the fourth, and pink is the fifth. This is not to indicate the build that a block of data belongs to, so it doesn't mean that all lost data that's coloured in red is from the same build. In many cases, it's impossible to relate any two blocks of data from different sections to each other.

Also, any patterns that are not used anywhere in the game will be preceeded by this red dot image:Reddot.gif. Patterns located in sections of lost data will not be marked in this way however.

0-FFVector table
100-200Header
15FA-????Programming to do wih decompression of art tiles to VRAMCompiled
5E8-B07Standard numbers/symbolsUncompressed
Further info
2264-24A1Unknown palettesFurther info
2516-2595Unknown paletteFurther info
28A6-28E1Unknown paletteFurther info
294E-2A15Palette pointersFurther info
2A16SEGA screen palette (00)Further info
2A96Title screen palette (01)Further info
2B16Level select palette (02)Further info
2B96Primary palette line (03)Further info
2BB6EHZ level palette (04, 05, 07, 0D, 12, 14)Further info
2C16WZ level palette (06)Further info
2C76MTZ level palette (08, 09)Further info
2CD6HTZ level palette (0B)Further info
2D36HPZ level palette (0C)Further info
2D96HPZ underwater palette (15)Further info
2E16OOZ level palette (0E)Further info
2E76MCZ level palette (0F)Further info
2ED6CNZ level palette (10)Further info
2F3606 level palette (0A)Further info
2F96CPZ level palette (11)Further info
2FF6CPZ underwater palette (15)Further info
3076ARZ level palette (13)Further info
30D6ARZ underwater palette (16)Further info
3156Sonic 1 special stage palette (17)Further info
3AD4-3B07Level select level orderFurther info
4140-4150Music playlist for levelsFurther info
4AAA-4ADBFunction to load collision index into ramCompiled
4ADC-4B63Pointers to collision indexesFurther info
5986-5A95Level size arrayFurther info
5A96-5B01Code for initial character and screen placementCompiled
5B02-5B89Character start location arrayFurther info
5E16-5E37Offset index of rasterised layer deformationFurther info
5E38Title screen layer deformation infoFurther info
5E5CEHZ layer deformation infoFurther info
5F60EHZ 2 player splitscreen layer deformation infoFurther info
6098WZ layer deformation infoFurther info
60D0MTZ layer deformation infoFurther info
6108HTZ layer deformation infoFurther info
6236Unknown layer deformation info (foreground free moving, background fixed)Further info
62B4Unknown layer deformation info (splitscreen, background fixed vertically, no deformation)Further info
6344HPZ layer deformation infoFurther info
640AOOZ layer deformation infoFurther info
6442MCZ layer deformation infoFurther info
6554Unknown layer deformation info (splitscreen, background fixed horizontally, no deformation)Further info
67AECNZ layer deformation infoFurther info
67F2Unknown layer deformation info (splitscreen, background fixed vertically, no deformation)Further info
687CCPZ layer deformation infoFurther info
6982ARZ layer deformation infoFurther info
6A7001, 03, 06, 09, 0E, 10 layer deformation infoFurther info
7FDCBridge (sprite)
85F8??????? (sprite)
8B9C??????? (sprite)
8D38Fixed large platform from CPZ (sprite)
9128Collapsing platform from OOZ (sprite)
9274Breakaway platform made up of small blocks from MZ in S1 (sprite)
999C??????? (sprite)
9A54??????? (sprite)
9C0C??????? (sprite)
9CE2??????? (sprite)
A012??????? (sprite)
A086Explosion giving off 100 points and an animal (sprite)
A11ERed explosion (sprite)
A2B0??????? (sprite)
A7C0100 points (sprite)
AC28??????? (sprite)
AD62Ring spray (sprite)
B29C??????? (sprite)
B46AContents of computer monitor flying up (sprite)
B7B4??????? (sprite)
B83A??????? (sprite)
BB54??????? (sprite)
BD76Game over text (sprite)
BE38??????? (sprite)
BF9A-BFDDMain game level orderFurther info
C944Spikes (sprite)
CD00Unknown (a block)
CD7C??????? (sprite)
D01A-D249Sprite programming pointersFurther info
D24A??????? (sprite)
E7B8Horizontal red spring (sprite)
F10C??????? (sprite)
F1F4Signpost (sprite)
FC48Sonic (sprite)
10E38Tails (sprite)
11F96??????? (sprite)
1207C??????? (sprite)
125CE??????? (sprite)
1264E??????? (sprite)
12B42??????? (sprite)
13B54Starpoll (sprite)
13DFC??????? (sprite)
144B0??????? (sprite)
148AC??????? (sprite)
149FC??????? (sprite)
14AFC??????? (sprite)
14B78??????? (sprite)
15090??????? (sprite)
15352??????? (sprite)
155A0??????? (sprite)
1561A??????? (sprite)
1572C??????? (sprite)
15B8CSee-saw (sprite)
1600CDiagnally moving and falling platform from HTZ (sprite)
1621CLarge platform from CPZ moving from side to side (sprite)
16468Boosters from CPZ (sprite)
165B0??????? (sprite)
16724Spin-tube from CPZ (sprite)
17174??????? (sprite)
1747C??????? (sprite)
1768ACap on top of spin tubes in CPZ (sprite)
17A4C??????? (sprite)
17CA0Platform on top of oil burners from OOZ (sprite)
17F0CSpikeball from OOZ (sprite)
180D0??????? (sprite)
181A0Weird spring that you push back on from OOZ (sprite)
18ABEBall on weird spring from OOZ (sprite)
18D9CButton (sprite)
18E78Block that propells sonic when he busts it from OOZ (sprite)
19250Spinball that shoots character out 90 degrees from entry from OOZ (sprite)
19660Arrow shooter from ARZ (sprite)
19850Piller that drops lower half in ARZ (sprite)
19A1ERaising pillar from ARZ (sprite)
1A0C4??????? (sprite)
1A30CWeird spring from ARZ and CPZ (sprite)
1A5CCSteam vent from MTZ (sprite)
1A8B4??????? (sprite)
1AA74??????? (sprite)
1AEBC??????? (sprite)
1B0C4Warp tube from MTZ (sprite)
1B520Block in MTZ with a spike coming out each side sequentially (sprite)
1B810Nut that character moves by running on in MTZ (sprite)
1BA30??????? (sprite)
1BCEC??????? (sprite)
1BF6C??????? (sprite)
1B720Floor spike in MTZ (sprite)
1C2E4Platform moving in circle (sprite)
1C4F8Diagnally moving platform from MTZ (sprite)
1C850??????? (sprite)
1CBCC??????? (sprite)
1CC54??????? (sprite)
1CE48??????? (sprite)
1D078Moving spikey arm from MCZ (sprite)
1D208??????? (sprite)
1D3C0Lowering stairs from CPZ (sprite)
1D594??????? (sprite)
1D74CSpring on spin tube cap from CPZ (sprite)
1D984Driving badnick from EHZ (sprite)
1DC54??????? (sprite)
1DEACBubble enemy (sprite)
1E010??????? (sprite)
1E62C??????? (sprite)
1E89CBuzz bomber (sprite)
1EBB8Octopus badnick from OOZ (sprite)
1EE68Bat (sprite)
1F2F0Alligator (sprite)
1F5E8Jumping fish from EHZ (sprite)
1F6E8??????? (sprite)
1F99C??????? (sprite)
1FC0A??????? (sprite)
2030C??????? (sprite)
205A6??????? (sprite)
20740??????? (sprite)
20E5C??????? (sprite)
21D40??????? (sprite)
223E2??????? (sprite)
22408Offset index of animated pattern and dynamic pattern load cue'sDouble offset
Further info
2244C01/WZ/03/06/09/MCZ/CNZ/GCZ/DEZ dynamic pattern load cueFurther info
2244EHTZ dynamic pattern load cueFurther info
22630EHZ/HPZ/MTZ/OOZ/CPZ/ARZ dynamic pattern load cueFurther info
22698EHZ animated pattern load cue (4)Further info
226FCMTZ animated pattern load cue (5)Further info
22754HTZ animated pattern load cue (4)Further info
227B8HPZ animated pattern load cue (2)Further info
227E4OOZ animated pattern load cue (4)Further info
2282ACPZ animated pattern load cue (0)Further info
2286601/WZ/03/06/09/MCZ/CNZ/GCZ/DEZ animated pattern load cue (empty)Further info
229A2Offset index of misc sprite definitionsFurther info
229C4EHZ/HTZ misc sprite definitionsFurther info
22A40MTZ misc sprite definitionsFurther info
22B14HPZ misc sprite definitionsFurther info
22C08OOZ misc sprite definitionsFurther info
22C6CCNZ misc sprite definitionsFurther info
22D10CPZ misc sprite definitionsFurther info
22D1CARZ misc sprite definitionsFurther info
22D6001/WZ/03/06/09/MCZ/GCZ/DEZ misc sprite definitionsFurther info
22DFCOnscreen display (lives/score/time/rings) (sprite)
23448-23B67Large and small numbers used in gameUncompressed
Further info
23DBEOffset index of object debug listsFurther info
23DE001/WZ/03/06/09/GCZ/DEZ object debug listFurther info
23DF2EHZ object debug listFurther info
23ECCMTZ object debug listFurther info
23FAEHTZ object debug listFurther info
24078HPZ object debug listFurther info
240F2OOZ object debug listFurther info
24194MCZ object debug listFurther info
24216CNZ object debug listFurther info
24228CPZ object debug listFurther info
242C2ARZ object debug listFurther info
24354Indexed main level load blockFurther info
24420Offset index of pattern load cue'sFurther info
2447APattern load cue'sFurther info
24804Lost pattern load cue's from previous compilationFurther info
24A30Leftover data from previous build
28000Animated cone shaped flower from EHZ and HTZUncompressed
Further info
28080Animated bubble like flower from EHZ and HTZUncompressed
Further info
28100Animated stringy flower from EHZ and HTZUncompressed
Further info
28180Animated leafy flower from EHZ and HTZUncompressed
Further info
28200Animated pulsing thing against checkered background in EHZUncompressed
Further info
28300Hills in background from HTZArt compression
192 blocks
28C2AClouds in background of HTZUncompressed
Further info
2902ASpinning metal cylinder from MTZUncompressed
Further info
2A02ALava patterns from EHZ and MTZUncompressed
Further info
2A62AAnimated section of MTZ backgroundUncompressed
Further info
2A86AHorizontal and vertical rotating screwUncompressed
Further info
2B06AWeird peice of alpha HPZ backgroundUncompressed
Further info
2B46AGiant pulsing ball in HPZUncompressed
Further info
2B76ATiny pulsing ball in OOZUncompressed
Further info
2B94ASquare rotating around ball in OOZUncompressed
Further info
2BD4AOil in OOZUncompressed
Further info
2CCEAAnimated background section from CPZ and DEZUncompressed
Further info
2CEEAWaterfall patterns from ARZUncompressed
Further info
2D1EACurve and resistance mappingFurther info
2D2EACollision arrayFurther info
2F2EAEHZ and HTZ primary 16x16 collision indexFurther info
2F5EAEHZ and HTZ secondary 16x16 collision indexFurther info
2F8EAWZ primary 16x16 collision indexFurther info
2FBEAMTZ primary 16x16 collision indexFurther info
2FEEAHPZ primary 16x16 collision indexFurther info
301EAHPZ secondary 16x16 collision indexFurther info
304EAOOZ primary 16x16 collision indexFurther info
307EADHZ primary 16x16 collision indexFurther info
30AEACNZ primary 16x16 collision indexFurther info
30DEACNZ secondary 16x16 collision indexFurther info
310EACPZ primary 16x16 collision indexFurther info
313EACPZ secondary 16x16 collision indexFurther info
316EAARZ primary 16x16 collision indexFurther info
319EAARZ secondary 16x16 collision indexFurther info
31CEA-3334D????????? (something to do with special stage)
3334ELevel layout offset indexUnique offset
Further info
333D6EHZ act 1 foregroundFurther info
33BD8EHZ act 2 foregroundFurther info
343DAEHZ act 1/2 backgroundFurther info
343E401 act 1/2 foreground/backgroundFurther info
343E8WZ act 1 foregroundFurther info
34BEAWZ act 2 foregroundFurther info
353ECWZ act 1 backgroundFurther info
35BEEWZ act 2 backgroundFurther info
363F003 act 1/2 foreground/backgroundFurther info
363F4MTZ act 1 foregroundFurther info
36BF6MTZ act 2 foregroundFurther info
373F8MTZ act 1/2/3 backgroundFurther info
3741EMTZ act 3 foregroundFurther info
37C2006 act 1/2 foreground/backgroundFurther info
37C24HTZ act 1 foregroundFurther info
38426HTZ act 2 foregroundFurther info
38C28HTZ act 1 backgroundFurther info
3942AHTZ act 2 backgroundFurther info
39C2CHPZ act 1/2 foregroundFurther info
3A42EHPZ act 1/2 backgroundFurther info
3A47809 act 1/2 foreground/backgroundFurther info
3A47COOZ act 1 foregroundFurther info
3AC7EOOZ act 2 foregroundFurther info
3B480OOZ act 1/2 foreground/backgroundFurther info
3B49ADHZ act 1 foregroundFurther info
3BC9CDHZ act 2 foregroundFurther info
3C49EDHZ act 1/2 backgroundFurther info
3C4B0CNZ act 1 foregroundFurther info
3CCB2CNZ act 2 foregroundFurther info
3D4B4CNZ act 1 backgroundFurther info
3DCB6CNZ act 2 backgroundFurther info
3DCC0CPZ act 1 foregroundFurther info
3E4C2CPZ act 2 foregroundFurther info
3ECC4CPZ act 1 foregroundFurther info
3ECF0GCZ act 1/2 foreground/backgroundFurther info
3ECF4ARZ act 1 foregroundFurther info
3F4F6ARZ act 2 foregroundFurther info
3FCF8ARZ act 1 backgroundFurther info
404FAARZ act 2 backgroundFurther info
40CFCDEZ act 1/2 foreground/backgroundFurther info
40D00Giant golden ringUncompressed
Further info
41940Blank space
42B7AGiant golden ring... again (uncompressed)
437BCVery end of palette
437C6??????????
44000Offset index of sprite locationsFurther info
4404AEHZ act 1 sprite locationsFurther info
442C6EHZ act 2 sprite locationsFurther info
445C0MTZ act 1 sprite locationsFurther info
4488AMTZ act 2 sprite locationsFurther info
44B30MTZ act 3 sprite locationsFurther info
44EFCHTZ act 1 sprite locationsFurther info
45130HTZ act 2 sprite locationsFurther info
4554AHPZ act 1 sprite locationsFurther info
45652HPZ act 2 sprite locations (empty)Further info
45658Unknown (empty)Further info
4565EOOZ act 1 sprite locationsFurther info
457C0OOZ act 2 sprite locationsFurther info
459ACDHZ act 1 sprite locationsFurther info
45A24DHZ act 2 sprite locationsFurther info
45A2ACPZ act 1 sprite locationsFurther info
45CC4CPZ act 2 sprite locationsFurther info
4605AARZ act 1 sprite locationsFurther info
46216ARZ act 1 sprite locationsFurther info
4634801, WZ, 03, 06, 09, CNZ, GCZ, DEZ sprite locations (empty)Further info
4634E??????????
474ACLost pallette
4760C??????????
48000Offset index of ring locationsFurther info
48044EHZ act 1 ring locationsFurther info
481DEEHZ act 2 ring locationsFurther info
483DC01 act 1 ring locations (empty)Further info
483DE01 act 2 ring locations (empty)Further info
483E0WZ act 1 ring locations (empty)Further info
483E2WZ act 2 ring locations (empty)Further info
483E403 act 1 ring locations (empty)Further info
483E603 act 2 ring locations (empty)Further info
483E8MTZ act 1 ring locations (empty)Further info
483EAMTZ act 2 ring locations (empty)Further info
483ECMTZ act 3 ring locations (empty)Further info
483EEMTZ act 4 ring locations (empty)Further info
483F006 act 1 ring locations (empty)Further info
483F206 act 2 ring locations (empty)Further info
483F4HTZ act 1 ring locationsFurther info
484EAHTZ act 2 ring locationsFurther info
48654HPZ act 1 ring locationsFurther info
487C6HPZ act 2 ring locations (empty)Further info
487C809 act 1 ring locations (empty)Further info
487CA09 act 2 ring locations (empty)Further info
487CCOOZ act 1 ring locationsFurther info
4889EOOZ act 2 ring locationsFurther info
48968DHZ act 1 ring locations (empty)Further info
4896ADHZ act 2 ring locations (empty)Further info
4896CCNZ act 1 ring locations (empty)Further info
4896ECNZ act 2 ring locations (empty)Further info
48970CPZ act 1 ring locationsFurther info
48A3ECPZ act 2 ring locationsFurther info
48B94GCZ act 1 ring locations (empty)Further info
48B96GCZ act 2 ring locations (empty)Further info
48B98ARZ act 1 ring locationsFurther info
48C76ARZ act 2 ring locationsFurther info
48DB0DEZ act 1 ring locations (empty)Further info
48DB2DEZ act 2 ring locations (empty)Further info
48DB4??????????
4B76CRock splashing into liquid (uncompressed)
4BAACLost pallette
4BC4C??????????
4E54AGrains of sand falling (uncompressed)
4E86AFire in bowl against stone background (uncompressed)
4EC6AData block acting as seperator
4EE00?????????? (uncompressed data blocks with massive repetition)
4FB98Data block acting as seperator
50000Patterns for SonicUncompressed
Further info
614C0Unknown offset indexFurther info
6160EUnknown (Something to do with mappings for Sonic)Further info
62598Patterns for TailsUncompressed
Further info
6DA4CUnknown offset indexFurther info
6DB9AUnknown (Something to do with mappings for Sonic)Further info
6DF8EPatterns for bubbleArt compression
32 blocks
6E114Stars from invincibilityArt compression
00, 34 blocks
6E1F6Patterns for smoke trails, dust, and splash in waterUncompressed
Further info
6FB3CUnknown offset indexFurther info
6FC46Unknown (Something to do with mappings for Tails)Further info
7056EUnknown offset indexFurther info
70678Unknown (Something to do with mappings for Tails)Further info
70960SEGA patternsArt compression
125 blocks
71520Title patternsArt compression
396 blocks
72E82Sonic patterns in title screenArt compression
193 blocks
739C6Fireballs from HTZ and WZArt compression
20 blocks
73B3CSome waterfll tiles form WZArt compression
24 blocks
73C42Another fireball from HTZArt compression
00, 16 blocks
73D90Peices of bridge from EHZArt compression
00, 8 blocks
73E68Flying fox system in HTZArt compression
48 blocks
7415COne way barrier from HTZArt compression
4 blocks
741D4See-saw from HTZArt compression
24 blocks
image:Reddot.gif7436CFireballArt compression
18 blocks
7447ARock from HTZArt compression
20 blocks
745B0badnick from HTZ with balls of flame spinning around him that he shoots at youArt compression
4 blocks
7461CSpinning grey wheel from MTZArt compression
120 blocks
74A74A ball shaped thing from MTZ patternsArt compression
9 blocks
74B1CSpear block from MTZArt compression
00, 8 blocks
74BEASteam from MTZArt compression
00, 15 blocks
74CF4Spike from MTZArt compression
00, 8 blocks
74DB6Unknown. Some similar shaded blocksArt compression
54 blocks
74E2CLava bubble from MTZArt compression
00, 9 blocks
74EE2Something from MTZ patternsArt compression
4 blocks
74F52Unknown. A block of some kind.Art compression
32 blocks
751FEStuff from MTZArt compression
8 blocks
752A0Mini rotating cog from MTZArt compression
12 blocks
75382Four blocks from MTZ tiles. All of the blocks are just one colourArt compression
00, 04 blocks
7538EBridge from HPZArt compression
21 blocks
75506Waterfall tiles for HPZArt compression
53 blocks
75868The master emeraldArt compression
32 blocks
75ADAPlatform thing from HPZArt compression
16 blocks
75B9APulsing light thing from HPZArt compression
34 blocks
75DD6Another platform thing from HPZ and those green blocksArt compression
22 blocks
75F70Patterns from raising platform in OOZArt compression
12 blocks
76060Spikeball thing from OOZArt compression
00, 32 blocks
76258Patterns for stuff in OOZArt compression
6 blocks
762EESome striped patterns from OOZArt compression
4 blocks
7635AOil patterns from OOZArt compression
16 blocks
764D6Some blocks of oil and stuff from OOZArt compression
14 blocks
76602Unknown. Damn I wish I could make this out, because it looks quite interesting.Art compression
20 blocks
76722Unknown. Ditto.Art compression
53 blocks
76A12Unknown. Whatever they are, they look OOZ style.Art compression
40 blocks
76CA6Unknown. Also look OOZ in style.Art compression
30 blocks
76E68Swinging platform from OOZArt compression
28 blocks
7708AWooden box from MCZArt compression
32 blocks
772C8Collapsing platform from MCZArt compression
00, 26 blocks
77472Vines around switch you pull on from MCZArt compression
16 blocks
7756AVines from MCZArt compression
10 blocks
77614A side on view of a log from WZ I suspect.Art compression
00, 4 blocks
77684Big moving platform in CPZArt compression
00, 16 blocks
777D2Surface of water from HPZ and CPZArt compression
00, 24 blocks
77942Unknown. It looks like a small cylinder kinda.Art compression
00, 4 blocks
779AABlue ball for enemy in CPZArt compression
00, 4 blocks
77A1CCPZ metal stuffArt compression
33 blocks
77C26Some blocks from CPZArt compression
4 blocks
77C66Some diagnally striped blocks from CPZArt compression
8 blocks
77CD2Little yellow moving platform from CPZArt compression
48 blocks
77EB4Block from CPZ, but with something else as well.Art compression
24 blocks
78074Spring on top of pipe from CPZ, and something else further down.Art compression
32 blocks
78270Top of water from ARZArt compression
00, 16 blocks
78356Leaves from ARZArt compression
00, 7 blocks
783E2Arrow and arrow shooter from ARZArt compression
00, 17 blocks
78540Splash from ARZArt compression
00, 4 blocks
78580ButtonArt compression
16 blocks
78658Vertical red springArt compression
00, 20 blocks
78774Horizontal red springArt compression
12 blocks
7883EDiagonal springArt compression
32 blocks
78A12Score, rings, time patternsArt compression
24 blocks
78B1ASonic lives counterArt compression
12 blocks
78C30Ring patternsArt compression
00, 14 blocks
78D24Monitor patternsArt compression
60 blocks
7914ESpikesArt compression
8 blocks
7919ENumbersArt compression
18 blocks
79278Beta starpollArt compression
10 blocks
7931ESignpost for end of levelArt compression
82 blocks
798F4Weird spring from CPZ and ARZArt compression
00, 28 blocks
79A44Long horizontal spikeArt compression
00, 8 blocks
79AC0Bubbles and numbers that count down when underwaterArt compression
00, 116 blocks
image:Reddot.gif7A11ACrocodileArt compression
00, 44 blocks
7A4BCBuzz bomberArt compression
00, 28 blocks
7A6A2Bat from HPZArt compression
00, 58 blocks
image:Reddot.gif7A9F8Octopus from OOZArt compression
00, 58 blocks
image:Reddot.gif7AD18RhinobotArt compression
00, 5 blocks
7B114DinobotArt compression
00, 48 blocks
image:Reddot.gif7B4EAPirhanaArt compression
00, 64 blocks
image:Reddot.gif7B9E2Seahorse from OOZArt compression
00, 62 blocks
image:Reddot.gif7BE30Spinning ball thingyArt compression
00, 27 blocks
image:Reddot.gif7C0C6BlinkyArt compression
24 blocks
image:Reddot.gif7C2F2Bubble monsterArt compression
00, 24 blocks
7C514Ground based badnick from EHZArt compression
26 blocks
image:Reddot.gif7C710Bouncer badnick from CNZArt compression
00, 42 blocks
7CA92Fish badnick from EHZArt compression
22 blocks
7CC9ERobotnic and his main shipArt compression
96 blocks
image:Reddot.gif7D3DACPZ bossArt compression
111 blocks
7D938Some kind of large explosionArt compression
00, 100 blocks
7DFC0A small explosionArt compression
00, 8 blocks
7E03ESome kind of trailing smokeArt compression
00, 16 blocks
7E124EHZ bossArt compression
128 blocks
7E910Chopper blades for EHZ bossArt compression
00, 20 blocks
7EA04Title card patterns for levelsArt compression
128 blocks
7F012Regular in level explosionArt compression
96 blocks
7F678Game/time over tilesArt compression
34 blocks
image:Reddot.gif7F80AVertical spring from S1Art compression
00, 16 blocks
image:Reddot.gif7F90CHorizontal spring from S1Art compression
14 blocks
image:Reddot.gif7F9E8Flash from entering giant ringArt compression
84 blocks
image:Reddot.gif7FB5CHidden end of level bonus pointsArt compression
00, 36 blocks
image:Reddot.gif7FE5EPatterns for continue screen from S1Art compression
37 blocks
image:Reddot.gif8010EPatterns for recieveing continue at end of special stage from S1Art compression
30 blocks
80348RabbitArt compression
00, 18 blocks
804A0White birdArt compression
14 blocks
805FCBlack birdArt compression
00, 18 blocks
80778SealArt compression
00, 14 blocks
80894PigArt compression
18 blocks
809CABlue birdArt compression
00, 14 blocks
80B04BearArt compression
00, 18 blocks
80C6016x16 block mappings for EHZFurther info
81C00EHZ/HTZ main level patternsArt compression
912 blocks
84A5016x16 block mappings for HTZ suppliment on EHZ tilesFurther info
85200HTZ pattern suppliment to EHZ level patternsArt compression
386 blocks
86626Initial blocks for dynamically reloaded and animated patterns in HTZArt compression
46 blocks
8692EEHZ/HTZ 128x128 block mappingsCompressed
Further info
89B8EWZ 16x16 block mappingsFurther info
8AB2EWZ main level patternsArt compression
798 blocks
8E826WZ 128x128 block mappingsCompressed
Further info
90456MTZ 16x16 block mappingsFurther info
91716MTZ main level patternsArt compression
783 blocks
94C56MTZ 128x128 block mappingsCompressed
Further info
97596HPZ 16x16 block mappingsFurther info
98B76HPZ main level patternsArt compression
725 blocks
9B9F8HPZ 128x128 block mappingsCompressed
Further info
9D778OOZ 16x16 block mappingsFurther info
9ED58OOZ main level patternsArt compression
693 blocks
A1A58OOZ 128x128 block mappingsCompressed
Further info
A3F88MCZ 16x16 block mappingsFurther info
A5248MCZ main level patternsArt compression
936 blocks
A8B6AMCZ 128x128 block mappingsCompressed
Further info
AB5CACNZ 16x16 block mappingsFurther info
ABF2ACNZ main level patternsArt compression
850 blocks
AE746Leftover data from previous build
AEF3CSome blocks from CNZArt compression
22 blocks
AF026CNZ 128x128 block mappingsCompressed
Further info
B0F26CPZ/DEZ 16x16 block mappingsFurther info
B2506CPZ/DEZ main level patternsArt compression
858 blocks
B6058CPZ/DEZ 128x128 block mappingsCompressed
Further info
B8558ARZ 16x16 block mappingsFurther info
B9E58ARZ main level patternsArt compression
1002 blocks
BF408Waterfall patternsArt compression
00, 11 blocks
BF568ARZ 128x128 block mappingsCompressed
Further info
C2138End of compressed ARZ 128x128 block mappingsFurther info
C2148large chunk of CNZ 128x128 block mappings (uncompressed)Further info
C943CCPZ 16x16 block mappings (Different to current beta)Further info
CAA1CCPZ main level patterns (797 blocks) (Different to current beta)Further info
CE03ACPZ 128x128 block mappings (uncompressed) (Different to current beta)Further info
D603AARZ 16x16 block mappings
D793AARZ main level patterns (1002 blocks) (Identical to current beta)
DCEEAWaterfall patterns (00, 11 blocks)
DD04AARZ 128x128 block mappings (uncompressed) (Different to current beta)
E504AIncomplete part of ARZ main level patterns (Identical to current beta)
E57E6Waterfall patterns (00, 11 blocks)
E5946Compressed ARZ 128x128 block mappingsFurther info
E8000Half of SEGA intro soundFurther info
EC000-ECFFF??????????
ED000-EFFFF?????????? (Something to do with music)
F0000-F1E8B?????????? (Something to do with music)
F1E8C-F7FFFSEGA intro sound16000Hz mono
8-bit unsigned
PCM raw audio
Further info
F8000-FEFFF?????????? (Something to do with music)
FF000-FFFFF?????????? (Something to do with sound fx)

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:

E6800: 004A 037A 5552 5552 5552 5552 5552 5552 0734 0BC0 10EE 10EE 1748 1AFC

Now this is the beginning of the offset index for the sprite locations. Now, can you see which values are the offset for MTZ act 2? They're 0BC0. All you had to do to get that was to take the level value for MTZ, which is 04, and count across four bytes for every value it is above 00, then across another two because it's the second act. Now we take that value and using a hex calculator, add it to the address of the offset table, which is E6800. That will give us a value of E73C0, which is the address in the rom of the MTZ act 2 sprite locations.

Also notice those 5552 values in there? Well those are for the unused level values in the game. You'll see some damn weird values put in for them in many places, and that's what causes the game to lockup in the final build of sonic 2 if you try and enter one of those levels.

There are other forms of an offset index such as the one where there's just one offset per level value, and another type that actually uses a double offset index. The first is easy enough, but a double offset index will specify two values per level, but that's not for act one and two, but rather two blocks of data to use for both acts.

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 S2B rom:

24354-2441F: Indexed main level load block (patterns/16x16/128x128)
24354-2435F: Emerald Hill zone (00)
24354: EHZ/HTZ main level patterns (81C00) [04]
24358: EHZ/HTZ 16x16 block mappings (80C60) [05]
2435C: EHZ/HTZ 128x128 block mappings (8692E) [04]
24360-2436B: Unknown (01)
24360: EHZ/HTZ main level patterns (81C00) [06]
24364: EHZ/HTZ 16x16 block mappings (80C60) [07]
24368: EHZ/HTZ 128x128 block mappings (8692E) [05]
2436C-24377: Wood zone (02)
2436C: WZ main level patterns (8AB2E) [08]
24370: WZ 16x16 block mappings (89B8E) [09]
24374: WZ 128x128 block mappings (9E926) [06]
24378-24383: Unknown (03)
24378: EHZ/HTZ main level patterns (81C00) [0A]
2437C: EHZ/HTZ 16x16 block mappings (80C60) [0B]
24380: EHZ/HTZ 128x128 block mappings (8692E) [07]
24384-2438F: Metropolis zone (04)
42384: MTZ main level patterns (91716) [0C]
42388: MTZ 16x16 block mappings (90456) [0D]
4238C: MTZ 128x128 block mappings (94C56) [08]
24390-2439B: Metropolis zone act 3 (05)
24390: MTZ main level patterns (91716) [0C]
24394: MTZ 16x16 block mappings (90456) [0D]
24398: MTZ 128x128 block mappings (94C56) [08]
2439C-243A7: Unknown (06)
2439C: EHZ/HTZ main level patterns (81C00) [10]
243A0: EHZ/HTZ 16x16 block mappings (80C60) [11]
243A4: EHZ/HTZ 128x128 block mappings (8692E) [0A]
243A8-243B3: Hill Top zone (07)
243A8: EHZ/HTZ main level patterns (81C00) [12]
243AC: EHZ/HTZ 16x16 block mappings (80C60) [13]
243B0: EHZ/HTZ 128x128 block mappings (8692E) [0B]
243B4-243BF: Hidden Palace zone (08)
243B4: HPZ main level patterns (98B76) [14]
243B8: HPZ 16x16 block mappings (97596) [15]
243BC: HPZ 128x128 block mappings (9B9F8) [0C]
243C0-243CB: Unknown (09)
243C0: EHZ/HTZ main level patterns (81C00) [16]
243C4: EHZ/HTZ 16x16 block mappings (80C60) [17]
243C8: EHZ/HTZ 128x128 block mappings (8692E) [0D]
243CC-243D7: Oil Ocean zone (0A)
243CC: OOZ main level patterns (9ED58) [18]
243D0: OOZ 16x16 block mappings (9D778) [19]
243D4: OOZ 128x128 block mappings (A1A58) [0E]
243D8-243E3: Dust Hill zone (0B)
243D8: DHZ main level patterns (A5248) [1A]
243DC: DHZ 16x16 block mappings (A3F88) [1B]
243E0: DHZ 128x128 block mappings (A8B6A) [0F]
243E4-243EF: Casino Night zone (0C)
243E4: CNZ main level patterns (ABF2A) [1C]
243E8: CNZ 16x16 block mappings (AB5CA) [1D]
243EC: CNZ 128x128 block mappings (AF026) [10]
243F0-243FB: Chemical Plant zone (0D)
243F0: CPZ main level patterns (B2506) [1E]
243F4: CPZ 16x16 block mappings (B0F26) [1F]
243F8: CPZ 128x128 block mappings (B6058) [11]
243FC-24407: Genocide City zone (0E)
243FC: EHZ/HTZ main level patterns (81C00) [20]
24400: EHZ/HTZ 16x16 block mappings (80C60) [21]
24404: EHZ/HTZ 128x128 block mappings (8692E) [12]
24408-24413: Aquatic Ruin zone (0F)
24408: ARZ main level patterns (B9E58) [22]
2440C: ARZ 16x16 block mappings (B8558) [23]
24410: ARZ 128x128 block mappings (BF568) [13]
24414-2431F: Death Egg zone (10)
24414: EHZ/HTZ main level patterns (81C00) [24]
24418: EHZ/HTZ 16x16 block mappings (80C60) [25]
2441C: EHZ/HTZ 128x128 block mappings (8692E) [14]

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 <a href="#Palettes">here</a>. 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 S2B rom:

002447AStandard block 1 (starpoll/score\rings\time/lives/ring/numbers)(4)
012449AStandard block 2 (monitor/bubble/stars)(2)
02244AEUnknown (explosion/rabbit/white bird)(2)
03244C2Game\time over (game\time over text)(0)
04244CAEHZ (EHZ\HTZ patterns/waterfall/bridge/fireball/spikes/D spring/V spring/H spring)(7)
05244FCEHZ (buzz bomber/tire badnick/fish)(2)
0624510WZ (WZ patterns)(0)
0724518WZ (spikes/D spring/V spring/H spring)(3)
0824532MTZ (MTZ patterns/4 blocks/wheel/ball/unknown/unknown/steam/spikeblock/spike)(8)
092456AMTZ (button/spikes/D spring/V spring/H spring/unknown/lava bubble/unknown/cog)(8)
0A245A2HTZ (EHZ\HTZ patterns/HTZ patterns/fireball/rock/conveyor/orbit badnick/spikes/D spring/V spring/H spring)(9)
0B245E0HTZ (unknown/fireball/HTZ barrier)(2)
0C245F4HPZ (HPZ patterns/bridge/waterfall/platform/pulsing ball/HPZ stuff/master emerald/water)(7)
0D24626HPZ (dinosaur badnick/bat/crocodile/buzz bomber/bat/rhinobot/dinosaur badnick/pirahna)(1)[7]
0E24658OOZ (OOZ patterns/rising platform/spikeball/stuff/stuff/oil/oil)(6)
0F24684OOZ (unknown/unknown/unknown/unknown/swinging platform/button/spikes/D spring/V spring/H spring/)(9)
10246C2MCZ (MCZ patterns/box/collapsing platform/pullswitch/vines)(4)
11246E2MCZ (H spike/spikes/log/lever spring/V spring/H spring)(5)
1224708CNZ (CNZ patterns/stuff)(1)
1324716CNZ (spikes/D spring/V spring/H spring)(3)
1424730CPZ (CPZ patterns/stuff/striped blocks/unknown/big platform/small platform/spring stopper/water/unknown/stuff)(9)
152476ECPZ (bubbles\numbers/spikes/unknown/level spring/V spring/ H spring)(5)
1624794ARZ (ARZ patterns/water/leaves/arrow shooter/splash)(4)
17247B4ARZ (bubbles\numbers/spikes/lever spring/V spring/H spring)(4)
18247D4Title card (title card patterns)(0)
19247DCEnd of signpost level (signpost/hidden bonuses/unknown)(0)[2]
1A247F0End of boss level (unknown boss/EHZ boss/unknown/unknown boss/unknown boss/small explosion/smoke trail/EHZ boss/unknown)(2)[8]


This 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 S2 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

The level layout in S2B is stored in the rom in a way similar to how the level layout is stored in the ram in S3&K. All the level data for a level is broken into two peices, one for the foreground of the level, and one for the background. When being read into the ram, this data is interleaved to give the entire level layout. The offset index that proceeds the actual level data is a unique offset index, and is similar to a double offset index. There are two offset values for each act. The first offset is linking to the data for the foreground for that act, and the second offset is linking to the background for that act. The level data itself is not compressed however, so you can just edit it directly. For information on how to edit it, check the savestate section.

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 S2B rom.

Main level block mappings

In the S2B rom, the 128x128 block mappings are compressed, but the 16x16 block mappings are not. This means you can edit the 16x16 block mappings directly, but the 128x128 block mappings must be decomporessed to be edited effectively. At this point in time, there is no untility that is capable of compressing data into the format used by 128x128 block mappings, so the only thing that's really possible for now is porting the block mappings from one level to another. For information on what the block mappings do, and how to edit them, check the savestate section.

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.

Mappings for Sonic/Tails

What the mappings do is they tell the game what patterns to display, and where to put them for each of the frames that the sprite has. The mappings for most sprites are contained within their function (go here for more details), but with the Sonic and Tails sprites, to allow the programmers to add a new frame easily without having to recompile the function, and hence the whole game because of the size difference, they created a separate array containing the mapping data for each frame. I haven't examined this to see how it works yet, but when I do I’ll explain the format here.

Sega intro sound

The Sega intro sound is just an 16000HZ wav sound. Opening up the rom in any sound editing program that supports raw audio with the settings listed next to the location on the list will enable you to playback the sound effect. You could also insert your own sound in the same place as long as it's at the same bitrate. The bitrate is to do with the quality of the sound. The lower it is the crappier it will sound, because that's to do with how often the output is modified. Just think of the difference between long play and short play on a VCR. Stuff recorded in long play does save space, but the quality of the recording is worse.

Art compression format

The art compression format is a very dense compression format. It's only used for art because the format relies on the data being in blocks of 64 bytes. This format is used for all the compressed art in sonic 1 and sonic 2 beta, and all the compressed art except for the main level pattern blocks in Sonic 2 and S3&K. As I said this format is very dense, and as such it requires a hell of a lot of computation to decompress. Because of this it also requires a hell of a lot of time and effort to crack. I've had a go at it, but the lightning has yet to strike. When I crack it I’ll post the format breakdown here, and create a simple program to decompress it, but until then it is impossible to directly edit any art using this format. The porting of a compressed block of art is simple though, so if you want to transfer beta art to the final, you can just tack it onto the end and enter the pointer into the pattern load cue of the level or event you want it to appear at, along with a VRAM location to load it into. Go Here for more information on that.

Dynamic pattern reloading

Dynamic pattern reloading is a method of loading patterns into the VRAM, but unlike the other methods, this one has no limitations, because it uses actual programmed code. Basically this is here for any effects to do with patterns changing in game that isn't posible using the normal load cue system, like the hills in the background of HTZ where the patterns to display are determined by the position of the screen Becuase the programming for it is in the form of compiled code, direct editing of it is not possible.

Animated pattern load cue's

Animated patterns require the art they are working with to be in an uncompressed form, so if you are attempting to make an animated pattern, make sure the art is uncompressed or it won't work. Now, the length of each load request on the cue varies depending on the animation. The first byte specifies a value that will determine how often to switch frames in the animation. If you use this value you will not be able to specify a frame as having a different duration to another. Setting this to FF will disable automatic frame control and allow the user to input a manual duration for each frame. This will mean that for every frame the user wants in the animation, they have to allow another byte at the end of the load request. If you want automatic pattern control, which you would use if you want all the animations frames to have the same duration. Just enter how many screen refreshes to wait until the next frame of the animation is displayed. Bytes 2,3, and 4 are the address in the rom to load the patterns from. Bytes 5 and 6 are the location in VRAM to load the patterns into. Byte 7 is the number of frames the animation has, and byte 8 is the number of spaces in VRAM to use for each frame. The function of the bytes beyond this point depend on whether or not automatic frame control is enabled, so refer to appropriate section below.

With automatic frame control:
One byte per frame of animation. This byte simply specifies the image to use for each frame of the animation. Based on the loading address entered, this value is the offset in 8x8 blocks to load each frame from in the rom. So if for example you were dealing with an animation that had 4 8x8 blocks per frame, and there were 4 frames of that, and you wanted it to display each frame one by one, you would enter the value 0004 080C.

Without automatic frame control:
Two bytes per frame of animation. The first byte is the offset of blocks in the file to load the animation frame from. This byte simply specifies the image to use for each frame of the animation. Based on the loading address entered, this value is the offset in 8x8 blocks to load each frame from in the rom. The second byte is the number of screen refreshes to keep that image loaded for, before going on to the next animation frame.

Misc sprite definitions

It looks like there are some sprites that get thier mappings and whatnot from this index, so they can reuse just a couple of sprites for some of the the miscellaneous objects in a level that the character doesn't actually interact with, but those objects can be completely different from one level to the next. A handy way of avioding programming each one individually, and thus saving a hell of a lot of space. As for how to edit them, well I haven't looked at that yet, but when I do i'll post an explination of the format here.

Rasterised layer deformation

Raster effects are simply effects to do with deformation of an image based on lines of pixels. In Sonic 2, these effects are used to create the movement effects for the backgrounds of all the levels, as well as the 2 player splitscreen effect. Because the programming for these effects are stored in the form of compiled code, you'll have to learn 68K ASM in order to edit them. Switching between levels is easy enough though, just change the corresponding value on the preceeding offset index to link to the effect you wish to use.

Palettes

All the main palettes used in the game are linked in a pointer table at 294E. In this pointer table there are 8 bytes per palette. The first four simply give a location in the rom for the data to load. The fifth and sixth bytes give the location in the system ram to load the data into, and the seventh and eighth bytes give the number of four byte blocks being loaded. Here's a palette pointer:

0000 2942 FB20 0007

Now in this case the palette is being loaded from 00002942 in the rom into the beginning of the second above water palette row (FB20), and it's loading 16 colours (0007). Here's a listing of the palette pointers in the S2B rom:

00294ESEGA screen palette (2A16)
012956Title screen palette (2A96)
02295ELevel select palette (2B16)
032966Primary palette line (2B96)
04296EEHZ level palette (2BB6)
05297601 level palette (2BB6)
06297EWZ level palette (2C16)
07298603 level palette (2BB6)
08298EMTZ level palette (2C76)
09299605 level palette (2C76)
0A299E06 level palette (2F36)
0B29A6HTZ level palette (2CD6)
0C29AEHPZ level palette (2D36)
0D29B609 level palette (2BB6)
0E29BEOOZ level palette (2E16)
0F29C6MCZ level palette (2E76)
1029CECNZ level palette (2ED6)
1129D6CPZ level palette (2F96)
1229DEGCZ level palette (2BB6)
1329E6ARZ level palette (3076)
1429EEDEZ level palette (2BB6)
1529F6HPZ underwater palette (2D96)
1629FECPZ underwater palette (2FF6)
172A06ARZ underwater palette (30D6)
182A0ESonic 1 special stage palette (3156)


To change the palette being loaded for each level, you need to change the palette index number in the main level load block. For more information on that go here. The palettes themeslves are very easy to modify as they are all uncompressed in the rom. Refer to the savestate hacking documents for information on how to edit palettes.

Level size array

All the sizes of the levels are stored in a simple array, and can be easily modified to change the boundaries of the level. This array is located at 5986, and for each act there are four values. The first gives the X start location of the level, and the second gives the X end location of the level. Likewise the third value gives the Y start location of the level, and the fourth gives the Y end location of the level.

Character start location array

The start location for the characers and the camera for each level are stored in this array at address 5B02. It couldn't be any simpler to modify, there's just two values per act, the first being the X location, and the second being the Y location.

Music playlist for levels

This is actually part of a sub in the code, but it's editable all the same. Pretty simple, just one byte per level. That one byte is the value of the song you wish to play. You must enter the value in the form in which it is displayed in the beta version, which is with 80 as the starting value, not 00 as it is displayed in the final. You'll notice with the value for death egg, it's 08 not 88, which is why there's no sound in the level.

Level order

There are several different sections in the game to do with the order of levels. The first one is the one that determins which level the game loads when someone finishes a level. The second one is the one which determins which level to load when you select a level from the level select menu. The level select one is easy to modify, just enter the level value followed by an act number for each of the levels you want to load, in the order you want them to be loaded. For a list of the level values for all the different stages, look at the beginning of the introduction to this page. Note that if you load the same level into the level order twice, when you link to it via the level select, it will continue the sequence from the last one in the list, not the first.

The second system for which level to load when one ends works slightly differently. There is a list of values, with two bytes allocated to each act of each level. That two byte value is simply the value of the level you wish to load when that level ends. So, if you wanted ARZ act 1 to load up when you finish MTZ act 2, you would take the location of the table, which in this case is BF9A, and you would add 18 bytes to that location, and then you would replace the next two bytes from that point with 0F00. That's becuase you add four bytes to the address for every level that comes before it, and in this case there are 4, and then you would add another 2 bytes becuase you want to alter the level to load when you finish the second act.

Also, note that when you want a level to be the last level in the game, you must enter the value FFFF as the stage to load when it finishes. This tells the game to end and return to the title screen.

Object debug list

This list is what determins what sprites you can place in debug mode, and in what levels. An offset index is used to locate which object debug list to use for which level, so if you want further info on that go <a href="#offset">here</a>. Now, there is a 2 byte value at the start of each debug list. That 2 byte value is simply the number of sprites in the list. After that there are 8 bytes per sprite. Here's an object that's present in an object debug list from sonic 2:

2601 2D36 0800 0680
1 2 3 4 5 6 7 8


And here's a quick referance sheet of what each byte does. For further info on each one, refer to information below.

1 Object number
2-4 Sprite mappings
5 Declaration
6 Frame to display
7 and 8 flip/mirror/palette/VRAM location


Object number:
This value is what determins which object to use. For a list of all the sprites in the game, check out the sprite programming section of this document here. In the case of the above example the object number is 26, which is a monitor.

Sprite mappings:
This is a pointer to the location in the rom to load the mappings for that sprite. This will be located in the programming for the sprite itself. Do not change this unless porting between levels, or you're absolutely sure you know what you're doing, or the game will most likely hang. This only affects the preview picture, not the placed object itself. In this case, the sprite mappings are being loaded from the address 012D36 in the rom.

Declaration:
This is the declaration for the loading of the sprite. For information on exactly what that is, go here. In this example the declaration is 08, which switches the type of monitor it is in the case of this sprite.

Frame to display:
This is simply the frame of the sprite that will be displayed on the preview picture before you place an object. Right now it's set to 00, which is the first frame.

Flip/mirror/VRAM location:
The first hex value of the 7th byte is to do with flipping and mirroring of the sprite, as well as the palette line to use for it. Refer to the following table for an explination of what responce each value will create.

Value pallette line flipped horizntally flipped vertically
0 1 n n
1 1 n y
2 2 n n
3 2 n y
4 3 n n
5 3 n y
6 4 n n
7 4 n y
8 1 n n
9 1 y n
A 2 n n
B 2 y n
C 3 n n
D 3 y n
E 4 n n
F 4 y n

In the case of our example, the value of 0 is used, so the preview image will use the first palette line, and will not be flipped or mirrored.

The last hex value of the 7th byte, and all of the 8th byte in this block combine to give a starting location in the VRAM to find the patterns to use for that sprite when displaying the preview. This is not an actual location, but merely the number of blocks after which to load the patterns from. After the value of 800 is passed, the block number resets to zero but the image is mirrored. In this case, that block number is 680.

And that's about it. I've just realised that this is a rediculous amount of detail for such a small thing, but at least you're sure to get it.

Leftover data from previous builds

All through the S2B rom, there are blocks of leftover data from earlier builds of the game. You see, when sonic team were working on the game, they would compile beta versions of the game onto flashcarts, for test purposes and distribution. Because the data was compiled directly onto the cart, any locations that didn't have to be written to retained the data they posessed before. On a final release cart, this simply would've resuled in blocks of data all contaning the value of FF, but in the case of this flashcart, data for earlier versions of the game had been written to these areas previously. Any areas of lost data that I have extra information about will be noted here.

End of compressed ARZ 128x128 block mappings

This small reminant of a rather recent build indicates a minor change in the above blocks of data, which resulted in a slightly shorter file size. This was most likely just a minor amendment to the block mappings for a level, resulting in them not compressing quite as well.

large chunk of CNZ 128x128 block mappings

This contains a large proportion of an earlier version of the CNZ 128x128 block mappings. The block of data is missing the first 3340 (D0C) bytes. From this we can see a massive chanage in CNZ between this compilation and the one in our beta. These block mappings have been changed so radically, that only a pattern in thier layout is recogniseable when compared to our current beta one. This indicates a massive restructuring in the order of the 16x16 block mappings of this build as well, but unfortunately that data was written over.

CPZ patterns/block mappings

These are the complete patterns and block mappings for an earlier version of CPZ. There are a few minor changes in the patterns, and some fairly major changes in the 16x16 and 128x128 block mappings.

Compressed ARZ 128x128 block mappings

This lost data is in an uncompiled form, and at first I mistook it for code. Apart from the fact it is in this form, the data appears to be very close to that of our current beta. There is a commented line at the very start of the block, which contains further information about the block of compressed data. Thanks go out to Iceknight, who figured out that the text in this comment was in Kanji, and thanks go out to Kojichao and sth2k for translating it. The commented line reads:

Before compression $8000 After compression $2c00 Compression ratio 34.4% Cell number 1024

I had already guessed the purpose of the first three numbers, But I still can't figure out the puropse of the last one, or at least not one that would be worth putting in a comment. If anyone has any idea what the fourth number is used for, let me know.

lost Pattern load cue's

Due to changes in the structure of the rom, there are quite a few pattern load cue's left from previous compilations. In fact, in this one small area in the rom, I have identified six different layers of lost data from previous compilations, and these compilations seem to be a lot newer than the remains of level data judging by some of the link locations on the cue. Here's a breakdown of the lost pattern load cue's:

24804End of boss level (unknown boss/unknown boss/small explosion/smoke trail/EHZ boss/unknown)(?)[5]
24828ARZ (lever spring/V spring/H spring)(?)[1/2+1]
24838Title card (title card patterns)(0)
24840End of signpost level (signpost/hidden bonuses/unknown)(0)[2]
24854End of boss level (unknown boss/EHZ boss/unknown/unknown boss/unknown boss/small explosion/smoke trail/EHZ boss/unknown/)(2)[8]
2488CEnd of boss level (smoke trail/EHZ boss/unknown)(?)[1/2+1]
2489CMCZ (log/invalid pointer (7976C)/V spring/H spring)(?)[3]
248B4CNZ (invalid pointer (AB748)/invalid pointer (AE75A))(1)
248C2CNZ (spikes/D spring/V spring/H spring)(3)
248DCCPZ (invalid pointer (B1D24)/stuff/striped blocks/unknown/big platform/small platform/spring stopper/water/unknown/stuff)(9)
2491ACPZ (spikes/unknown/invalid pointer (7976C)/V spring/H spring)(4)
2493AARZ (invalid pointer (B9686)/water/leaves/arrow shooter/splash)(4)
2495AARZ (spikes/invalid pointer (7976C)/V spring/H spring)(3)
24974Title card (invalid pointer (7E222))(0)
2497CEnd of signpost level (signpost/invalid pointer (7F37A)/invalid pointer (7F206))(2)
24990End of boss level (invalid pointer (7C4BC)/invalid pointer (7D942)/invalid pointer (7E12E)/invalid pointer (7C4BC)/invalid pointer (7CBF8)/invalid pointer (7D7DE)/invalid pointer (7D85C)/invalid pointer (7D942)/invalid pointer (7E12E))(2)[8]
249C8ARZ (invalid pointer (?AD00)/invalid pointer (7976C)/V spring/H spring)(?)[1/2+2]
249DCTitle card (invalid pointer (7E222))(0)
249E4End of signpost level (signpost/invalid pointer (7F37A)/invalid pointer (7F206))(2)
249F8End of boss level (invalid pointer (7C4BC)/invalid pointer (7D924)/invalid pointer (7E12E)/invalid pointer (7C4BC)/invalid pointer (7CBF8)/invalid pointer (7D7DE)/invalid pointer (7D85C)/invalid pointer (7D942)/invalid pointer (7E12E))(2)[8]


If you want more info on the pattern load cue's, go here. From these load cue's we can see that there were some changes in the locations of some of the small blocks of compressed art, and that has resulted in some of the older pointers linking to the wrong data. The thing that I find most interesting about this deals with the load cue for the end of signpost level load cue. You'll notice with this cue that the last two load requests were cutoff in our beta, which link to those hidden bonues at the end of an act in Sonic 1, and more importantly, the flash effect from entering the giant golden ring, that leads to a special stage. The patterns for this ring are in the rom, but until I saw this I wasn't convinced that it was ever implemented in the game. Now, if you look at the cue that's colour coded yellow, you'll notice it isn't cutoff yet, but in the green compilation it has been, so somewhere between those two compilations, the ideas they were using for the method of entering the special stage, and the bonus points at the end of a level were changed. If you compare the link locations of the main level patterns for any of the levels in the yellow load cue's with the current link locations, and the lost block mappings and art there, it's clear that all these cue's are for compilations made after the compression methods for both 16x16 and 128x128 block mappings were put in place, which either means that those blocks of data with the block mappings and level patterns are from a much earlier compilation than I figured, or the ideas for the end of a level were changed just before the time of our beta.

Sprite programming

The programming for a sprite in the sonic games are stored as a function, and that function can take one declaration. People often confuse this declaration with a subtype value, but it's not really. What that basically means for the non programmers out there is that when the game places a sprite, you can enter a value along with the sprite number that may alter something about that sprite, but what it does varies depending on what sprite you're working with. Now because these functions are now compiled, the only way you can effectively edit them is to find the code for it and decompile it into assembly, alter it as necessary, and then recompile it and enter it back into the rom. This document will contain all the info necessary to enter a new sprite or replace an old one, but when it comes to the ASM you're on your own.<p>

Now, the value assigned to a sprite in the game is done by a pointer index at D01A-D249. It’s pretty simple, just one pointer per address value. Here's the pointer list in Sonic 2 beta:

01