I didn't want to derail where the main GFF format thread was going, so I thought I'd ask here if my understanding of the GDA on-disk format makes any sense... and I've seen the wiki page on the GFF format...
I'll try to differentiate GFF structs from in-memory structures by calling the latter C structs. This is a bit long, but I've tried to be somewhat thorough of a simple example, but I tried to stick more to how it applies to GDAs than to GFF files in general.
So here's a simple custom 2DA: one row, a string label column, and an integer column.

Here's how the GDA looks in the toolset in its GFF viewer:

I've tried to highlight related data in the following hex dump below. I'll try to talk about what's in it using coloured text to relate to it better.
* CLICK TO ENLARGE *

The number of GFF structs can be seen as 3 in the hex dump, which matches the number of unique GFF struct types on disk, not the total number of C structs that might need to be created in memory.
There's the top-level GFF struct, GFF struct element type for G2DA_COLUMN_LIST, and GFF struct element type for G2DA_ROW_LIST - 3 GFF struct types.
The first two GFF struct types each have two fields and the C struct is 8 bytes large (makes enough sense for two 32-bit fields). The third GFF struct type is 12 bytes, which also makes for three 32-bit fields, and that a pointer to the string label is stored instead of the whole string itself.
I've created a red arrow linking the struct type to its first GFF field. The fields are packed in pretty tight and don't contain or link to any actual data values - at least not in any GDA I've encountered yet. Instead they just contain the 32-bit label, field type, and offset. Let's hand-wave over how the field type can refer to a list; I understand it - I just don't want to go off on a tangent right now.
Now the wiki makes a vague statement about the field offset: "offset to the location of the data". From what I can tell, it's basically like the C offsetof macro. So for example, if the GFF struct type has 3 simple 32-bit fields, the offsets will normally go 0, 4, and 8.
Now the purple-coloured address is where the raw data block begins, according to the GFF header, which I've linked from with a purple arrow. The first data there belongs to the top-level struct. Looking back at the field-array, the top-level struct has 2 GFF stuct list fields at offsets 0 and 4.
So in little endian format, the data at raw data block offset 0 is 0x00000008. So seek 8 bytes into the raw data block to get a list size of 3 GFF-struct elements.
Now we get to the what you might call the "real information"... what the different C structs will have for values. So the C struct values seem to come in tuples determined by the GFF-struct "template" they're used by. So in the case of the first set of values, there are three 2-tuples of data as I've marked in the hex dump screen shot. Those get read in order and initialize the C structs in a list.
Then looking back at the top-level struct, the next field is at offset 4, which is the value 0x00000024. So seek 36 (24h) bytes from the start of the raw data block and you'll find a list header that indicates it has one element, as pointed to with the yellow arrow in the screen shot of the hex dump. Since this GFF-struct template has three 32-bit members, it reads in the next 12 bytes.
Now I've highlighted a 32-bit block of data with a cyan arrow pointing to some more data that runs until the end of the file. This would appear to be a string reference with the value 0x00000034. Seek 52 (34h) bytes from the start of the raw data block to address 0xD4. The first 32-bit field seems to be the size of the string, including a NULL word. In this example, each letter is two bytes, including the null character at the end, an array of WCHARs according to the wiki. I'm not sure if the game or toolset expects sizeof(WCHAR) to always be 2, or if it'll depend on the encoding, or how much we have to worry about that in practice.
Modifié par FollowTheGourd, 28 décembre 2009 - 08:53 .





Retour en haut






