LEX (File Format)
LEX (LE-CODE Extension) is a file format defined by Wiimm. A LEX file is usually stored as part of a track SZS under the name course.lex. It's like KMP's course.kmp, but it provides additional settings and modifications outside of a KMP. The main idea is, that global game settings can be overridden by track dependent settings in cases, where it is not possible yet.
LEX is designed to be open for future extension by third persons. Anyway, each new section identifier (a 4 byte ASCII magic) should be requested to Wiimm. He will guarantee unique identifiers.
At least LE-CODE will support LEX. Maybe CTGP will do it too.
Design Notes
There were some prerequisites before the definition of the file format:
- The format should be open for future extensions.
- Extensions are managed by sections. Each section is identified by an unique ID (magic).
- ID (magic) should be 4 ASCII characters to make viewing by a hex-dumper easier.
- Old implementations must work, event if new unknown subtypes were added. Therefore, the code needs an easy skip mechanism.
- Tools to edit LEX files must be able to handle unknown subtypes as well (not deleting them when saving).
- The order must be stable to support sections, that depend on other prior defined sections.
- Fast and easy scanning support.
- The data of an element should be easy to use for the game extender like LE-CODE.
File Format
Each file starts with a LEX header, followed by a sequence of LEX elements. The chain of elements is closed by a special termination element.
All values are stored in network byte order (big endian). Each element is aligned to 4 bytes.
Offset | Type | Description |
---|---|---|
0x00 | char[4] | File magic, always »LE-X« |
0x04 | uint16 | The major version number. Usually 1. It is incremented, if the data structure changes in an incompatible way. This is not expected. |
0x06 | uint16 | The minor version number. It starts with 0 and is incremented, if this header is expanded in a compatible way. |
0x08 | uint32 | Total size of file. Use it for sanity cheeks. |
0x0c | uint32 | Offset of first element of the chain relative to the beginning of this structure. Usually the value is 0x10, but this may change in future versions. |
0x10 | End of file header |
- Notes
- The version number is printed as »%u.%u«. At the moment it is 1.0.
- Don't expect the first element of the chain at offset 0x10. Use Offset of first element instead.
The list of elements is managed as chain. The header of each element contains a magic to identify it, and the size of the embedded data:
Offset | Type | Description |
---|---|---|
0x00 | uint32 | A magic to identify the element (type of element). An alternative datatype is char[4]. |
0x04 | uint32 | Size of the element data. It is an offset to the next element relative to the data member too. The size is always a multiple of 4. |
0x08 | u8[SIZE] | Binary data of the element. |
0x08+SIZE | The next element |
- Notes
- Duplicates of the same element are forbidden.
- The chain of elements is well ordered. Tools should usually not change this order, except they know exactly what they do.
- The offset of the next element is: current_offset + 8 + element_size
- Magic and size of the final element (terminator) are 0.
Example Implementation
For example code in C, see »LEX (File Format)/C example«.
Elements
Each element has its own identity (magic). This magic is an integer of 4 bytes. It can be interpreted as 4 characters. So it created by printable ASCII characters. At the moment, the identities are manged by Wiimm to guarantee unique values.
Identity / Magic | Date of definition |
Description | |
---|---|---|---|
ASCII | uint32 | ||
0 | 2019-02-28 | Termintor of chain. | |
---- | 0x2d2d2d2d | 2019-02-28 | Invalidated element. Ignore it. |
CANN | 0x43414e4e | 2019-02-28 | Cannon settings. |
CANN : Cannon settings
Offset | Type | Description |
---|---|---|
0x00 | uint32 | N = Number of defined cannon types |
0x04 | float[4] | 4 settings for cannon type #0 |
0x14 | float[4] | 4 settings for cannon type #1 |
0x24+ | ... | |
4+N*16 | End of data |
See »Cannon Characteristics« for details about the settings. This format can be used to define more than three cannon types, but doing so makes the track incompatible with distributions not supporting the LEX file format.
Wiimms SZS Tools
As of v2.01a, Wiimms SZS Tools will support LEX files. The implementation is similar to KMP:
- Command wlect cat[1] will print the content of a LEX file to stdout.
- Command wlect decode[2] will decode a binary LEX file into a text form, that can be modified by tools and editors.
- Command wlect encode[3] will create a text file into a binary LEX file. There a 2 pass compiler is used.
- Command wszst lex[4] will search file course.lex and will print the content of it to stdout.
- Encoding and decoding is integrated in tool wszst for automated decoding and encoding (like KMP before).
- Commands filetype and fileattrib of all tools detect LEX files (binary and text).
Example commands
Command wlect create will create an LEX text file as template:
wlect create lex > course.lex.txt
Use command wlect encode to create a binary LEX file after your edits. The output is stored as course.lex and can be copied to the tarck's SZS. Option --overwrite (short: -o) allows the tool to overwrite an already existing file.
wlect encode -o course.lex.txt
Use command wlect cat to view the content of a binary LEX file as text in a console window:
wlect cat course.lex