The TRN files contain all data about tournaments. This includes the tournament logo, opponent stats, texts, quotes, etc. The format is based on reading offsets, with most of the file data being random trash. Sections of the file have been protected with a simple XOR operation.
The file contains texts and logos for certain languages for localization reasons. The languages (in correct order) are below:
Offset | Length | Type | Description |
---|---|---|---|
0 | 4 | int | Number of opponents in the tournament |
4 | 4 | int | Victory texts offset |
8 | 14 | string | Ending BK file used by the tournament. 14th byte is always 0. |
22 | 4 | float | Winnings multiplier |
26 | 4 | ? | ? |
30 | 4 | int | Registration fee |
34 | 4 | int | Assumed initial value |
38 | 4 | int | Tournament ID |
At offset 300 (0x12C), there is a list of dword file offsets, that tell the positions of enemy data blocks. Everything between this and the header block is trash data. The list has number_of_opponents + 1 entries, with the last entry being the first byte offset after the last block.
The first entry in the offset list tells the starting position of the enemy data blocks. This is usually (always?) at offset 1100 (0x44C). Everything between the end of the offset list and this position is trash data.
The enemy data block consists of two parts. The first is the block containing the enemy data, and the second one that contains the quote strings for the enemy.
This block is always exactly 428 bytes in length. It is XORred for each byte by linearly growing uint8 (starting from (428 & 0xFF), growing by 1, and wrapping around at 0xFF). This is essentially the same as in the language files. After de-xorring, the following data can be found:
Offset | Length | Type | Description |
---|---|---|---|
0 | 4 | dword | ? |
4 | 18 | byte[] | Enemy name |
22 | 2 | uword | Wins |
24 | 2 | uword | Losses |
26 | 2 | uword | HAR ID |
28 | 8 | byte[] | Enemy stats |
36 | 2 | uword | Offense |
38 | 2 | uword | Defense |
40 | 4 | udword | Money |
44 | 1 | ubyte | Color 1 |
45 | 1 | ubyte | Color 2 |
46 | 1 | ubyte | Color 3 |
TODO: Other bytes
After the data block comes the quote string block, which contains 10 strings for each language supported by OMF.
String format:
Offset | Length | Type | Description |
---|---|---|---|
0 | 2 | uword | String length. Always set, even if length is 0. |
2 | n | char[] | Variable size string, ending in 0. If string length is 0, this will not exist. |
This section starts directly after the last enemy data block, and can be easily found by jumping to the last offset in the enemy block offset list.
This block contains exactly 10 logos in the standard sprite format (one for each language). If the sprite does not exist, it has a length of 0 in the sprite header. The sprite headers will always exist, even if they do not have data. Nonexistant sprites may have random sizes, but their length will always be 0.
After the logo section, there is a single palette that can be used for rendering the logos. The palette is exactly 120 bytes (40 colors) long, and should be set to color offset 128 in palette when read. This is a standard 6bit VGA palette, so remember to do conversion!
char palette[256][3]; char temp[3]; for(int i = 128; i < 168; i++) { read_data(temp, 3); // Read a single palette color from the file palette[i][0] = ((temp[0] << 2) | (temp[0] >> 4)); palette[i][1] = ((temp[1] << 2) | (temp[1] >> 4)); palette[i][2] = ((temp[2] << 2) | (temp[2] >> 4)); }
This section starts directly after the palette, and contains simply the name of the related PIC file. The string is in the same format as the quote strings.
This section starts just after the PIC section. It contains the titles and descriptions of the tournament. There are 10 title-description pairs, each string in the same format as the quote strings.
for(int i = 0; i < 10; i++) { int title_len = read_uword(); if(title_len > 0) { string title_text = read_text(title_len); } int desc_len = read_uword(); if(desc_len > 0) { string desc_text = read_text(desc_len); } }
Victory texts start directly after the tournament descriptions. The offset can also be found in the file header. This is the last section of the file; after the victory texts the file ends.
For each language, there are defined 11 HARs. Each HAR may contain 10 strings of test (“pages”). The strings are in the same format as the quote strings. The reading can be done with simple nedted for-loops.
int language, har, page; for(language = 0; language < 10; language++) { for(har = 0; har < 11; har++) { for(page = 0; page < 10; page++) { int length = read_uword(); if(length > 0) { string text = read_text(length); } } } }