#include #include typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned char uchar; typedef struct atomic { uint frameindex; uint geometryindex; } atomic; typedef struct split { uint indexcount; uint matindex; uint *indices; } split; typedef struct texture { ushort filterflags; char *tex; char *alpha; } texture; typedef struct material { char color[4]; uint texcount; texture *tex; } material; typedef struct geometry { ushort flags; ushort nuv; uint facec; uint vertexc; uint framec; float ambient; float diffuse; float specular; uchar **vcolors; float **uvcoords; ushort **faces; float **vertices; float **normals; uint matcount; material *mat; uint bmfacetype; uint bmsplitcount; uint bmindexcount; split *splt; } geometry; typedef struct frame { float rotmatrix[3] [3]; float pos[3]; uint ipframe; void *pframe; /* cast it to pointer to frame! */ char *name; } frame; typedef struct clump { uint objcount; atomic *atm; uint frmcount; frame *frm; uint geocount; geometry *geo; } clump; int skipheader(FILE *rw) { int size; fseek(rw, 4, SEEK_CUR); fread(&size, 4, 1, rw); fseek(rw, 4, SEEK_CUR); return size; } int main(int argc, char *argv[]) { int i, j, k, l; int rwvers; int length; FILE *dff, *obj; clump clp; geometry geo; if (argc < 3) { printf("Usage: %s dff obj\n", argv[0]); exit(1); } if ((dff = fopen(argv[1], "r")) == NULL) { printf("Couldn't open file: %s\n", argv[1]); exit(1); } if ((obj = fopen(argv[2], "w")) == NULL) { printf("Couldn't open file: %s\n", argv[2]); exit(1); } fseek(dff, 8, SEEK_CUR); /* Clump */ fread(&rwvers, 4, 1, dff); skipheader(dff); /* Struct */ fread(&clp.objcount, 4, 1, dff); if (rwvers != 0x310) fseek(dff, 8, SEEK_CUR); skipheader(dff); /* Frame List */ skipheader(dff); /* Frame data */ fread(&clp.frmcount, 4, 1, dff); clp.frm = (frame *) malloc(clp.frmcount*sizeof(frame)); for (i = 0; i < clp.frmcount; i++) { /* Read Struct */ fread(&clp.frm[i].rotmatrix, 4, 9, dff); fread(&clp.frm[i].pos, 4, 3, dff); fread(&clp.frm[i].ipframe, 4, 1, dff); fseek(dff, 4, SEEK_CUR); } for (i = 0; i < clp.frmcount; i++) { /* Read Names */ j = skipheader(dff) + ftell(dff); length = skipheader(dff); clp.frm[i].name = (char *) malloc(length+1); fread(clp.frm[i].name, length, 1, dff); clp.frm[i].name[length] = '\0'; fseek(dff, j, 0); /* Skip hanim PLG if there is one */ } /* Frame data end */ skipheader(dff); skipheader(dff); fread(&clp.geocount, 4, 1, dff); clp.geo = (geometry *) malloc(clp.geocount*sizeof(geometry)); for (j = 0; j < clp.geocount; j++) { skipheader(dff); skipheader(dff); fread(&clp.geo[j].flags, 2, 1, dff); fread(&clp.geo[j].nuv, 2, 1, dff); fread(&clp.geo[j].facec, 4, 1, dff); fread(&clp.geo[j].vertexc, 4, 1, dff); fread(&clp.geo[j].framec, 4, 1, dff); if ((rwvers == 0x0C02FFF || rwvers == 0x310) == 0) { fread(&clp.geo[j].ambient, 4, 1, dff); fread(&clp.geo[j].diffuse, 4, 1, dff); fread(&clp.geo[j].specular, 4, 1, dff); } /* If Flag Prelit is set, read Vertex Colors */ if ((clp.geo[j].flags & 0x08) != 0) { clp.geo[j].vcolors = (uchar **) malloc(clp.geo[j].vertexc*4); for (i = 0; i < clp.geo[j].vertexc; i++) { clp.geo[j].vcolors[i] = (uchar *) malloc(4); fread(clp.geo[j].vcolors[i], 1, 4, dff); } } /* If Flag Textured is set, read UV Coordinates */ if ((clp.geo[j].flags & 0x04) != 0) { clp.geo[j].uvcoords = (float **) malloc(clp.geo[j].vertexc*4); for (i = 0; i < clp.geo[j].vertexc; i++) { clp.geo[j].uvcoords[i] = (float *) malloc(clp.geo[j].vertexc*4); fread(clp.geo[j].uvcoords[i], 4, 2, dff); } } /* Read Faces */ clp.geo[j].faces = (ushort **) malloc(clp.geo[j].facec*4); for (i = 0; i < clp.geo[j].facec; i++) { clp.geo[j].faces[i] = (ushort *) malloc(8); fread(clp.geo[j].faces[i], 2, 4, dff); } fseek(dff, 24, SEEK_CUR); /* skip bounding sphere */ /* Read Vertices */ clp.geo[j].vertices = (float **) malloc(clp.geo[j].vertexc*4); for (i = 0; i < clp.geo[j].vertexc; i++) { clp.geo[j].vertices[i] = (float *) malloc(12); fread(clp.geo[j].vertices[i], 4, 3, dff); } /* If Flag Normals is set, read Normals */ if ((clp.geo[j].flags & 0x10) != 0) { clp.geo[j].normals = (float **) malloc(clp.geo[j].vertexc*4); for (i = 0; i < clp.geo[j].vertexc; i++) { clp.geo[j].normals[i] = (float *) malloc(12); fread(clp.geo[j].normals[i], 4, 3, dff); } } skipheader(dff); /* Material List */ skipheader(dff); /* Struct */ fread(&clp.geo[j].matcount, 4, 1, dff); fseek(dff, 4*clp.geo[j].matcount, SEEK_CUR); clp.geo[j].mat = (material *) malloc(clp.geo[j].matcount*sizeof(material)); for (k = 0; k < clp.geo[j].matcount; k++) { skipheader(dff); skipheader(dff); fseek(dff, 4, SEEK_CUR); fread(&clp.geo[j].mat[k].color, 1, 4, dff); fseek(dff, 4, SEEK_CUR); fread(&clp.geo[j].mat[k].texcount, 1, 4, dff); clp.geo[j].mat[k].tex = (texture *) malloc(clp.geo[j].mat[k].texcount*sizeof(texture)); fseek(dff, 12, SEEK_CUR); for (l = 0; l < clp.geo[j].mat[k].texcount; l++) { skipheader(dff); skipheader(dff); fread(&clp.geo[j].mat[k].tex[l].filterflags, 2, 1, dff); fseek(dff, 2, SEEK_CUR); length = skipheader(dff); clp.geo[j].mat[k].tex[l].tex = (char *) malloc(length+1); fread(clp.geo[j].mat[k].tex[l].tex, length, 1, dff); clp.geo[j].mat[k].tex[l].tex[length] = '\0'; length = skipheader(dff); clp.geo[j].mat[k].tex[l].alpha = (char *) malloc(length+1); fread(clp.geo[j].mat[k].tex[l].alpha, length, 1, dff); clp.geo[j].mat[k].tex[l].alpha[length] ='\0'; skipheader(dff); } skipheader(dff); } j = skipheader(dff) + ftell(dff); skipheader(dff); fread(&clp.geo[i].bmfacetype, 4, 1, dff); fread(&clp.geo[i].bmsplitcount, 4, 1, dff); fread(&clp.geo[i].bmindexcount, 4, 1, dff); clp.geo[i].splt = (split *) malloc(clp.geo[i].bmsplitcount*sizeof(split)); for (k = 0; k < clp.geo[i].bmsplitcount; k++) { fread(&clp.geo[i].splt[k].indexcount, 4, 1, dff); fread(&clp.geo[i].splt[k].matindex, 4, 1, dff); clp.geo[i].splt[k].indices = (uint *) malloc(clp.geo[i].splt[k].indexcount*4); fread(clp.geo[i].splt[k].indices, 4, clp.geo[i].splt[k].indexcount, dff); } fseek(dff, j, 0); } clp.atm = (atomic *) malloc(clp.objcount*sizeof(atomic)); for (i = 0; i < clp.objcount; i++) { length = skipheader(dff); skipheader(dff); fread(&clp.atm[i].frameindex, 4, 1, dff); fread(&clp.atm[i].geometryindex, 4, 1, dff); fseek(dff, length-20, SEEK_CUR); } /* Print everything to an obj file */ /* for (i = 0; i < clp.geo[j].vertexc; i++) fprintf(obj, "v %f %f %f\n", clp.geo[j].vertices[i][0], clp.geo[j].vertices[i][1], clp.geo[j].vertices[i][2]); if ((clp.geo[j].flags & 0x10) != 0) for (i = 0; i < clp.geo[j].vertexc; i++) fprintf(obj, "vn %f %f %f\n", clp.geo[j].normals[i][0], clp.geo[j].normals[i][1], clp.geo[j].normals[i][2]); if ((clp.geo[j].flags & 0x04) != 0) for (i = 0; i