Main Page and Datasheet: Difference between pages
(Difference between pages)
Jump to navigation
Jump to search
→Header
imported>Leoetlino m (Changed protection level for "Main Page": allow news to be edited without sysop rights ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))) |
imported>Leoetlino (→Header) |
||
Line 1: | Line 1: | ||
{{ | {{File format|name=Datasheet|version=1|magic=gsht|endianness=little}} | ||
'''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 treated as a dictionary/mapping rather than a array. | ||
== [[ | |||
== Format == | |||
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 === | |||
{| class="wikitable" | |||
!Offset | |||
!Type | |||
!Description | |||
|- | |||
|0x0 | |||
|char[4] | |||
|Magic (<code>gsht</code>) | |||
After pointer relocation, the magic is set to <code>GSHT</code>. | |||
|- | |||
|0x4 | |||
|int | |||
|Version (must be 1) | |||
|- | |||
|0x8 | |||
|u32 | |||
|? Some kind of hash? (unused {{check}}) | |||
|- | |||
|0xC | |||
|u8 | |||
|Bool type size (must be 1) | |||
|- | |||
|0xD | |||
|u8 | |||
|Pointer size (must be 8) | |||
|- | |||
|0xE | |||
|u8 | |||
|?{{Check}} | |||
|- | |||
|0x10 | |||
|const char* | |||
|Name | |||
|- | |||
|0x18 | |||
|u32 | |||
|Number of root fields | |||
|- | |||
|0x1C | |||
|u32 | |||
|Number of fields in total | |||
|- | |||
|0x20 | |||
|Value* | |||
|Values | |||
|- | |||
|0x28 | |||
|u32 | |||
|Number of values | |||
|- | |||
|0x2C | |||
|u32 | |||
|Size of each value | |||
|} | |||
The header is immediately followed by the root fields (a <code>Field[num_root_fields]</code> array). | |||
=== Field === | |||
<syntaxhighlight lang="c++"> | |||
enum class Type : u16 { | |||
Struct = 0, | |||
Bool = 1, | |||
Int = 2, | |||
Float = 3, | |||
String = 4, | |||
}; | |||
enum class Flag : u16 { | |||
IsNullable = 1 << 0, | |||
IsArray = 1 << 1, | |||
IsKey = 1 << 2, | |||
b3 = 1 << 3, // unknown | |||
IsEnum = 1 << 4, | |||
b5 = 1 << 5, // unknown | |||
}; | |||
</syntaxhighlight> | |||
{| class="wikitable" | |||
!Offset | |||
!Type | |||
!Description | |||
|- | |||
|0x0 | |||
|const char* | |||
|Name (must be non-null) | |||
|- | |||
|0x8 | |||
|const char* | |||
|Type name | |||
|- | |||
|0x10 | |||
|Field::Type | |||
|Type | |||
|- | |||
|0x11 | |||
|u8 | |||
|?{{Check}} | |||
|- | |||
|0x12 | |||
|Field::Flag | |||
|Flags | |||
|- | |||
|0x14 | |||
|u16 | |||
|Offset of this field in the value structure | |||
|- | |||
|0x16 | |||
|u16 | |||
|Size of this field in the value structure | |||
For strings and arrays, this is always 0x10. | |||
|- | |||
|0x18 | |||
|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 | |||
|u16 | |||
|[For structs] Number of fields | |||
|- | |||
|0x20 | |||
|Field* | |||
|[For structs] Fields | |||
|- | |||
|0x28 | |||
|Field* | |||
|Parent (filled in during parsing; always 0xdeadbeefdeadbeef when serialized) | |||
|} | |||
Fields must be properly aligned to 0x30 byte boundaries. | |||
Key fields cannot be arrays or Nullable types. | |||
Key fields must be of type String or Int. | |||
=== 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" | |||
|+Field data serialization | |||
!Type | |||
!Serialized data format | |||
|- | |||
|Nullable<T> (non-strings) | |||
|<code>struct { T* data; }</code> (nullptr if no value) | |||
|- | |||
|Array<T> | |||
|<code>struct { T* data; u32 size; }</code> (aligned to 0x10 bytes{{Check}}) | |||
|- | |||
|Struct | |||
|<code>struct { Fields...; }</code> | |||
|- | |||
|Bool | |||
|bool (1-byte) | |||
|- | |||
|Int | |||
|s32 | |||
|- | |||
|Float | |||
|f32 | |||
|- | |||
|String | |||
|<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'' == | |||
Datasheets are extensively used to configure game logic and to store miscellaneous data. They are located in [[rom:/region_common/datasheets]] and their file extension is .gsheet. | |||
Text versions of datasheets are available in the [https://github.com/leoetlino/la-re-notes/tree/master/data/datasheets leoetlino/la-re-notes] repository on GitHub. | |||
[[Category:File formats]] |