Difference between revisions of "FF8/WorldMap charaone"
my_wiki>MaKi (→Header) |
my_wiki>MaKi |
||
Line 1: | Line 1: | ||
+ | by Maki | ||
file is different than field [[FF8/FileFormat_ONE|[ONE]]] | file is different than field [[FF8/FileFormat_ONE|[ONE]]] | ||
+ | Basically you have to read the whole file step-by-step as there are minimum pointers and no sizes at all. Therefore just to read one character on world map you have to actually read all content of chara.one. | ||
+ | You have to read whole TIM textures first, calculate the global size of TIM texture and advance further. Textures are always 0x10000000 08000000. My approach is to read uint64 and check if it contains TIM header. If not, then geometry section (see Chara). I named the bones/animation section as "section 12" because game engine calls function for chara.one files with 0x11 for reading the header data (chara) and then again with argument 0x12 having pointer to data as in Wiki in EAX. It's like: | ||
+ | |||
+ | uint myPointer = charaOneFunction(pointer_to_Chara_section, 0x11...); | ||
+ | charaOneFunction(myPointer, 0x12...); | ||
+ | |||
== Header == | == Header == |
Revision as of 18:25, 16 February 2019
by Maki file is different than field [ONE] Basically you have to read the whole file step-by-step as there are minimum pointers and no sizes at all. Therefore just to read one character on world map you have to actually read all content of chara.one. You have to read whole TIM textures first, calculate the global size of TIM texture and advance further. Textures are always 0x10000000 08000000. My approach is to read uint64 and check if it contains TIM header. If not, then geometry section (see Chara). I named the bones/animation section as "section 12" because game engine calls function for chara.one files with 0x11 for reading the header data (chara) and then again with argument 0x12 having pointer to data as in Wiki in EAX. It's like:
uint myPointer = charaOneFunction(pointer_to_Chara_section, 0x11...); charaOneFunction(myPointer, 0x12...);
Header
Offset | Length | Description |
---|---|---|
0x00 | uint | EOF |
0x04 | (TIM_height * (TIM_width * 4) ) / 2 + 64 | TIM texture |
*(this) != x 10 00 00 00 08 00 00 00 | Varies | Chara |
Chara
Offset | Length | Description |
---|---|---|
0x00 | uint | bone section? length (shift left 6) |
0x04 | uint | unknown struct size. Multiply by 8 |
0x08 | uint | unknown size |
?? | uint | 32 * *(dword_24FEE48[v24] + 36)) |
0x38 | uint | section 12 pointer + 2 |
section 12 (arg4 == 0x12)
names are WIP, I'm not quite sure if it's animation, geometry or bones...
Offset | Length | Description |
---|---|---|
0x00 + ( i==0 ? 0 : sizeof(entry[i-1])) | sizeof(entry) | while entry.countOfEntries != null |
- there's no count for these objects, so you have to read all entries one-by-one. In order to understand when to stop you have to check if reading new entry.countOfEntities == 0
Entry:
Offset | Length | Description |
---|---|---|
0x00 | ushort | count of entities |
0x02 | ushort | count of bone rotations |
0x04 + (entityID * (countOfBoneRot * 6) + 6) | 6 + (countOfBoneRotations*6) | entityObject |
entityObject:
Offset | Length | Description |
---|---|---|
0x00 | short | X offset |
0x02 | short | Z offset |
0x04 | short | Y (up) offset |
0x06 + (boneID*6) | short | Bone[boneID].RotX |
0x08 + (boneID*6) | short | Bone[boneID].RotZ |
0x0A + (boneID*6) | short | Bone[boneID].RotY |