BMG (File Format)
A BMG file is a message file. Each message is referenced by a message id (MID).
Raw BMG File
The message file consists of a header and three data sections:
- The offset table into the string pool.
- The string pool with 16 bit wide characters.
- The list of related message ids (MID).
Header
In BMG files all numbers are stored in big endian format. Each BMG file starts with a BMG header:
Offset | Type | Description |
---|---|---|
0x00 | Char[8] | File magic. Always MESGbmg1 in ASCII. |
0x08 | UInt32 | Length of the file in bytes. |
0x0C | UInt32 | Number of sections. Usually 3, and sometimes 2 outside from MKWii. |
0x10 | byte | Encoding. 1=CP1252, 2=UTF-16, 3=Shift-JIS, 4=UTF-8. UTF16 in MKWii. |
0x11 | Byte[15] | Unknown. Probably padding. |
The header is followed by the sections. Each section starts with an section type independent part:
Offset | Type | Description |
---|---|---|
0x00 | Char[4] | Section magic. |
0x04 | UInt32 | Length of the section in bytes. |
- GNU C example
#define BMG_MAGIC "MESGbmg1" #define BMG_MAGIC_NUM 0x4d455347626d6731ull typedef struct bmg_section_t { char magic[4]; // a magic to identify the section be32_t size; // total size of the section u8 data[0]; // section data } __attribute__ ((packed)) bmg_section_t; typedef struct bmg_header_t { char magic[8]; // magic "MESGbmg1" be32_t size; // total size of file be32_t n_section; // number of sub sections be32_t unknown1; // = 0x02000000 char unknown2[0xc]; // unknown data bmg_section_t section[0]; // first sub header } __attribute__ ((packed)) bmg_header_t;
Text Index Table
The text index table is usually the first section of a BMG file.
Offset | Type Size |
Description |
---|---|---|
0x00 | Char[4] | Section magic. Always INF1 in ASCII. |
0x04 | UInt32 | Length of the section in bytes. |
0x08 | UInt16 | N = Number of messages. |
0x0A | UInt16 | LEN = The length of each item, always 8 in MKWii. |
0x0C | UInt32 | Unknown. Probably padding, usually 0. |
0x10 | N * LEN | N items of the length LEN. |
Format of each item:
Offset | Type Size |
Description |
---|---|---|
0x00 | UInt32 | Offset into text pool of the DAT1 section. |
0x04 | LEN - 4 | Attributes. The real length varies, but is equal for the same file. |
In Mario Kart Wii each item has 2 data members:
Offset | Type | Description |
---|---|---|
0x00 | UInt32 | Offset into text pool of the DAT1 section. |
0x04 | UInt32 | An attribute. The highest byte is used for font selection:
Other values are not used by Mario Kart Wii and most will freeze the game. |
- GNU C example
#define BMG_INF_MAGIC "INF1" #define BMG_INF_STD_FLAGS 0x01000000 typedef struct bmg_inf_item_t { be32 text_index; // offset into text pool be32 attribute; // attribute of the string, 0x01000000 is standard } __attribute__ ((packed)) bmg_inf_item_t; typedef struct bmg_inf_t { char magic[4]; // magic "INF1" be32_t size; // total size of the section be16_t n_msg; // number of messages be16_t inf_size; // size of inf items be32_t unknown; // = 0 bmg_inf_item_t list[0]; // data } __attribute__ ((packed)) bmg_inf_t;
String Pool
The second section contains the string pool. Strings are sequences of 16-bit values (like UTF-16 or Windows wide char) terminated by a NULL value. But NULL values are also possible in the middle of the string, if they are part of a 0x1A escape sequence.
Offset | Type | Description |
---|---|---|
0x00 | Char[4] | Section magic. Always »DAT1« in ASCII. |
0x04 | UInt32 | The total size of the section. Always a multiple of 4 and usually a multiple of 32. |
0x08 | Char16[*] | The string pool. |
- GNU C example
#define BMG_DAT_MAGIC "DAT1" typedef struct bmg_dat_t { char magic[4]; // magic "DAT1" be32_t size; // total size of the section u8 text_pool[]; } __attribute__ ((packed)) bmg_dat_t;
Message IDs
The third section contains the table with the message ids (MID). The number of elements of this table is equal to element number of the text index table. Elements with the same table index are attributes for the same string.
The start menu of the Wii uses similar BMG files, but without this »MID1« section. Without »MID1«, a BMG file is only an iteration of strings instead of a numerical indexed array.
Offset | Type | Description |
---|---|---|
0x00 | Char[4] | Section magic. Always MID1 in ASCII. |
0x04 | UInt32 | Length of the section in bytes. |
0x08 | UInt16 | N = Number of messages. |
0x0A | UInt16 | Unknown. Usually 0x1000. |
0x0C | UInt32 | Unknown. Probably padding, usually 0. |
0x10 | UInt32[N] | N message IDs (MID). |
- GNU C example
#define BMG_MID_MAGIC "MID1" typedef struct bmg_mid_t { char magic[4]; // magic "MID1" be32_t size; // total size of the section be16_t n_msg; // number of messages be16_t unknown1; // = 0x1000 be32_t unknown2; // = 0 u32 mid[0]; // message id table } __attribute__ ((packed)) bmg_mid_t;
0x1A Escape Sequences
Nintendo uses sequences starting with the 16 bit value 0x1A to embed binary data in the strings. This binary data may contain NULL values that normally used as end of string marker.
Offset | Hex Value | Description |
---|---|---|
0x00 | 001A | Start of the sequence. 0x1A is also known as CTRL-Z or ASCII SUB (substitute). |
0x02 | xxyy |
|
0x04 | nnnn | The binary value (big endian). The size depends on the xx above:
|
Here are some well known escape sequences:
Hex Values | Description |
---|---|
1A 602 0000 | Name of the current player. |
1A 800 0000 00xx | Set the font size to xx percent. |
1A 800 0001 00xx | Set the text color (xx: 00=grey, 02=white, 40+20+32=red, 30=yellow, 33=green, 21+31=blue, 08=transparent) |
1A 801 xxxx xxxx | Unicode character U+xxxxxxxx. |
1A 802 0012 0000 | Name of a player. |
1A A02 0010 000x 000y | Context dependent integer with (at least) #y digits. #x is a zero based index into the integer parameter list. |
For more escape sequences see the List of found 0x1A escape sequences.
BMG files in Mario Kart Wii
In Mario Kart Wii BMG files are only found in the language dependent SZS files of directory /Scene/UI. All language dependent files have an underscore and a language letter before .szs, like Event_G.szs. All BMG files can be found in a subdirectory of the SZS named /messages/. The file names are: Common.bmg, Menu.bmg, Number.bmg, Race.bmg and StaffRoll.bmg.
The messages are repeated in the different files. All messages with the same message ID of the same language have always the same text, no differences between the text files can be found.
Wiimms BMG Text File
Wiimm has specified a text representation of the BMG files for his SZS Tools. The idea is to make editing and creating string tables much easier for humans and scripts. Wiimms SZS Tools accept binary and text BMG files as input and can convert each format to each other. Moreover BMG files of both formats can be used to patch other BMG files of both formats.
→ Syntax and Semantics of BMG text files
Messages of Mario Kart Wii
Here you can find all messages of the supported languages of Mario Kart Wii as text files.
Tools
The following tools can handle BMG files:
- CTools Pack, by MrBean35000vr and Chadderz
- SZS Modifier, by MrBean35000vr and Chadderz
- Wiimms SZS Tools, by Wiimm
Only Wiimms SZS Tools can handle BMG-Text files.