This page describe all information needed to translate Final Fantasy II (US version which is (almost) equivalent to Final Fantasy IV Japanese version) to other language (than English).
Some part of this information may be able to apply to Japanese version of Final Fantasy IV.
I released the first version early September. The document is far from complete, but I will continuously update it along with my FF4 Thai translation.
Current know FF2 translation project are Spanish translation and Thai translation.
You may want to read basic concept on translating game ROM. These are some useful links.
These are the tools I use.
Figure 1. FF2 font table. The tile No. 8Ah - BFh and CAh - F6h are
free (letter v, w, H, ... and v at bottom are not used.)
Code.
Unfortunately, the code used in FF2 is not ASCII. It is propritary code. From
figure 1, capital letter A - Z are located at 42h - 5Bh, lower letter a - z
are located at 5Ch - 75h. Digit 0 - 9 are located at 80h - 89h. Finally,
some mark are located at C0h - C9h.
For example, the word 'Hello.' will be kept in ROM as 49h 60h 67h 67h 6Ah
C1h.
Dual-tile encoding.
Most story texts in FF2 are kept compressed. They are encoded with simple
algorithm 'Dual-tile encoding'. Square select most frequency used
two-character such as 'th', 'at', 're', etc. and use single byte to represent
these two-character set. For example, 8Ch is used to keep 'th' and 8Dh is
used to keep 'he'.
80h | 0 | 90h | a | A0h | yo | B0h | en | C0h | ' | D0h | et | E0h | ot | F0h | ge | |||||||
81h | 1 | 91h | s | A1h | y | B1h | ed | C1h | . | D1h | le | E1h | be | F1h | n | |||||||
82h | 2 | 92h | er | A2h | i | B2h | hi | C2h | - | D2h | f | E2h | el | F2h | ee | |||||||
83h | 3 | 93h | in | A3h | al | B3h | or | C3h | _ | D3h | g | E3h | om | F3h | wi | |||||||
84h | 4 | 94h | re | A4h | ar | B4h | , | C4h | ! | D4h | es | E4h | 's | F4h | M | |||||||
85h | 5 | 95h | d | A5h | h | B5h | I | C5h | ? | D5h | ro | E5h | il | F5h | ke | |||||||
86h | 6 | 96h | an | A6h | r | B6h | u | C6h | % | D6h | ne | E6h | de | F6h | we | |||||||
87h | 7 | 97h | o | A7h | s | B7h | me | C7h | / | D7h | ry | E7h | gh | F7h | p | |||||||
88h | 8 | 98h | on | A8h | at | B8h | ta | C8h | : | D8h | l | E8h | ay | F8h | ig | |||||||
89h | 9 | 99h | st | A9h | n | B9h | b | C9h | , | D9h | us | E9h | nt | F9h | ys | |||||||
8Ah | e | 9Ah | w | AAh | c | BAh | I | CAh | f | DAh | no | EAh | Wh | FAh | B | |||||||
8Bh | t | 9Bh | o | ABh | ng | BBh | te | CBh | d | DBh | ut | EBh | Yo | FBh | am | |||||||
8Ch | th | 9Ch | m | ACh | ve | BCh | of | CCh | ow | DCh | ca | ECh | wa | FCh | ld | |||||||
8Dh | he | 9Dh | ha | ADh | ll | BDh | ea | CDh | se | DDh | as | EDh | oo | FDh | W | |||||||
8Eh | t | 9Eh | to | AEh | y | BEh | ur | CEh | DEh | Th | EEh | We | FEh | la | ||||||||
8Fh | ou | 9Fh | is | AFh | nd | BFh | l | CFh | it | DFh | ai | EFh | g | FFh |
There are a lot of free space in character table to do this. Square use data from 8Ah to BFh and CAh to FEh to keep these two-character.
For example, the word 'thank' can be kept in ROM as 8Ch 96h 66h. This can save two bytes. Imagin that there are tens of kilobyte of text, thus dual-tile encoding can save a lot of space.
The decoding can be disable so you will see actual data instead of two character it represent. For example, you will see the tile 8Ch instead of letters 'th' in above example. You can change the font so you will know that the tile 8Ch is displayed.
To disable the decoding, change the byte 003472h in ROM image from 8Ah to
FFh.
Texts Address.
There are a lot of text in the game, character names, items, magics, etc.
They are located in groups and thus translating them is easy. However,
curtain text are encoded with dual-tile encoding. Most of story text and
conversation do, also some of message dialogs.
Text in FF2 can be divided into 2 groups, series of constant length text and variable length text. First group consists of character names, jobs, items, monster and called monster. Second group can be devided into 2 types, story text and other text. Story text is big issue so I will discuss it in next section.
All constant length text are kept unencoded. Most story text are kept encoded and some of other text does.
Constant length texts are kept in series. Table 2 shows start address of each series, size of each item and number of items in series.
Texts | Start Addr | Size | Number |
Character Names | 07A910h | 06h | 000Eh |
Jobs | 07A964h | 07h | 000Eh |
Items | 078200h | 09h | 0100h |
Magic | 078B00h | 06h | 0048h |
Monster | 071A00h | 08h | 00E0h |
Called Monster | 078CB0h | 08h | 0068h |
All texts in option screen except the word Level are kept unencoded. Search for them strightforwardly.
Story Text.
Stories are kept at various address in the ROM. It is impossible to list all
of them here. Just search it by using Hex Editor. Or you can wait me to
release my searching tool. (I can't guarantee when will it be released!)
If you decide to search, make sure that you have disabled the dual-tile encoding. Or you won't found them.
There are a lot of code used in story text. For example, the code 01h means new line marker, the code 09h means one blank line, etc. Table 3 shows known codes.
Code | Meaning |
00h | End of message marker |
01h | End of line marker |
02h | Unknown |
03h XXh | Sound Effect (To be explain.) |
04h XXh | Character name. See Characters subsection below. |
05h | Unknown |
06h XXh | Some constant used in status box (at the top of screen in fighting screen.) For example, 'Learn xxx', 'Receive xxx GP', etc. (To be explain.) |
07h | Unknown |
08h | Unknown |
09h | One blank line. Use more than one of 01h to put more than one blank line won't work. You can put 01h at the first position to advance to new line. But next blank line, you need 09h. |
Characters Due to the fact that player can change character's name. The name mentioned in any text was kept as a code. For example, Cecil's name was kept as 04h 00h. This 2 bytes code represents Cecil's name (whatever his name is.)
Name | Code | Name | Code | |
Cecil | 04h 00h | Palom | 04h 07h | |
Kain | 04h 01h | Porom | 04h 08h | |
Rydia | 04h 02h | Cid | 04h 09h | |
Tellah | 04h 03h | Edge | 04h 0Ah | |
Edward | 04h 04h | FuSoYa | 04h 0Bh | |
Rosa | 04h 05h | Golbez | 04h 0Ch | |
Yang | 04h 06h | Anna | 04h 0Dh |
For example, the text 49h 64h C4h FFh 04h 00h C1h represents "Hi! Cecil."
Level, Parry and Change.
The word 'Level' in option screen and 'Parry' and 'Change' in fighting
screen are very annoying. How hard method square use to keep easy word! I
found that the word 'Parry' is kept as 'Pary' and the word 'Change' is kept
as 'Chnge'. 'Pary' is kept at 0B7D90h and 'Chnge' is kept at 0B7D94h
When the word will be displayed, the game insert third letter of 'Pary' (r) at forth position. Thus makes the word 'Parry'! The bad thing goes worse, the game use second letter of word 'Pary' inserts at third position of 'Chnge'. And... Haleluya! We get 'Change'!
I will work to disable those insertions. But as I know *very* little about 65816 assembly, don't expect it will be solve soon. (It may not be solved by me at all.)
I still don't know about the word 'Level'. :-(
![]() |