Author Topic: FIELD.TDB - PSX faces  (Read 4397 times)

meesbaker

  • *
  • Posts: 324
    • View Profile
FIELD.TDB - PSX faces
« on: 2014-12-13 15:27:21 »
Hi everyone, I know that the file structure of field.tdb is explained on the wiki but I do not understand which faces belong to which palette.

In the model section of the .dat file of some field every model gets a face ID, 00 being Cloud's face. Now this id fully defines a face that is contained in field.tdb. A face consists of tim data for the shapes of the eyes and a color palette. Now every tim inside field.tdb is 512 bytes in size while the palettes at the end of the file are 32 bytes each.

Now if I want to extract Cloud's face I look at his ID=00. Means I copy the first face from 0x10-0x210 and the first palette at the end of the file. Comparing this to the face data found in wm0.bsz, Cloud's world model, i see that this data is correct.

It does not work for any other character though. The faces of tifa and cid are very deep in the file.The palette count always matches the face id but i do not understand how to calculate the location of the correct tim data. Cids id is 05 so he is the sixth face so it should be at 0xa10-0xc10 but it is somewhere around 0x5000 , completely different. Sephs face id is 0x15 so he is the 22nd face, in fact it is the 102nd face in field.tdb.

I dont get it. The palette is always correct but not the tim data. I must've known it  because I have a field.tdb with seph and cloud's faces correctly swapped but I do not understand it anymore.

Lazy Bastard

  • *
  • Posts: 290
  • I may be lazy, but I can...zzzZZZzzzZZZzzz...
    • View Profile
    • GameHacking.org
Re: FIELD.TDB - PSX faces
« Reply #1 on: 2015-01-20 02:44:44 »
So, meesbaker and I schemed about this for a little while. I verified via Akari's source how to pull palettes:

    int offset_to_clut = GetU32LE( 0xc ) + face_id * 32;

So, looking at a decompressed copy of FIELD.TDB, if I grab the 32-bit little-endian value at 0xC (0x0000FE10), and add (face_id * 32), I'll get 0x0000FE10 (Cloud's face id is zero, and zero times 32 equals zero). That means Cloud's CLUT data should be at 0x0000FE10.

Doing the same for Cid, if his ID is 05, would yield 0x0000FE10 + (5d * 32d = 160d = 0xA0) = 0x0000FEB0.

...but his source confuses me when it comes to actual face image data:

        for( int i = 1; i < face_row[ face_id ].size(); ++i )

        int offset_to_image = GetU32LE( 0x8 ) + face_row[ face_id ][ i ] * 512;


So, we started looking at actual offsets for face image data, and the offset we expected via 0x10 + (face_id * 0x200). For example:

Cloud face id is 0x0 or 0d
offset 0x0010
should be 0x10
difference is 0.

Tifa's face id is 0x03 or 3d
offset 0x3010
should be 0x610
difference is 2A00

cid 0x5 or 5d
offset 0x5010
should be 0xA10
difference 4600

Zack 0x9 or 9d
offset 0x9010
should be 0x1210
difference 7e00

sephiroth's face 0x15 or 21d
offset - 0xCC10
should be 0x2a10
difference is a200


difference between a200 and 7e00 is 2400.

2400 divided by 200(512d) equals 12.
12 is the number of models between Seph (21d) and Zack (9d).

So, every model increase, the difference between the supposed offset and the real offset increases by 0x200 (512d).

But, it turned out this didn't hold up for models before Zach.

A few more attempts at figuring out what was going on yielded this:

The first 10 models (0x0 - 0x9) are at offsets of 0x1000 bytes each. To get any of those, simply multiply 0x1000 * face_id, and add 0x10 for the header at the beginning. Cid is face_id 5, so 0x1000 * 0x5 = 0x5000, + 0x10 = 0x5010.

But after model 0x9, each model is only 0x400 bytes after the last. To get any of these, simply multiply 0x400 * (face_id - 0xA), and add 0xA010. Sephiroth is face_id 0x15, so (0x400 * (0x15 - 0xA = 0xB) =  0x2C00, + 0xA010 = 0xCC10.

It should be noted that we're still not clear exactly what data is in between.

What's interesting about this is that the first 10 models are all main characters, who have BCX files, etc...except Zach. This seems to imply that when they were making FIELD.TDB, they still considered Zach to be a main character.

meesbaker: I'm pretty tired, so let me know if I've missed anything.

meesbaker

  • *
  • Posts: 324
    • View Profile
Re: FIELD.TDB - PSX faces
« Reply #2 on: 2015-01-20 02:57:27 »
Yeah, as you said we are not sure what exactly the data between the faces is. Fact is, that the main character's faces including zack have mouths while all others do not. Their faces cover 0x1000 bytes while the others cover just 0x400.  On psx the mouths do not show up but they are there as can be seen in Makou Reactor.

Additionally world models also only have eyes but they use the same face data that can be found in field.tdb, only they need to use just 512 bytes. Cloud uses 1024 however its twice the same data. Cid is using only 512 bytes, I guess they made two kinds of texture sections in case they make a world model for a character without eye symmetry as Red 13. Cloud using cid's model as basis, swapping all his stuff and texture in looks exactly the same way.

So....

What we can definately conclude from this is that 512 bytes is at least enough to make both eyes mirrored show up properly because world models can do it. What I assume because of this is that one eye is 512 bytes while the mouth is 3072 bytes.
« Last Edit: 2015-01-20 02:59:46 by meesbaker »

Lazy Bastard

  • *
  • Posts: 290
  • I may be lazy, but I can...zzzZZZzzzZZZzzz...
    • View Profile
    • GameHacking.org
Re: FIELD.TDB - PSX faces
« Reply #3 on: 2015-01-20 19:58:03 »
Looking back, I realize my post above is somewhat dense to read. So, to summarize:


Image data (TIM):

For faces 0x00 to 0x09:

0x10 + (face_id * 0x1000)

For example, Cid is face_id 0x05, so:
0x10 + (0x05 * 0x1000 = 0x5000) = 0x5010


For faces 0x0A to 0x21:

0xA010 + ( (face_id - 0x0A) * 0x400 )

For example, Sephiroth is face_id 0x15, so:
0xA010 + ( (0x15 - 0x0A = 0x0B) * 0x400 = 0x2C00) = 0xCC10



Palette data (CLUT):

0x0000FE10 + (face_id * 0x20)

For example, Cid is face_id 0x05, so:
0x0000FE10 + (0x05 * 0x20 = 0xA0) = 0x0000FEB0.
« Last Edit: 2015-01-20 23:38:42 by Lazy Bastard »

meesbaker

  • *
  • Posts: 324
    • View Profile
Re: FIELD.TDB - PSX faces
« Reply #4 on: 2015-01-20 20:48:35 »
Now you mixed it up mate, maths are good but the 32byte data is the collor pallette and the larger face data is tim data. :)

Lazy Bastard

  • *
  • Posts: 290
  • I may be lazy, but I can...zzzZZZzzzZZZzzz...
    • View Profile
    • GameHacking.org
Re: FIELD.TDB - PSX faces
« Reply #5 on: 2015-01-20 23:38:46 »
Hah, you're right. Fixed.