LEX (File Format)

From Custom Mario Kart
Jump to: navigation, search
Lecode-circ-160x160.png

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 otherwise.

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.

LE-CODE supports 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 a section 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 sections. The chain of sections is closed by a special termination section.

All values are stored in network byte order (big endian). Each section is aligned to 4 bytes.

File header of LEX files
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 section 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 section of the chain at offset 0x10. Use Offset of first section instead.

The list of sections is managed as chain. The header of each section contains a magic to identify it, and the size of the embedded data:

Section header of LEX files
Offset Type Description
0x00 uint32 A magic to identify the section (type of section). An alternative datatype is char[4].
0x04 uint32 Size of the section data. It is an offset to the next section relative to the data member too. The size is always a multiple of 4.
0x08 u8[SIZE] Binary data of the section.
0x08+SIZE The next section
Notes
  • Duplicates of the same section are forbidden.
  • The chain of sections is well ordered. Tools should usually not change this order, except they know exactly what they do.
  • The offset of the next section is: current_offset + 8 + section_size
  • Magic and size of the final section (terminator) are 0.

Example Implementation

For example code in C, see »LEX (File Format)/C example«.

Sections

Each section 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.

List of defined sections
Identity / Magic Date of
definition
Description
ASCII uint32
0 2019-02-28 Termintor of chain.
---- 0x2d2d2d2d 2019-02-28 Invalidated section. Ignore it.
CANN 0x43414e4e 2019-02-28 Cannon settings.
TEST 0x54455354 2020-01-10 Define test settings.

CANN : Cannon settings

Data of section "CANN" (ID 0x43414e4e)
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.

TEST: Define test settings

Section TEST defines values to test scenarios build by Extended presence flags. The idea is to force different modes so that a single player can test all possible scenarios offline. This test section should only be used during track testing, a finished released custom track should not contain a TEST section in its LEX file. Option --lt-clear of Wiimms SZS Tools remove the test section on creating or patching a track file.

Data of section "TEST" (ID 0x54455354)
Offset Type Name Description
0x00 uint8 OFFLINE-ONLINE If 1: Force offline mode. If 2: Force online mode. Otherwise enable automatic detection.
0x01 uint8 N-OFFLINE If >0: Force number of players at Wii. It is robust, so values >4 are accepted, but rounded down to 4 (offline) or 2 (online).
0x02 uint8 N-ONLINE If >0: Force number of total players for online modes. It is robust, so values >99 are rounded down to 99. Can be combined with FORCE-ONLINE.
0x03 int8 COND-BIT If between 0 and 15: If testing the settings (1-8) of a DEFINITION_OBJECT for CONDITIONS, ignore the calculation of a bit number by previous data members and use this bit number.
0x04 uint8 GAME-MODE Force a game mode: 0=AUTO (default), 1=STANDARD (ignore extension), 2=BALLOON, 3=COIN, 4=VERSUS, 5=ITEMRAIN.
0x05 uint8 RANDOM If between 1 and 6: Force a random scenario.
0x06 2bytes padding

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. Without keyword, you get a list of possible keywords.

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 track's SZS. Option --overwrite (short: -o) allows the tool to overwrite an already existing file. Use this command after every change of of the text 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. It is also possible to redirect the output to a file:

wlect cat course.lex
wlect cat course.lex > proof.txt