Msbt: Difference between revisions

3,862 bytes added ,  4 years ago
no edit summary
imported>Zephenryus
(Added msbt File Specification)
 
imported>CEObrainz
No edit summary
 
(19 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{lowercase}}
{{lowercase}}
<onlyinclude>
<onlyinclude>
<code>msbt</code> files are message standard binary files. These files define how text is displayed and interacted with by the player.
'''MeSsage StuDio BiNary Text'''
<code>MSBT</code> files are Message Studio Binary files. These files define how text is displayed and interacted with by the player.
</onlyinclude>
</onlyinclude>


== msbt File Layout ==
== msbt File Layout ==
msbt files are made up of four sections that are aligned to 16-bytes.
msbt files are made up of four sections that are aligned to 16-bytes.
* Header
* Header
* Labels
* Labels
Line 16: Line 15:


=== Header Structure ===
=== Header Structure ===
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 31: Line 29:
| 2
| 2
| Unsigned Short
| Unsigned Short
| Byte-Order Marker
| Byte-Order Mark
|-
|-
| 0x0a
| 0x0a
| 2
| 2
|  
|  
| Unknown (padding?)
| Padding? {{check}}
|-
|-
| 0x0c
| 0x0c
| 2
| 2
| Unsigned Short
| Unsigned Short
| Version? 1.3?
| Version? 1.3? {{check}}
|-
|-
| 0x0e
| 0x0e
| 2
| 2
| Unsigned Short
| Unsigned Short
| Section Count?
| Section Count? {{check}}
|-
|-
| 0x10
| 0x10
| 2
| 2
|  
|  
| Padding?
| Padding? {{check}}
|-
|-
| 0x12
| 0x12
Line 61: Line 59:
| 10
| 10
|  
|  
| Padding?
| Padding? {{check}}
|}
|}


== Labels Section ==
== Labels Section ==
The labels section has a header followed by an offset table and finally a string table with meta data regarding the later text section.
The labels section has a header followed by an offset table and finally a string table with meta data regarding the later text section.


=== Labels Section Header ===
=== Labels Section Header ===
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 95: Line 90:


=== Labels Section Offset Table ===
=== Labels Section Offset Table ===
Offsets in the offset table are relative to the end of the Labels Section Header (byte `0x10`). The offset table length is defined in the first four bytes of the table.
Offsets in the offset table are relative to the end of the Labels Section Header (byte `0x10`). The offset table length is defined in the first four bytes of the table.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 109: Line 102:
| Offset count
| Offset count
|}
|}
Each entry in the offset table is 8 bytes. 4 bytes indicating the number of null-terminated strings at the offset and an offset relative to the beginning of the offset table.
Each entry in the offset table is 8 bytes. 4 bytes indicating the number of null-terminated strings at the offset and an offset relative to the beginning of the offset table.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 130: Line 121:


=== Labels Section String Table ===
=== Labels Section String Table ===
 
The labels can be determined by iterating through the offset table and reading the number of null-terminated strings from the address. The first byte at the offset indicates the size of the label. One label can contain ''zero'' or more null-terminated strings but will not exceed the indicated total length.
The labels can be determined by iterating through the offset table and reading the number of null-terminated strings from the address. The first byte at the offset indicates the size of the label. One label can contain *zero* or more null-terminated strings but will not exceed the indicated total length.


After each null-terminated string, there are 4 bytes indicating which index in the texts table this label corresponds to. See the text table section for more information.
After each null-terminated string, there are 4 bytes indicating which index in the texts table this label corresponds to. See the text table section for more information.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 147: Line 136:
|-
|-
| 0x01
| 0x01
| *n*
| ''n''
| char[*n*]
| char[''n'']
| String count number of null-terminated strings<ref>A label can contain *zero* or more null-terminated strings</ref>
| String count number of null-terminated strings<ref>A label can contain ''zero'' or more null-terminated strings</ref>
|-
|-
| 0xnn
| 0xnn
Line 158: Line 147:


== Attributes Section ==
== Attributes Section ==
Attributes are not fully understood at this time. The attribute seem to indicate which actor should be attributed with the dialog (A good example is in <code>100enemy.msbt</code> where <code>NPC_GodVoice</code> is referenced).
Attributes are not fully understood at this time. The attribute seem to indicate which actor should be attributed with the dialog (A good example is in <code>100enemy.msbt</code> where <code>NPC_GodVoice</code> is referenced).


The attributes seem to correspond to an entry in the text table with the same table index, since the attribute and text tables are usually the same size<ref>Needs validation with more research</ref>.
The attributes seem to correspond to an entry in the text table with the same table index, since the attribute and text tables are usually the same size {{check}}.


=== Attributes Section Header ===
=== Attributes Section Header ===
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 190: Line 176:


=== Attributes Section Offset Table ===
=== Attributes Section Offset Table ===
Offsets in the offset table are relative to the end of the Attributes Section Header (byte <code>0x10</code>). The first 4 bytes of the table are the number of offsets and the second 4 bytes indicate the size of each offset (or table entry) in bytes.
Offsets in the offset table are relative to the end of the Attributes Section Header (byte <code>0x10</code>). The first 4 bytes of the table are the number of offsets and the second 4 bytes indicate the size of each offset (or table entry) in bytes.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 209: Line 193:
| Attribute data size
| Attribute data size
|}
|}
Each entry in the offset table is a 4-byte relative offset from the beginning of the table.
Each entry in the offset table is a 4-byte relative offset from the beginning of the table.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 225: Line 207:


=== Attributes Section String Table ===
=== Attributes Section String Table ===
The attributes can be determined by iterating through the offset table and a null-terminated string from the address. Strings in this table are UTF-16 (Wii U files are UTF-16-BE encoded) encoded and take up 2 bytes for each character. Strings are terminated with a UTF-16 null character <code>00 00</code> or <code>\u0000</code>.
The attributes can be determined by iterating through the offset table and a null-terminated string from the address. Strings in this table are UTF-16 (Wii U files are UTF-16-BE encoded) encoded and take up 2 bytes for each character. Strings are terminated with a UTF-16 null character <code>00 00</code> or <code>\u0000</code>.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 235: Line 215:
|-
|-
| 0x00
| 0x00
| *n*
| ''n''
| char[2]
| char[2]
| Unicode character
| Unicode character
Line 241: Line 221:


== Texts Section ==
== Texts Section ==
The text section contains a table of strings.
The text section contains a table of strings.


=== Texts Section Header ===
=== Texts Section Header ===
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
The section header includes a signature, table size and padding making the header 16 bytes. Table size is relative to the end of the section header.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 271: Line 248:


=== Texts Section Offset Table ===
=== Texts Section Offset Table ===
Offsets in the offset table are relative to the end of the Texts Section Header (byte `0x10`). The offset table length is defined in the first four bytes of the table.
Offsets in the offset table are relative to the end of the Texts Section Header (byte `0x10`). The offset table length is defined in the first four bytes of the table.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 285: Line 260:
| Offset count
| Offset count
|}
|}
Each entry in the offset table is a 4-byte relative offset from the beginning of the table.
Each entry in the offset table is a 4-byte relative offset from the beginning of the table.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 301: Line 274:


=== Texts Section String Table ===
=== Texts Section String Table ===
The attributes can be determined by iterating through the offset table. Strings in this table are UTF-16 (Wii U files are UTF-16-BE encoded) encoded and take up 2 bytes for each character.
The attributes can be determined by iterating through the offset table. Strings in this table are UTF-16 (Wii U files are UTF-16-BE encoded) encoded and take up 2 bytes for each character.


String length is determined by reading until the next offset in the table and not exceeding the end of the file. Strings cannot be read as null-terminated strings since many strings will have multiple null characters in them.
String length is determined by reading until the next offset in the table and not exceeding the end of the file. Strings cannot be read as null-terminated strings since many strings will have multiple null characters in them.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 313: Line 284:
|-
|-
| 0x00
| 0x00
| *n*
| ''n''
| char[2]
| char[2]
| Unicode character
| Unicode character
|}
|}


=== Text Commands ===
== Text Commands ==
 
{{expand section}}
Some string include interpolation operators or commands within the strings. These commands tell the game to behave in a certain way while displaying the string. Commands include choices, selling items, buying items and interacting with objects.
Some string include interpolation operators or commands within the strings. These commands tell the game to behave in a certain way while displaying the string. Commands include choices, selling items, buying items and interacting with objects.


Commands are indicated in the strings with <code>00 0e</code> or <code>\u000e</code>.
Commands are indicated in the strings with <code>00 0e</code> or <code>\u000e</code>.
{| class="wikitable"
{| class="wikitable"
!Offset (h)
!Offset (h)
Line 340: Line 310:
| Command type
| Command type
|}
|}
For example, in <code>100enemy.msbt</code> the following data appears:
For example, in <code>100enemy.msbt</code> the following data appears:
<pre>  | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |                   
<pre>  | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |                   
---|-------------------------------------------------|------------------|
---|-------------------------------------------------|------------------|
Line 355: Line 322:
70 | 00 02 00 03 00 04 00 05 02 03 00 00            | ............    |
70 | 00 02 00 03 00 04 00 05 02 03 00 00            | ............    |
</pre>
</pre>
 
At byte <code>0x68</code> is the command indicator followed by the type of <code>1</code>. Command types of <code>1</code> seem to be variable length. The type (in this instance) is followed by the number of additional Unsigned Shorts <code>6</code> and 6 shorts or choices in text. Each choice is a reference to another .msbt file or action.
At byte <code>0x68</code> is the command indicator followed by the type of <code>1</code>. Command types of <code>1</code> seem to be variable length. The type (in this instance) is followed by the number of additional Unsigned Shorts <code>6</code> and 6 shorts.


<code>[00 0A] [00 02] [00 03] [00 04] [00 05] [02 03]</code>
<code>[00 0A] [00 02] [00 03] [00 04] [00 05] [02 03]</code>


The commands are not fully understood at this time, but below is a list of the known command identifiers and variable counts.
There is also the <code>[00 00]</code> at the end which is a reference when a criteria is met. In this example the criteria is an unpowered Master Sword.  


=== Commands ===
The commands are not fully understood at this time, but below is a list of the known command identifiers and variable counts.
{| class="wikitable"
{| class="wikitable"
!Type
!Type
!Additional Bytes
!Additional Shorts
!Notes
!Notes
|-
|-
| 0
| 0
| 3
| 3
|
|Modify text. Followed by modifiers. (Text Modifiers)
|-
|-
| 1
| 1
| *n*
| ''n''
| Variable length. Length is the unsigned short following the type.
| Stop Text. Followed by stop type.
|-
|-
| 2
| 2
Line 385: Line 353:
| 4
| 4
| 3
| 3
| Often end with <code>XX CD</code>
| End with <code>XX CD</code> for choice
|-
|-
| 5
| 5
Line 391: Line 359:
| Seem to always end with a line-feed character <code>00 0A</code>
| Seem to always end with a line-feed character <code>00 0A</code>
|}
|}
==== Text Modifiers ====
The Modify text or 0 command can have up to 3 shorts after it. The shorts follow in this order <code>Font</code> <code>Color Modifier</code> <code>Color</code>.
'''Note:''' These 6 colors appear to be the only choices availible. <ref>https://github.com/Argo-SC/BOTW-re-notes/blob/master/MSBT/Colour_Test.txt</ref>
Below are the known Hex codes for the shorts.
{| class="wikitable"
!Type
!Hex
!Notes
|-
|Font
|<code>[00 03]</code>
|English font which allows color changing.
|-
|Font
|<code>[00 01]</code>
|Hylian Font. Does not allow color changes.
|-
|Color Modifier
|<code>[00 02]</code>
|Allows changes in color
|-
|Color
|<code>[00 00]</code>
|Red
|-
|Color
|<code>[00 01]</code>
|Green
|-
|Color
|<code>[00 02]</code>
|Blue
|-
|Color
|<code>[00 03]</code>
|Gray
|-
|Color
|<code>[00 05]</code>
|Orange
|-
|Color
|<code>[FF FF]</code>
|White
|}
==== Text Stop Types ====
The Stop text or 1 command has varying stops depending on the type. There are two known stop types at this time: <code>Choice</code> and <code>Delay</code>
*'''Choice''' is a stop of the text until the player makes a choice which then moves the the text option choosen. A choice is shown above in <code>100enemy.msbt</code>.
*'''Delay''' is a stop of the text for X number of frames. This is then followed by the frame counter and number of frames.
{| class="wikitable"
!Type
!Code
!Note
|-
|Choice
|<code>[00 XX]</code>
|X is the number of choices availible. This can reference an event, text in its document, or text in other documents.
|-
|Delay
|<code>[00 00]</code>
|Immedietly Followed by the frame counter
|-
|Frame Counter
|<code>[00 04]</code>
|Followed by 4 nibbles <code>[00 00 00 XX]</code> where XX is the number of frames in hex. EX: 1 sec = 30 frames = <code>[1E]</code>
|-
|}
===== Example =====
A great example of Text stop and modifiers in use is in <code>Demo700_0.msbt</code> the following data appears:
<pre>  | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |                 
---|-------------------------------------------------|------------------|
80 | 54 58 54 32 00 00 00 E4 00 00 00 00 00 00 00 00 | TXT2...d........ |
90 | 00 00 00 01 00 00 00 08 00 54 00 68 00 61 00 74 | .........T.h.a.t |
A0 | 00 20 00 69 00 73 00 20 00 61 00 20 00 0E 00 00 | ...i.s...a...... |
B0 | 00 03 00 02 00 00 00 53 00 68 00 65 00 69 00 6B | .......S.h.e.i.k |
C0 | 00 61 00 68 00 20 00 53 00 6C 00 61 00 74 00 65 | .a.h...S.l.a.t.e |
D0 | 00 0E 00 00 00 03 00 02 FF FF 00 2E 00 20 00 0E | ................ |
E0 | 00 01 00 00 00 04 00 00 00 4B 00 54 00 61 00 6B | .........K.T.a.k |
F0 | 00 65 00 20 00 69 00 74 00 2E 00 20 00 0E 00 01 | .e...i.t........ |
</pre>
*'''Text Modifier:''' At byte <code>0xAD</code> command starts exicuting text color. The English Font is referenced at <code>0xB1</code> which leads into the Color Modifier. Then the color red is chosen. To end the red text and go back to white, the same command is ran after the words at <code>0xD2</code> but with white as the color.
*'''Text Stop:''' At byte <code>0xDF</code> command starts and a text stop command is run. Following the time stop, the delay command is chosen <code>0xE3</code>. The delay command tells us that there is a 4B delay <code>0xE9</code> before the next line.  Convert this to decimal is 75, devide 75 by 30 fps (botw default fps) and you get a 2.5 second delay.


== Compiling the Sections ==
== Compiling the Sections ==
The sections are held together by the indexes in the labels table. The indexes correspond to the attributes table and the texts table. The data can be compiled using the index.
The sections are held together by the indexes in the labels table. The indexes correspond to the attributes table and the texts table. The data can be compiled using the index.


By default the indexes in the labels table are not in order, but the text table is (and possibly the attributes table). Below is the labels table in <code>100enemy.msbt</code>.
By default the indexes in the labels table are not in order, but the text table is (and possibly the attributes table). Below is the labels table in <code>100enemy.msbt</code>.
{| class="wikitable"
{| class="wikitable"
!String Count
!String Count
Line 519: Line 573:
| 2
| 2
|}
|}
And the texts table.
And the texts table.
{| class="wikitable"
{| class="wikitable"
!Index
!Index
Line 562: Line 614:
| Cancel  
| Cancel  
|}
|}
Using the indexes to match the labels to the attributes and texts tables, the following table can be compiled.
Using the indexes to match the labels to the attributes and texts tables, the following table can be compiled.


The empty labels are not fully understood.
The empty labels are not fully understood.
{| class="wikitable"
{| class="wikitable"
!Label
!Label
Line 633: Line 683:
| Cancel
| Cancel
|}
|}
The attribute table is still not fully understood. In this example, there are 8 attribute entries in the table, but they correctly map to the 8 blocks of dialog.


The attribute table is still not fully understood. In this example, there are 8 attribute entries in the table, but they correctly map to the 8 blocks of dialog.
<references />
 
[[Category:File formats]]
[[Category:File extensions]]
[[Category:File extensions (MSBT)]]
 
== Tools ==
{{tool table|category=Tools (MSBT)}}
 
[[Category:File formats]]
Anonymous user