-
Notifications
You must be signed in to change notification settings - Fork 1
Translating map labels
Most strings for labels for map locations are written into 1ST_READ.BIN, while others are found in chapter script files.
The map labels that do not change throughout the game are located in 1ST_READ.BIN. Their properties are described in consecutive chunks of data.
Address | Description |
---|---|
8c2028b8 |
Les Chattes Noires |
8c203590 |
City 1 |
8c203ddc |
City 2 |
8c2043a8 |
Bleumer Estate |
This is an example found at 0x1928b8
.
Offset | Example value | Description |
---|---|---|
0x0 |
00 00 00 ff |
Mask? |
0x4 |
00 00 00 00 |
00 |
0x8 |
64 00 00 00 |
ID? |
0xC |
42 00 00 00 |
Label graphic width; default values are in multiples of 22 pixels per character |
0x10 |
00 4c 22 8c |
Little-endian pointer to string; this one at 8c224c00 is "@fs22,22@fm24,0下町へ" |
0x14 |
00 00 00 00 |
Floating point for X coordinate of hotspot location |
0x18 |
9a 99 11 c1 |
Floating point for Y coordinate of hotspot location |
The default strings change the text size to 22 and the character offset to 24. See the documentation on control codes.
To edit this label, write a new string into a free location, change the pointer to that location, and change the label graphic width accordingly.
- Demul
- Cheat Engine
- Ghidra
- Graphic editor of your choice
- utils/utils.py in this repository
- Use Demul to play the game until a map screen is reached. Save a state at this point.
- Point the in-game map cursor to a hotspot to reveal the label.
- Open the Demul process in Cheat Engine and open the Memory Viewer.
- In the Memory Viewer, navigate to the applicable memory region in the table above, minus
60000000
, e.g.2c2028e4
for the pointer in the table for the label "@fs22,22@fm24,0ポーチ" in Les Chattes Noires. - Run utils.py. You will be prompted to enter a string. Input the new text for the label and the encoded bytes will be printed. Ensure each string is prepended with
{@fs22,22@fm9,0}
without a space afterward, e.g.{@fs22,22@fm9,0}Label Text
. Copy these bytes to the clipboard.- The curly brackets
{ }
are used to escape control code sequences in the encoded bytes. Without them, they will be interpreted as literal characters.
- The curly brackets
- Select a new memory location in SKFONT.CG for the new string and paste the encoded string bytes into the memory viewer.
- The English translation writes new strings into the arbitrary location
8cda0c00
(0xc8d40
in SKFONT.CG). These strings are placed0x50
bytes apart. The order of these strings follows the original order in 1ST_READ.BIN.
- The English translation writes new strings into the arbitrary location
- In Cheat Engine, change the pointer to the address of the new string in little-endian order, e.g.
00 0c da 8c
. Changes will occur immediately. - The four bytes before the pointer are the label width. Select the first byte and use the
+
and-
keys on the keyboard to adjust the label width until the text is centered. The graphic will change size to accommodate the width as it is updated.
Repeat these steps for each label in the current map. Note that some labels may have duplicate table entries. If a label does not change with any of the above steps, it is a label defined in script files. The procedure below describes how to change these labels.
When all labels have been edited and centered in Cheat Engine, make the same changes to these bytes in Ghidra. Use the Byte Viewer window and click the button at the top to enable editing.
At 0x21581
in 1ST_READ.BIN is a string that is prepended to strings in the script files that contain the map location label: "@fs22,22@fm24,0"
When the map label is rendered, the number of characters in the string in the script file is used to calculate the length of the label graphic. It is recommended to edit kanji tiles in SKFONT.CG into the translated text and change the string in the script file to the former kanji. In order to facilitate this change, the above string should be changed to "@fs22,22@fm22,0", setting the @fm
value equal to the @fs
value.
- Follow the instructions on creating custom font tiles, then replace tiles beginning at the first Shift-JIS characters at
0x28998
: "亜唖娃阿哀愛挨姶逢葵". - In the script file, replace the name of the label with each kanji that was replaced with the custom tiles.
- Rebuild the image, then reach the map with the label that was replaced.
- Most likely, the tiles will need to be edited to center the text in the label. Using Cheat Engine, navigate to the memory address where the tiles were replaced.
- Update your tile image with the text position changed to center the label, then repeat step 1. Paste it over the original tile data. Repeat until the text is centered.
- If necessary, update the tile data in SKFONT.CG using Ghidra and export again.
This can be repeated as many times as needed with successive characters to translate all such labels. Because the font offset is changed to remove the gap between tiles, some experimentation with text placement within the tiles will be needed to center the label. In most cases, the text should be written slightly right of center. See the below example:
Formats
- ASCR format
- SBX/SBN
- LIP file
- SKFONT.CG
- ADCG texture
- BPV1 container
- LC1 file
- EYECATCH.BIN
- OpOption.bin
- Miscellaneous information
English translation technical details
Translation Instructions
- Extracting assets and rebuilding disc images
- Ghidra setup
- Emulation and memory searching
- Debugging Flycast with gdb-multiarch
- Script files
- Custom font tiles
- Map labels
- Editing compressed graphics
- Texture locations
- SRPG strings
- Menu strings
- Video encoding