What's new

Melee Arcive Viewer (MAV) in development project.

revel8n

New member
Pl**.dat - general model information
Pl**Nr.dat - model data (also includes files with other color designation besides 'Nr')
Pl**Aj.dat - animation data

if i remember correctly.
 
OP
Tcll

Tcll

Complexity == Fun >:3
Pl**.dat - general model information
Pl**Nr.dat - model data (also includes files with other color designation besides 'Nr')
Pl**Aj.dat - animation data

if i remember correctly.

o_O
how/where did you figure that out??
 
Last edited:

revel8n

New member
The dat file have a weirdly structured layout. The 32-byte header structure i outlined earlier contains an offset to a list of offset values, the count of which is also listed in the header. This list of offsets point to small structures of information within the files, which themselves also begin with another offset to the actual data, along with possibly some data about the intent of the information at that offset. The actual data within the files may or may not be in order, but these offset lists usually are in a specific ordering. Usually for models this would be: texture/material information, vertex information, then mesh information. Determining what is what and the actual counts and what not are things i am still looking into, but once you parse the header information and list of offset values to offset values, you can technically tell where everything in the file is located...even if you cannot tell what that information at those offsets actually is (well you can visually, which may be enough for the things some people are attempting to do, but there is still the information in those substructures to find the remaining designators of what data is what and other properties). i originally stopped once i got to that point as other things came up that took priority, but now that i am getting back into looking into things i will hopefully be able to make the connections to what is what and hopefully finalize a general way of reading the data for each sub-type of dat file. Will have to see. i will attempt to get the binary template file i had for some of the header and offset information rewritten and post it when i can. if anything that will definitely help those looking to just find file offsets for hacking and what not, and may even allow them to test changing values that will even further verify what information in the files are used for what purpose.
 
OP
Tcll

Tcll

Complexity == Fun >:3
This info is impressive...

how long have you been doing this??
 

revel8n

New member
i started on the Melee formats around the same time i started on the Metroid Prime formats mentioned in another thread in this section (which was around September last year i think). Just didn't get to work on things as much as i had wanted, and hadn't really touched it until recently when some things came up regarding Brawl (which i also plan on looking into) in addition to your interest in the formats. Overall i have probably only really invested about a week or so of active work on the Melee formats though, before now anyways. i believe a lot of the information left comes down to flag values that determine data type, data sizes, and in cases where it cannot be determined from some other method, data counts.

i have a lot of formats i am working on or towards, so i tend to jump around a lot between them. Hope to get caught up eventually though, only time will tell.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
OMG RLY... o_O
SRSLY...

I've been working on the Melee formats for a few years... go figure
and here I get showed up by you... again, go figure
that makes me look bad... :(

but I'm not offended...
tell me your sorces (if you can rmbr them)
I want to know what you know.
 

Milun

New member
Nice info on the animation file, I'm definitely going to look into that (It'd be so awesome to have custom animations!).
 
OP
Tcll

Tcll

Complexity == Fun >:3
hey Milun...
for deciphering the faces...
what was that equation you used??
 
OP
Tcll

Tcll

Complexity == Fun >:3
hey revel8n...

you were talking about the header having offset values that linked to certain offset values wich linked those to the ~ final values...
do you know of a good way to convert that??

if you could maybe give me an equation or something to go by...
that would be nice :)

I've got somewhat of a code here that I've worked on...
Code:
import struct as S
off = open("import.dat", 'rb')
out = open("export.obj", 'w')
t0 = off.read(32)#header
a = 0
while (a == 0):
 
    h = S.pack("<HHH", int(off.read(2).encode('hex'), 16), int(off.read(2).encode('hex'), 16), int(off.read(2).encode('hex'), 16))
    h = S.unpack("<hhh", h)
    v = "v "+(float(h[0]) * 0.01).__str__()+" "+(float(h[1]) * 0.01).__str__()+" "+(float(h[2]) * 0.01).__str__()
    if (v == 'v 0.0 0.0 0.0'):
        a = 1
 
        while (a == 1):
            h = off.read(1).encode('hex')+off.read(1).encode('hex')
            print h
 
            if (h == '9800'):
                a = 2
 
            #face code will be put here
 
        off.close()
        out.close()
    else:
        #print v
        #out.write(v+"\n")
it just goes straight down to the face hex... (after converting the vert hex of course.)
but I'm sure there will be a mis-hap with other dat files.

that '9800' ain't always gonna be in the same place.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
here is an update to the original code...
it's written more in the Python manner.
Code:
import struct as S
dat = open("import.dat", 'rb')
obj = open("export.obj", 'w')
#mtl = open("export.mtl", 'w')
def vert(v): 
    return (float(S.unpack("<h", S.pack("<H", int((v.encode('hex')), 16)))[0]) * 0.01).__str__()
    #v x y z
"""
def face ():
    return 
    #f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 (tri)
    #f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 v4/vt4/vn4 (quad)
"""
t0 = dat.read(32)#header
a = 0
while (a == 0):
    v = "v "+vert(dat.read(2))+" "+vert(dat.read(2))+" "+vert(dat.read(2))
       if (v == 'v 0.0 0.0 0.0'):
        a = 1
        #f = "f "+face()+" "+face()+" "+face()
    else:
        print v
        #obj.write(v+"\n")
you can use it if you wan't...
you can delete those little notes I've left myself if you want. =]

yea...
if you havn't figured out yet,
I'm kinda using this forum as an update log...
 
Last edited:

Milun

New member
hey Milun...
for deciphering the faces...
what was that equation you used??

Uh... not sure what you mean by that, but I had no equation. All I did was I converted the numbers in the 2 left columns (06 46, 06 47, 06 48) into decimal values, then added one to the result, and every 3 that I had were a face.



Also, how would I go about using your above code? Do I copy the face data into a .txt, or rename a .dat into import.dat or what? Sorry, despite the fact I use Blender a lot, I'm a really big Python noob.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
never mind... forget the equation...

hmm... seems I don't know nearly as much as I thought...
I got the verts completed... the faces should only be a little tougher...

do you have the code you used for the faces??
maybe I can decipher that to get an idea...

as for your last Q:
just rename the dat :)
but faces don't work yet...
it's just a re-type of the original code.

your probably not as much of a noob as me :p
but it's not really hard at all...
if you know algebra, Python shoud be a breeze.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
YAY!!! :bouncy:

I got the faces importing finally

yea it still needs a bit of fine tuning... :(

can anyone help me on identifying the normal (vn) values??
 
Last edited:

Milun

New member
Nice! Sorry, I can't help you with the normals, I never figured them out.

A sad fact though, even if you get all the faces decoded, Pikachu will still have about 66% gaps in the faces. I haven't been able to figure out how to fix them.

Edit: I may have found a sure fire way to patch up the holes. I need to research it a bit, but as soon as I do, I'll upload!
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
hmm...
then it looks like I've got a good model to start with. =]

I'm going over jahra!ns code right now...
just to see if I can't figure anything else out...
 

revel8n

New member
0x98 is the primitve type value for triangle strips. unlike triangle list every 3 vertices does not form a single triangle. After the initial 3 vertices, every vertex after that uses the previous 2 index values to create a new triangle.

So if you have the index values:
0 1 2 3 4 5 6
if you treated this as a triangle list you would get:
[0 1 2], [3 4 5]
and not have enough index values.

instead for a triangle strip the actual triangles will be:
[0 1 2], [1 2 3], [2 3 4], [3 4 5], and [4 5 6]
which means you would have missed 3 whole triangles if you interpreted things as a list of triangles.

So you have to make sure you take the various primitive types into account. The normals and uvs should work similarly except since normals are unit length you would have to divide the values you get by say 32,767 if the values are 16-bit, which would convert values to a range of -1 to 1 in floating point. UV coordinates would be converted similarly. This is under that assumption the values are not already in floating point, and are 16-bit within the range of -32,767 and 32,767.


As far as faces go, like i mentioned earlier, the gamecube/wii allows for indexing vertices, normals, and uv coordinates separately, so unfortunately you will not always be able to setup faces from just a single index. As such you may have to do a preprocessing step that duplicates any necessary data, unless the application, format or api you are working with also supports indexing values separately.


So if you have vertices normals and uv coordinates, every 3 index values would represent a single vertex, and every 3 groups (of three index values) would define a triangle if the primitive type is triangle list.
 

Milun

New member
And.... I was wrong about being wrong... yay!



Ok, here's how they work (ignore the red '00', I put them there to shuffle the code to the right). The filled squares are the normal faces (the ones we've deciphered), and the outlines are the new faces. Notice that the new faces are just one row down from the real ones (The purple has a gap because repeats are ignored). I haven't made a code to test it, but I really hope we'll be able to get near gap-less models now.

Here's my trial with my terrible Game Maker program:



Edit: There is still one thing I'm not sure of. The isolated purple outline circles the end of one face, however, it's also in the location of the start of another outlined face... I'm not sure whether we should interpret the isolated hex for one face or two.

The one on the left is the after shot, the one on the right is with the old code. I still haven't perfected my code, which is why there are still gaps, but I think that my above theory is still fine, and the issue is with my code.
 
Last edited:

Top