What's new

Melee Arcive Viewer (MAV) in development project.

OP
Tcll

Tcll

Complexity == Fun >:3
[MENTION=70286]Milun[/MENTION]

I know what you're dealing with...

thanx for the extra info. :0

and don't worry bout getting preoccupied :p
I got a little preoccupied with my anime and my site

it only took me about an hour to find my mistake in the last post. :D

using my method for the normals and the uv's...
this is what I've managed to do so far: (images not linked)
QmV5FzWVTw4gVvyHd6NvtCjADv6UQjfh9JZgopnYu8wHFw

QmVkLajUYACeErPMQjuTLnriwUyQoXLU6BJKGp5ZUeBTKa

I love the smell of progress...
smells like burning cpu with the stench of BO. XD

anyways...
my original file kept returning errors when imported into blender...
so these were the other 2...

as you can see..., the first is better than the second...
once I separate the objects...
it should come out a little better..., if not perfect.




EDIT: never mind...
I managed to split the objects up...
externally of course...
-----
the objects are separated by 2 new lines.
just add 'g object_#' to the beginning of every object.
note: you must change the '#' to 0 and count +1 for each object.
-----
anyways...
I got the same results
of course..., they're split up..., but nothing has changed position wise.

but I'm still not sure how to fix it...
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
Nope. Sorry, this ones a bit complicated. See, the face hex usually starts with '98 00', and follows a pattern afterward. For instance, in TyEievui.dat, the face hex starts at offset 0x000215E0, and ends around 0x00047BD0. Now, this is really something complex, because I've actually just been estimating where it ends. After you copy and paste it, you have to look for the last occurrence of '98 ?? ??' (in this case '98 00 07') and increase the number of the 3rd Hex to something like '17' (so now it's '98 00 17'). Then add the 'CC'. This makes my program go over the limit of the data, and reach the CC's, otherwise it crashes (yes I know, this is extremely complicated and unnecessary, I'm sorry). Anyway, after it reads everything, it will send out a .obj, which you have to look through (with notepad) to see if it printed 'ERROR!!!' anywhere. It will always print error at the end. Go to the very end of the file, and remove all the lines with 'ERROR!!!' in them, and any that have 2 large numbers (like '34, 35') and then end with '1'. These aren't real values either.

Now I'm going to go and actually make this program usable, as after typing this, I realize just how tedious all this is to do.

what do you mean by the CC's??
 

GameWatching

New member
have a problem with the meleevertconverter.exe oO
i modded the trophy of mewtwo to make him have long ears,
when i opened meleevertconverter.exe,

i wrote in input file : mew2.obj (which i edited)

output file : mew2.txt

then i opened mew2.txt and i found only this :
v 3.2894e+006 3.2894e+006 3.2766e+006

only this,
not hex numbers oO

any help ?
 
OP
Tcll

Tcll

Complexity == Fun >:3
have a problem with the meleevertconverter.exe oO
i modded the trophy of mewtwo to make him have long ears,
when i opened meleevertconverter.exe,

i wrote in input file : mew2.obj (which i edited)

output file : mew2.txt

then i opened mew2.txt and i found only this :
v 3.2894e+006 3.2894e+006 3.2766e+006

only this,
not hex numbers oO

any help ?

no there not hex...
but those are some awfully large values there o_O

v 3289400.0 3289400.0 32766000000.0

milun... I think you may need to fix that...

@ GW the model's fine...
just scale it down when you import it
 

Milun

New member
have a problem with the meleevertconverter.exe oO
i modded the trophy of mewtwo to make him have long ears,
when i opened meleevertconverter.exe,

i wrote in input file : mew2.obj (which i edited)

output file : mew2.txt

then i opened mew2.txt and i found only this :
v 3.2894e+006 3.2894e+006 3.2766e+006

only this,
not hex numbers oO

any help ?

Well, you're in luck. While my C++ program will not export into Hex just yet, I have made a program earlier on that will.

It's here: http://meleeconverter.bravehost.com/downloads.htm

I hesitated to mention it, because it has a tendency to crash when converting multiple files. I wouldn't recommend using it to export from hex to .obj, but vice-versa it works fine. Be sure to read the guide included there on how to set up your .obj to work with it. It's written in Game Maker, which is why it's a bit dodgy with file opening. But here's proof that it works:



It has a guide that explains very clearly how to do everything (including Hex -> .obj), So If you're still having issues, the guide should tell you all you need to know. Just a hint, the .obj you want to convert needs to be opened, a new line added at the bottom, and 'Q' written in.

what do you mean by the CC's??

Don't worry about them. I'm refining it to avoid having to use them.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
dude :D

IDK yet how to get it back to hex...
can I see your source??
 

Milun

New member
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <iterator>
#include <cstring>
using namespace std;

char *CHAR;

string Input;
string Output;

///We already know what this does.
string fn_DecToHex (unsigned int value) {
	char conHex[256];
	int rawDec = value; //this is variable
	sprintf(conHex,"%x",rawDec);
	return conHex;
}

int fn_HexToDec (char rawHex[]) {
	int conDec; 
	sscanf(rawHex, "%x", &conDec);
	return conDec;
}

string fn_IntToString(int intValue) {
  char *myBuff;
  string strRetVal;
  myBuff = new char[100];
  memset(myBuff,'\0',100);
  itoa(intValue,myBuff,10);
  strRetVal = myBuff;
  delete[] myBuff;
  return(strRetVal);
}

int fn_StringToInt(string strConvert) {
  int intReturn;
  intReturn = atoi(strConvert.c_str());
  return(intReturn);
}

void fn_StringToChar(string STR) {
     int TempNumOne=STR.size();
     for (int a=0;a<=TempNumOne;a++)
     {
         CHAR[a]=STR[a];
     }
}



int main() {

  ///Same as before.
  string line;///Makes a new variable called 'line', the 'line' in this case being the entire hex contained copy-pasted within the .txt, so it's large.
  cout << "Opening files." << endl;///This just shows text in command prompt, and makes a new line.
  
  cout << "Input file: ";
  cin >> Input;///This asks for the complete filename.
  cout << endl;///New line.
  
  ifstream myfile (Input.c_str());///Makes a filename out of 'Input'.
  
  cout << "Output file: ";
  cin >> Output;
  cout << endl;
  
  ofstream outfile (Output.c_str()); ///Makes a filename out of 'Output'.
  
  cout << "Writing vertice data to file." << endl;
  
  
  
  if (myfile.is_open() && outfile.is_open())
  {
    while (! myfile.eof() )
    {   
      ///Same variables.
      getline (myfile,line);
      CHAR  = new char[100];
      unsigned int Offset = 0;
      unsigned int MaxOffset = line.length();
      string HexA;
      string HexB;
      
      ///Ok, here we go.
      unsigned int Face1;///Stores the vertice number for first triangle point.
      unsigned int Face2;///Stores the vertice number for second triangle point.
      unsigned int Face3;///Stores the vertice number for third triangle point.
      unsigned int Face4;///Stores the vertice number in-case of a quadratic.
      unsigned int Duration;///Stores the Datablock size.
      
      //0xB8 // points
      //0xA8 // lines
      //0xB0 // line strip
      //0x90 // triangles
      //0x98 // triangle strip
      //0xA0 // triangle fan
      //0x80 // quads
      
      ///Just all the different faces.
      string LineNor = "A8 0";
      string LineStrip = "B0 0";
      
      string TriStrip = "98 0";
      string TriNor = "90 0";
      string TriFan = "A0 0";
      
      string Quad = "80 0";
      
      ///////////////////////
      string LengthA;
      int LengthB;
      
      ///This aids in the search through the string.
      size_t found;
      
      ///These values are mainly for debugging; they basically show where the nearest face value is on every step.
      int TriStripFound;
      int TriNorFound;
      int QuadFound;
      
      ///The offset for the line after all equations are performed.
      int FinalOffset = 0;
      
      string Type = "";
      
      ///Length is back///
      unsigned int Length;
      
      /////////////////////////////////
      unsigned int FileOffset;

      ///Loop.
      FindLength:
      
      ///These are for debugging. The '999' prevents the search from skipping over a particular header.
      Duration = 0;
      TriStripFound = 999;
      TriNorFound = 999;
      QuadFound = 999;
      
      ///Convert the first 9 characters ('98 00 23 ' for example) to characters.
      fn_StringToChar(line.substr(FinalOffset,9));
      
      ///Used for debugging. Basically, it prints the above string, so I can look for a flaw in my code if it isn't '98', '80' etc.
      //cout << "Last Offset words: " << CHAR << endl;
      
      ///Get's rid of everything we were working on before we looped (later), leaving the start of the file to be '98 00 23 '.
      ///This prevents overly large offset numbers.
      line.erase(0,FinalOffset);
      
      ///Look for the first occurence of a Triangle Strip, over 36 characters (12 lots of hex).
      found = line.find(TriStrip,36);
      
      //cout << "\n" << "TriStrip found at:                " << found << endl;///Debug; Show me where you found it. It worked if it is 36 (or 0, only at the start of the process).
      
      if (found!=string::npos)///If you actually found it at all...
      {
          if (int(found) == 36 || int(found) == 0)///If it's the right values.
          {
              TriStripFound = int(found);///Make this equal where you found it.
          }
          else
          {
              ///Now, when changing headers, theres usually an intermission of '00' before. So the Triangle Strip would not be at position 36 anymore.
              ///This solves that problem (although, not too well).
              found = line.find("00 00 00 00 00 " + TriStrip,0);
      
              if (found!=string::npos)
              {
                  TriStripFound = int(found)+15;///It adds 15, because of the '00's.
              }
          }
      }
      
      ///Now do the same for other face types.
      found = line.find(TriNor,36);
      //cout << "TriNor found at:                  " << found << endl;
      if (found!=string::npos)
      {
          if (int(found) == 36 || int(found) == 0)
          {
              TriNorFound = int(found);
          }
          else
          {
              found = line.find("00 00 00 00 00 " + TriNor,0);
              if (found!=string::npos)
              {
                  TriNorFound = int(found)+15;
              }
          }
      }
      
      ///And again.
      found = line.find(Quad,36);
      //cout << "Quad found at:                  " << found << endl;
      if (found!=string::npos)
      {
          if (int(found) == 36 || int(found) == 0)
          {
              QuadFound = int(found);
          }
          else
          {
              found = line.find("00 00 00 00 00 " + Quad,0);
      
              if (found!=string::npos)
              {
                  QuadFound = int(found)+15;
              }
          }
      }
      
      if (line.find(TriNor,36) == line.find(Quad,36) && line.find(TriNor,36) == line.find(TriStrip,36))
      {
          goto Done;///THIS CONPARRISSON MIGHT NOT WORK ALL THE TIME! I DOUBT IT DOES, BECAUSE, WHAT IF IT FINDS ONE LEGIT, BUT CAN'T FIND TWO? MAYBE COMPARE ALL 3?
      }
      
      //////////////////
      /// DEBUG ZONE ///
      //////////////////
      /*
      cout << "TriFan found at:                  " << line.find(TriFan,0) << endl;
      cout << "LineNor found at:                 " << line.find(LineNor,0) << endl;
      cout << "LineStrip found at:               " << line.find(LineStrip,0) << endl;
      */
      //////////////////////////////
      /// NOW LEAVING DEBUG ZONE ///
      //////////////////////////////
      
      ///If TriNor (Triangles; '90') is at the location 36 (remember, all others have been set to '999')
      if (TriNorFound < TriStripFound)
      {
          if (TriNorFound < QuadFound)
          {
              ///Go to its offset.
              FinalOffset = TriNorFound;
      
              ///Now we know what type to convert.
              Type = "Nor";
              
              ///Go to the convertion.
              goto NoConvert;
          }
      }
      
      ///Again.
      if (TriStripFound < TriNorFound)
      {
          //cout << "TriStripFound:                               " << TriStripFound << endl;
          if (TriStripFound < QuadFound)
          {
              FinalOffset = TriStripFound;
              Type = "Strip";
              goto NoConvert;
          }
      }
      
      ///Again.
      if (QuadFound < TriNorFound)
      {
          //cout << "QuadFound:                            " << QuadFound << endl;
          if (QuadFound < TriStripFound)
          {
              FinalOffset = QuadFound;
              Type = "Quad";
              goto NoConvert;
          }
      }
      
      ///Now we convert.
      NoConvert:
      
      ///Debug.          
      //cout << "FinalOffset of type: " << FinalOffset << endl;
      //cout << "Type:                " << Type << endl;
      
      ///This looks familiar. Remember, since 'FinalOffset' is still placed before '98 00 23 ', we need to add values.
      ///In this case, we're getting '00' as a value.
      fn_StringToChar(line.substr(FinalOffset+3,2));
      LengthA = CHAR;
      ///Now LengthA == '00'.
      
      ///Now we get '23'
      fn_StringToChar(line.substr(FinalOffset+6,2));
      
      ///And add to it, so we get '0023'///
      ///I do this because space (' ') won't get read.
      LengthA += CHAR;
      
      ///And finally, Length == decimal value of '0023'.
      fn_StringToChar(LengthA);
      Length = fn_HexToDec(CHAR);
      
      ///More debug.
      fn_StringToChar(line.substr(FinalOffset,9));
      //cout << "Now converting from offset:       " << CHAR << endl;
      //cout << "The length is:                    " << Length << endl << endl;
      
      ///Like Amy once said, 'just wait a minute'.
      ///YOU WOULD SERIOUSLY NEED TO CONCIDER REMOVING THIS, OR IT WILL PAUSE AFTER EVERY HEADER.
      //system ("pause");
      
      ///Add 9, so we go past '98 00 23 ', and reach the first value after. Let's say it's '03 15 '
      FinalOffset += 9;
      
      ///Now we convert for real.
      ConvertFace:
      
      ///Convert the '03'.
      fn_StringToChar(line.substr(FinalOffset,2));
      HexA = CHAR;
      
      ///Convert the '15'.
      fn_StringToChar(line.substr(FinalOffset+3,2));
      HexB = CHAR;
      
      ///Our powers combined, we are '0315'.
      HexA += HexB;
      
      fn_StringToChar(HexA);
      
      ///Now Face1 is the decimal value of that.
      Face1 = fn_HexToDec(CHAR);
      
      ///We add 1, because '00' counts, yes theres no such thing as the 0th vertice.
      Face1++;
      
      ///Add to the amount of times we've converted a face.
      Duration++;
      
      ///And again.
      fn_StringToChar(line.substr(FinalOffset+18,2));
      HexA = CHAR;
      fn_StringToChar(line.substr(FinalOffset+21,2));
      HexB = CHAR;
      HexA += HexB;
      fn_StringToChar(HexA);
      Face2 = fn_HexToDec(CHAR);
      Face2++;
      
      ///And again.
      fn_StringToChar(line.substr(FinalOffset+36,2));
      HexA = CHAR;
      fn_StringToChar(line.substr(FinalOffset+39,2));
      HexB = CHAR;
      HexA += HexB;
      fn_StringToChar(HexA);
      Face3 = fn_HexToDec(CHAR);
      Face3++;
      
      ///And once more, incase we have a Quad.
      fn_StringToChar(line.substr(FinalOffset+54,2));
      HexA = CHAR;
      fn_StringToChar(line.substr(FinalOffset+57,2));
      HexB = CHAR;
      HexA += HexB;
      fn_StringToChar(HexA);
      Face4 = fn_HexToDec(CHAR);
      Face4++;
      
      ///If we're not using a Quad.
      ///Also checks if we have double values anywhere.
      if (Type != "Quad"){
      if (Face1 == Face2 || Face1 == Face3 || Face2 == Face3){
      if (Face1 == Face2){Face2 = Face4;}
      if (Face1 == Face3){Face3 = Face4;}
      if (Face2 == Face3){Face3 = Face4;}}
      }
      
      ///Go forward 6 hex spaces ('XX XX XX XX XX XX ').
      FinalOffset += 18;
      
      ///Depending on what type, we need to add more than that.
      if (Type == "Nor"){
               FinalOffset += 36;
               Duration += 2;}
      
      if (Type == "Quad"){
               FinalOffset += 54;
               Duration += 3;}
      
      ///Check for duplicate values. It writes 'ERROR!!!' if we do... This rfeally shows how much faith I have in this code.
      if (Type != "Quad")
      {
          if (Face1 == Face2 || Face1 == Face3 || Face2 == Face3)
          {
              outfile << "f " << Face1 << " " << Face2 << " " << Face3 << " ERROR!!!" << endl;
              //cout << "f " << Face1 << " " << Face2 << " " << Face3 << " ERROR!!!" << endl;
          }
          else
          {///And if we don't have duplicates, don't worry, be happy.
              outfile << "f " << Face1 << " " << Face2 << " " << Face3 << endl;
              //cout << "f " << Face1 << " " << Face2 << " " << Face3 << endl;
          }
      }
      else
      {///Quads get special treatment, due to the extra point.
          outfile << "f " << Face1 << " " << Face2 << " " << Face3 << " " << Face4 << endl;
          //cout << "f " << Face1 << " " << Face2 << " " << Face3 << " " << Face4 << endl;
      }
      
      ///NOW, THIS PART IS VERY IMPORTANT!
      
      ///See how it checks for that particular value?
      ///That is the way I check to see if we reached the end of the file.
      ///What I do is, at the end of the text in the .txt, I type a heap of 'CC CC CC CC CC CC CC CC '
      ///52429 happens to be what you'de get if you converted 'CC CC' to decimal and added 1.
      ///So it checks if we haven't reached the end of the file.
      if (Face1 != 52429)
      {
          if (Type != "Quad")///If we're not Quad's.
          {
              if (Length-3 >= Duration)///If we haven't reached the end of the length the header specified.
              {
                  goto ConvertFace;///Go back and convert again.
              }
              else
              {///But if we have.
                  if (Type == "Nor")
                  {
                      FinalOffset -= 36;///This fixes the offset, because '90' triangles are a bit weird for me.
                  }
                      
                  goto FindLength;///Look for another header.
              }      
          }
          else
          {///If we are using Quad's.
              if (Length-4 >= Duration)///Etc.
              {
                  goto ConvertFace;
              }
              else
              {
                  FinalOffset -= 36;
                  goto FindLength;
              }      
          }
      }
      else
      {
          Done:
          ///If we are done, then tell me.
          cout << endl << "Done!" << endl << endl;
      }
    }
    myfile.close();
    outfile.close();
  }
  else cout << "Unable to open file";

	system ("pause");
	return 0;
}

Ok, here's the new one. You don't need to add the CC's at the end or anything. To get it to work, just copy from the start of the face data (just Ctrl-F '98 0' in a hex editor, such as HxD, and it will eventually find the start, which is a '98 xx xx etc.' underneath a line of '00's. Now just copy down till where you think the end is. It will finish by itself, but you'll have to look over the .obj file still, and remove any buggy lines. Here's an example:

......37 38
f 37 38 35
f 38 35 93
f 35 38 93
f 38 93 39
f 1 3 31649
f 3 31649 4101
f 31649 4101 1
f 4101 1 3
f 1 3 1 ERROR!!!
f 3 1 1 ERROR!!!
f 1 16257 16257 ERROR!!!
f 1 1 16257 ERROR!!!
f 1 16257 1 ERROR!!!


The ones in bold, need to be removed. Easy ways to tell are:

1. If it has ERROR!!! at the end.
2. If it has a small number(s), and an overly large number.
3. If it goes out of the pattern:

38 35 93
35 38 93
38 93 39
1 3 31649

See how it follows a happy pattern of 30's and then suddenly goes to the '1 3 31649'? That's a giveaway.

Here's the executable: http://www.megaupload.com/?d=JQT4UAOC

dude :D

IDK yet how to get it back to hex...
can I see your source??

What do you mean? Are you using my Game Maker program from my website? Oh wait... oh, that's what you mean. Well, I can't really share my Game Maker code with you at the moment, I have it saved elsewhere, sorry ,there saved at my school. But, as I recall, all I did was reverse the process. Let me see if I can remember how to list it:

1. Object files are formatted with lines of 'v 1.4 35 12'.
2. The Offset starts at the second place of the first line, before the '1.4'.
3. It looks for the next instance of ' ' (space). Then it gets the number in between (1.4), and floors it.
4. If it's smaller than 0, then add 256.
5. This becomes the whole number for X. Then that floored number is subtracted from the original to get '0.4'. That number is multiplied by 256, floored, and you get the Decimal number.
6. Convert both to Hex, and put them together, so you get (Whole Number converted to Hex) a space, (Decimal number converted to Hex). So lets pretend that that conversion makes: '01 6A'.
7. Repeat that for the other two numbers.
8. Go to a new line and repeat.

Yeah, again sorry. I'm going to try to recreate it in C++ if I can.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
Well, I can't really share my Game Maker code with you at the moment, I have it saved elsewhere, sorry ,there saved at my school. But, as I recall, all I did was reverse the process. Let me see if I can remember how to list it:

1. Object files are formatted with lines of 'v 1.4 35 12'.
2. The Offset starts at the second place of the first line, before the '1.4'.
3. It looks for the next instance of ' ' (space). Then it gets the number in between (1.4), and floors it.
4. If it's smaller than 0, then add 256.
5. This becomes the whole number for X. Then that floored number is subtracted from the original to get '0.4'. That number is multiplied by 256, floored, and you get the Decimal number.
6. Convert both to Hex, and put them together, so you get (Whole Number converted to Hex) a space, (Decimal number converted to Hex). So lets pretend that that conversion makes: '01 6A'.
7. Repeat that for the other two numbers.
8. Go to a new line and repeat.

Yeah, again sorry. I'm going to try to recreate it in C++ if I can.

ah... KK...
eh... guess that's just one of those times :p
 
OP
Tcll

Tcll

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

meet me at my forum
it's not so crowded there...
 

GameWatching

New member
Milun,

if i took TyMew2.dat and i want to use the Melee to Obj Converter done with GM,
from which offset to start and which one to end ?

because i can't find this pattern :
F5 50 F5 60 0A E0 FF E0 00 00 0B 00 0A 90 0A A0
04 C0 00 00 0A A0 0A E0 FF E0 FC 90 01 E0 F7 A0
FB F0 0B 00 09 C0 04 10 0A D0 F6 10 09 D0 0A F0
04 00 04 10 04 E0 09 D0 F6 30 0A E0 FB D0 09 D0
04 B0 FB E0 FB F0 04 A0 F6 20 0A 50 07 E0 04 30
FB C0 07 F0 0A 40 F5 B0 07 C0 FB B0 04 40 07 B0
F5 A0 0A 50 07 C0 FB B0 FB C0 07 B0 F5 A0 04 40
87 F0 0A 40 03 70 0D 90 F7 80 F5 B0 07 E0 04 30
F6 30 04 D0 04 10 F5 60 74 C0 F0 00 03 70 F2 10
 

Milun

New member
Uuuuuuuuuuuuuuuuuuuuuuuum... Not sure what you mean there. I assume you want the offsets of the vertice hex?

Well, it starts on the second line (0x00000020) and ends at 0x00003A3A...

Oh, and I see what you mean. Mewtwo is pretty confusing. I'm afraid I can't check at the moment, but If that doesn't work, there's a chance that 0x00003A40 - 0x000074F0 could work. I'll check it tomorrow if you still have trouble.
 

GameWatching

New member
Milun,

the model converter made with GM don't work at all D:
i cannot create an obj with the hex !
and when i tried to convert obj->hex (i made the obj with meleevertconverter.exe)
i don't work D:

help please D:
can you make a tutorial with pics and take the TyMew2.dat as example ?
 

Milun

New member
...I'm afraid, as I would have liked to upload a tutorial right now, it is already 11:30 PM where I live. I have the images and files ready, but ImageHost won't upload such large amounts. I'm afraid you'll have to wait until tomorrow.

Sorry about that, but trust me, it'll be good.
 
OP
Tcll

Tcll

Complexity == Fun >:3
sry...

I wasn't on last night due to a power outage that lasted about 2 minutes...

now my OS is corrupted and I have to repair it...
luckily there's 3 computers and a 2 Wii's here...

but I'm stuck with my wii right now, as I can't use the last computer with net...
(good thing I have a usb keyboard) :p
my other computer gets net from my main computer...

and the last wii isn't connected yet...

so you see my prob...

I should have my OS fixed soon...
just gotta replace a few files... :p
 
OP
Tcll

Tcll

Complexity == Fun >:3
well... I had to reinstall windows because of a power outage D:

srsly OMG D:<

now I get to waste this day reinstalling about 50 programs...
thank god it's not all my programs...
got around 30 more that are safe...
or should I say portable... :p

heh... me and my crappy life with a computer that tries to sabatoge me at every turn...

I want to burn it but it's the only "good" computer I got...
the other one crashes when you run anything 3D on it... (including N64 3D) D:

guess that's what I get for digging up free computers from the dumpster... :p
 

revel8n

New member
i still haven't had the time to code all these things up, but looking at the progress made so far, Milun could probably make really good use of the last template file i sent you Tcll.

Feel free to ask any questions about the information it contains. But it has everything you need to get from the root headers to the vertex specifications to the texture data, if you follow the structures correctly.

Hopefully someone here will beat me to coding something useful, but i will be getting back to things soon hopefully.
 
OP
Tcll

Tcll

Complexity == Fun >:3
hey... glad to see you're back :)

I'll send the files...
I'm installing the updates on my computer right now, so it may be a while before I can get them posted...
 
OP
Tcll

Tcll

Complexity == Fun >:3
KK...
so I've finished installing the updates...

now I just need to install like 25 programs that use the registry and I'll be ready to start reorganizing my files...

what a way to waste a perfectly good day...
and all because of a power loss... D:
 
OP
Tcll

Tcll

Complexity == Fun >:3
FINALLY everything's taken care of... D:

anyways...
here's the download :)
http://docs.google.com/leaf?id=0B1T13qYbnHNKMDZhMWE3ZTgtZDY3YS00ODUxLWI2YjAtNWMwYjlmNjU1ZjA3&hl=en

@ Revel

this doesn't include your new file...
if you wanted me to upload that...

then...

@ Milun

here you go
Code:
/*****************************************************************************
 * dat.bt - Structure definitions for Super Smash Brothers Melee - dat file related entities.
 *
 *****************************************************************************
 * Revision History:
 *  2009/09/29 - revel8n - Original
 *  2010/02/22 - revel8n - Changes based on information from breakpoint
 *  2010/02/22 - revel8n - More structure updates
 *  2010/02/23 - revel8n - Started adding other structures (FIGHTER and FIGATREE)
 */
#include "common-types.bt"
local uint32 t, cnt, savedFilePointer;
void PushFP(void) { savedFilePointer = FTell(); }
void PopFP(void) { FSeek(savedFilePointer); }
// used only to provide a way of giving "empty" structures a perceived size
void PopOffsetFP(uint32 offset) {FSeek(savedFilePointer + offset);}
void FSeekOfs(uint32 ofs) { FSeek(0x20 + ofs); }
// returns the number of consecutive 32-bit values until zero is reached
// zero itself is not included in the count, and file pointer is not moved
uint32 GetArrayCount(void)
{
    local uint32 cnt = 0;
    PushFP();
    while (ReadUInt(FTell()) != 0)
    {
        FSeek(FTell() + 4);
        cnt++;
    }
    PopFP();
    return cnt;
}
void DumpTransform(uint32 ofs);
void DumpJObj(uint32 ofs);
void DumpDObj(uint32 ofs);
void DumpMObj(uint32 ofs);
void DumpPObj(uint32 ofs);
void DumpTObj(uint32 ofs);
void DumpVtxAttr(uint32 ofs);
void DumpImageHeader(uint32 ofs);
void DumpPaletteHeader(uint32 ofs);
void DumpMaterialColors(uint32 ofs);
void DumpJointWeights(uint32 ofs);
void DumpDisplayList(uint32 ofs);
void DumpFighter(uint32 ofs);
SetReadOnly(true);
// #pragma displayname("dat structures")
// #pragma fileextensions(".dat")
// #pragma byteorder(big_endian)
BigEndian();
// mark used bytes with a light green background
local int64 filePos = FTell();
  
// pobj, aobj, lobj, gobj, tobj, mobj, cobj, fobj, sobj, robj, dobj, wobj
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 transformOffset   <format = hex>; // inverse transform
 uint32 unknown0x3C;
 
 if (transformOffset != 0)
 {
  DumpTransform(transformOffset);
 }
    // dump dobj
    if (dobjOffset != 0)
 {
  struct
  {
   DumpDObj(dobjOffset);
  } dobjs;
 }
};
struct DOBJ_DATA
{
 uint32 unknown0x00;
 uint32 nextOffset <format = hex>; // next dobj structure
 uint32 mobjOffset <format = hex>; // mobj structure - material information?
 uint32 pobjOffset <format = hex>; // pobj structure - mesh information?
    if (mobjOffset != 0)
        DumpMObj(mobjOffset);
    // dump pobj
    if (pobjOffset != 0)
 {
  struct
  {
   DumpPObj(pobjOffset);
  } pobjs;
 }
};
struct MOBJ_DATA
{
 // 0x00
 uint32 unknown0x00;
 uint32 unknownFlags0x04  <format = hex>;
 uint32 tobjOffset        <format = hex>; // tobj structure
 uint32 materialOffset    <format = hex>; // material colors?
 // 0x10
 uint32 unknown0x10;
 uint32 unknown0x14;
    if (tobjOffset != 0)
        DumpTObj(tobjOffset);
    if (materialOffset != 0)
        DumpMaterialColors(materialOffset);
};
struct MATERIAL_COLORS
{
 // 0x00
 uint32 unknownColor0x00 <format = hex>; // diffuse?
 uint32 unknownColor0x04 <format = hex>; // ambient?
 uint32 unknownColor0x08 <format = hex>; // specular?
 float  unknown0x0C;
 // 0x10
 float  unknown0x10;
};
struct TOBJ_DATA
{
 uint32 unknown0x00[19];
 uint32 imageOffset       <format = hex>; // image header information
 uint32 paletteOffset     <format = hex>; // palette header information
 uint32 unknown0x54;
 uint32 unknownOffset0x58 <format = hex>;
    if (imageOffset != 0)
        DumpImageHeader(imageOffset);
    if (paletteOffset != 0)
        DumpPaletteHeader(paletteOffset);
};
struct IMAGE_HEADER
{
 uint32 imageOffset <format = hex>; // image data
 uint16 height;
 uint16 width;
 uint32 imageFormat;
};
struct PALETTE_HEADER
{
 uint32 paletteOffset <format = hex>; // palette data
 uint32 paletteFormat;
 uint32 unknown0x08;
 uint16 colorCount;
 uint16 unknown0x0A;
};
struct POBJ_DATA
{
 // 0x00
 uint32 unknown0x00;
 uint32 nextOffset        <format = hex>;
 uint32 vertexAttrArray   <format = hex>; // Unk04 structure - geometry information?
 uint16 unknownFlags0x0C  <format = hex>;
 uint16 displayListSize0x0C;              // number of 0x20 (32) byte block occupied by display list data
 // 0x10
 uint32 displayListOffset <format = hex>; // display list
 uint32 weightListOffset  <format = hex>; // joint weight info?
    if (vertexAttrArray != 0)
        DumpVtxAttr(vertexAttrArray);
    if (displayListOffset != 0)
        DumpDisplayList(displayListOffset);
    if (weightListOffset != 0)
        DumpJointWeights(weightListOffset);
};
// vertex declaration and attribute information
// attr, type, cnt, data_type, flags?, file_offset
struct ATTR_DATA
{
 // 0x00
 uint32 vtxAttr;     // attr
 uint32 vtxAttrType; // index_type
 uint32 compCnt;     // cnt
 uint32 compType;    // data_type
 // 0x10
 uint16 unknown0x10;
 uint16 vtxStride;
 uint32 dataOffset   <format = hex>; // data offset
};
struct WEIGHT_DATA
{
 uint32 jobjOffset <format = hex>;
 float  weight;
};
struct DISPLAY_LIST
{
 uint8  primitiveFlags <format = hex>;
 uint16 indexCount;
};
struct ACTION_INFO
{
 // 0x00
 uint32 nameOffset <format = hex>;
 uint32 dataOffset <format = hex>;
 uint32 dataSize   <format = hex>;
 uint32 unknownOffset <format = hex>;
 // 0x10
 uint32 unknown0x10 <format = hex>;
 uint32 unknown0x14 <format = hex>;
};

struct FIGHTER_DATA
{
 // 0x00
 uint32 unknownOffset0x00 <format = hex>; // 0x184
 uint32 unknownOffset0x04 <format = hex>;
 uint32 unknownOffset0x08 <format = hex>; // 0x18 - {uint32; offset; uint32; offset; uint32[2];}
 uint32 unknownOffset0x0C <format = hex>; // 0x18 - {offset; uint32[2]; offset; uint32[2];}[] --
 // 0x10
 uint32 unknownOffset0x10 <format = hex>; // 0x??
 uint32 unknownOffset0x14 <format = hex>; // 0x18 - {offset; uint32[2]; offset; uint32[2];}[] -- win animation info?
 uint32 unknownOffset0x18 <format = hex>; // 0x1C?x
 uint32 unknownOffset0x1C <format = hex>; // 0x?? - {offset[];}
 // 0x20
 uint32 unknownOffset0x20 <format = hex>; // 0x04 - {offset;} - JOBJ_DATA
 uint32 unknownOffset0x24 <format = hex>; // 0x18?
 uint32 unknownOffset0x28 <format = hex>;
 uint32 unknownOffset0x2C <format = hex>; // 0x14 - {uint32; offset; uint32; offset; uint32;}
 // 0x30
 uint32 unknownOffset0x30 <format = hex>; // 0x08 - {uint32; offset;}
 uint32 unknownOffset0x34 <format = hex>; // 0x08?
 uint32 unknownOffset0x38 <format = hex>; // 0x28
 uint32 unknownOffset0x3C <format = hex>; // 0x18
 // 0x40
 uint32 unknownOffset0x40 <format = hex>; // 0x30
 uint32 unknownOffset0x44 <format = hex>; // 0x1C
 uint32 unknownOffset0x48 <format = hex>; // 0x0C+ - {offset; offset; offset;}
 uint32 unknownOffset0x4C <format = hex>; // 0x38 - {offset; uint32[6]; offset; offset; uint32[5];}
 // 0x50
 uint32 unknownOffset0x50 <format = hex>; // 0x08 - {uint32; float;}
 uint32 unknownOffset0x54 <format = hex>; // 0x14
 uint32 unknownOffset0x58 <format = hex>; // 0x34
 uint32 unknownOffset0x5C <format = hex>; // 0x40 - JOBJ_DATA
    // dump jobj
    if (unknownOffset0x20 != 0)
 {
  if (ReadUInt(unknownOffset0x20 + 0x20) != 0)
  {
   struct
   {
    DumpJObj(ReadUInt(unknownOffset0x20 + 0x20));
   } jobjs;
  }
 }
 
    if (unknownOffset0x5C != 0)
 {
  struct
  {
   DumpJObj(unknownOffset0x5C);
  } jobjs;
 }
};

struct FIGATREE_DATA
{
 // 0x00
 uint32 unknown0x00;
 uint32 unknown0x04;
 float  unknown0x08;
 uint32 unknownOffset0x0C <format = hex>;
 // 0x10
 uint32 unknownOffset0x10 <format = hex>;
};
void DumpJObj(uint32 ofs)
{
 local int64 filePos = FTell();
 FSeekOfs(ofs);
 
 SetBackColor(cLtGreen);
 struct JOBJ_DATA jobj;
 // need to store local copies of variables before recursing into the function again
 // otherwise on the next iteration the 'jobj' variable changes, and contains the wrong jobj info
 //local uint32 dobjOfs = jobj.dobjOffset;
 local uint32 childOfs = jobj.childOffset;
 local uint32 nextOfs = jobj.nextOffset;
 // iterate into children nodes first
 if (childOfs != 0)
  DumpJObj(childOfs);
 // then iterate sibling nodes
 if (nextOfs != 0)
  DumpJObj(nextOfs);
  
 FSeek(filePos);
}
void DumpTransform(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
 
 float3x4 transform;
  
 FSeek(filePos);
}
void DumpDObj(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct DOBJ_DATA dobj;
    // need to store local copies of variables before recursing into the function again
    // otherwise on the next iteration the 'jobj' variable changes, and contains the wrong jobj info
    //local uint32 mobjOfs = dobj.mobjOffset;
    //local uint32 pobjOfs = dobj.pobjOffset;
    local uint32 nextOfs = dobj.nextOffset;
    // then iterate sibling nodes
    if (nextOfs != 0)
        DumpDObj(nextOfs);
  
 FSeek(filePos);
}
void DumpMObj(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct MOBJ_DATA mobj;
 FSeek(filePos);
}
void DumpPObj(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct POBJ_DATA pobj;
 
    local uint32 nextOfs = pobj.nextOffset;
    // then iterate sibling nodes
    if (nextOfs != 0)
       DumpPObj(nextOfs);
  
 FSeek(filePos);
}
void DumpTObj(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct TOBJ_DATA tobj;
 FSeek(filePos);
}
void DumpImageHeader(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct IMAGE_HEADER imageHeader;
 FSeek(filePos);
}
void DumpPaletteHeader(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct PALETTE_HEADER paletteHeader;
 FSeek(filePos);
}
void DumpMaterialColors(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct MATERIAL_COLORS materialColors;
 FSeek(filePos);
}
void DumpVtxAttr(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
 struct
 {
  do
  {
   struct ATTR_DATA vtxAttribute;
  } while (vtxAttribute.vtxAttr != 0x000000FF);
 } vtxAttributes;
 FSeek(filePos);
}
void DumpJointWeights(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
 
 local uint32 dataCount = GetArrayCount();
 
 if (dataCount > 0)
 {
  struct
  {
   local uint32 dataCount = GetArrayCount();
   uint32 weightOffsets[dataCount] <format = hex>;
   
   struct
   {
    PushFP();
    local uint32 dataNum = 0;
    for (dataNum = 0; dataNum < dataCount; ++dataNum)
    {
     FSeek(weightOffsets[dataNum] + 0x20);
     struct
     {
      do
      {
       struct WEIGHT_DATA jointWeight;
      } while (jointWeight.jobjOffset != 0);
     } jointWeights;
    }
    PopFP();
   } weightInfo;
  } weightInfo;
 }
 
 FSeek(filePos);
}
void DumpDisplayList(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct DISPLAY_LIST displayList;
 FSeek(filePos);
}
void DumpFighter(uint32 ofs)
{
 local int64 filePos = FTell();
    FSeekOfs(ofs);
    struct FIGHTER_DATA fighterData;
 FSeek(filePos);
}
// DAT_FILE File Structure
struct DAT_FILE
{
// #pragma lockAt(0x00000000)
 // DAT_HEADER - DAT file header information structure
 SetBackColor(cLtGreen);
 struct DAT_HEADER
 {
  // 0x00
  uint32 fileSize0x00                 <format = hex>;
  uint32 dataBlockSize0x04            <format = hex>; // size of main data block
  uint32 relocationTableCount0x08;                    // unknown data size / 4
  uint32 rootCount0x0C;                               // unknown data size / 8
  // if combined "data sizes" + 0x20 is less than file size, then offset to string table?
  // overwritten data addresses (as such, assumed they are unimportant?)
  // - 0x20 - start + 0x20?
  // - 0x24 - start + dataBlockSize0x04 + 0x20 - offsets to offsets?
  // - 0x28 - start + [0x24] + (relocationTableCount0x08 * 4)
  // - 0x2C - start + [0x28] + (jobjCount0x0C * 8)
  // - 0x30 - start + [0x2C] + (unknown0x10 * 8)
  // - 0x3C - or'ed with 0x01
  // - 0x40 - start
  // 0x10
  uint32 unknown0x10; // unknown data size / 8
  uint32 unknown0x14; // '001B' in main Pl*.dat files
  uint32 unknown0x18;
  uint32 unknown0x1C;
 } fileHeader;
 
 if (0 < fileHeader.rootCount0x0C)
 {
  FSeek(0x20 + fileHeader.dataBlockSize0x04 + (fileHeader.relocationTableCount0x08 * 4));
  SetBackColor(cLtRed);
  struct
  {
   struct
   {
    uint32 rootOffset0x00        <format = hex>;
    uint32 stringTableOffset0x04 <format = hex>; // offset to name string?
    
    filePos = FTell();
    FSeek(0x20 + rootOffset0x00);
    union
    {
     SetBackColor(cLtGreen);
     //struct
     //{
     // DumpJObj(rootOffset0x00);
     //} jobjData;
     
     struct
     {
      DumpFighter(rootOffset0x00);
     } ftData;
     
     SetBackColor(cLtBlue);
     uint16 mappedData <format = hex>;
    } mappedData;
    FSeek(filePos);
   } rootNodes[fileHeader.rootCount0x0C] <optimize = false>;
  } rootNodes;
 }
 
 if (0 < fileHeader.unknown0x10)
 {
  FSeek(0x20 + fileHeader.dataBlockSize0x04 + (fileHeader.relocationTableCount0x08 * 4) + (fileHeader.rootCount0x0C * 8));
  SetBackColor(cLtBlue);
  struct
  {
   struct
   {
    uint32 rootOffset0x00        <format = hex>;
    uint32 stringTableOffset0x04 <format = hex>;
     
    filePos = FTell();
    FSeek(0x20 + rootOffset0x00);
    SetBackColor(cLtBlue);
    uint16 mappedData <format = hex>;
    FSeek(filePos);
   } unknownData0x10[fileHeader.unknown0x10] <optimize = false>;
  } unknownData0x10;
 }
 
 // string table data
 if (0 < fileHeader.rootCount0x0C ||
  0 < fileHeader.unknown0x10)
 {
  FSeek(0x20 + fileHeader.dataBlockSize0x04 + (fileHeader.relocationTableCount0x08 * 4) + (fileHeader.rootCount0x0C * 8) + (fileHeader.unknown0x10 * 8));
  SetBackColor(cLtYellow);
  struct
  {
   struct
   {
    string nodeName0x00;
   } stringTable[fileHeader.rootCount0x0C + fileHeader.unknown0x10] <optimize = false>;
  } stringTable;
 } 
 
 if (0 != fileHeader.dataBlockSize0x04 &&
  0 < fileHeader.relocationTableCount0x08)
 {
  FSeek(0x20 + fileHeader.dataBlockSize0x04);
  SetBackColor(cLtBlue);
  uint32 relocationTable[fileHeader.relocationTableCount0x08] <format = hex>;
  
  local uint32 offsetNum = 0;
   
  filePos = FTell();
  
  FSeek(0x20 + fileHeader.dataBlockSize0x04);
  SetBackColor(cLtRed);
  struct
  {
   for (offsetNum = 0; offsetNum < fileHeader.relocationTableCount0x08; ++offsetNum)
   {
    FSeek(0x20 + relocationTable[offsetNum]);
    uint32 mappedOffsets <format = hex>;
   }
   FSeek(filePos);
  } relocatedOffsets;
  
  FSeek(0x20 + fileHeader.dataBlockSize0x04);
  SetBackColor(cLtBlue);
  struct
  {
   for (offsetNum = 0; offsetNum < fileHeader.relocationTableCount0x08; ++offsetNum)
   {
    //FSeek(0x20 + ReadUInt(0x20 + relocationTable[offsetNum]));
    FSeek(0x20 + relocatedOffsets.mappedOffsets[offsetNum]);
    uint16 mappedData <format = hex>;
   }
   FSeek(filePos);
  } relocatedData;
 }
};
struct DAT_FILE fileInfo;

there you go :)
 

Top