Sonic 2/Text Editing
From Sonic Retro
| Sonic Community Hacking Guide|
One of the most useful things to change in the game is the text. Though, there are many different formats for the many different types of text in the game. The known formats are listed here.
Two-Player Mode Text
The text starts at byte_874A in Xenowhirl's disassembly. It uses a non-ASCII format, but thanks to AS' macro capabilities can be edited in the disassembly as plain text.
The text starts at byte_97CA in Xenowhirl's disassembly, and once again can be edited as plain text. The in-game format for each character is as follows:
|00 - Space||10 - 0||11 - 1||12 - 2|
|13 - 3||14 - 4||15 - 5||16 - 6|
|17 - 7||18 - 8||19 - 9||1A - *|
|1B - ©||1C - :||1D - .||1E - A|
|1F - B||20 - C||21 - D||22 - E|
|23 - F||24 - G||25 - H||26 - I|
|27 - J||28 - K||29 - L||2A - M|
|2B - N||2C - O||2D - P||2E - Q|
|2F - R||30 - S||31 - T||32 - U|
|33 - V||34 - W||35 - X||36 - Y|
|37 - Z||0E - Start a new text line||10 - Start a new selection box|
Level Select Text
The level select uses a plane map for the foreground and background graphics. The plane map for the text is located at MapEng_LevSel in Xenowhirl's disassembly, and is Enigma-compressed. It is 40x28 tiles wide, with each word in it representing one 8x8 tile, arranged row-by-row.
The highlighting uses a different system, based on the array at byte_96EE. There are four bytes per level select entry. The first byte is the row offset into the plane map for the level name text, the second byte is the column offset for the same text multiplied by 2. The third byte is the row offset into the plane map for the act number text. If this is 0, no highlighting is performed for this text. The fourth byte is the column offset for the act number text multiplied by 2.
The level select icons are even simpler, based on an array at byte_96D8 in the 2007 xenowhirl disassembly. One byte per level select entry. Use the table below to choose an icon:
As for the horizontal selection array. That one is just about as easy to edit as the icons. Each entry is a single byte representing the next text selection if left or right is pressed for that entry. The array itself is at byte_95A2 in the 2007 xenowhirl disassembly.
© 1992 SEGA Text
The "© 1992 SEGA Text" on the title screen is located at CopyrightText in Xenowhirl's disassembly, and uses a different format. Each word represents one character. The word values corresponding to each character are:
|00 00 - Space||06 80 - 0||06 81 - 1||06 82 - 2|
|06 83 - 3||06 84 - 4||06 85 - 5||06 86 - 6|
|06 87 - 7||06 88 - 8||06 89 - 9||06 8A - *|
|06 8B - ©||06 8C - :||06 8D - .||06 8E - A|
|06 8F - B||06 90 - C||06 91 - D||06 92 - E|
|06 93 - F||06 94 - G||06 95 - H||06 96 - I|
|06 97 - J||06 98 - K||06 99 - L||06 9A - M|
|06 9B - N||06 9C - O||06 9D - P||06 9E - Q|
|06 9F - R||06 A0 - S||06 A1 - T||06 A2 - U|
|06 A3 - V||06 A4 - W||06 A5 - X||06 A6 - Y|
|06 A7 - Z|
The credits and intro texts use X and Y coordinates to place the character on the screen rather than just using a fixed font. While the intro text uses only one position and pointer array, located at off_B2B0, the credits text uses a separate position and pointer array for each screen, and the pointers to these arrays are located at off_B2CA.
Each entry in the position and pointer array consists of one longword followed by one word. The longword is an absolute pointer to the actual text data. The word is the VRAM location, inside the plane A table, to write the characters to.
The text data is preceded by a single byte which is of the format PCCVH000 in case of the credits text, and PCCVH101 in case of the intro text, with P being the high priority flag, CC being the palette index to use, and V and H being the vertical and horizontal flip flags, respectively. The actual text uses one byte per 8x8 tile. However, most of the characters are 16 pixels wide and therefore take up two bytes. The text can be edited as ASCII inside the disassembly, and the actual format in-game is as follows for the intro text:
|00 - Space||01 & 02 - A||03 & 04 - B||05 & 06 - C|
|07 & 08 - D||09 & 0A - E||0B & 0C - F||0D & 0E - G|
|0F & 10 - H||11 - I||12 & 13 - J||14 & 15 - K|
|16 & 17 - L||18 & 19 - M||1A & 1B - N||1C & 1D - O|
|1E & 1F - P||20 & 21 - Q||22 & 23 - R||24 & 25 - S|
|26 & 27 - T||28 & 29 - U||2A & 2B - V||2C & 2D - W|
|2E & 2F - X||30 & 31 - Y||32 & 33 - Z||34 & 35 - 2|
|36 - (||37 - )||38 - "||39 - .|
|3A - ©||3B & 3C - 1||3D & 3E - 9||3F & 40 - :|
and as follows for the credits text:
|00 or 01 - Space||02 & 03 - A||04 & 05 - B||06 & 07 - C|
|08 & 09 - D||0A & 0B - E||0C & 0D - F||0E & 0F - G|
|10 & 11 - H||12 - I||13 & 14 - J||15 & 16 - K|
|17 & 18 - L||19 & 1A - M||1B & 1C - N||1D & 1E - O|
|1F & 20 - P||21 & 22 - Q||23 & 24 - R||25 & 26 - S|
|27 & 28 - T||29 & 2A - U||2B & 2C - V||2D & 2E - W|
|2F & 30 - X||31 & 32 - Y||33 & 34 - Z||35 & 36 - 2|
|37 - (||38 - )||39 - "||3A - .|
|3B - ©||3C & 3D - 1||3E & 3F - 9||40 & 41 - :|
An FF signifies the end of the string.
Title Card Text
The title card text loads all common patterns (red stripe, act numbers, letters E, N, O and Z (spells ZONE), etc) into VRAM. The other letter art loaded, however, differs from zone to zone, and the letters loaded for each zone are governed by the offset table at byte_15820. This table has one byte per level, that byte being an offset into word_15832, which contains the data for letters to load for each level. For each entry in word_15832, the first byte specifies the 8x8 ID of the starting tile, and the second byte is the number of 8x8s to load. The 8x8 ID for each letter is as follows:
|00 - A||04 - B||08 - C||0C - D|
|10 - F||14 - G||18 - H||1C - I|
|1E - J||22 - K||26 - L||2A - M|
|30 - P||34 - Q||38 - R||3C - S|
|40 - T||44 - U||48 - V||4C - W|
|52 - X||56 - Y||5A - .|
An FF FF signifies the end of the entry. Since this table only governs the letters to load, repeated letters are mentioned only once, and the letters E, N, O and Z are not loaded at all, since they are part of the main title card patterns.
The actual level name display is handled by the title card mappings, located at Obj34_MapUnc_147BA. Each frame from 0 to $10 in these mappings corresponds to the title card of the level with the same ID:
|Level ID||Level Name|
|00||Emerald Hill Zone|
|05||Metropolis Zone Act 3|
|06||Wing Fortress Zone|
|07||Hill Top Zone|
|08||Hidden Palace Zone|
|0A||Oil Ocean Zone|
|0B||Mystic Cave Zone|
|0C||Casino Night Zone|
|0D||Chemical Plant Zone|
|0E||Death Egg Zone|
|0F||Aquatic Ruin Zone|
|10||Sky Chase Zone|
These mappings can be edited in SonMapEd or Flex 2 by taking a VRAM dump while the title card for a particular level is on-screen, loading this dump as the art file, and then editing the appropriate frame in the mappings.