Actions

Sonic Advance 3/Technical information

From Sonic Retro

Revision as of 18:39, 26 August 2007 by Scarred Sun (talk | contribs) (Ported first part)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Exclamation.svg This article is actively undergoing a major edit.
As a courtesy, please do not make edits to this article while this message is displayed in order to avoid edit conflicts. If you need to know who is working on the article and when the edit session began, check the edit history.

This is the Sonic Community Hacking Guide for Sonic Advance 3. Guide based on Erik JS' Sonic Advance 3 Hacking Guide.

Introduction

In this page I'll show you the most important aspects of SA3 ROM. Read carefully before going into RAM and ROM sections.

Let's start with the header. The game title is a string that starts at 0x0000A0. Its max size is no more than 11 bytes. At 0x0000AC, there's the serial string (4 bytes). In American SA3, it's B3SE. That "E" belongs to USA region. J is for Japan and P for Europe. At 0x0000BD is the checksum byte. On VBA, go to File-> ROM information. The value outside parenthesis is the right checksum for the game. If the inside value (actual checksum) isn't equal, and the ROM doesn't work, just change it to the correct and it should work. This method is valid for any GBA ROM (specially the intro'ed ones).

Let's go to the pointers. Pointers are nothing more than a group of four bytes that indicates a location at ROM that contains certain data. When something needs to be read from ROM, the pointer points to a ROM location + 08000000h. It's like that because the area reserved for games in GBA starts at 0x08000000 - you can see that at VBA, going to Tools-> Memory viewer. For instance, sprite palettes are at 0x353CCC. In ROM, their respective pointer will be like CC 3C 35 08 (this byte order is called Little Endian). If you are using Visual C++, then you don't need to reverse the order of the bytes when searching for a pointer. VC++ automatically searches reversed values - just search for 08353CCC. Also, note that in ROM and RAM section everything is treated as Little Endian, unless stated otherwise.

Now, the palette. GBA supports 32768 colors, and the cubic root of this number is 32, which means that each color level (red, green and blue) has 32 variations. In order to represent a color, GBA uses 2 bytes. Black is 0000 and white is 7FFF. But don't forget what I said about how the ROM stores values, in Little Endian ordering (white would be found as FF7F) If you want to know how to edit the palette, I have a proper page for that. Click here to open it in another window. And remember that VBA has a palette viewer (Tools-> Palette viewer).

Time to talk about texts. Majority of them are sprites, and can be edited through Tile Layer Pro. That includes: "press start", copyright info at title screen and the main menu options, for instance. On VBA, go to Tools-> OAM viewer, and slide the bar. If the text isn't "letter by letter" then it's a sprite. Text that is "letter by letter" are coded, like the level select text from Sonic 1 for Genesis.

Last, I want to talk about the monoblock technique that is used in the game. As I said before, sprite palette is at 0x353CCC. If you check out, you'll figure that it's Sonic palette. And it has a pointer. Now, where's the pointer for Cream's, Tails', Knuckles', Amy's and the rest??? Answer: it's the same for all the sprites! What happens is that all the palettes are in one big group (what I call monoblock), and if you alter the palette pointer you'll notice the "effect" in all of game's sprites. That pattern is followed by sprites, palettes and their mappings. About mappings, they give hints where to find sprites. For instance, the first mapping is for Sonic standing on foot, sprite state 0, second is Sonic looking up, sprite state 1... that'll be explained better at the proper section.

ROM Hacking

Sprites

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.

Main Sprite Pointer: 0x00000404

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.

Sprite data

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.

Location: 0x0076CB1C
Pointer: 0x00331500

In TLP, put the location address in Go To dialog, so you will be able to see the tiles correctly.

Sprite mappings

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.

Location 0: 0x0032FD20
Location 1: 0x00E2C3A8
Location 2: 0x003524FC
Pointer 0: 0x003314F0
Pointer 1: 0x003314F4
Pointer 2: 0x003314F8

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

Location: 0x00353CCC
Pointer: 0x003314FC

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! ;).

Sound Test

General sprite selections

0x000D729C: selection for Play button - 8 bytes for each language.
0x000D72CC: selection for Back/Stop button - 8/8 bytes.
0x000D7334: selection for Sound Test title for each language - 8 bytes.
0x000D7364: selection for numbers - 8 bytes.
0x000D73B4: selection for double arrows - 8 bytes. (btw, the sprite is doubled here, there's no double arrow sprite state)
8 bytes format: XXXX YYYY ZZZZ ZZZZ
XXXX: sprite state (see Sprites)
YYYY: sprite sub-state - determines which part of sprite state is used. All the sprites are stored (programmed) in form of states, hence it can contain various frames.
ZZZZ ZZZZ: unknown function.

The double arrow is a perfect guinea pig for seeing which animation a sprite state does.

Music titles

0x000D73BC: beginning of music titles - ASCII.

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:

  • Upper/Lower case letters;
  • Numbers from 1 to 9;
  •  !@#$%&*()?.:-/_[]{} (these are the ones I've tested);

Special notes:

  • Using 0 (30h) results in space;
  • Char ] (5Dh) appears with wrong palette, probably it's from an error at its mapping. The beta version also has this bug.

Music assignments

Location: 0x000D71A4

2 bytes per title. The value corresponds to music pointer order. See Musics section for more details.

Dynamic text

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! ;)

0x00E7E6E8: Pointer to Japanese set
0x00E7E6EC: Pointer to English set
0x00E7E6F0: Pointer to German set
0x00E7E6F4: Pointer to French set
0x00E7E6F8: Pointer to Spanish set
0x00E7E6FC: Pointer to Italian set

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! :)

Text format

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:

0151h: Spacer. The next 2 bytes tell the size of the space.
0152h: Timer. The next 2 bytes tell the speed which letters appear.
0153h: Line break (lik when you press ENTER in a text editor).
0154h: Button request. Player must press A button to see the rest of the text.
0155h: EOT (end of text).

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.

Sonic Community Hacking Guide
General
SonED2 Manual | Subroutine Equivalency List
Game-Specific
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (Master System) | Sonic 3 | Sonic 3 & Knuckles | Chaotix | Sonic Jam | Sonic Jam 6 | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Forces
Technical information
Sonic Eraser | Sonic 2 (Nick Arcade prototype) | Sonic CD (prototype; 1992-12-04) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic & Knuckles Collection | Sonic R | Sonic Shuffle | Sonic Advance | Sonic Advance 3 | Sonic Battle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Free Riders | Sonic Lost World
Legacy Guides
The Nemesis Hacking Guides The Esrael Hacking Guides
ROM: Sonic 1 | Sonic 2 | Sonic 2 Beta | Sonic 3

Savestate: Sonic 1 | Sonic 2 Beta/Final | Sonic 3

Sonic 1 (English / Portuguese) | Sonic 2 Beta (English / Portuguese) | Sonic 2 and Knuckles (English / Portuguese)
Move to Sega Retro
Number Systems (or scrap) | Assembly Hacking Guide | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | SMPS Music Hacking Guide | Mega Drive technical information