Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Binary Message Group (BMG) file structure documentation
- //
- // INFO:
- // BMG files contain sections that have information about text in a game.
- // It is a proprietary format that Nintendo has used off and on for almost two decades now.
- // A precursor to BMG files existed from around 2000 until 2002.
- // The precursor had the BMG INF & DAT sections split up into two files.
- //
- // HEADER:
- // The BMG structure begins with a 32 (0x20) byte header.
- // The header is as follows:
- // Magic: char[] 8 bytes (MESGbmg1)
- // File Size: uint 4 bytes (NOTE: This is sometimes wrong. Developers may have modified it by hand, or there may have been a bug in the packing tool.)
- // Section Count: uint 4 bytes Number of sections contained in the file.
- // Encoding: byte 1 byte The encoding format used in the BMG. (NOTE: This does not always mean that the text data will be encoded in that format. Some games use proprietary formats e.g. Animal Forest e+.)
- // Padding: byte[] 15 bytes Unused data. May have been reserved for future format revisions.
- //
- // ENCODINGS:
- // From what I have found, there are four encoding types.
- // 1 = CP1252 (Also known as Windows 1252)
- // 2 = UTF-16
- // 3 = Shift-JIS
- // 4 = UTF-8
- //
- // NOTE: There may be more encoding types. As mentioned before, the BMG's encoding type does not necessarily mean that the text data
- // will be encoded in the set format. Some games implement a custom encoding scheme and ignore the BMG's encoding type.
- //
- // SECTIONS:
- // BMG files consist of the header, and a specified number of sections.
- // Each section has a Magic that identifies what it is.
- // Sections must be aligned to 32 (0x20) bytes.
- // I have seen a few different section types. Developers may be able to specify custom section types as well.
- // There are two sections that are mandatory for a BMG file to have. The INF1 & DAT1 sections.
- // These are the known sections:
- // INF1:
- // [REQUIRED SECTION]
- // Long name: Info
- // Description: Contains information about each message in the BMG file.
- // Header Structure: 16 (0x10) bytes in size.
- // Magic: char[] 4 bytes (INF1)
- // Size: uint 4 bytes Size of the section. Do not trust this. Some BMG files have had incorrect sizes. The developers likely modified it manually.
- // EntryCount: ushort 2 bytes The number of message info entries.
- // EntrySize: ushort 2 bytes The size of each message info entry.
- // Padding: byte[] 4 bytes Unknown and possibly unused.
- //
- // InfoEntries[]: EntryCount * EntrySize.
- // DataOffset: uint 4 bytes Offset into the DAT1 section where the message begins.
- // Parameters: dynamic[] ?? The leftover data is usually used for game-specific parameters.
- //
- // NOTE: A good way to get the actual INF1 size is as follows: int INFSize = ((INF.EntryCount * INF.EntrySize) + 0x1F) & ~0x1F;
- // It is possible that the developers added extra padding between the end of the section and the next section.
- // Either way, this should at least be checked for good measure.
- // NOTE: This section is meant to always be the first section.
- //
- // DAT1:
- // [REQUIRED SECTION]
- // Long name: Data
- // Description: Contains the encoded message data for every message.
- // Header Structure: 8 bytes in size.
- // Magic: char[] 4 bytes (DAT1)
- // Size: uint 4 bytes Size of the section. Usually is accurate.
- //
- // TextData: byte[INF.EntryCount][dynamic]
- // Contains the encoded message data for each message.
- // To calculate the size of a given message, the following formula can be used:
- // int messageSize = 0;
- // if (entryNum < INF.EntryCount - 1) {
- // messageSize = INF.Entries[entryNum + 1].DataOffset - INF.Entries[entryNum].DataOffset;
- // }
- // else if (entryNum == INF.EntryCount - 1) {
- // messageSize = DAT.Size - INF.Entries[entryNum].DataOffset;
- // }
- //
- // MID1:
- // [OPTIONAL SECTION]
- // Long name: Message IDs
- // Description: Contains a message id for each message.
- // Header Structure: 16 (0x10) bytes in size.
- // Magic: char[] 4 bytes (MID1)
- // Size: uint 4 bytes Size of the section.
- // EntryCount: ushort 2 bytes The number of message id entries. Should be the same as in INF1 section.
- // Unknown: ushort 2 bytes Unknown. May be a single byte. Possibly flags? Seems to usually be 0x1000.
- // Padding: byte[] 4 bytes Unknown and possibly unused.
- //
- // MessageIDs: uint[EntryCount]
- // Each message id entry corresponds to the info & data entry with the same index.
- // Example: MessageIDs[0] is set to 0x0A (10). This means that the first entry in the file can be accessed by requesting message 0x0A.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement