Datasheet: Difference between revisions
→Header
imported>Leoetlino (document datasheets) |
imported>Leoetlino (→Header) |
||
(10 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
'''GSHT''' (G?sheet) is a custom Grezzo binary serialization file format that is used to store structured, strongly typed data. GSHT documents are called '''datasheets'''. | '''GSHT''' (G?sheet) is a custom Grezzo binary serialization file format that is used to store structured, strongly typed data. GSHT documents are called '''datasheets'''. | ||
A datasheet contains structure type information followed by arrays of structures. Optionally, one of the structure fields may be declared as a key field, in which case the contents are a dictionary rather than a array. | A datasheet contains structure type information followed by arrays of structures. Optionally, one of the structure fields may be declared as a key field, in which case the contents are treated as a dictionary/mapping rather than a array. | ||
== Format == | == Format == | ||
Documents are little endian and their sizes are always 0x10 | Documents are little endian and their sizes are always rounded up to be a multiple of 0x10. | ||
Pointers are encoded as absolute offsets and relocated when the document is loaded by the game. | |||
=== Header === | === Header === | ||
Line 15: | Line 17: | ||
|0x0 | |0x0 | ||
|char[4] | |char[4] | ||
|Magic (<code> | |Magic (<code>gsht</code>) | ||
After pointer relocation, the magic is set to <code>GSHT</code>. | |||
|- | |- | ||
|0x4 | |0x4 | ||
|int | |int | ||
|Version (must be 1) | |Version (must be 1) | ||
|- | |||
|0x8 | |||
|u32 | |||
|? Some kind of hash? (unused {{check}}) | |||
|- | |- | ||
|0xC | |0xC | ||
Line 31: | Line 39: | ||
|0xE | |0xE | ||
|u8 | |u8 | ||
| | |Alignment (usually 4 or 8) | ||
|- | |- | ||
|0x10 | |0x10 | ||
|const char* | |const char* | ||
|Name | |Name (must be non-null) | ||
|- | |- | ||
|0x18 | |0x18 | ||
|u32 | |u32 | ||
|Number of | |Number of root fields | ||
|- | |- | ||
|0x1C | |0x1C | ||
Line 55: | Line 63: | ||
|0x2C | |0x2C | ||
|u32 | |u32 | ||
| | |Size of each value | ||
|} | |} | ||
The header is immediately followed by the root fields (a <code>Field[num_root_fields]</code> array). | |||
=== Field === | === Field === | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
enum class Type : | enum class Type : u8 { | ||
Struct = 0, | Struct = 0, | ||
Bool = 1, | Bool = 1, | ||
Line 72: | Line 82: | ||
IsArray = 1 << 1, | IsArray = 1 << 1, | ||
IsKey = 1 << 2, | IsKey = 1 << 2, | ||
b3 = 1 << 3, | b3 = 1 << 3, // unknown | ||
IsEnum = 1 << 4, | IsEnum = 1 << 4, | ||
b5 = 1 << 5, | b5 = 1 << 5, // unknown | ||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 88: | Line 98: | ||
|0x8 | |0x8 | ||
|const char* | |const char* | ||
|Type name | |Type name (must be non-null) | ||
|- | |- | ||
|0x10 | |0x10 | ||
Line 104: | Line 114: | ||
|0x14 | |0x14 | ||
|u16 | |u16 | ||
| | |Offset of this field in the value structure | ||
|- | |- | ||
|0x16 | |0x16 | ||
|u16 | |u16 | ||
| | |Size of this field in the value structure | ||
For strings and arrays, this is always 0x10. | |||
|- | |- | ||
|0x18 | |0x18 | ||
|u16 | |u16 | ||
| | |Size of the data | ||
For strings and inline types (inline structs, ints, floats, bools), this is the same as the size in the value structure. | |||
|- | |- | ||
|0x1A | |0x1A | ||
|u16 | |u16 | ||
| | |[For structs] Number of fields | ||
|- | |- | ||
|0x20 | |0x20 | ||
|Field* | |Field* | ||
| | |[For structs] Fields | ||
|- | |- | ||
|0x28 | |0x28 | ||
Line 133: | Line 147: | ||
=== Value === | === Value === | ||
Combining all the root fields gives a structure (in the sense of a C or C++ structure). That structure is called a Value in this documentation. | |||
{| class="wikitable" | {| class="wikitable" | ||
|+Field data serialization | |+Field data serialization | ||
Line 158: | Line 174: | ||
|String | |String | ||
|<code>struct { const char* data; u32 length; }</code> (aligned to 0x10 bytes) | |<code>struct { const char* data; u32 length; }</code> (aligned to 0x10 bytes) | ||
For empty strings ''that are Nullable'', data is nullptr and length is 0. Empty strings that are ''not'' Nullable have a 0 length but still point to a null byte. | |||
|} | |} | ||
== Usage in ''Link's Awakening'' == | == Usage in ''Link's Awakening'' == |