Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - tasior2

Pages: [1]
1
Hi guys, thanks for good words! Yes, new release is in progress:) Lately I didn't have much time to work on this viewer and I needed to take a brake from FF9;)
In the meantime I started working on Chrono Cross. I have totally beta version of battlefields viewer here: http://cc-tasior.c9.io/view.html if somebody is interested.

Any way this viewer is still in progress and  I will add more functionalities.

2
Just a quick one. I added textures to spells models:)

Enjoy!

3
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!

4
Thanks guys,

small update, it's work in progress but I would like to share it with you. As you know I'm looking for summon models so I'm digging in directory 13 and I was able to locate 3d meshes there, lots of spells have them (e.g. Death, Frog drop, Shiva). So I added spell model viewer:) It's just mesh without animation and textures. I don't know where are animation yet but I know where and how to load textures just need to find how to match them to mesh.

Unfortunately I didn't find summon models.

A lot of these models use Type-B and Type-C polygons/triangles. I didn't have time to work on Type-C but here is what I got about Type-B:

Quad Type-B:
Code: [Select]
struct {
  short vertex_index1;
  short vertex_index2;
  short vertex_index3;
  short vertex_index4;
  short uv_index1;
  short uv_index2;
  short uv_index3;
  short uv_index4;
  byte color[3]; // 24 bit color value, not sure about that
  byte texture; // not sure about that
  int unknown[3]; //don't know yet what are these values
} QUAD_B;
Triangle Type-B:
Code: [Select]
struct {
  short vertex_index1;
  short vertex_index2;
  short vertex_index3;
  short uv_index1;
  short uv_index2;
  short uv_index3;
  byte color[3];  // 24 bit color value, not sure about that
  byte unknown; //probably padding
  short unknown2[3]; //don't know yet what are these values
  short texture; //not sure about that
} TRI_B;

I also added directory 13 to file browser.

Some screenshots of spell models:





5
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.

6
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.

7
Hi Tirlititi,

I just posted some information about directory 13 (spells), hope that will be helpful somehow.

http://forums.qhimm.com/index.php?topic=13840.0

8
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

9
Sweet update:)

I had to take a break from summons and I decided to create exporter:) Lucky winner from 3d formats is Collada (simplest), it support skeleton and animation and multiple texture. So here it is ... Eiko model in blender:



Export button is at top of options at right side menu. After click it will produce zip containing model(s) and textures. If your browser hang just wait:)

World map can't be exported at this point.

Enjoy:)

10
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-03-09 14:34:39 »
Small update:
 - added world map viewer, without textures (I will add texture mapping in next release)
 - added reverse material checkbox on monster viewer.

I could be wrong but it seems that sometimes the textures are loaded in the reverse order. I will try to find out if it's true. For workaround with checkbox works fine:)

World map loading is very slow so you need to be patient;)

EDIT:

I will now focus on summons so probably for couple weeks there will be no new releases.

11
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-26 23:26:29 »
Hi guys, I was playing with directory 13 today and I found some strange texture:) Probably never used in game.



Anyone knows what does it mean?

12
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-26 09:02:53 »
I was using absolute value for texture window x/y coordinates. It appears that this negative values are correct:) More info about 0x12 file can be found here:

http://forums.qhimm.com/index.php?topic=15962.0

13
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-25 17:36:54 »
Hi guys, I fixed texture mapping on map models:)



I'm still struggling with monsters... and trying to figure out directory 13.

I also figured out how to read sprites (image only) I'll try to add this feature on next release. Here is some work in progress screenshot (fire sprite from first scene in game):


14
Just want to say, GREAT WORK Tirlititi!!!

15
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-23 11:10:04 »
Where can you download this viewer? Is it only available online, and not accessible by those without an internet connection?

Hmm since everything is on client side (in browser) I don't see why not make offline version. Just unzip archive and open reverse_ff9.html in your browser.
Offline version:
http://beta-reverseff9.rhcloud.com/reverse_ff9_offline.zip

One suggestion I would make is to be able to select an individual keyframe of the animation. A slider would work.

Added to my TODO list:)

Right now I'm able to export the .db files, but will it eventually be possible to export the models and textures as obj or FBX (to retain animations).

At some point I have a plan to do that but right now I'm more focused on viewing stuff. There will be no problem with exporting textures (maybe I will add that in next release) but model w/ animation will require to write FBX/Collada exporter and that will be time consuming.

I got really excited with 'world map models' thinking it was going to be the world map itself, are there any plans to implement that at some point, or field environments (surprisingly there doesn't appear to be any tools for viewing FF9's field backgrounds).

Yes, map and fields backgrounds are on TODO list.


I'm trying to fix texture issues (monsters / world map models) but I'm distracted by Directory 13:) There's a lot of sprites there (that I can't read right now) but I really want to find summons:) So forgive me if I will not release anything in this week:)

16
FILE STRUCTURE

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

Code: [Select]
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_count

struct {
    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_count

struct {
    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_count

struct {
    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_count

struct {
    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]
#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]
u_short GetTPage(
int tp, // Texture mode
// 0: 4bitCLUT
// 1: 8bitCLUT
// 2: 16bitDirect
int 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 Forward
int x, int y) // Texture page address



That's all:) I hope that it will be useful for somebody.

17
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-20 15:07:25 »
@MaKiPL

I split quads into two triangles in following way:

Code: [Select]
i0-i3 - indexes from vertices array
uv0-uv3 - indexes from UV table

Quad Type-A:
{
  indices: [i0, i1, i2, i3],
  uvs: [uv0, uv1, uv2, uv3]
}

Triangle 1:
{
  indices: [i0, i1, i2],
  uvs: [uv0, uv1, uv2]
}


Triangle 2:
{
  indices: [i1, i2, i3],
  uvs: [uv1, uv2, uv3]
}

It work fine for all meshes that use Quad Type-A (didn't find other types yet).

In WebGL (OpenGL ES) you need to have UVs in range [0,1] so after that I needed to divide UVs by texture width/height:

Code: [Select]
4bit - texture size = 64x64
8bit - texture size = 128x128
16/24bit - texture size = 256x256 (there are no textures in this mode in FF9)

You can get texture mode from tpage value from 0x12 file (I will post this later in separate thread - how to read 0x12 file).

EDIT:
P.S. Nice to see some one from Poland on this forum:)

18
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-20 14:16:27 »
Thanks Tirlititi, I'm glad to hear that:)

You're right in fields there is no information which animations are for which model, only default animation can be obtain from 0x12 file. But some times like in this case there is no default animation so you need to find animation manually:)

I corrected typos:) Later I will create a thread about how I read 0x12 file and some other stuff.

19
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-20 13:17:59 »
@paul

Animation - same for all models
Materials - some special cases: weapons always use same tpage, monsters - didn't figured out yet (materials are swapped sometimes)

@Kaldarasha

You're probably right:) But since is beta and I will change domain I didn't want to post this in tools. I will as soon I release first non beta version.

20
FF9 Tools / Re: [FF9] Online viewer
« on: 2015-02-20 11:44:05 »
Yes it's a tool but since there is message to 'NOT create new threads here.' in Tool forum I posted here:)

Most data is on wiki (mesh / animations / 0xdb cluster / file structure). Rest is my own investigation:)

For textures I emulated psx vram. Materials are stored in 0x12 files like wiki said but I needed to dig into Psy-Q SDK to figure out how to read tpage and clut data. I also had some difficulties with animation and monsters (data is in two separated directories).
I can post information how to read this file (probably in separate thread(s)).


21
Hi all,

I finally got some time to create a FF9 online viewer. It's beta version so don't worry about bugs or if your browser will hang:)
It works in browsers that supports WebGL (Tested in: FireFox 27.0.1, Chrome 40.0.2214.111 m).

Features (so far):
  • View/export* files
  • Export 3D models to Collada format(DAE)**
  • View weapons
  • View playable characters w/ animations
  • View fields models w/ animations
  • View monsters w/ animations (bug with textures)
  • View map models w/ animations
  • View world map w/o textures
  • View spell models
* Currently only files in directories can be saved. Just double click on file.
** World map not supported yet

To do:
  • Fix texture bug on monsters
  • Add possibility to export files from cluster (0xDB)
  • Add dialog viewer
  • Add battle fields viewer
  • Add map viewer
  • Add fields backgrounds viewer
  • Add animation controls
  • Add sprite viewer
  • Add textures to world map

Viewer URL:

http://beta-reverseff9.rhcloud.com/

Offline version:
http://beta-reverseff9.rhcloud.com/reverse_ff9_offline.zip

Changelog:
Code: [Select]
beta 0.0.5.1:
 - added textures to spells models
beta 0.0.5:
 - added directory 13 to file browser
 - added spells models viewer
beta 0.0.4:
 - added exporter - collada (DAE) w/ animation
 - fixed render options state after model change

beta 0.0.3:
 - added switch to reverse textures for monster models
 - added world map viewer w/o textures

beta 0.0.2:
 - fixed texture mapping problem on map models

beta 0.0.1:
  - added possibility to view file structure
  - added possibility to view 3D models w/ animations ( weapons/playable characters/monsters/field models/map models )

Screenshots:

File browser:

Weapons:

Playable characters:

Map models:


Enjoy!

Let me know what you think about it and if you spot any bugs please report:)

Pages: [1]