19,903
edits
(many clarifications) |
(better wording and example for instance and file ID) |
||
| Line 244: | Line 244: | ||
The data table occupies the majority of the file and stores all the instance data (though this data sometimes points to the location of more data in a raw/separate file). We peeked at this table before when we looked at the instance descriptor for SUBTsubtitles. The table's starting point is found at the offset given in the header, in this case 0x03BCA0, saving us the trouble of adding up the size of the four preceding segments of the file and then aligning to the next 32-byte boundary. | The data table occupies the majority of the file and stores all the instance data (though this data sometimes points to the location of more data in a raw/separate file). We peeked at this table before when we looked at the instance descriptor for SUBTsubtitles. The table's starting point is found at the offset given in the header, in this case 0x03BCA0, saving us the trouble of adding up the size of the four preceding segments of the file and then aligning to the next 32-byte boundary. | ||
The reason we'd need to align to 32 bytes is that the start of each instance's record (the ID | The reason we'd need to align to 32 bytes is that the start of each instance's record (the instance ID) is always 32 byte-aligned. Thus, even though the template descriptors ended at 0x03BC9C, there are four empty bytes here so that the data table can begin at 0x03BCA0, which divides evenly by 32. This alignment rule also means that the instance-specific data will always start at an offset like 0x0008, 0x0028, 0x0148, etc. | ||
The instance ID and file ID are not actually part of the instance data but are considered to be the resource header. The engine always keeps pointers to the start of the type-specific data itself; we saw this before when we jumped to 0x25ED68 and saw the data for the SUBT rather than the header for this data. The instance ID and file ID are accessed using negative offsets when needed (usually to find the name or template tag of an instance, given a pointer to it). | The instance ID and file ID are not actually part of the instance data but are considered to be the resource header. The engine always keeps pointers to the start of the type-specific data itself; we saw this before when we jumped to 0x25ED68 and saw the data for the SUBT rather than the header for this data. The instance ID and file ID are accessed using negative offsets when needed (usually to find the name or template tag of an instance, given a pointer to it). | ||
| Line 250: | Line 250: | ||
{{Table}} | {{Table}} | ||
{{OBD_Table_Header}} | {{OBD_Table_Header}} | ||
{{OBDtr| 0x00 | res_id | | 01 | {{OBDtr| 0x00 | res_id | | 01 0B 04 00 | 1035 | instance ID 1035 }} | ||
{{OBDtr| 0x04 | lev_id | | 01 00 00 | {{OBDtr| 0x04 | lev_id | | 01 00 00 06 | 3 | level 3 }} | ||
{{OBDtr| 0x08 | ... | | ... | ... | [[OBD:File types|type-specific data]]... }} | {{OBDtr| 0x08 | ... | | ... | ... | [[OBD:File types|type-specific data]]... }} | ||
|} | |} | ||
This example is taken from level 3 so that the file ID is more instructive. In the OBD documentation, these fields are called res_id and lev_id as seen above. | |||
The '''file ID''' is computed from the number found in the name of the instance file: | The '''instance's ID''' is stored as "(instance descriptor index << 8) | 1". Thus the 1,035th entry in the instance descriptor index will be encoded as 0x40B00. The '1' allows the engine to know which IDs have already been converted to pointers (an instance pointer will always be 8-byte aligned, so it will never have the zero bit already set). These pointer flags were retained when the file was written to disk but are meaningless now. At level-load time the flags are cleared and then set again when Oni allocates memory for each instance. The purpose of left-shifting the index number appears to simply be leaving the lowest byte open for the pointer flag. | ||
Again, the 1 is used by the engine to know which file IDs have been converted to pointers at runtime, but on disk this is a relic which has no meaning to us. | The '''file ID''' is computed from the number found in the name of the instance file: "(level number << 25) | 1". Thus instances found in level3_Final.dat will have the file ID encoded as 0x6000001. Again, the '1' is used by the engine to know which file IDs have been converted to pointers at runtime, but on disk this is a relic which has no meaning to us. The reason for left-shifting the level number might have been to store it alongside the instance ID and the pointer flag in a single int32, but they are separate numbers now, perhaps so that both IDs can have their own pointer flag. | ||
After the header, the size of each instance's data is of a somewhat arbitrary length depending on the template this instance falls under. As mentioned under "Instance descriptors", the data size given by the descriptor includes the 8-byte resource header and the padding at the end of the data to align the next instance on 32 bytes. | After the header, the size of each instance's data is of a somewhat arbitrary length depending on the template this instance falls under. As mentioned under "Instance descriptors", the data size given by the descriptor includes the 8-byte resource header and the padding at the end of the data to align the next instance on 32 bytes. | ||