God Hand DAT Files - akitotheanimator/God-Hand-Tools GitHub Wiki
God hand has DAT files. Which each one store files inside, like a ZIP file. However, God hand doesn't stablish a format for it. the DAT files may vary a lot depending on the DAT type.
This wiki is NOT programmer friendly.
This wiki assumes you're a experienced programmer and that you know what you're doing.
Determining the DAT type
There's several DAT types that GOD HAND utilizes. Some for models, some for maps. Here's some of the differences.
Type 0 (GPF)
- The first 4 bytes of the file measures how much files are packed.
- Offset 4 return a adress that doesn't point to blank uint32 bytes.
- The offsets list start from offset 4.
Type 1 (MPF)
- The first 4 bytes of the file counts how many elements after the header contains. But these aren't the file adresses. i have no clue what the offsets are.
- Offset 4, 8 and 12 returns a adress that point to blank uint32 bytes.
- The offsets list start from offset 16.
- The packed files measure has to be calculated from the adress that offset 16 points to.
Type 2 (PEF)
- I have no clue what the first 4 bytes are.
- The offset 4 points to the start of the MOT Adresses.
- The offset 8 points to a string section which tells the el DATs used in the MOT's.
- The offset 12 points to the end of the string section.
- The offset 16 points to the start of the MOT Files datas.
- The offset 28 points to the end of the MOT Files datas.
With these informations, you can calculate and determine the type of each dat.
Now that you know which type is the DAT you're using in, we can check how they're calculated.
DAT Type 0
The most common type for a DAT. It is encountered on Game Model dats.
0 FL(UInt32)Where :
FLis how much files the .DAT contains. The adresses from all of the files in the container is gathered like this:SO = 4 + FO EO = (FL * 4) + SOWhere :
SOis the Starting OffsetEOis the Ending Offset.FOis the file start. in type 0, it is equals 0.and while iterating though the offsets, it gathers the containing file offsets using the following formula:
for(int i = SO; i < EO; i+=4) OFFSETS_ADRESSES.add(ReadUInt32(i))Where
OFFSETS_ADRESSESis a UInt List where all the offsets are storediis the current file offset.ReadUInt32is a fictional function to return the UInt32 Value from the dat file at offseti.each added uint on
OFFSETS_ADRESSESreturns is the offset where the file starts. now, to get where the file ends, it's quite simple.for(int i = 0; i < OFFSETS_ADRESSES.Count-1, i+=1) OFFSETS_END_ADRESSES.add(OFFSETS_ADRESSES[i+1]) OFFSETS_END_ADRESSES.add(DFL);Where :
OFFSETS_END_ADRESSESis a UInt List where all the end of the offsets are storediis the current file offset.The file formats are identified, but there's no names for them, because dat files it's based on indexing. TO get the file format, you gotta iterate again.
for(int i = SO + (FL * 4); i < EO + (FL * 4); i+=4) OFFSETS_STRING.add(GetString(i,4))Where :
OFFSETS_STRINGis a String List were all the file formats are stored. the file formats always store a 4 length string.
DAT Type 1
The dat type 1 is used to store maps and so. DATs type 1 are just like DATs type 0, but with some changes.
0 NULL FRO(UInt32) Where:
FROis the adress that the dat offsets starts.After determining the
FROvalue, the rest of the process is the same of DAT Type 0. But with theFOof type 0 DAT being the value ofFRO.
DAT Type 2
The dat type 1 is used to store animation events, like cutscenes. Wildly different from both type 0 and type 1.
0 (Byte) 1 (Byte) 2 (Byte) 4 (Int32) 8 (Int32) 12 (Int32) NULL FGMQ(Byte) GEQ(Byte) MSO(UInt32) SSSO(UInt32) SSEO(UInt32) FSPO(UInt32) NULL NULL NS NS FEPO(UInt32) Where:
GMQis the Fist Group MOT Quantity, the quantity of mots that is given before the elements field.GEQis the Given Element Quantity, the quantity of Elements the file has.MSOis the MOT Start Offset, the offet where the mot adresses are given.SSSOis the String Section Start Offset, which is the offset that the utilized .dats names list starts.SSEOis the String Section End Offset, which is when the string section stops.FSPOis the File Start Position Offset, which is where the MOT datas starts to be given.FEPOis the File Ending Position Offset, which is where the MOT datas ends to be given.NSis the Offsets that are not set to a specific value, sometimes it's value is blank, but sometimes it can point to a .SEQ.The type 2 DAT doesn't give you the packed file types, so you will need to find them by your own. Luckly, the only two "important" files in type 2 is the MOT's and the SEQ's.
- 16 to
MSO= SEQ Files.MSOtoSSSO= MOT Files.SSEOtoFSPO= MOT Files.FEPOto FILE_SIZE_OR_MOT = other/misc/unrecognized.After gathering these values, you will need to apply a series of rules to sucesfully gather all the offsets.
To gather the .SEQ files offsets, iterate from offset 16 until offset
MSO, adding 4 to each iteration.for(int i = 16; i < MSO; i+=4)Now, read each
ioffset and check if the value is higher than 1, and if the readen value ofiis not equalsFEPOif(ReadUInt32(i) > 0 && ReadUInt32(i) != `FEPO`)that's how you gather the offsets of the SEQ files.
To gather the .MOT files offsets, you will need to make two iterations. Firstly, iterate from offset
MSOuntil offsetSSSO, adding 4 to each iteration.for(int i = MSO; i < SSSO; i+=4)Apply the same rule of "if > 0"
if(ReadUInt32(i) > 0)Secondly, iterate from offset
SSEOuntil offsetFSPOfor(int i = SSEO; i < FSPO; i+=4) if(ReadUInt32(i) > 0)that's how you gather the offsets of the MOT files.
FEPOis already a adress, so nothing need to be done. To finish, Sort all of the adresses you've gathered based on offset number i.e:
- if offset[0] = 46
- and offset[1] = 29 then the sort should be like this:
- 29
- 46 and after gathering and sorting all the adresses correctly, you can save the files.
Saving the files
To save the files, you do this operation:
for(int i = 0; i < OFFSETS_ADRESSES; i+=1) saveFile(OFFSETS_ADRESSES[i], OFFSETS_ADRESSES[i + 1], OFFSETS_STRING[i]);Where :
OFFSETS_ADRESSESis a array containing all of the adresses you just gathered.OFFSETS_STRINGis a array containing all of the file formats as string you just gathered.saveFileis a function that saves all the bytes of the .dat in a file, reading bytes from adress A to adress B with the format name of C.