HeroQuest Strings Format

From ModdingWiki
Jump to navigation Jump to search

The .BIN files in HeroQuest are used to store any text in the game that is not contained inside the QUESTxx.BIN files. These are the files that do not have the "QUEST##.BIN" format.
It is basically an LZW compressed archive with the pointer section on the top and a block containing all the text formatted to fit the scroll graphic.
Each message in the game is written onto a scroll. Both the text and the scroll are drawn relative to the 18×27 (hex values) matrix screen. 00 00 is top left, 18 27 is bottom right.
The following header precedes each text in the language file:

File structure

0x0000-0x0253 - The first 596 Bytes contains the 298 pointers of the strings within the files relative to the top.
0x0254-0x???? - Size is variable, depending on the language used.

It is possible to add space at the bottom of the file to add new strings (not every pointer at the top of the file are actually used) or relocate there those who need more space for the text.
The size limit for the unpacked file is 16.701 Bytes (413Dh).


05 05 14 07 0D 09 6B 35 00 00 FF FF 11 05 05
|  |  |  |  |  |  | /   |  |  |  |  |  |  |
|  |  |  |  |  |  |/    |  |  |  |  11 Y  X  First line header
|  |  |  |  |  |  |     |  |  |  |
|  |  |  |  |  |  |     Fixed code, means end of options
|  |  |  |  |  |  "1st option" string pointer (usually "OK")
|  |  |  |  X  Y "1st option" string position
|  |  |  Scroll height (UPPER ROLL + PAPER containing TEXT LINES + LOWER ROLL)
|  |  Scroll lenght (lenght changes only on even values 1A, 1C etc.)
X  Y  Scroll's top-left position

The pointers in the first block points directly to the first byte of the above header in case of "text in a scroll". For normal labels (like Strenght potion) the pointer marks the first letter of the label.
The "first option" is in the most cases, OK, CANCEL, CONGRATULATIONS. There are some occasions when the game asks the player to choose between two options; the second option is injected between those two zeroes in the exact same fashion of the first option: 4 bytes (X,Y,pointer).
The Line header precedes each following line of the box.
The start position coordinates can be adjusted at will.
Each string must ends with 0x00. That's the stop character.
The language.bin files must be recompressed to be accepted as proper file, though a dummy-compression is sufficient.

Accented characters

b = à
e = è
v = ù
p = ò


88ED is the function that draws the scroll.

To find out in the QUEST.EXE code where a particular string is located, search for opcodes of mov bx or mov si followed by the pointer offset in LANGUAGE.BIN.
So if you want to search the code for the string pointed by 0246 search for:
BB4602 (mov bx, 0246)
BE4602 (mov si, 0246)

If bx is used, then 88ED is called right after, if si is used then 1A35 is called (that moves si to bx first then calls 88ED):

01EF:1A35 8BDE      mov  bx,si
01EF:1A37 E8B36E    call 000088ED ($+6eb3)

Research credits

  • The compression was figured out by Shelwien from encode.su forum
  • TheRuler from the OldGamesItalia translation project mapped the format of the strings files.