#include #include #include #include "../rw.h" #include "dff.h" int rwvers; void writedword(int dword, FILE *file) { fwrite(&dword, 4, 1, file); } void writefloat(float dword, FILE *file) { fwrite(&dword, 4, 1, file); } void writeword(short word, FILE *file) { fwrite(&word, 2, 1, file); } int writeframelist(_clump *clp, FILE *dff) { int i; int ssize, headera; int oldpos; int len; _frame *fp; ssize = 0; headera = ftell(dff); WriteHeader(FRAMELIST, 0, rwvers, dff); WriteHeader(STRUCT, 0, rwvers, dff); ssize += 12; writedword(clp->nframe, dff); ssize += 4; for (i = 0; i < clp->nframe; i++) { fp = &clp->frm[i]; fwrite(fp->rotmatrix, 4, 3 * 3, dff); ssize += (4 * 3 * 3); fwrite(fp->posv, 4, 3, dff); ssize += (4 * 3); writedword(fp->parent, dff); ssize += 4; writedword(fp->unknown, dff); ssize += 4; } oldpos = ftell(dff); fseek(dff, headera+12, SEEK_SET); WriteHeader(STRUCT, ssize-12, rwvers, dff); fseek(dff, oldpos, SEEK_SET); for (i = 0; i < clp->nframe; i++) { fp = &clp->frm[i]; if (fp->name == NULL) { WriteHeader(EXTENSION, 16, rwvers, dff); ssize += 12; WriteHeader(FRAME, 4, rwvers, dff); ssize += 12; writedword(0x656e6f6e, dff); ssize += 4; } else { len = strlen(fp->name); WriteHeader(EXTENSION, len+12, rwvers, dff); ssize += 12; WriteHeader(FRAME, len, rwvers, dff); ssize += 12; fwrite(fp->name, 1, len, dff); ssize += len; } } oldpos = ftell(dff); fseek(dff, headera, SEEK_SET); WriteHeader(FRAMELIST, ssize, rwvers, dff); ssize += 12; fseek(dff, oldpos, SEEK_SET); return ssize; } int writetexture(_material *mat, int j, FILE *dff) { int i; int ssize, headera; int oldpos; int len; _texture *tex; tex = &mat->tex; ssize = 0; headera = ftell(dff); WriteHeader(TEXTURE, 12, rwvers, dff); WriteHeader(STRUCT, 4, rwvers, dff); ssize += 12; writeword(tex->filterflags, dff); writeword(tex->unknown, dff); ssize += 4; len = strlen(tex->tex); len += 4 - (len % 4); WriteHeader(STRING, len, rwvers, dff); ssize += 12; for (i = 0; i < strlen(tex->tex); i++) putc(tex->tex[i], dff); for ( ; i < len; i++) putc(0, dff); ssize += len; len = strlen(tex->alpha); len += 4 - (len % 4); WriteHeader(STRING, len, rwvers, dff); ssize += 12; for (i = 0; i < strlen(tex->alpha); i++) putc(tex->alpha[i], dff); for ( ; i < len; i++) putc(0, dff); ssize += len; WriteHeader(EXTENSION, 0, rwvers, dff); ssize += 12; oldpos = ftell(dff); fseek(dff, headera, SEEK_SET); WriteHeader(TEXTURE, ssize, rwvers, dff); fseek(dff, oldpos, SEEK_SET); return ssize + 12; } int writematerial(_geometry *geo, int i, FILE *dff) { int ssize, headera; int oldpos; _material *mat; mat = &geo->mat[i]; ssize = 0; headera = ftell(dff); WriteHeader(MATERIAL, 12, rwvers, dff); WriteHeader(STRUCT, 0, rwvers, dff); ssize += 12; writedword(mat->unknown0, dff); ssize += 4; fwrite(mat->color, 1, 4, dff); ssize += 4; writedword(mat->unknown1, dff); ssize += 4; writedword(mat->hastex, dff); ssize += 4; writedword(mat->unknown2, dff); ssize += 4; writedword(mat->unknown3, dff); ssize += 4; writedword(mat->unknown4, dff); ssize += 4; oldpos = ftell(dff); fseek(dff, headera+12, SEEK_SET); WriteHeader(STRUCT, ssize-12, rwvers, dff); fseek(dff, oldpos, SEEK_SET); if (mat->hastex) ssize += writetexture(mat, i, dff); WriteHeader(EXTENSION, 0, rwvers, dff); ssize += 12; oldpos = ftell(dff); fseek(dff, headera, SEEK_SET); WriteHeader(MATERIAL, ssize, rwvers, dff); fseek(dff, oldpos, SEEK_SET); return ssize + 12; } int writematlist(_geometry *geo, FILE *dff) { int i; int ssize, headera; int oldpos; ssize = 0; headera = ftell(dff); WriteHeader(MATERIALLIST, 0, rwvers, dff); WriteHeader(STRUCT, 4 + geo->nmaterial*4, rwvers, dff); ssize += 12; writedword(geo->nmaterial, dff); ssize += 4; for (i = 0; i < geo->nmaterial; i++) { writedword(-1, dff); ssize += 4; } for (i = 0; i < geo->nmaterial; i++) ssize += writematerial(geo, i, dff); oldpos = ftell(dff); fseek(dff, headera, SEEK_SET); WriteHeader(MATERIALLIST, ssize, rwvers, dff); ssize += 12; fseek(dff, oldpos, SEEK_SET); return ssize; } int writegeo(_clump *clp, int l, FILE *dff) { int i; int ssize, headera; int extsize, exta; int faceinc; _geometry *geo; _split *split; geo = &clp->geo[l]; ssize = 0; faceinc = 0; headera= ftell(dff); WriteHeader(GEOMETRY, 12, rwvers, dff); WriteHeader(STRUCT, 0, rwvers, dff); ssize += 12; writeword(geo->flags, dff); ssize += 2; putc(geo->nuv, dff); ssize++; putc(0, dff); ssize++; writedword(geo->facec, dff); ssize += 4; writedword(geo->vertexc, dff); ssize += 4; writedword(geo->framec, dff); ssize += 4; if (rwvers == VCPS2 || rwvers == GTA3_1 || rwvers == GTA3_2) { writefloat(geo->ambient, dff); ssize += 4; writefloat(geo->diffuse, dff); ssize += 4; writefloat(geo->specular, dff); ssize += 4; } /* Vertex Colors */ if ((geo->flags & HASVCOLORS) != 0) { fwrite(geo->vc, 4, geo->vertexc, dff); ssize += geo->vertexc * 4; } /* UV Coordinates */ if ((geo->flags & HASUV) != 0) { fwrite(geo->uv, 2 * 4, geo->vertexc, dff); ssize += geo->vertexc * 2 * 4; } /* Faces */ fwrite(geo->face, 4 * 2, geo->facec, dff); ssize += geo->facec * 4 * 2; /* Bounding Sphere */ fwrite(geo->bs, 4, 4, dff); ssize += (4 * 4); fwrite(&geo->bspos, 4, 1, dff); ssize += 4; fwrite(&geo->bsnor, 4, 1, dff); ssize += 4; /* Vertices */ fwrite(geo->vertex, 3 * 4, geo->vertexc, dff); ssize += 3 * 4 * geo->vertexc; /* Normals */ if ((geo->flags & HASNORMALS) != 0) { fwrite(geo->normal, 3 * 4, geo->vertexc, dff); ssize += 3 * 4 * geo->vertexc; } fseek(dff, headera+12, 0); WriteHeader(STRUCT, ssize-12, rwvers, dff); fseek(dff, 0, SEEK_END); ssize += writematlist(geo, dff); exta = ftell(dff); extsize = 0; WriteHeader(EXTENSION, 12, rwvers, dff); ssize += 12; WriteHeader(BINMESH, 0, rwvers, dff); extsize += 12; writedword(geo->facetype, dff); extsize += 4; writedword(geo->nsplit, dff); extsize += 4; writedword(geo->nindex, dff); extsize += 4; for (i = 0; i < geo->nsplit; i++) { split = &geo->split[i]; writedword(split->nindex, dff); extsize += 4; writedword(split->matindex, dff); extsize += 4; fwrite(split->indices, 4, split->nindex, dff); extsize += split->nindex * 4; } fseek(dff, exta, SEEK_SET); WriteHeader(EXTENSION, extsize, rwvers, dff); WriteHeader(BINMESH, extsize-12, rwvers, dff); ssize += extsize; fseek(dff, headera, SEEK_SET); WriteHeader(GEOMETRY, ssize, rwvers, dff); fseek(dff, 0, SEEK_END); return ssize + 12; } int writegeolist(_clump *clp, FILE *dff) { int i; int ssize, headera; int oldpos; ssize = 0; headera = ftell(dff); WriteHeader(GEOMETRYLIST, 0, rwvers, dff); WriteHeader(STRUCT, 4, rwvers, dff); ssize += 12; writedword(clp->ngeometry, dff); ssize += 4; for (i = 0; i < clp->ngeometry; i++) ssize += writegeo(clp, i, dff); oldpos = ftell(dff); fseek(dff, headera, SEEK_SET); WriteHeader(GEOMETRYLIST, ssize, rwvers, dff); ssize += 12; fseek(dff, oldpos, SEEK_SET); return ssize; } int writeatomic(_clump *clp, int i, FILE *dff) { int ssize, headera; ssize = 0; headera = ftell(dff); WriteHeader(ATOMIC, 0, rwvers, dff); WriteHeader(STRUCT, 16, rwvers, dff); ssize += 12; writedword(clp->atm[i].frmindex, dff); ssize += 4; writedword(clp->atm[i].geoindex, dff); ssize += 4; writedword(clp->atm[i].unknown0, dff); ssize += 4; writedword(clp->atm[i].unknown1, dff); ssize += 4; WriteHeader(EXTENSION, 0, rwvers, dff); ssize += 12; fseek(dff, headera, SEEK_SET); WriteHeader(ATOMIC, ssize, rwvers, dff); ssize += 12; fseek(dff, 0, SEEK_END); return ssize; } void writeclump(_clump *clp, FILE *dff) { int i; int ssize; rwvers = 0x0C02FFFF; ssize = 0; WriteHeader(CLUMP, 0, rwvers, dff); WriteHeader(STRUCT, 12, rwvers, dff); ssize += 12; writedword(clp->natomic, dff); ssize += 4; writedword(0, dff); ssize += 4; writedword(0, dff); ssize += 4; ssize += writeframelist(clp, dff); ssize += writegeolist(clp, dff); for (i = 0; i < clp->natomic; i++) ssize += writeatomic(clp, i, dff); WriteHeader(EXTENSION, 0, rwvers, dff); ssize += 12; fseek(dff, 4, SEEK_SET); writedword(ssize, dff); }