TextBox
TextBox are mainly found in the menu, for example for the tutorial. They can be composed of:
- An ID
- A title
- A parent TextBox ID (the one we used to get to the current TextBox)
- Often different cursor location id
- Button info
- And sometimes a left box id and/or a right box id to be able to move with the left or right cross.
These pages power the Information menu (main menu → Information): a hypertext browser (menu program 21) with links, a parent page per entry and a 127-deep navigation history.
There are 6 sections with string info in it (raw files 128-133 of mngrp.bin), and before those a “Seek map” section (raw file 127) which indicates the position of every String Entry.
Seek Map
The seek map (raw file 127, loaded to its own buffer at menu start of the Information browser) is composed of 4 bytes containing the number of seek locations, then 4 bytes per seek location. So the total size of the seek map is 4 + 4*(Number seek). The seek index is the page id used by links and by the parent/left/right fields.
Number seek
| Type | Size | Value | Description |
|---|---|---|---|
| UInt32 | 4 | Count | Number of seek locations. |
Seek location info
| Type | Size | Value | Description |
|---|---|---|---|
| UInt16 | 2 | Seek_Location | From beginning of section to start of String Entry |
| UInt16 | 2 | Section_Number | 0-5 |
String Entry
Then each string complex section is composed of the following data:
| Type | Size | Value | Description |
|---|---|---|---|
| UInt16 | 2 | Parent TextBox ID | 0xFFFF for the first TextBox |
| UInt16 | 2 | Left TextBox ID | 0xFFFF if no TextBox linked |
| UInt16 | 2 | Right TextBox ID | 0xFFFF if no TextBox linked |
| UInt16 | 2 | Entry_Length | Exact length of the entry in bytes, from the start of the entry, terminators included. |
| FF8 String | Depends | Title | The title of the TextBox, no offset specified to know the end. The 0x00 determines the end of the title |
| FF8 String | Entry_Length - 8 - Title_size | TextBox content | The text in the TextBox, ends with 0x00 |
Entries start on a 4-byte boundary: the next entry begins at align4(entry_start + Entry_Length), so 0 to 3 padding bytes (0x00) can follow an entry.
How the engine reads an entry
The in-game information browser locates an entry through the Seek Map, then:
- reads the three link IDs at +0/+2/+4 (Parent is followed with the Square button, the two others with the page-navigation buttons; 0xFFFF disables the button),
- ignores Entry_Length entirely,
- copies the title from +8 up to its 0x00 terminator,
- takes the content as the string starting right after the title terminator.
So Entry_Length and the 4-byte alignment are storage conventions of the original files rather than something the browser depends on, but tools should preserve them.
Content control codes
Besides the normal FF8 String codes, the Information browser interprets two extra codes inside the TextBox content:
- 0x0A n — visibility / dynamic value:
- n = 0x3F: the following text is always visible;
- n = 0x40-0xBF: the following text is only visible if bit (n - 0x40) of the savemap tutorial-info bitfield is set (topics unlocked as the story progresses);
- n ≥ 0xC0: inserts a live counter as digits: (n - 0xC0) = 0 steps walked, 1 total battles, 2 battles won, 3 battles escaped, 16-23 kill count of character 0-7, 24-31 KO count of character 0-7, 32-47 kill count of GF 0-15, 48-63 KO count of GF 0-15.
- 0x0B a b — link hotspot: places a selectable cursor position at the current text location, jumping to page id (a « 7) + b - 4128 on confirm.
Engine addresses (FF8 PC 2000, FF8_EN.exe)
| Address | Name | Role |
|---|---|---|
| 0x4D5F10 | Menu_InfoBrowser_Update | Loads TextBox sections (mngrphd entry 128 + section number) and resolves entries via the map |
| 0x4D6B20 | Menu_InfoBrowser_ParseContent | Parses a page content: control codes above, link hotspots, text metrics |
| 0x4D5E00 | (program 21 init) | Builds the topic list (EXE table 0xB88578 filtered by unlocked topics) and loads the seek map (raw 127) |
| 0x1D82E48 | (loaded Seek Map) | RAM copy of the map; entries from +4: per page {LOWORD: entry offset, HIWORD: section number} |