Qhimm.com Forums
Miscellaneous Forums => Scripting and Reverse Engineering => Topic started by: Darkness on 2002-09-03 03:44:21
-
Once again, im interested in writing a program to convert a file format. Heres the question. How do I read from hex/binary in C?
-
Hmm i think it was discussed before but anyhow, here is some basic code to read few data from file:
#include <stdio.h> //library with file utils
void main( void ) //program starts here
{
FILE *f; //file handle
long l; // vv i define few variables here vv
float f;
char ch;
char name[20];
f = fopen( "file.dat", "rb" ); //rb = open file for reading in binary mode
if ( f == NULL ) //if could not open => exit
return;
fread( &l, 4, 1, f ); //lets read one long from file. it is 4 bytes long
fread( name, 1, 20, f ); //now string 20 bytes long
fread( &f, sizeof( float ), 1, f ); //and float which is 4 bytes long
fread( &ch, 1, 1, f ); //and char is 1 byte long
fclose( f ); //close file
}
But before doing something like file converter, you should play around with c trying it ...
Hmm, and btw what file format do you want to convert ?
-
warcraft 3 unit animation files. thanks, mirex. this will also help me learn the stdio header. i am currently only familiar with ones such as fstream/iostream.
-
Gehh! *Points to the edit button.* USE IT!
Sephiroth 3D
"Macintoshs are to Computers as Spam is to Food." - Greg Higgins
Sephiroth 3D.com (http://www.sephiroth3d.com)
[email protected]
-
yet ANOTHER edit:
void main() //program starts here
{
FILE *fr;//file handle
FILE *fw;
unsigned long l, interval_1, interval_2, end, numverts, startpoint; // vv i define few variables here vv
char ch;
char name[80];
char vrtx[4];
float x, y, z;
startpoint = 0;
fr = fopen( "File.mdx", "rb" ); //rb = open file for reading in binary mode
fw = fopen( "File2.obj", "w" ); //w = write?
if ( fr == NULL ) //if could not open => exit
return;
fseek( fr, 0L, SEEK_END);
end = ftell (fr);
do {
for (; startpoint < end; startpoint++) {
fseek( fr, startpoint, SEEK_SET);
fread( &vrtx, 1, 4, fr );
if((vrtx[0] == 'V') && (vrtx[1] == 'R') && (vrtx[2] == 'T') && (vrtx[3] == 'X')) {
startpoint++;
break;
if(startpoint > end) {
goto a;
}
}
}
fread( &numverts, 4, 1, fr );
for (int counter = 0; counter < numverts; counter++) {
fread( &x, 4, 1, fr );
fread( &y, 4, 1, fr );
fread( &z, 4, 1, fr );
fprintf( fw, "v %f %f %f\n", x, y, z);
}
} while (ftell(fr) < end);
a:
fclose( fw );
fclose( fr ); //close file
there has to be something wrong with one of the loops..... it produces about 10 k or so too many verteces.
-
ok... maybe a bit less then 10k.... but it repeats the last vert several times:
v 87.254501 -0.272330 5.281180
v 78.815498 -6.367190 11.685000
v 79.081001 0.845960 6.541410
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
v 73.868202 -0.900610 4.069060
EDIT: The last set of Vertices has 45. there are 46 repeated verticies. 1 at the end of the last set, and 45 of the fake set.
-
What a coincidence! Im working on war3 format too. I saw a request here, I think it was from you darkness, but i could not find that topic.
I've included it into my Conv. At present i can read geometry, objects & texture coords. Also i can read War 3 *.blp textures, both uncompressed & compressed. Right now im working on texturing & materials.
I'll try to upload Conv with these changes ASAP. Probably tomorow.
So lets look at the code:
;
fr = fopen( "File.mdx", "rb" );
// >!< we should move check directly after trying-to-open
if ( fr == NULL ) //if could not open => exit
return;
// >!< "w" should work too, but "wt" means write in text mode
fw = fopen( "File2.obj", "wt" ); //w = write?
fseek( fr, 0L, SEEK_END);
end = ftell (fr);
do {
// >!< for loops are usually done like this
for ( startpoint = 0; startpoint < end; startpoint++) {
fseek( fr, startpoint, SEEK_SET);
fread( &vrtx, 1, 4, fr );
// >!< easier compare
if ( memcmp( vrtx, "VRTX", 4 ) == 0 ) {
break;
/ >!< not sure, but i think that this won't execute, because of break
if(startpoint > end) {
goto a;
}
}
}
fread( &numverts, 4, 1, fr );
for (int counter = 0; counter < numverts; counter++) {
fread( &x, 4, 1, fr );
fread( &y, 4, 1, fr );
fread( &z, 4, 1, fr );
fprintf( fw, "v %f %f %f\n", x, y, z);
}
} while (ftell(fr) < end);
a:
fclose( fw );
fclose( fr ); //close file
Btw, what tool do you use to unpack MPQ's ? I have a few but all of them crash often, of can't unpack compressed files.
-edit-
Here (http://www.mypage.sk/trashbin/FILES/Conw.rar) is beta of Conv, it is good only for previewing... and sample (http://www.mypage.sk/trashbin/FILES/jaina.png)
-
Hey good job Mirex.. I used your program to convert my War3 screenies (TGA format) to BMP and it worked... exact resolution as well (crappy Apple Viewer doesn't convert correctly)... But the screenshot became inverted after I convert them. (Easily fixed by using MS Paint :) )
Anyway, no more further comments. I'm not really into 3D modelling and stuff yet... so I can't really give too much feedback. The only 'feedback' I can give is that everytime I convert the War3 screenies they end up inverted.... nothing big deal considering that your program is only a Beta version one........
-
i use MPQ View for extraction, and MPQ2k to add files.
also: have you looked at the animations? i dont quite understand them. They dont seem to refer to any bones.
-
FFTactic_Boy: could you please send me an example files (input and output) that do that ? they should not .... And also an program version number please ... i'll try to fix it asap.
Darkness: anims ... i will work on that later. I've seen some BONE chunk inthere, but understanding it will be hard. First i would like to do that texturing.
-
for ( startpoint = 0; startpoint < end; startpoint++) {
fseek( fr, startpoint, SEEK_SET);
unfortunately, i cant do this. this part of the code is intended to begin searching after that set of vertecies.
-
FFTactic_Boy: could you please send me an example files (input and output) that do that ? they should not .... And also an program version number please ... i'll try to fix it asap.
Program v0.821
Input File: Targa file (*.tga), <if you capture screenshots in Warcraft3 (i.e. Print Screen while in game) the file generated will be in that Targe format>
Output File: Bitmap file (*.bmp)
-
ok.... it makes a model now :)
#include <stdio.h> //library with file utils
#include <iostream.h>
#include <string.h>
void main() //program starts here
{
FILE *fr;//file handle
FILE *fw;
unsigned long end, numverts, startpoint, currentpos, numnorm, numtvert, numtri;
unsigned short a, b, c;
char vrtx[4], norm[4], tvert[4], face[4];
char inname[20];
char outname[20];
cout << "Enter MDX Filename: ";
cin.get(inname, 20);
cin.ignore(80,'\n');
cout << "Enter OBJ Filename: ";
cin.get(outname, 20);
cin.ignore(80,'\n');
float x, y, z;
startpoint = 0;
currentpos = 0;
fr = fopen( inname, "rb" ); //rb = open file for reading in binary mode
if ( fr == NULL ) //if could not open => exit
return;
fw = fopen( outname, "wt" ); //w = write text mode
fseek( fr, 0L, SEEK_END);
end = ftell (fr);
while (startpoint < end) {
for (; startpoint < end; startpoint++) {
fseek( fr, startpoint, SEEK_SET);
fread( &vrtx, 1, 4, fr );
if(memcmp( vrtx, "VRTX", 4 ) == 0) {
cout << "Geoset Found!\n";
break;
}
if(ftell( fr) >= end) {
return;
}
}
fread( &numverts, 4, 1, fr );
cout << "Vertices: " << numverts << endl;
for (int counter = 0; counter < numverts; counter++) {
fread( &x, 4, 1, fr );
fread( &y, 4, 1, fr );
fread( &z, 4, 1, fr );
fprintf( fw, "v %f %f %f\n", x, y, z);
}
fseek( fr, 4L, SEEK_CUR);
fread( &numnorm, 4, 1, fr );
cout << "Normals: " << numnorm << endl;
for (counter = 0; counter < numnorm; counter++) {
fread( &x, 4, 1, fr );
fread( &y, 4, 1, fr );
fread( &z, 4, 1, fr );
fprintf( fw, "vn %f %f %f\n", x, y, z);
}
//faces
for (startpoint = ftell(fr); startpoint < end; startpoint++) {
fseek( fr, startpoint, SEEK_SET);
fread( &face, 1, 4, fr );
if(memcmp( face, "PVTX", 4 ) == 0) {
fread( &numtri, 4, 1, fr );
cout << "Faces: " << numtri << endl;
cout << ftell(fr) << endl;
for (counter = 0; counter < (numtri / 3); counter++) {
fread( &a, 2, 1, fr );
a++;
fread( &b, 2, 1, fr );
b++;
fread( &c, 2, 1, fr );
c++;
fprintf( fw, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", a, a, a, b, b, b, c, c, c);
}
break;
}
}
//end faces
//tvert
for (startpoint = ftell(fr); startpoint < end; startpoint++) {
fseek( fr, startpoint, SEEK_SET);
fread( &tvert, 1, 4, fr );
if(memcmp( tvert, "UVBS", 4 ) == 0) {
fread( &numtvert, 4, 1, fr );
cout << "TVerts: " << numtvert << endl;
cout << ftell(fr) << endl;
for (counter = 0; counter < numtvert; counter++) {
fread( &x, 4, 1, fr );
fread( &y, 4, 1, fr );
fprintf( fw, "vt %f %f\n", x, y);
}
break;
}
}
//end tvert
startpoint++;
}
fclose( fw );
fclose( fr ); //close file
}
the models overall look normal, but some things are off. for example, you can only see shadris' cape from the front, and none of the flat spell-ish planes appear. i know the code is sloppy, but do you have any ideas?
-
Yes. There are more objects in file. Hint: try searching for another VRTX.
-
all of those are in a giant "while" loop. anyway, i think all of the vertices are there.... but the faces are somehow wrong.
-
alright. i got it ^^
-
Hey, isn't there supposed to be some 3D models of SC units hidden somewhere in WC3? Or was that just screenshots that are hidden in there?
Anyway, if the case is the former, you oughta see if you can get those. They might be of use to modding comminties out there for FPS games.
-
Yes there are a few. I know there is a Hydralisk, Marine & Zergling there. But zergling looks pretty strange. I'll try to get some screenshots
--edit--
So here is that zergling (http://bin.mypage.sk/FILES/zergling.jpg)(15kb).
And here is another beta conw (http://bin.mypage.sk/FILES/conw821b2.rar) which can save too. It can view w3 model with textures, but textures have to be in same dir as model. And it is no good, textures arent shown as should. All objects are mapped with 1st texture in the list. Its a beta you know. :)
FFTactic_Boy:
Oh and it has that TGA loading fixed too (i think). But for TGA conversion i would recommend other programs, for example PaintShopPro.
-
Yep it worked properly now :D
I don't have Paint Shop Pro... I have this silly Apple Viewer, which didn't really convert the screenshots properly. At least your small program does. :) Thanks.
-
the zergling has always looked like a modified felhound to me.
and theres a chaotic space orc (name is obviosly from wh 40k)
-
Heh....this reminds me of what Artanus says when you select him too many times in a row:
"This is not warcraft in Space!!!"
-
mirex-> you can find my program at www.infoceptor.com in the War3 files section. I go by the name of darky there.
next: bones
-
Taken From Frostmourne Pedistal MDL
Bone "Mesh18" {
ObjectId 9,
Parent 13, // "StandDummy"
BillboardedLockZ,
GeosetId 1,
GeosetAnimId 0,
Scaling 3 {
Bezier,
GlobalSeqId 1,
0: { 1, 1, 1 },
InTan { 0, 0, 0 },
OutTan { 1.1574, 1.1574, 1.1574 },
533: { 0.909091, 0.909091, 0.909091 },
InTan { 0.909091, 0.909091, 0.909091 },
OutTan { 0.909091, 0.909091, 0.909091 },
1067: { 1, 1, 1 },
InTan { 1.1574, 1.1574, 1.1574 },
OutTan { 0, 0, 0 },
}
}
I understand the parent an stuff, but why does a bone need to be so complex. shouldn't it just have x, y , and z values relative to the parent?
-
Darkness: I've tried your program and it works just fine. And I think that I should send them my proggie as well.
I have no idea about bones, havent looked at them so far, sorry...