SCHG:Sonic Advance 3/ROM Editing
From Sonic Retro
Huh! Don't you know what is sprite? Sprites are all visible objects that stay over a background. That includes certain texts (level titles, copyright info at title screen) and some "bars". Anything that appears at VBA's OAM Viewer should be treated as sprite. Though changing a sprite doesn't basically mean changing colors. An image is made of colors in a certain order - sprite data is the order. ||||||| That bunch of lines can have multiple or no meaning for you, but + these two line crossed you know perfectly that they are an add signal. What sprite data does is reference colors in a palette.
The pointer above points to 0x003314F0, where there are five pointers. In SA3, a sprite is made of five parts: three mappings, palette and its data. After these five pointers, you'll see two more, but I don't know what they handle.
The GBA sprite data format is very simple. It uses 1 byte for every 2 pixels. Each nybble (half-byte) points to a color on palette (from 0 to F, the palette has 16 colors). Just for the hell of it the pixels are reversed! So F0 must be treated as 0F for visualisation purposes. That is, before mounting an image, reverse the nybbles. Images are formed by a bunch of tiles, and tiles are nothing more than a block of 8x8 pixels. If you're good at math you'll soon find out that each tile occupies 32 (20h) bytes. For 1-tile (8x8) images, you won't have too much work to edit them. But for 2 tiles or more you can never tell if the next 32 bytes are from the upper or lower part of the image, and that's for what mappings exist. You can see tiles using Tile Layer Pro. And before I forget it, references to the first color (0) of the palette result in transparency.
In TLP, put the location address in Go To dialog, so you will be able to see the tiles correctly.
Do you remember what I said above about mounting images with more than 1 tile? Well, the part that handles the tile arrangement is called mapping. Sprite mappings indicate which, how many and where the tiles appear, and which palette to use.
There are three kinds of mappings. If you look at their locations, you'll find more pointers! They refer to the sprite states, and follow the respective topic at RAM section. The first pointer is Sonic standing on foot (sprite state 0), the second is Sonic looking up (sprite state 1)... maybe I change the name of this topic to "Animation mapping". Mapping 0 is directly linked to the sprite that is shown. There, I figured how to change the palette index used, which sprite to use and the time of frames, but there are more things to figure out. You can use SA3 Pointer Reader (Downloads) to get pointers from any sprite state. Palettes
Palettes are sets of colors that are used by a certain sprite state. They are "called" through hidden flags (indexing), which change in groups of 16 colors. In mapping 0, it's possible to load more or less than 16 colors, but the first color to load will be the first color of the palette that corresponds to the index requested, due to the programming style that is used in the game. According to my calculations, there's a total of 551 palette indexes (0 to 226h).
Each color is formed with 2 bytes, and each index has 16 colors, which means that the difference from an index to the next is 32 (20h) bytes. That is, index 0 means to load starting at 0x00353CCC; index 1, start at 0x00353CEC... and so. Click here to know how to edit GBA palette.
You may have noticed that different char states from Sonic use different palette indexes, and all of them are equal! Sonic Team seems to have never noticed it before. This "feature" is annoying while editing Sonic palette to something else... but, hey! Games weren't supposed to be hacked! ;).
General sprite selections
The double arrow is a perfect guinea pig for seeing which animation a sprite state does.
Let's start with the first one. Before "OPENING", there's a byte which its value is 7. As you may already guessed, this byte tells the game how many letters must be read.
To edit a title, you can use ASCII chars, with some rules:
Characters that appear correctly:
2 bytes per title. The value corresponds to music pointer order. See Musics section for more details.
Dynamic text is nothing more than the kind of text that is shown in order to send a message to the player. The most common source of that are the Omochaos. This includes the beginning text ("The evil scientist, Dr. Eggman!..") and that one from Nonaggression ("Sonic! Use your tag action..."). Here's a sample:
Well, "dynamic text" could be the incorrect designation, but who discovered how to edit this shit anyway? Get used to my terminology and don't argue! ;)
Theoretically, each language has 256 dynamic texts. That means in the location given by the language pointer there are 256 pointers, one after other, which belong to text data. However only 1/4 (64) of them points to "real" data. The remaining 192 pointers can be used to assemble new texts, because there is a space of 1.5 MB at the end of the file that Sonic Team kindly left for us! :)
It isn't that hard to understand. Each character uses 2 bytes. Its value minus 92h is equal to its ASCII value. Be aware when you come across the following values:
The useless pointers do nothing more than point to a bunch of 0155h. Numbers follow a different pattern. If x (char value) is >= C8h and <= D1h, the formula should be: ASCII = x - 98h instead of ASCII = x- 92h.
In this page you will find information on how to change the zones of the game. Whenever I use the expression "scene" (with quotation marks), I will be referring to the value that Chao's Playground, Sonic Factory, Route 99 Map, etc, uses as scene flag. Go to RAM section to know more.
Main zone pointers
Each pointer of Group 2 corresponds to a "scene" of the game, according to its flags. On the side of Group 1, there are four pointers per "scene". First, I will explain how Group 1 works. We will use "scene" 03 (Zone 1 Act 1) as example:
The selected part corresponds to the pointers of that "scene". The first pointer (0838B590) is for BG1. The second is for BG2 (0838B5B4). Each one of them points to a sequence of 36 (24h) bytes, that contain the information about layout and palette for those BG's. The last two pointers (085DC428 and 085DEA24) point each one to a sequence of 28 (1Ch) bytes, that have to do with the image of 256 colors that is exhibited in BG's 0 and 3. If you still don't know why I call everything like BG, go into the menu Tools->Map Viewer of VBA and guess it :P.
Let's see how are the 36 bytes pointed by the first two pointers:
The byte marked with black is the beginning of the block. The pointer marked with blue tells where are the tiles. A tile is a block of 64 pixels (8x8). The pointer marked with yellow says where is the palette. There are 256 colors (512 bytes). In this case, only the second pointer (from BG2) is relevant, because, somehow, it overwrites the first. The pointer marked in red refers to the mappings of 96x96 blocks that form the layout. Last, the green pointer indicates where is the layout (1 byte per block).
Now let's see the 28 bytes from BG0 of this same "scene" to know how he game handles images of 256 colors:
Did you notice that I used the same colors of the previous picture? What is marked with black, blue and yellow has the same function that was attributed to those colors previously. The pointer in red, however, has the function of mapping and layout. The format of BG3 is the same.
Time to talk about Group 2, collision. Again from "scene" 03, it's at 0x0038B5D8. 6 pointers, plus 12 bytes.
I didn't mess a lot with the pointers, for now I cannot give more details on how they work.
This section is about musics and sound effects in game, how to handle them and other things. I discovered the playlist for maps and acts. But first you need to know how musics are ordered. The Sound Test list has nothing to do with the real order. They are referenced by their order at sound pointer list. Well, let's find out what is this...
Sound pointer list
Believe it or not, I found this by chance. It starts at 0x000EB420. Each sound uses 4 bytes for the location, plus 4 more bytes for unknown function. Any pointer that points to 0x000ECE08 (080ECE08) results in no sound. Fortunately SA1 and SA2 uses the same system, so music importing/exporting is possible. However, copy & paste isn't enough. The music itself has pointers at the end of its blocks that need to be changed to fit in the new game (only "loopable" musics).
Musics and sound effects are in this list.
The location given by the sound pointer holds a header made of 8 bytes. The first 2 bytes tells how many parts the music is formed, and consequently, how many pointers must be read after the header. The next 2 bytes have unknown function. The last 4 are the pointer for instrument definition, something like a sound driver maybe, it's essential however. Let's take music 01 (title) as example. It's at 0x00264A9C. At the header, you'll fin the following bytes, in this order: 06 00 14 80 F8 51 0E 08. The first 2 bytes indicate that there are 6 blocks used to form this music. So, after the last byte of the header, the game should read 6 groups of 4 bytes (6 pointers). Notice that those block pointers point to data behind the header. As the first block pointer is which points to the far away data (pointer with smaller value), then when you want to copy the whole music to other ROM or other place, begin to copy starting from the location of that pointer until the last byte of the last block pointer. After that, change the block pointers in accordance where the music is now. Example: the header was in CE0h, and now it is in 33450h. What you should have to do is to add 32770h (the difference between 33450h and CE0h) to the value of the block pointers.
In the case of music that loops, it has other pointers that are in the end of each block. Those pointers should also be adjusted as the block pointers.
But that is not everything that forms the music. When passing from a game to other, it is necessary to modify the pointer of the instrument definition, or the sound won't play, the game will crash, that kind of thing. Importing instrument definition from a game to another is what I have yet to discover.
Normal zones playlist
1 byte per act. Zone 1 - Map; Zone 1 Act 1; Zone 1 Act 2... and then until Zone 7 Act 3. The byte value follows the order which musics have at sound pointer list. 00 = opening, 01 = title and so.
First of all, you won't learn here how to access this menu, simply because neither I don't know how! Second, I decided to create this subsection because there are evidences of this being a "working" menu, so I'll put everything I discovered about it here.
These texts are in the beta, and there are more! Those "extra" texts from beta refer to the ability of choosing between tag and single play. Why did they changed something that doesn't work? Well, that could mean that it works!
Each byte corresponds to an act. Zone 1 Act 1, Zone 1 Act 2... until Zone 7 Act 3. Those are the values used by the scene flag. Read about scene flag at RAM section.
This section concerns about editing things in Special Stages.
Rings for checkpoints
2 bytes Little-Endian values. SS1 - first checkpoint, SS1 - last checkpoint, SS2 - first checkpoint... and then until SS7 - last checkpoint. Change these values to make the stages easier/harder to pass.