#include #include #include #include #include "devil1pld.h" #include "devil1tex.h" bool writedata(const char *basename, unsigned int id, const char *data, unsigned int dsize) { bool status = false; char *fn = (char*)malloc(sizeof(char) * strlen(basename) + 4); sprintf(fn, "%s_%d", basename, id); FILE *out = fopen(fn, "w"); if (out != NULL) { fwrite(data, sizeof(char), dsize, out); fclose(out); status = true; } free(fn); return status; } void splitpld(const char *filedata, unsigned int filesize, const struct PldHeader *ph, const char *name) { char *wbuffer = NULL; // write buffer that will change. unsigned int wsize = 0; // size of wbuffer. unsigned int i; unsigned int start = 0; // ending offset for data unsigned int end = 0; // ending offset for data for (i = 0; (i + 1) < (ph -> numOffset) + 1; i++) { start = ph -> offsets[i]; // the last offset still has some data until the end of file end = (i == (ph -> numOffset) - 1) ? filesize : ph -> offsets[i + 1]; // copy sector to write buffer wsize = end - start; wbuffer = (char*)malloc(sizeof(char) * wsize); memcpy(wbuffer, filedata + start, wsize); // create a file. writedata(name, i, wbuffer, wsize); free(wbuffer); } } char *loadfile(const char *fname, unsigned int *s) { FILE *f = fopen(fname, "rb"); unsigned int size = 0; // number of elements to buffer; unsigned int rcnt = 0; // number of char's read by fread(...) if (f == NULL) { perror("Error 1: "); return NULL; } // this method of determining file size doesn't work until 2 GB. fseek(f, 0, SEEK_END); size = ftell(f); rewind(f); char *buf = (char*)malloc(sizeof(char) * size); if (buf == NULL) { perror("Error 2: "); free(buf); return NULL; } rcnt = fread(buf, sizeof(char), size, f); if (rcnt < size) { perror("Error 3: "); free(buf); return NULL; } fclose(f); *s = rcnt; return buf; } bool unpackpld (const char *filedata, unsigned int filesize, const char *filename) { bool status = false; printf("fsize is %i\n", filesize); if (filedata != NULL && filesize != 0) { struct PldHeader *pldh = getpldh(filedata); splitpld(filedata, filesize, pldh, filename); destroypldh(pldh); status = true; } return status; } /* void unpacktextures(const char *filedata, unsigned int filesize) { struct TexturePack *tp = (struct TexturePack*)filedata; struct TextureBatchDescriptor **bds = NULL; bds = (struct TextureBatchDescriptor**)malloc(tp -> batchNumber); gettbd(bds, filedata, filesize); printtph(tp); int i; for (i = 0; i < tp -> batchNumber; i++) { printtbd(bds[i]); } free(bds); return; const char *fmt = (const char*)malloc(strlen(filename) + 3 + 3); strcat(fmt, filename); strcat(fmt, "%d.dds"); } */ void unpacktextures(const char *filedata, unsigned int filesize) { struct TexturePack *tp = (struct TexturePack*)filedata; struct TextureBatch **batches = NULL; batches = (struct TextureBatch**)malloc(tp -> batchNumber); struct TextureBatchDescriptor **descripts = NULL; descripts = (struct TextureBatchDescriptor**)malloc(tp -> batchNumber); gettbd(descripts, filedata, filesize); // array of pointers - texture data exists in memory in filedata. unsigned int texturecount = gettexturebatch(batches, descripts, filedata, filesize); struct Texture **textures = NULL; textures = (struct Texture**)malloc(texturecount); unsigned int i; unsigned int j; // k is access to index of textures. unsigned int k = 0; unsigned int offset = 0; for (i = 0; i < tp -> batchNumber; i++) { for (j = 0; j < descripts[i] -> texNumber; j++) { printf("texture offsets %x\n", offset + tp -> firstBatchOffset); textures[k] = (struct Texture*)batches + offset; offset += descripts[i] -> textureSize; k++; } } free(textures); free(descripts); free(batches); } int main(int argc, char ** argv) { char *f = argv[1]; unsigned int bufsize = 0; char *buffer = loadfile(f, &bufsize); // unpackpld(buffer, bufsize, f); // unpacktextures(buffer, bufsize); unpacktextures(buffer, bufsize); free(buffer); return 0; }