FF7 Crisis Core - File Format and Data Investigation

  • Thread starter Thread starter koral
  • Start date Start date
Status
Not open for further replies.
I really like you two, speculative thinkers with the game-programmers mindset :-D
Although I have divided my reply, I hope both parts will be read and considered!

X-Dina:
Yes, understanding those "padding" values would be the key to solving this enigma. I have discovered some interesting patterns to help determine the vertex-data from the "extra" data:


  • Firstly, all "real" vertices begin with two floats in the range 0 to 1. Never entirely 0, never entirly 1. The remaining values could be anything (4 unknown bytes, 3 shorts XYZ, and 2 unknown bytes almost always zeros).
  • Secondly, following the definitive vertex tag "0000803f" there may be any number of floats with values of zero, which should be ignored as padding.
  • Thridly, if the second byte of the 4-unknown-bytes within a possible vertex is zero, then that vertex isn't a vertex (will either have a zero UV or messed up XYZ value).


These three are the most "concrete" rules, because they seem to work through all the files I have examined. The other tags which i had posted about a while back are unreliable.

Also, I noticed an interesting value at offset 0x14 (from the first byte after the "77777777777777" chunk seperator).
If you read it as a SHORT and minus one from it, it gives you the count of how many 24-byte (TYPE-1) vertices are listed starting from offset 0x1C.

So for the Moogle file (02373), the (absolute) file offset is 0x714 (local chunk offset 0x14), which gives a value of 0x42 (66). Then starting from (absolute) file offset 0x718 (local chunk offset 0x1C), you will find the first TYPE-1 vertex (tagged by "0000803f"), followed by 64 more such TYPE-1 vertices.

But the pattern breaks down after that, reaching TYPE-2 vertex data. I am sure there must be some kind of offset here too to determine where the next batch of TYPE-1 vertices begin, but it isn't easy to spot.

The Reno file (02190) has a value of 0x1 at the 0x14-offset (absolute:0xcb4), and contains zeros at 0x1c (ie, no TYPE-1 vertices), leading upto the first occurance of the "0000803f" tag (in this case it is an "embedded" TYPE-1 Vertex within the TYPE-2 data chunk).


MrAdults:
Interesting observation :-)
I know that z-sorting of transparent polys has to be done when developing for PC's, but dont games-console PPUs handle that sort of thing automatically? I am not an expert on console-hardware, so I will assume that the vertices would need to be stored in batches for optimal rendering of transparent objects.

Could we not conclude then, that we would expect to find similar transparancy-parts (eg, hair clumps) grouped together, not with any other vertices belonging to "solid" parts?
For example, for Reno, the vertices making up his hair would be distinct from the vertices from everything else (indexed or not).

The Moogle texture file is interesting.

The only alpha it contains is within its wing-segment, but I can recall that the vertices belonging to the wings were a seperate batch of TYPE-1 vertices from its head. Likewise, Moogle-san's ears and nose were separate batches of TYPE-1 vertices from each other too.

Each of those seperate parts (batches of TYPE-1 vertices) has its own UV-space on the texture-map.
Maybe they just modelled (and later stored) these model parts in such a way that the transparant-parts would be differentiated on their own just as a "side-effect" of seperating the parts to better fit the UV map?

In other words, no discreet form of "transparent-part-tagging" or indexing would have been neccessary (or present)?
 
I think I know why they were separated into different groups.

When I import a 3DS file from 3DS Max, all of the edges that correspond to separate texture chunks, are always cut open and I have to re-sew them together again.

I believe the engine that saved the files had to separate the verts so there wouldn't be any texture warping on the model when rendered.

This would mean that when read by the PSP itself, it looks solid, only because the verts are touching each other, but in actuality there are sliced open edges all over.

Can you confirm this?

As for transparency, I believe the alpha is simply drawn as solid on the first pass over the entire model, then the engine does a secondary render that multiplies the alpha to create the transparency(the transparent rendering is kept in memory and is written to the screen from there rather than directly from the disc).

Again... speculation... based on past experience.

I believe, in a shorter phrase, the entire models are treated as alpha transparent enabled unless the texture image has NO alpha at all.


As for the 0x14 data.... that's very interesting...I had a feeling there was a header that noted the size in there somewhere...


and !!! the unknown data you mentioned that is 'will either have a zero UV or messed up XYZ value' could be the bone weighting info we've been guessing about!
 
Yeah, it is possible that they just leave both blending and depth writing enabled, and have the verts that reference part of the uv that is actually transparent ordered after the non-transparent verts. However, they would still have to software-sort their models by distance to camera in this case, or you would have cases where you would not see another character model behind a transparent surface, as that kind of sorting can't be done on the hardware level (due to the fact that it would need to defer rasterization to support it). It also assumes the PSP GPU has blend optimizations to save fillrate on blend operations if the written depth fragment is previously clear, which it may, but I'm unsure.

In either case, it would make a lot more sense to me to, at the very least, have some kind of marker between vertices to signify a change in blend mode, unless they were very desperate to cut down on primitive batches, without regard to the cost of software distance sorting or potentially greater fill expense. However, it doesn't make a lot of sense to do a post-depth alpha blend pass if you have rendered your alpha surfaces to the depth buffer, and the information in the framebuffer is stomped on whenever a depth fragment passes, which is why the hardware itself can't support an alpha post-multiply.

I'll have a look around some of those verts that reference transparent areas of the texture map, and see if I can find anything that would be indicative of a change in blending between batches. It seems more and more like the verts are more like a "draw command list" of some sort, which would explain some of the seemingly arbitrary tagging values thrown in there. However, I don't know enough about programming for the PSP, particularly with commercial GPU interface libs, to know if there are any official display list formats this data could resemble.
 
I awake..... from my slumber....

When I helped reverse the FF8/CC models, it was no unheard of for the programmers to put GPU opcodes in the model data.

Sadly, I only know how the GPU works in the PSX/PS2. I have not have any hands on experience with the PSP.

Keep in mind the models probably were made from object trees (waist, torso, head, left_upper_arm, left_frearm, left_hand, etc). You probably need to work on parsing one body part at a time as the vertex pools are usually grouped together by body part. The Mog head was a good start.
 
All I want to say is - this is one great piece of work. I'm looking forward to this project being finished and able to fully render the models.
 
I awake..... from my slumber....

When I helped reverse the FF8/CC models, it was no unheard of for the programmers to put GPU opcodes in the model data.

Sadly, I only know how the GPU works in the PSX/PS2. I have not have any hands on experience with the PSP.

Keep in mind the models probably were made from object trees (waist, torso, head, left_upper_arm, left_frearm, left_hand, etc). You probably need to work on parsing one body part at a time as the vertex pools are usually grouped together by body part. The Mog head was a good start.
Halkun do you have any FF8 info that isn't posted anywhere? It would certainly help me out if you could add it to my Model Project thread, where I'm compiling model format info links.

All I want to say is - this is one great piece of work. I'm looking forward to this project being finished and able to fully render the models.
I think everyone that's posted here is eagerly awaiting the completion.

Yeah, it is possible that they just leave both blending and depth writing enabled, and have the verts that reference part of the uv that is actually transparent ordered after the non-transparent verts. However, they would still have to software-sort their models by distance to camera in this case, or you would have cases where you would not see another character model behind a transparent surface, as that kind of sorting can't be done on the hardware level (due to the fact that it would need to defer rasterization to support it). It also assumes the PSP GPU has blend optimizations to save fillrate on blend operations if the written depth fragment is previously clear, which it may, but I'm unsure.

In either case, it would make a lot more sense to me to, at the very least, have some kind of marker between vertices to signify a change in blend mode, unless they were very desperate to cut down on primitive batches, without regard to the cost of software distance sorting or potentially greater fill expense. However, it doesn't make a lot of sense to do a post-depth alpha blend pass if you have rendered your alpha surfaces to the depth buffer, and the information in the framebuffer is stomped on whenever a depth fragment passes, which is why the hardware itself can't support an alpha post-multiply.

I'll have a look around some of those verts that reference transparent areas of the texture map, and see if I can find anything that would be indicative of a change in blending between batches. It seems more and more like the verts are more like a "draw command list" of some sort, which would explain some of the seemingly arbitrary tagging values thrown in there. However, I don't know enough about programming for the PSP, particularly with commercial GPU interface libs, to know if there are any official display list formats this data could resemble.
I suppose you know a lot more about how alpha is rendered than I... I'll just let you handle that area XD;
 
I don't, I just remember seeing GPU packets mixed in with the UV data. The Packed discribed if the pool of vertexes were a triangle or a quad...

Hold on....

Hey, did you know that the GPU for the PSX could take a quads as primitive, along with triangles? The PS2 could take Tirangles, Quads, triangle fans, and triangle strips. Maybe that might help. You might be processing everything as if they were just triangles. (I'm blindly guessing here). Like I said, I don't know much about the PSP's GPU, but it could stand to reason that it may be similar to the PS2's...
 
The more (people interested) the merrier!  :wink:

One of the first things I tried was rendering those vertices as quads, tri-lists and tri-strips (similar mechanism to rendering FF8 MCH files), but that didn't work because not all the vertices in these !-Files are vertices at all!
There are padding bytes, and distinct sub-headers of sorts, all garbled together.

The model "parts" are definitly categorised depending on the number of bones which influence them (TYPE1 being single weighted, TYPE2 being multi-weighted), but the ordering of these parts must be in-sync with how the PSP would render them, taking transparency into account. So heavy-transparent parts (like hair strands) we would expect to find towards the end of the vertex-data chunks. I haven't been able to confirm this yet.

Those "tags" are most definitly some kind of GPU opcodes (NeoCloudStrife has suggested this to me before).
For some reason (most likely because of improved efficiency) it looks like the mesh data is read directly from the UMD (or RAM) to the GPU for rendering, which is unlike how meshes usually get rendered on other consoles.
Maybe its a PSP thing, or maybe its just Crises Core?

What about Dissidia? Would that be worth looking into?


We really need to start by understanding how the PSP works I suppose!  :lol:
Are there any good documents available? I haven't been able to find anything detailed enough.

Its funny how FF7's file-format investigation had fueled better understanding of the PSX all those years ago, and now it seems like Crises-Core will do the same for the PSP  :-P
 
Yeah, I agree, having some PSP hardware/GPU documentation would make this a lot easier. Unfortunately, Googling is not turning up too many resources, but I don't think I'm searching for the right things. I keep getting this thread thrown back near the top of my search results. :)

I know that homebrew libraries have been able to utilize 3D features for some time. Unfortunately, I know those libraries work by loading official Sony kernel modules, so just looking at the homebrew devkit probably will not reveal low-level register info or GPU formats. I guess I'll keep Googling. Please anyone else who has some helpful links in this area, feel free to chime in. :) I'll report back if I find any applicable documentation.

Edit: I think I have just found almost everything we need to know in the source code for "Potemkin", a PSP emulator. It has vertex decoding/pipeline modules, and lists for all of the types and flags for vertex types, and it even shows how to handle the vertex weights within the vertex stream! :) The PSP appears to support up to 8 bones per command list, so meshes/command lists will no doubt be broken up for characters that use more than 8 bones. Now we just have to figure out the bone data. Each bone should be a 3x4 (or 4x3) matrix. From the emulator source, I believe it has to be floating point, but I may be missing a part where it does conversion.

Edit 2: I've verified that these vertex blocks are indeed a match to the PSP GPU formats and are decoded in the same way hardware decodes them. For "type 1" vertex blocks, there is a DWORD of value "0x00000723" usually 1 DWORD before the actual number of vertices. This value means:

Code: [Select]
Code:
 int tc = 3; //2 floats int col = 0; //no color int nrm = 1; //x, y, z in bytes int pos = 2; //3 shorts int weighttype = 3; //float int idx = 0; //none int morphcount = 0; int nweights = 0; DWORD fmt = 0; fmt |= tc; fmt |= (col<<2); fmt |= (nrm<<5); fmt |= (pos<<7); fmt |= (weighttype<<9); fmt |= (idx<<11); fmt |= (morphcount<<18); fmt |= (nweights<<14); //(fmt == 0x00000723)
When you get the sizes and offsets of the various components with that vertex type DWORD, padding and aligning along the way according to hardware spec, you get 24 byte vertex blocks with correct offsets to uv, position, and normal. Now that we have this knowledge, no matter what "type" a vertex is, we can know how it should be indexed (if at all), and where to get the essentials to render, such as position and UV. Now the only thing left to do is to figure out a reliable way to get those GPU control codes out between vertex batches. There is no reliable offset to the next control code/vertex number, from what I can find, and I'm not sure what the other bytes in between chunks mean yet.
 
Last edited:
Success! :)

mogmodel.jpg


You guys can probably piece things together from what I've said so far, but I will nonetheless be writing up the spec details (to include the PSP-related info) once everything is a bit more automated. Still haven't located a place to read the exact number of segments, or bothered to see if there is a command-terminator (there probably is).
 
Holy damn. That's really great about findind how the GPU works.
However I'd like to ask if it's normal that some of the textures that I view with the 0.30 version appear to have noise or scanlines on them, making them impossible to tell what are they. I was looking for Sephiroth's and Hojo's texture, I swept through all the model files and couldn't find them in those that were viewable, so my guess is their must be in those that have noise/scanlines or them, any way to fix that??
 
Alright, got this working perfectly with all of the models I have.
reno.jpg

There is a single WORD (2 bytes) value after every segment, which is conveniently just "1" all the way until the last chunk, where it is 0. :) Another WORD right after that gives you an offset to look for the beginning of the next vertex data. Can anyone send me some more models to try out? Ideally some more characters (Genesis, Tifa, Zack, etc). I would like to start looking for skeletal data soon in order to actually make use of the bone weights.

Edit: Here is a full blog write-up of my findings, skip to the bottom for the meat:
http://www.richwhitehouse.com/index.php?postid=28
Please feel free to directly or indirectly take any information or code snippets and assimilate it into this thread or the wiki.
 
Last edited:
i must say i am impressed with how fast this was figured out.

either the consoles are getting more intuitive, or the hackers are getting smarter ;-)
 
HOORAY!!!!
WOOO!!!
haha! you guys did it! majorly awesome :D
really, thank you, all of you :D
i'm just sorry i couldnt help more!
 
WOOHOOO!!!
Fantastic stuff Mr Adults!

I tried it out, and it worked absolutely brilliantly!

witness the Crises-Core Character Collage (sample):



Alpha-blending has been disabled temporarily because Irrlicht needs a little work to correctly sort out the polys. I was just being lazy  :-P

The two Clouds (infantry and SOLDIER costumes) and Sephi have some strange texture-map issues, but there is no doubt the geometry can be parsed and rendered fully using this method.
I now just need to find a way to correct the texture problem, and it should be good to go for another public release!

To be honest, bones and animations were never on my TODO list (unless they had been required to correctly render the meshes) so I may not go any deeper into these Model files.
If Mr Adults tools would want to incorporate those things, then it would make it easier for me to just move onto something else.

THANKYOU EVERYONE for helping me get so much done so quick!
I suppose all the right people just happened to be at the right place at the right time (doing the right thing) :lol:
 
Now if only someone could compile a viewer for those and release it since I have totally no experiance with coding whatsoever, only 3Ds Max, Maya and Photoshop.
 
Wow !!!  :-o
Awesome work !!  :wink:

Please continue  :-)
Now if only someone could compile a viewer for those and release it since I have totally no experiance with coding whatsoever, only 3Ds Max, Maya and Photoshop.
I'm agree with you Aurenasek116  ;)
 
Just a question, is it possible to add a sort of "Convertor" type thing for the models like what biturn has? for instance to just turn these models into .OBJ or .3ds files, because i have vista, and 3DRipperDX seems to have trouble with vista as far as i can tell. it crashes the instant i try to dump with shader model 3.0, and when i use shader model 2.0, it doesn't do it right at all...
But you guys rock! apart from animations and bones, what else would there be to look into for this game?
 
Neocloudstrife, 3d printscreen would work well with it i think. If we try with it first, it's less work for Koral/MrAdults.
 
Once again I would like to say thank you to koral and those others ( ignitz, mradults, x-dina ) for this awesome project.

The models from CC put be great for the mods Im working on.

Muchas gracias
 
Status
Not open for further replies.
Back
Top