Author Topic: FF9 "Type 3" directory  (Read 5994 times)

arcanis

  • *
  • Posts: 3
    • View Profile
FF9 "Type 3" directory
« on: 2012-11-10 19:05:50 »
Hi,

I've seen this topic, however I don't fully understand what are type 3 directories.

Could someone provide more details about this ?

Thanks !

tasior2

  • *
  • Posts: 21
    • View Profile
    • Reverse FF9
Re: FF9 "Type 3" directory
« Reply #1 on: 2015-04-01 12:44:55 »
Hi all,

I know it's an old topic but since I'm working on this directory at the moment I'd like to share what I got so far.

Entries in this directory are related to spells/attacks (including summons, trance, etc.). Spell ID is related to entry index.

DIRECTIRY ENTRIES:

Code: [Select]
typedef struct {
int type //The type of subdirectory this is
file_count //This gives the number of files within the subdirectory.
directory_information_sector //Sector that contains the directory information (IE file sector list).
first_file_sector
} DIR;

This structure can be found here: http://wiki.qhimm.com/view/FF9/IMGRootDir

No when we got this information we can seek to DIR.directory_information_sector (remember that is a sector so to obtain pointer you need to multiply this value by 2048 or shift left by 11 (0xB) ).

Now we got an array of sectors related to DIR.first_file_sector.
Code: [Select]
short ENTRIES[DIR.file_count];

So if we want to obtain sector to spell data we need to add entry sector to first file sector.
Code: [Select]
// Example for spell with id 94 (Death):
SPELL_DATA_SECTOR = DIR.first_file_sector + ENTRIES[94]

Keep in mind that not all spells are present on all disks! [EDIT:]Tirlititi is right: 0xFFFF are always at the same positions[/EDIT]
Some entries are equal 0xFFFF and should be omitted.


ENTRY STRUCTURE:

So far I got this:

Information about file structure is in 1st sector. It's kind of structure but with one exception. More about that bellow.

I will start with example (Death again), it's in little endian:
Code: [Select]
0100                          // chunk count
    0000 0400             // chunk index, entires count
        00 05 2B00        // id1, id2, size - always textures ?
        01 01 0800        // id1, id2, size
        02 01 1300        // id1, id2, size - mesh, AKAO ... probably animations as well
        0000                  // after id1=2 && id2=1 there is always integer value (not always 0, eg. in Madeen it equals 0500)
        03 00 1400        // id1, id2, size - this entry (id1=3) always got memory pointer as a first value

As you can see it will be nice structure if not this integer value. But it's always there and you need to remember about it!

Items starts from sector 1 and to obtain start sector of next element you need to remember size of previous one. Here is above example with start, end sectors:
Code: [Select]
count: 1
  chunk: 0 4
    item: 0 5 43 [1, 44]
    item: 1 1 8 [44, 52]
    item: 2 1 19 [52, 71]
    unknown: 0
    item: 3 0 20 [71, 91]

There's some more information in first sector at offset 0x400. I don't know what is this data yet.

EDIT:
I will post later about how to read textures from item id1=0
« Last Edit: 2015-04-10 11:27:58 by tasior2 »

Tirlititi

  • *
  • Posts: 886
    • View Profile
Re: FF9 "Type 3" directory
« Reply #2 on: 2015-04-01 13:10:17 »
The datas at 0x400 is the animation sequencing.
It's a list of sequence codes, ending with 0.
EDIT : I was wrong about the arguments' lengths. All the codes use 2 bytes-long arguments, even the "End of sequence" one.
They all use 2 bytes as arguments, though it may be for conveniency purpose and they may not be all used.

Here are the codes I figured out this far (I'll get back to it soon) :
0x0 → End of sequence
0x1 → Wait for some time
0x2 → Play caster animation
0x23 → Camera-related stuff
0x25 → Effect point ; 1st argument is the character and 2nd is the effect type (see below)
0x28 → Put character back in non-active mode ; 1st argument is the character
0x29 → Play camera
0x2A → Set battle scene transparency ; 1st argument is alpha, 2nd is the fade time
0x2B → Wait for animation
0x2D → Play sound ; 1st argument is a sound ID
0x5B → Play animation ; 1st argument is the character and 2nd is the animation kind ("hit", "use item", "fall", etc...)
0x80 → Play model on target

For the character arguments, I've seen either 0 (the target of the spell), 0x10 (the caster) and 0xFF (all targets).
For the effect type, I've seen either 0 (damage point : the spell deals damage, status aliments and the character play a "hitted" animation) and 1 (damage figure : displays the damage dealt by the last damage point).

Keep in mind that not all spells are present on all disks! Therefore some entries are equal 0xFFFF. It mean that this spell is not present and should be omitted.
Are you sure? I think there are only holes in the entries. I checked the different disks and the 0xFFFF are always at the same positions. I do think all the spells are present on all disks.

Thanks a bunch for the informations here and the ones to come though !
« Last Edit: 2015-04-13 23:10:08 by Tirlititi »

tasior2

  • *
  • Posts: 21
    • View Profile
    • Reverse FF9
Re: FF9 "Type 3" directory
« Reply #3 on: 2015-04-01 13:23:25 »
Thanks Tirlititi! That's a really useful information!

Are you sure? I think there are only holes in the entries. I checked the different disks and the 0xFFFF are always at the same positions. I do think all the spells are present on all disks.

I need to double check that:) You may be right. I've got US version only at the moment, I will compare it with EU and JP ones later.

tasior2

  • *
  • Posts: 21
    • View Profile
    • Reverse FF9
Re: FF9 "Type 3" directory
« Reply #4 on: 2015-04-01 15:10:40 »
TEXTURES:

Textures are located in item with id1=0. However there are no standard TIM images with proper file header.
Most important part in reading this textures is that it's buffered (probably for faster reading from CD). Buffer size is 32 sectors.

It starts with following header:
Code: [Select]
struct {
  uint texture_info_pointer;        // pointer to texture information
  uint data_pointer;                    // pointer to texture and clut data
  uint clut_data_count;
  short clut_4bit_count;
  short clut_8bit_count;
} HEADER;

// After header there are two arrays containing clut information:
short clut_4_table[ HEADER.clut_4bit_count ];
short clut_8_table[ HEADER.clut_8bit_count ];

Now we seek to texture info and we got:
Code: [Select]
struct {
    short unknown1;
    short unknown2;
    int count;
    RECT textures[ count ]; // see bellow for RECT struct
} TEX_INFO;


When we got texture information we can read data. After seeking to HEADER.data_pointer first there is a clut(s) data:
Code: [Select]
for( i=0; i < HEADER.clut_data_count; i++ ) {
    RECT clut_rect;
    short data[ clut_rect.w * clut_rect.h ];
}
Directly after clut data we start reading textures data. Now is the point where we need to remember that data is in 32 sector buffer.
Code: [Select]
for( i=0; i < TEX_INFO.count; i++) {
    RECT rect = TEX_INFO.textures[ i ];
    short texture_buffer[ rect.w * rect.h ];
    // now read 128*64 shorts
    // check if there is another 128*64 shorts in 32 sector buffer, if so read another 128*64 shorts
    // if not continue reading from another buffer
    // when you fill texture_buffer start reading another texture
}

Here is a RECT structure that I used above:
Code: [Select]
typedef struct{
   short x;
   short y;
   short w;
   short h;
} RECT;

And that's it:) I hope that this explanation is clear enough.

EDIT:
Item id1=0 doesn't contain all textures!!! E.g. summons models textures are somewhere else.
« Last Edit: 2015-04-01 15:14:47 by tasior2 »

tasior2

  • *
  • Posts: 21
    • View Profile
    • Reverse FF9
Re: FF9 "Type 3" directory
« Reply #5 on: 2015-04-10 11:48:59 »
Some info about item ID1=2

This item contain lot of different files (AKAO, mesh, ...).

It starts with integer value, it's a size of an array of pointers in bytes. So if you want to get length of this array divide it by 4.
Next there is an array of pointers to files. All integers.

Code: [Select]
struct {
  int count;
  int pointers[count/4];
} HEADER;

Pointers are calculated from start of item.

0x2D (2 bytes-long arguments) → Play sound ; 1st argument is a sound ID

Sounds ID match array index+1 (maybe array is one-based index) which points to AKAO file.

MESH:

File header:
  short magick; // always 0x736f
  short count; // always 1 (I could be wrong about that)
  short mesh_ptr; // pointer to mesh

Mesh is a standard one described on the wiki with one exception. Lot of models use Type-B and Type-C polygons.

[EDIT:]
Thanks Tirlititi for information about sequence. It was really useful for me!