[FF9] 0x12 file structure (models information)

  • Thread starter Thread starter tasior2
  • Start date Start date
Status
Not open for further replies.
T

tasior2

Guest
FILE STRUCTURE

Here is what I figured out about 0x12  file. This file contains information about models and structure is as follow:

Code: [Select]
Code:
It always starts with following header:struct {    uint8 tag;       // always 'DC'    uint8 model_count;  // models count    int16 padd;         // align to 32 bits - irrelevant data} header;After header there is an array of models infos. Lenght of this array == header.model_countstruct {    uint16 mesh_id;                 // 0x02 file id - mesh    uint16 default_animation_id;    // 0x03 file id - animation ( this value can be -1, it means that there is no default animation )    uint8  materials_count;         // materials count    uint24 materials_pointer;       // pointer to materials array ( calculated from begining of stucture )    uint16 id_0x19;                 // 0x19 file id - ??? ( can be -1 )    uint8  unknown1;                // possibly id of some file    uint8  unknown2;                // unknown ( align to 32 bits? )} model_info;Materials:First there is an array of tpage/clut values. Length == model_info.materials_countstruct {    uint16 tpage;    uint16 clut;} tpage_clut;Then array of textures windows (actually just x,y), this values should be added to tpage.x and tpage.y to obtain top-left corner of material texture.  Length == model_info.materials_countstruct {    int16 x;    // This value can be negative!    int16 y;    // This value can be negative!} tw;Next there is an array that probably is face/eye position in VRAM. For fields models this values are quite ok but not for playable charachters.For weapons it's always [0, 0, 0, 0] and for playable characters it's [2, 2, 0, 0] or [1, 1, 0, 0]. Length == model_info.materials_countstruct {    int16 x1;   // x of face/eye ???    int16 y1;   // y of face/eye ???    int16 x2;   // very often this value is equal x1    int16 y2;   // very often this value is equal y1} eye_anim;



HOW TO READ MONSTERS

In all cases meshes (0x02) animations (0x03) and textures (0x04) are in the same cluster with 0x12 file. The only exception are monsters that are separated into two directories:
Directory 5 - Contains 0x12 file
Directory 7 - Contains 0x02, 0x03 and 0x04
To read monster first you need to read information from 0x12, when you got meshes id you can load corresponding clusters from directory 7. Id of cluster from directory 7 always match id of mesh that is inside this cluster. Some times there is more than one mesh in 0x12 file for monsters!




HOW TO DECODE TPAGE AND CLUT

Information about how to decode tpage/clut value can be found in Psy-Q SDK. In file: psx/include/LIBGPU.H we can find following macros:

Code: [Select]
Code:
#define getTPage(tp, abr, x, y)      \  ((((tp)&0x3)<<7)|(((abr)&0x3)<<5)|(((y)&0x100)>>4)|(((x)&0x3ff)>>6)| \  (((y)&0x200)<<2))#define getClut(x, y) \ (((y)<<6)|(((x)>>4)&0x3f))#define dumpTPage(tpage)      \ GPU_printf("tpage: (%d,%d,%d,%d)\n",    \      ((tpage)>>7)&0x003,((tpage)>>5)&0x003, \      ((tpage)<<6)&0x7c0,    \      (((tpage)<<4)&0x100)+(((tpage)>>2)&0x200))#define dumpClut(clut) \ GPU_printf("clut: (%d,%d)\n", (clut&0x3f)<<4, (clut>>6))
and from documentation:

Code: [Select]
Code:
u_short GetTPage(int tp,    // Texture mode     // 0: 4bitCLUT     // 1: 8bitCLUT     // 2: 16bitDirectint abr,    // Semitransparency rate     // 0: 0.5 x Back + 0.5 x Forward     // 1: 1.0 x Back + 1.0 x Forward     // 2: 1.0 x Back - 1.0 x Forward     // 3: 1.0 x Back + 0.25 x Forwardint x, int y)   // Texture page address



That's all:) I hope that it will be useful for somebody.
 
Last edited:
Status
Not open for further replies.
Back
Top