Changes

Jump to navigation Jump to search

FF8/FileFormat X

4,607 bytes added, 21:55, 23 December 2020
m
0 Default: fix size of animation frame
|-
| Texture
| 01 10 00 00 00 09 (Always)| Contains one .TIM texture , 8 BPP
|}
|}
'''====Objects group:'''Group====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
|}
'''=====Objects list:'''List=====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
|}
'''=====Settings 1:'''=====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
| 0
| uInt16
| Pointers count. Fixed (02 00 () '''[Unused in code)/ pointers count]'''
|-
| 2
| uInt16
| Relative jump to CameraSetting. Should be (08 00)
|-
| 4
| uInt16
| Relative jump to CameraAnimationCameraAnimationCollection. Should be (20 00)
|-
| 6
| uInt16
| Camera data size (starting from 0) '''[unused in code]'''
|-
| 8
| 32
| ?? bytes
| CamerasCamera Animation Collection
|}
====Camera Setting:====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
| ???
|}
Cameras:====Camera Animations Collection==== 
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
| 0
| uint16
| NumberOfCamerasNumOfSets
|-
| 2 *(CameraSet index)
| uint16
| Relative pointer to camera animationAnimation Set
|-
| 2 *(CameraSet index)+ 2
| uint16
| Relative pointer to Camera EOF
|-
| 2 *(Camera) + 4CameraAnimationSetPointer
| CameraAnimationSet
| CameraAnimationSet
|}
Camera Animation =====CameraAnimationSet=====Seems to be 8 pointers in each set.{| border="1" cellspacing="1" cellpadding="3" align="center" style="border:1px solid black; border-collapse: collapse;"! style="background:rgb(204,204,204)" | Offset! style="background:rgb(204,204,204)" | Length! style="background:rgb(204,204,204)" | Description|-|0|ushort|AnimPointer*2 |-|AnimPointer|Varies 144-146-148 bytes usually|CameraAnimation|}
== Camera Animation (WIP) ==
All this is based on best effort knowledge from reversing by Maki. I'm just trying to understand it.
=== Control Word ===
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
! style="background:rgb(204,204,204)" | Length
! style="background:rgb(204,204,204)" | Description
|-
| 0
| uint16_t (bit varies)
| Main controller. If 0xFFFFU END
|}
==== FOV ====
Control Word & 0b0000'0000'1100'0000U
===== 1 Default =====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
! style="background:rgb(204,204,204)" | Length
! style="background:rgb(204,204,204)" | Description
|-
| None
| None
| Start = 0x200
|-
| None
| None
| End = 0x200
|}
===== 2 Same =====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
! style="background:rgb(204,204,204)" | Length
! style="background:rgb(204,204,204)" | Description
|-
| 0
| uint16_t
| Start
|-
| 2
| uint16_t
| Padding
|-
| None
| None
| End = Start
|}
===== 2 Different =====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
! style="background:rgb(204,204,204)" | Length
! style="background:rgb(204,204,204)" | Description
|-
| 0
| uint16_t
| Start
|-
| 2
| uint16_t
| Padding
|-
| 4
| uint16_t
| End
|}
==== ROLL ====
Control Word & 0b0000'0011'0000'0000U
===== 0 Unknown =====
TODO
===== 1 Default =====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
! style="background:rgb(204,204,204)" | Length
! style="background:rgb(204,204,204)" | Description
|-
| None
| None
| Start = 0x000
|-
| None
| None
| End = 0x000
|}
===== 2 Same =====
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
|-
| 0
| uint16uint16_t| NumOfAnimations Start|-| None| None| End = Start|}===== 2 Different ====={| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"! style="background:rgb(Only 7 are valid204,204,204)" | Offset! style="background:rgb(204,204,204)" | Length! style="background:rgb(204,204,204)" | Description|-| 0| uint16_t| Start
|-
| 2 *| uint16_t| End|} ==== LAYOUT ==== Control Word & 0b0000'0000'0000'0001U===== 0 Default ===== You'll loop through the data till the first value is less than 0. pushing back to a variable length container.{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"! style="background:rgb(KeypointID204,204,204)" | Offset! style="background:rgb(204,204,204)" | uint16Length| Relative pointer to camera Animation ! style="background:rgb(only 7 are valid204,204,204)" | Description
|-
| 2 *(NumOfKeypoints)+ 20| uint16int16_t| Camera EOFif < 0 break; could be related to time of frame.
|-
| KeypointPointer2| Keyframe16 bytes| KeyframeAnimation Frame
|}
===== 1 Other ===== TODO===Time=== Time is calculated from number of frames. You basically set starting position World+lookat and ending position, then mark number of frames to interpolate between them. Every frame is one draw call and it costs 16. Starting time needs to be equal or higher for next animation frame to be read; If next frame==0xFFFF then it's all done.=== Animation:Frame ===
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
! style="background:rgb(204,204,204)" | Offset
! style="background:rgb(204,204,204)" | Description
|-
|0|UNKNOWNuint16_t|UNKNOWNis frame durations shot|-| 2| Vertice<uint16_t> (x,y,z)| World|-| 8| uint16_t| is frame ending shot
|-
|8*2 10| Vertice<uint16_t> (not quite sure whyx, but engine just skips 8*2 bytesy,z)|UNKNOWN|RealCameraTransformLook At
|}
=====Dependency=====
Explained CAMERA:EIDOS/Square did really made it a bit tougher -Camera Settings -Camera Animation Collection (even three collections in a0stg006.x and up to 7 in a0stg101.x!) | | -Camera animation Set (Always 8 camera animations, may be empty (0xFFFF); look for some reasonexample to a0stg127.x collectionId==1; there are 8 animations, but 7 of them are 0xFFFF (pointers increase by 2)) | | - Camera animation
1. Engine loads CameraSettings and CameraAnim pointers (the one you get after obtaining available Cameras, which is usually one only. I don't know what happens when there are two cameras)
2. Camera Animation Set holds collection of camera sequences designed for different monster spectrums. I don't know yet what triggers the engine to load which animation set, but I think this may be related to encounter data=====Example=====
3a0stg006. After getting x:<br>0x5d8 -> 02 00 08 00 20 00 # Get EOF-> *(0x5d8 + 8) -> 32# Jump to EOF -> 0x5d8 + 32 = 0x5F8 (This is now Camera Animation Collection)# Get pointer to specific correct anim you get the correct collection. In this case we will use AnimCollectionID == 0, so: *(0x5F8 + 0*2 + 2) -> 0x0c# Jump to Anim collection data: 0x5F8 + 0x0c = 0x604 (This is now Camera Animation Set)# Jump to Camera animation. It startby cameraAnimSetID, let's with 08 00 that indicates 8 pointers take for example cameraAnimSetID == 7, so: *(including himself0x604 + 7*2)-> 0x25E. Engine just skips over Now carefully, jump by multiplying it by 82! ## 0x604 + (0x25E *2 to get to data from which finally renders ) = 0xAC0 Therefore: a0stg006.x Camera animation 7 in camera animation.collection 0 is at 0xAC0
== Geometry ==
=== Texture page calculation ===
Byte TPage = InputBytes[TexturePage_index] & 0F;
Bitwise TPage byte AND 0F, to delete first 4 bits
int TPageINT = TPage * 64;
For 16 bit TIM's, the texture page is 64 pixels wide
 
====Example====
For 24-bit TIM:
0xB2 byte is: 2*48 = 96
Unsure about this one. It could be 42.667 instead of 48. It takes 1.5x the space of 16 bit. I haven't seen a file that uses 24-bit yet.
 
For 16-bit TIM:
0xB2 byte is: 2*64= 128
 
For 8-bit TIM:
0xB2 byte is: 2*128 = 256
Byte TPage = InputBytes[TexturePage_index] & 0F; //Bitwise TPage byte AND 0F, to delete first For 4 bits int TPageINT = TPage * 128; //For 16 -bit TIM's, the texture page : 0xB2 byte is 128 sized: 2*256 = 512
Example:0xB2 byte Each time you half the number of bits you double the amount of data you can store in the same space. So the calculated Texture Page is:2*128 = 256different.
=== Face order / Translation/ triangulation ===
'''1.====Quad wing order:'''====
ABCD ---> ABDC
example:
f 1 2 4 3
'''2.====Quad triangulation face order'''====
ABDC > ABD
ACD (same for VT)
f 1 2 4
f 1 3 4
'''3.====Triangles VT order:'''====
A/T1 > A/T2
B/T2 > B/T3
C/T3 > C/T1
====Example:====
(Also with quad triangulation face order!)
f 1/1 2/2 7/4 6/3
27
edits

Navigation menu