Advertisement
Moolah60

BMG Doc

May 15th, 2019
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.53 KB | None | 0 0
  1.     // Binary Message Group (BMG) file structure documentation
  2.     //
  3.     // INFO:
  4.     //  BMG files contain sections that have information about text in a game.
  5.     //  It is a proprietary format that Nintendo has used off and on for almost two decades now.
  6.     //  A precursor to BMG files existed from around 2000 until 2002.
  7.     //  The precursor had the BMG INF & DAT sections split up into two files.
  8.     //
  9.     // HEADER:
  10.     //  The BMG structure begins with a 32 (0x20) byte header.
  11.     //  The header is as follows:
  12.     //      Magic:          char[]  8 bytes (MESGbmg1)
  13.     //      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.)
  14.     //      Section Count:  uint    4 bytes Number of sections contained in the file.
  15.     //      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+.)
  16.     //      Padding:        byte[] 15 bytes Unused data. May have been reserved for future format revisions.
  17.     //
  18.     // ENCODINGS:
  19.     //  From what I have found, there are four encoding types.
  20.     //      1 = CP1252 (Also known as Windows 1252)
  21.     //      2 = UTF-16
  22.     //      3 = Shift-JIS
  23.     //      4 = UTF-8
  24.     //
  25.     //  NOTE: There may be more encoding types. As mentioned before, the BMG's encoding type does not necessarily mean that the text data
  26.     //        will be encoded in the set format. Some games implement a custom encoding scheme and ignore the BMG's encoding type.
  27.     //
  28.     // SECTIONS:
  29.     //  BMG files consist of the header, and a specified number of sections.
  30.     //  Each section has a Magic that identifies what it is.
  31.     //  Sections must be aligned to 32 (0x20) bytes.
  32.     //  I have seen a few different section types. Developers may be able to specify custom section types as well.
  33.     //  There are two sections that are mandatory for a BMG file to have. The INF1 & DAT1 sections.
  34.     //  These are the known sections:
  35.     //      INF1:
  36.     //          [REQUIRED SECTION]
  37.     //          Long name: Info
  38.     //          Description: Contains information about each message in the BMG file.
  39.     //          Header Structure: 16 (0x10) bytes in size.
  40.     //              Magic:      char[]   4 bytes (INF1)
  41.     //              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.
  42.     //              EntryCount: ushort   2 bytes The number of message info entries.
  43.     //              EntrySize:  ushort   2 bytes The size of each message info entry.
  44.     //              Padding:    byte[]   4 bytes Unknown and possibly unused.
  45.     //          
  46.     //          InfoEntries[]: EntryCount * EntrySize.
  47.     //              DataOffset: uint     4 bytes Offset into the DAT1 section where the message begins.
  48.     //              Parameters: dynamic[] ??     The leftover data is usually used for game-specific parameters.
  49.     //
  50.     //          NOTE: A good way to get the actual INF1 size is as follows: int INFSize = ((INF.EntryCount * INF.EntrySize) + 0x1F) & ~0x1F;
  51.     //                It is possible that the developers added extra padding between the end of the section and the next section.
  52.     //                Either way, this should at least be checked for good measure.
  53.     //          NOTE: This section is meant to always be the first section.
  54.     //
  55.     //      DAT1:
  56.     //          [REQUIRED SECTION]
  57.     //          Long name: Data
  58.     //          Description: Contains the encoded message data for every message.
  59.     //          Header Structure: 8 bytes in size.
  60.     //              Magic:      char[]   4 bytes (DAT1)
  61.     //              Size:       uint     4 bytes Size of the section. Usually is accurate.
  62.     //
  63.     //          TextData: byte[INF.EntryCount][dynamic]
  64.     //              Contains the encoded message data for each message.
  65.     //              To calculate the size of a given message, the following formula can be used:
  66.     //                  int messageSize = 0;
  67.     //                  if (entryNum < INF.EntryCount - 1) {
  68.     //                      messageSize = INF.Entries[entryNum + 1].DataOffset - INF.Entries[entryNum].DataOffset;
  69.     //                  }
  70.     //                  else if (entryNum == INF.EntryCount - 1) {
  71.     //                      messageSize = DAT.Size - INF.Entries[entryNum].DataOffset;
  72.     //                  }
  73.     //
  74.     //      MID1:
  75.     //          [OPTIONAL SECTION]
  76.     //          Long name: Message IDs
  77.     //          Description: Contains a message id for each message.
  78.     //          Header Structure: 16 (0x10) bytes in size.
  79.     //              Magic:      char[]   4 bytes (MID1)
  80.     //              Size:       uint     4 bytes Size of the section.
  81.     //              EntryCount: ushort   2 bytes The number of message id entries. Should be the same as in INF1 section.
  82.     //              Unknown:    ushort   2 bytes Unknown. May be a single byte. Possibly flags? Seems to usually be 0x1000.
  83.     //              Padding:    byte[]   4 bytes Unknown and possibly unused.
  84.     //
  85.     //          MessageIDs: uint[EntryCount]
  86.     //              Each message id entry corresponds to the info & data entry with the same index.
  87.     //              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