Difference between revisions of "FF8/FileFormat X"

From Final Fantasy Inside
< FF8
Jump to navigation Jump to search
my_wiki>MaKiPL
my_wiki>MaKiPL
(TIM Texture width/height resolving: Updated code- faster, less data and unimportant stuff.)
Line 312: Line 312:
  
 
=== TIM Texture width/height resolving ===
 
=== TIM Texture width/height resolving ===
 +
 +
            //Updated - 19.07.2015 by MaKiPL
  
             Byte[] OPN = File.ReadAllBytes(@"PATH TO .X stage file"); //Change this
+
             Byte[] Stage = File.ReadAllBytes(@"PATH TO .X stage file"); //Load file to memory
+
             Byte[] TIMtexture = { 0x10, 0x00, 0x00, 0x00, 0x09 }; //Initialize 8BPP header
+
             int TIMoffset = ByteSearch(Stage, TIMtexture, 0); //Search in Stage for TIM header
             Byte[] TIMtexture = { 0x10, 0x00, 0x00, 0x00, 0x09 };
+
             int TIMoffsetCLUTetc = TIM + 18; // Logic pass
             int TIMoffset = ByteSearch(OPN, TIMtexture, 0); //Byte search is special search for byte array custom function
+
             UInt16 CLUTsize = BitConverter.ToUInt16(Stage, TIMoffsetCLUTetc); //GET CLUT size to UInt16
             int TIMoffsetCLUTetc = TIMoffset + 18;
+
             TIMoffsetCLUTetc += 2 + (CLUTsize * 512) + 8; // Logic pass - pass CLUT offset, to get to sensitive data
            Byte[] CLUT = new byte[2];
+
             UInt16 szerU = BitConverter.ToUInt16(Stage, TIMoffsetCLUTetc); //Get raw UInt16 value of width from texture data
            Array.Copy(OPN, TIMoffsetCLUTetc, CLUT, 0, 2);
+
             UInt16 wysoU = BitConverter.ToUInt16(Stage, TIMoffsetCLUTetc + 2); //Get raw UInt16 height value from texture data (real)
             UInt16 CLUTsize = BitConverter.ToUInt16(CLUT, 0);
+
             int width = szerU * 2; //Calculate real texture width (For 8BPP = width*2)
            //DETERMINE HOW MUCH TO PASS
 
             TIMoffsetCLUTetc += 2 + (CLUTsize * 512) + 8;
 
            Byte[] szer = new byte[2];
 
            Byte[] wyso = new byte[2];
 
            Array.Copy(OPN, TIMoffsetCLUTetc, szer, 0, 2);
 
            Array.Copy(OPN, TIMoffsetCLUTetc + 2, wyso, 0, 2);
 
             UInt16 szerU = BitConverter.ToUInt16(szer, 0);
 
             UInt16 wysoU = BitConverter.ToUInt16(wyso, 0);
 
             int newSzerU = szerU * 2;
 
  
 
=== Face order / Translation/ triangulation ===
 
=== Face order / Translation/ triangulation ===

Revision as of 20:11, 19 July 2015

By MaKiPL. Thanks for help in research for: shakotay2 (XeNTaX), Halfer, Yagami Light.

Info

.X file is uncompressed 3D stage model with texture embedeed. The file contains basic info (currently unknown, probably for editor?), camera data, movement, translations and geometry data.

Name Usually starting with: Description
Info/Script E8 FF BD 27 01 00 02 Currently unknown. Probably header + info, that is not needed in game itself. Can be null'ied and nothing will happen ingame.
Camera data + movement 02 00 08 00 20 00 (usually 0x5d4/8) Camera animations, movement (pre-keyed)
Geometry 01 00 01 00 (See geometry section info) Divides to object (group) and it's sub-objects + vert/triangle grouping
Texture 01 00 00 00 09 (Always) Contains one .TIM texture

Info/Script

Currently unknown, takes up to ~1400 bytes from start. Unused in-game. Can be null'ied and nothing happen.

Camera data

Offset Length Description
0 2 bytes Number of cameras
2 2 bytes Number of camera animations?
?? / Camera data Varies Currently unknown

Camera data contains:

  1. Prekeyed camera movement
  2. Camera zoom
  3. Camera FOV (horizontal and vertical)
  4. Orthogenical projection
  5. Rotation
  6. Special effects like earthquake
  7. More, unknown?

This file does not contain camera animations for victory, summons and etc.

Geometry

Geometry contains groups, that contains Triangles and/or quads poligons. Models always stars at 01 00 01 00, and needs to be after camera data, either it's not model itself, but some other data.

Group

Offset Length Description
0 4 bytes Always 01 00 01 00 / Header of object
4 2 bytes Uint16 / number of vertices.
6 Number of vertices * 6 Vertex data, short X; short Y; short Z;
6 + (Number of vertices *6) (AbsolutePosition MOD 4) + 2 Padding
varies (just after above) 2 bytes uint16 / number of triangles
varies (just after above) 2 bytes uint16 / number of quads
varies (just after above) 4 bytes padding
varies (just after above) number of triangles * 20 Triangle data. If NumOfTriangles = 0, then instead of any triangle data, there's quad data.
varies (just after above) number of quads * 24 Triangle data. If NumOfQuads = 0, then instead of any quad data, there's either next header 01 00 01 00, or end of group.
Triangle
Name Type Description
F1 (A) uint16 A of face indice
F2 (B) uint16 B of face indice
F3 (C) uint16 C of face indice
U1 Byte U of first texture coordinate
V1 Byte V of first texture coordinate
U2 Byte U of second texture coordinate
V2 Byte V of second texture coordinate
OP Byte Opacity / Alpha channel blend
Unknown Byte PSOne GPU related?
U3 Byte U of third texture coordinate
V3 Byte V of third texture coordinate
Special (see below / After QUAD table) 8 Byte See below (after QUAD table)
Hide Byte/Bool Bool. Hides or shows texture
Red Byte Texture colourization (Red)
Green Byte Texture colourization (Green)
Blue Byte Texture colourization (Blue)
PSone GPU related Byte PSOne instruction
Quad
Name Type Description
F1 (A) uint16 A of face indice
F2 (B) uint16 B of face indice
F3 (C) uint16 C of face indice
F4 (D) uint16 D of face indice
U1 Byte U of first texture coordinate
V1 Byte V of first texture coordinate
OP Byte Opacity / Alpha channel blend
Unknown Byte PSOne GPU related?
U2 Byte U of second texture coordinate
V2 Byte V of second texture coordinate
Special (see below) 8 Byte See below (after table)
Hide Byte/Bool Bool. Hides or shows texture
U3 Byte U of third texture coordinate
V3 Byte V of third texture coordinate
U4 Byte U of fourth texture coordinate
V4 Byte V of fourth texture coordinate
Red Byte Texture colourization (Red)
Green Byte Texture colourization (Green)
Blue Byte Texture colourization (Blue)
PSone GPU related Byte PSOne instruction

Special Byte: This byte, needs to be divided to two bytes. So, for example, a 0xE5 needs to be treated like two bytes: 0x0E 0x05 Other way is to treat first one as 6 BIT's, and second one as 2 BIT.

Singular of char Example Description
First char/ 6 BIT's B2 --> 0B Unknown
Second char / 2 BIT B2 --> 02 Texture page number.

Texture

Contains one TIMs with various size 512x256, 673x256, 768x256 (8BPP).

UV calculation algorithm

Float U = (float)U_Byte / (float)(TIM_Texture_Width * 2) + ((float)Texture_Page/(TIM_Texture_Width * 2));

Texture page calculation

               string StrByte = InputBytes[TexturePage_index].ToString("X2"); //Gets TPage byte as HEX text
               StrByte = "0" + StrByte.Substring(1); // Deletes the first char/ 6 bits
               Byte TPage = Byte.Parse(StrByte); // Parses result as new byte
               int TPageINT = TPage * 128; //For 8 bit TIM's, the texture page is 128 sized

Example: 0xB2 byte is: 2*128 = 256

TIM Texture width/height resolving

           //Updated - 19.07.2015 by MaKiPL
           Byte[] Stage = File.ReadAllBytes(@"PATH TO .X stage file"); //Load file to memory
           Byte[] TIMtexture = { 0x10, 0x00, 0x00, 0x00, 0x09 }; //Initialize 8BPP header
           int TIMoffset = ByteSearch(Stage, TIMtexture, 0); //Search in Stage for TIM header
           int TIMoffsetCLUTetc = TIM + 18; // Logic pass
           UInt16 CLUTsize = BitConverter.ToUInt16(Stage, TIMoffsetCLUTetc); //GET CLUT size to UInt16
           TIMoffsetCLUTetc += 2 + (CLUTsize * 512) + 8; // Logic pass - pass CLUT offset, to get to sensitive data
           UInt16 szerU = BitConverter.ToUInt16(Stage, TIMoffsetCLUTetc); //Get raw UInt16 value of width from texture data
           UInt16 wysoU = BitConverter.ToUInt16(Stage, TIMoffsetCLUTetc + 2); //Get raw UInt16 height value from texture data (real)
           int width = szerU * 2; //Calculate real texture width (For 8BPP = width*2)

Face order / Translation/ triangulation

1.Quad wing order:

 ABCD ---> ABDC
 example:
  f 1 2 3 4
 to:
  f 1 2 4 3

2.Quad triangulation face order

 ABDC > ABD
        ACD (same for VT)
 example:
 f 1 2 4 3
 to:
 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
 to:
 f 1/1 2/2 7/4
 f 1/1 6/3 7/4
 where:
 A=1 B=2 C=6 D=7