What's new

Melee Arcive Viewer (MAV) in development project.

OP
Tcll

Tcll

Complexity == Fun >:3
@ Revel

you sent this to me in an email...
in the meantime, here are some additional structure definitions that may be helpful if you have happened to dig a bit further in the script i posted.
struct ROOT_NODE
{
uint32 dataOffset <format = hex>;
uint32 stringTableOffset <format = hex>; // relative to the end of root node arrays
};
struct JOBJ_DATA
{
// 0x00
uint32 unknownOffset0x00 <format = hex>;
uint32 flags <format = hex>;
uint32 nextOffset <format = hex>; // next jobj structure?
uint32 childOffset <format = hex>; // child jobj structure?
// 0x10
uint32 dobjOffset <format = hex>; // dobj structure - object information?
float3 rotation; // rotation?
float3 scale; // scale?
float3 translation; // translation?
uint32 unknownOffset0x38 <format = hex>;
uint32 unknown0x3C;
};
For toy and player color data files the root node data offsets point to the jobj structure above. form there you can get to all the other data in the file.

I saw this data somewhere...
but I can't rmbr where DX<

what were the flag types again??

EDIT:

or are these them??

0x0001 - NoTransform
0x0002 - FixedTranslation
0x0004 - FixedRotation
0x0008 - FixedScale
0x0010 - Unk1
0x0100 - Unk2
0x0200 - HasGeometry

(these are mdl0 bone flags)
not sure if they're exactly the same... :p
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
you know what...

I'm going to try to make a python program that will export the hex data to an html...
or something of the sort...
maybe even an html/js program that will open the file and display colored file data in a table...

just ideas being tossed around... :p

hopefully this'll help me get a much better understanding of this though...
 
Last edited:

Milun

New member
...Well, you guys sure did a lot in my absence. Either way, as promised, my website is currently being updated with the tutorial and files for exporting and importing from Melee.

Only trouble is, the images aren't uploading properly...

EDIT: Well, I'm done. Now to figure out what Tcll and Revel sent me...
 
Last edited:

Milun

New member
Yes they do. The first page of the tutorial has a .rar with all the images the tutorial requires. I would have put them on the site itself, but my bandwidth wouldn't allow it.

And Tcll and Revel, thanks for all your coding examples. I'll be sure to use what I understand. Thanks!
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
Yes they do. The first page of the tutorial has a .rar with all the images the tutorial requires. I would have put them on the site itself, but my bandwidth wouldn't allow it.

why don't you use Picasa??
that's what I use...

and it's quite friendly too :)
 
OP
Tcll

Tcll

Complexity == Fun >:3
And Tcll and Revel, thanks for all your coding examples. I'll be sure to use what I understand. Thanks!

sorry for separate posts :p
my other hand is holding a sandwich...

but yea... I'm still coming out with more :p
 

GameWatching

New member
galp0158.png
 
Last edited:

Myuutsuu

forever.
Awesome, GameWatching. x.0
Is it possible to do that with the actual character (Pl) files, though? Just from what I've seen, trophies and Pl stuff work somewhat differently.
 
OP
Tcll

Tcll

Complexity == Fun >:3
Awesome, GameWatching. x.0
Is it possible to do that with the actual character (Pl) files, though? Just from what I've seen, trophies and Pl stuff work somewhat differently.

it should work with verts...
 
OP
Tcll

Tcll

Complexity == Fun >:3
I'm going to try to work on Melee+

or should I say...
getting my one hack to work on Gecko... (wii)

I'm thinking something like:
SD:/codes/GALP01.gct (of course)

SD:/private/wii/app/GALP/pf/ (main hacks directory)
other directories include:
SD:/private/wii/app/GALP/pf/root/
SD:/private/gamecube/app/GALP/pf/
SD:/private/gamecube/app/GALP/pf/root/

anyone got any more ideas??
 

Milun

New member
Nice work there GameWatching, but I see that my program messed up and gave you jagged edges too (if not as much as my example, but still there). I intend to look into that.

And as much as that Gecko thing would save me in terms of DVD's, I'm afraid that the Homebrew hacking is out of my league, as I can't get a single reader to let me write to my SD card. Sorry.

EDIT: Well, here's the new version of my converter. This one still gives uneven edges, but less than before. I'm not entirely sure what's wrong.

http://www.megaupload.com/?d=H3FDY4OW

I'm still pretty disappointed at how wonky the edges are :(.

On a side note: Tcll, could you please tell me how you decode the UV hex (that which follows the vertices). I've tried just converting it to numbers, and got a tangled mess, and I've tried the whole 'subtract 256 if larger than 128', but nothing. I'm just interested in how you got Pikachu's shape in your UV window. Thanks.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
On a side note: Tcll, could you please tell me how you decode the UV hex (that which follows the vertices). I've tried just converting it to numbers, and got a tangled mess, and I've tried the whole 'subtract 256 if larger than 128', but nothing. I'm just interested in how you got Pikachu's shape in your UV window. Thanks.

there's probably more... to do than just this...
but I used the conversion method for the verts on the UV's...
but it probably needs to be byte swapped or something...
and for faces...
some faces are: f vert,nor,uv
and others are: f vert,uv,nor

I only got lucky with pikachu...
everything else comes out in a tangle
something's missing and I'm not sure what

here's my code with only the uv parts selected:
Code:
[COLOR=gray]import struct as S[/COLOR]
[COLOR=gray]dat = open("import.dat", 'rb')[/COLOR]
[COLOR=gray]obj = open("export.obj", 'w')[/COLOR]
[COLOR=gray]#mtl = open("export.mtl", 'w')[/COLOR]
def HexToDec(h):
    return float(S.unpack("<h", S.pack("<H", int((h.encode('hex')), 16)))[0])
def vert(v): 
    return (HexToDec(v)* 0.01).__str__()
def f():
    f = int(HexToDec(dat.read(2))+1).__str__()
    nor = int(HexToDec(dat.read(2))+1).__str__()
    uv = int(HexToDec(dat.read(2))+1).__str__()
    #nor = int(HexToDec(dat.read(2))+1).__str__() #flipped face
 
    if (int(f, 10) >= 0):
        return f+"/"+uv+"/"+nor
 
[COLOR=gray]t0 = dat.read(32)#header[/COLOR]
[COLOR=gray]g = 0[/COLOR]
[COLOR=gray]a = 0[/COLOR]
[COLOR=gray]while (a == 0):[/COLOR]
[COLOR=gray]   v = "v "+vert(dat.read(2))+" "+vert(dat.read(2))+" "+vert(dat.read(2))[/COLOR]
[COLOR=gray]   if (v == 'v 0.0 0.0 0.0'):[/COLOR]
[COLOR=gray]       a = 1#main loop[/COLOR]
[COLOR=gray]       while (a == 1):[/COLOR]
[COLOR=gray]         s = dat.read(6)[/COLOR]
[COLOR=gray]         s = dat.read(1).encode('hex')[/COLOR]
[COLOR=gray]         if (s == '00'):[/COLOR]
            a = 2
            s = dat.seek(1,1)
            obj.write("\n")
            while (a == 2):#UV's
              vt = "vt "+vert(dat.read(2))+" "+vert(dat.read(2))#+" "+vert(dat.read(2))
              if (vt == 'vt 0.0 0.0'):# 0.0'):
                a = 3
              [COLOR=gray]  while (a == 3):[/COLOR]
[COLOR=gray]                 s = dat.read(6)[/COLOR]
[COLOR=gray]                 s = dat.read(1).encode('hex')[/COLOR]
[COLOR=gray]                 if (s == '00'):[/COLOR]
[COLOR=gray]                   a = 3.1[/COLOR]
[COLOR=gray]                   s = dat.seek(1,1)[/COLOR]
[COLOR=gray]                   obj.write("\n")[/COLOR]
[COLOR=gray]                   while (a == 3.1):#normals[/COLOR]
[COLOR=gray]                     vn  = "vn "+vert(dat.read(2))+" "+vert(dat.read(2))+" "+vert(dat.read(2))[/COLOR]
[COLOR=gray]                     if (vn == 'vn 0.0 0.0 0.0'):[/COLOR]
[COLOR=gray]                       a = 3.5[/COLOR]
 
[COLOR=gray]                       obj.write("\n"+'o object'+g.__str__()+"\n")[/COLOR]
[COLOR=gray]                       while (a == 3.5):[/COLOR]
[COLOR=gray]                           g = g+1[/COLOR]
 
[COLOR=gray]                           # attempt to ensure processing starts at the beginning of a data section[/COLOR]
[COLOR=gray]                           #h = dat.read(1).encode('hex')+dat.read(1).encode('hex')+dat.read(1).encode('hex')[/COLOR]
[COLOR=gray]                           #if (h == '0000B8' or h == '0000A8' or h == '0000B0' or h == '000090' or h == '000098' or h == '0000A0' or h == '000080'):  #this may also work and find even more matches, need to update backtrack offset if used[/COLOR]
[COLOR=gray]                           h = dat.read(1).encode('hex')+dat.read(1).encode('hex')+dat.read(1).encode('hex')+dat.read(1).encode('hex')[/COLOR]
[COLOR=gray]                           if (h == '0000B800' or h == '0000A800' or h == '0000B000' or h == '00009000' or h == '00009800' or h == '0000A000' or h == '00008000'):[/COLOR]
[COLOR=gray]                               a = 4[/COLOR]
[COLOR=gray]                               s = dat.seek(-2,1)[/COLOR]
[COLOR=gray]                               pos = dat.tell()[/COLOR]
[COLOR=gray]                               #print pos.__str__()+": "+h[/COLOR]
[COLOR=gray]                               while (a == 4):[/COLOR]
[COLOR=gray]                                   pos = dat.tell()[/COLOR]
[COLOR=gray]                                   h = dat.read(1).encode('hex') #+dat.read(1).encode('hex')[/COLOR]
[COLOR=gray]                                   #print pos.__str__()+": "+h[/COLOR]
[COLOR=gray]                                   if (h == 'B8' or h == 'A8' or h == 'B0' or h == '90' or h == '98' or h == 'A0' or h == '80'):[/COLOR]
[COLOR=gray]                                       #s = dat.seek(-1,1)[/COLOR]
[COLOR=gray]                                       index = HexToDec(dat.read(2))#index count[/COLOR]
[COLOR=gray]                                       if (h == 'B8'): #point[/COLOR]
[COLOR=gray]                                           while (index > 0):[/COLOR]
[COLOR=gray]                                               f0 = f()[/COLOR]
[COLOR=gray]                                               index = index - 1[/COLOR]
[COLOR=gray]                                               print "f "+f0[/COLOR]
[COLOR=gray]                                               obj.write("f "+f0+"\n")[/COLOR]
 
[COLOR=gray]                                       elif (h == 'A8'): #line[/COLOR]
[COLOR=gray]                                           while (index > 1):[/COLOR]
[COLOR=gray]                                               f0 = f()[/COLOR]
[COLOR=gray]                                               f1 = f()[/COLOR]
 
[COLOR=gray]                                               index = index - 2[/COLOR]
[COLOR=gray]                                               print "f "+f0+' '+f1[/COLOR]
[COLOR=gray]                                               obj.write("f "+f0+' '+f1+"\n")[/COLOR]
 
[COLOR=gray]                                       elif (h == 'B0'): #line strip[/COLOR]
[COLOR=gray]                                           while (index > 1):[/COLOR]
[COLOR=gray]                                               f0 = f()[/COLOR]
[COLOR=gray]                                               f1 = f()[/COLOR]
 
[COLOR=gray]                                               index = index - 1[/COLOR]
[COLOR=gray]                                               if (index > 1):[/COLOR]
[COLOR=gray]                                                   seek = dat.seek(-6,1)[/COLOR]
[COLOR=gray]                                               if (f0 != f1):[/COLOR]
[COLOR=gray]                                                   print "f "+f0+' '+f1[/COLOR]
[COLOR=gray]                                                   obj.write("f "+f0+' '+f1+"\n")[/COLOR]
 
 
[COLOR=gray]                                       elif (h == '90'): #triangle[/COLOR]
[COLOR=gray]                                           while (index > 2):[/COLOR]
[COLOR=gray]                                               f0 = f()[/COLOR]
[COLOR=gray]                                               f1 = f()[/COLOR]
[COLOR=gray]                                               f2 = f()[/COLOR]
 
[COLOR=gray]                                               index = index - 3[/COLOR]
[COLOR=gray]                                               print "f "+f0+' '+f1+' '+f2[/COLOR]
[COLOR=gray]                                               obj.write("f "+f0+' '+f1+' '+f2+"\n")[/COLOR]
 
[COLOR=gray]                                       elif (h == '98'): #triangle strip[/COLOR]
[COLOR=gray]                                           flip = 1[/COLOR]
[COLOR=gray]                                           while (index > 2):[/COLOR]
[COLOR=gray]                                               f0 = f()[/COLOR]
[COLOR=gray]                                               f1 = f()[/COLOR]
[COLOR=gray]                                               f2 = f()[/COLOR]
 
[COLOR=gray]                                               index = index - 1[/COLOR]
[COLOR=gray]                                               if (index > 2):[/COLOR]
[COLOR=gray]                                                   seek = dat.seek(-12,1)[/COLOR]
[COLOR=gray]                                               if (f0 != f1 and f1 != f2 and f2 != f0):[/COLOR]
[COLOR=gray]                                                   if (flip):[/COLOR]
[COLOR=gray]                                                       print "f "+f0+' '+f2+' '+f1[/COLOR]
[COLOR=gray]                                                       obj.write("f "+f0+' '+f2+' '+f1+"\n")[/COLOR]
[COLOR=gray]                                                   else:[/COLOR]
[COLOR=gray]                                                       print "f "+f0+' '+f1+' '+f2[/COLOR]
[COLOR=gray]                                                       obj.write("f "+f0+' '+f1+' '+f2+"\n")[/COLOR]
[COLOR=gray]                                               flip = 1 - flip[/COLOR]
 
[COLOR=gray]                                       elif (h == 'A0'): #triangle fan[/COLOR]
[COLOR=gray]                                           f0 = f()[/COLOR]
[COLOR=gray]                                           index = index - 1[/COLOR]
 
[COLOR=gray]                                           while (index > 1):[/COLOR]
[COLOR=gray]                                               f1 = f()[/COLOR]
[COLOR=gray]                                               f2 = f()[/COLOR]
 
[COLOR=gray]                                               index = index - 1[/COLOR]
[COLOR=gray]                                               if (index > 1):[/COLOR]
[COLOR=gray]                                                   seek = dat.seek(-6,1)[/COLOR]
 
[COLOR=gray]                                               if (f0 != f1 and f1 != f2 and f2 != f0):[/COLOR]
[COLOR=gray]                                                   print "f "+f0+' '+f1+' '+f2[/COLOR]
[COLOR=gray]                                                   obj.write("f "+f0+' '+f1+' '+f2+"\n")[/COLOR]
 
[COLOR=gray]                                       elif (h == '80'): #quad[/COLOR]
[COLOR=gray]                                           while (index > 3):[/COLOR]
[COLOR=gray]                                               f0 = f()[/COLOR]
[COLOR=gray]                                               f1 = f()[/COLOR]
[COLOR=gray]                                               f2 = f()[/COLOR]
[COLOR=gray]                                               f3 = f()[/COLOR]
 
[COLOR=gray]                                               index = index - 4[/COLOR]
[COLOR=gray]                                               print "f "+f0+' '+f1+' '+f2+' '+f3[/COLOR]
[COLOR=gray]                                               obj.write("f "+f0+' '+f1+' '+f2+' '+f3+"\n")[/COLOR]
[COLOR=gray]                                       else:[/COLOR]
[COLOR=gray]                                           a = 3 # should no longer get here, but just in case...[/COLOR]
[COLOR=gray]                                   else:[/COLOR]
[COLOR=gray]                                       # backtrack over invalid primitive type bytes[/COLOR]
[COLOR=gray]                                       a = 3[/COLOR]
[COLOR=gray]                                       s = dat.seek(-1,1)[/COLOR]
[COLOR=gray]                           else:        [/COLOR]
[COLOR=gray]                                #backtrack over trailing bytes so that[/COLOR]
[COLOR=gray]                                #the entire file is scanned a byte at a time[/COLOR]
[COLOR=gray]                                s = dat.seek(-3,1)[/COLOR]
[COLOR=gray]                     else:[/COLOR]
[COLOR=gray]                       print vn[/COLOR]
[COLOR=gray]                       obj.write(vn+"\n")[/COLOR]
 
              else:
                print vt
                obj.write(vt+"\n")
 
[COLOR=gray]   else:[/COLOR]
[COLOR=gray]       print v[/COLOR]
[COLOR=gray]       obj.write(v+"\n")[/COLOR]

yea... I know...
there was more I forgot to mention...
flipping the face...

IDK why...
but sometimes the UV and normal data is reversed...

so if you get like a grid...
or a circle of UV's...

you may be reading normal data...
 
Last edited:

Milun

New member
...Hm, Ok, so that's not my origin of error. I'll keep trying.

Btw, you now how the face data occasionally has those intermissions of '00'? Does that mean that that's where one object ends and a new object begins?

EDIT: Oh, guess it does. You wouldn't know how to separate objects within the same file would you? I tried the Pikachu method in your quote, but Blender still treats it as a single object. Maybe I'm doing it wrong? I place the line you said inbetween different faces in the 'f 1243 etc.' area.

EDIT2: Hold that thought, I think I know how.

EDIT3: Ok, now I get it. No matter what I do, a .obj imported into Blender will only be one object. So I'll have to make my program export multiple .obj's if I want it to work.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
hold on...

it does work...
look at this:

(didn't read the uv data right) :p

I'm not exactly sure how...
but my script was able to export spaces between the face data...

I added this to write 'o object ##' into each space
here's the simple code:
Code:
[COLOR=#808080]
[/COLOR][COLOR=black][COLOR=blue]obj.write("\n"+'o object'+g.__str__()+"\n")[/COLOR]
                       while (a == 3.5):
                           g = g+1[/COLOR]
the blue code is what writes it

and for importing to blender, select object
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
well I've redone my script a little...
and got it to import like it did in that other image... (the one with the almost perfect UV's)
but now it can import objects as well... (as v1.4 is supposed to do)

here's the image:

(this image has been fixed up a little)

I got it to import like this by switching the vert data conversion order to vert, normal, uv...
instead of vert, uv, normal... (this is not data for faces)

here's the obj if you're interested
Download
you will have to scale the uv's to 0.01, and reface the normals
I'm impressed at how there were so little normals to reface... :eek:
Q3D shows alot more reversed normals...
 
Last edited:

Milun

New member
Wow, thanks! This explains a lot. For starters, my object separators had underscores in them, which is probably why Blender ignored them. It shouldn't be hard for me to incorporate this into my program now. It's just a darn shame that we can't get consistent UV output. I just wonder what's so special about Pikachu...
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
it may be because I brute forced it...

it may only work for that file...
 
OP
Tcll

Tcll

Complexity == Fun >:3
alright...
I may not be working on this project too much now...

just got a boat load of mdl0 info from my friends over at HCBH...
so I get to work on an importer and an exporter for blender...

my keyboard's on fire because I've been trying to stay updated with them...

but yea...
I'll be off this project for a while...

in the meantime, you can continue your work on here and fill me in on any new discoveries. :)
 

Top