Map Data String Body

The String Data Section Body
String Sections appear as part of a GameX MSQ Block or located in the Data Segment 2 of the WL.EXE file.

They are a container for textual information. They are divided into two parts, a Strings Header and a Strings Body (described here).

The individual strings are compressed using a standard String Compressor. The Header contains a key for decrypting the strings, and a pointer table which tells how the Body is split up. Each entry in the Pointer Table points to a separate string in the body.

The Strings section is basically a list of all the text strings spewed by the game. The Strings Section in a GameX MSQ block contains the strings pertinent to the current map (Since each MSQ block contains the data for exactly one map).

The Strings Sections found in the WL.EXE program contain stuff which appears at specific points in the game, and in various menus and so on.

The strings in the body are laid out end-to-end and are compressed into a 5-bits-per-character representation. Except for a few 'control codes', each 5-bit value represents an entry in the Character Table. See the String Compressor page for more details and examples. The encoding for each string section starts at bit 0 of the byte pointed-at by its entry in the pointer table. At the end of a string, a '0x00' is found, which indicates that the decryption should stop. Therefore, each string is encoded separately, and there's no need to decrypt all of the strings in order to just read one half-way-through.

Separate Encodings for each string?
Unlike the map data, which needs to be all available at once, decoding all the strings at once would be a monumental waste. The user may never need to access a string. Therefore, each string is encoded separately. The Pointer in the Strings Header associated with this string will point to its first byte, where the encoding starts. This then runs until the character code 0x00 falls out from the decoding algorithm, at which point the string terminates. This means that the program only needs to decode a string at the point where it needs it, rather than decoding the whole kit and caboodle and having it hanging about in memory until it's used.

Issues?
Well, the first two bytes after the end of the Strings Header Pointer Table seem to be random. We're not sure what they do. They're not part of the first string, and are never accessed. No pointer points at them, and they are not part of a string. They may be 'end of pointer list' markers, but in that case are redundant because the end of the pointer list is 2bytes before the first entry in pointer table, as with every other pointer table in the gameX file.

Also, the first string "The Limestone cliffs..." in the Highpool map //starts// with the 0x00 character, which is normally used to terminate strings. Therefore, a special flag must be kept around to keep a note whether the first character is 0x00, and discard it (since an empty string is pointless). Our best guess at the moment is that this is done for padding reasons to ensure everything starts on a byte boundary.

How all this was discovered
By lots of hard work, and endless trawling through Assembler. Also, by the use of copious quantities of coffee. Some lateral thinking was also used. Because of the link to Coffee and Thinking, and in memory of the hard-working developers who devised this masochistic scheme (evil so-and-sos!), we dedicate the following passage:

It is by caffeine alone I set my mind in motion.

It is by the beans of Java that thoughts acquire speed,

the hands acquire shaking,

the shaking becomes a warning.

It is by caffeine along I set my mind in motion.

{comment by eyemixer} Just imagine if you guys had the real spice :D