#include "devil1tex.h" #include #include #include #include void printtph (struct TexturePack *tp) { if (tp != NULL) { printf("id: \t %c %c %c %c \n", tp -> id[3], tp -> id[2], tp -> id[1], tp -> id[0]); printf("batch#: \t %i \n", tp -> batchNumber); printf("1st batch: \t %i \n", tp -> firstBatchOffset); printf("unknownA: \t %i\n", tp -> unknownA); } return; } void printtbd(struct TextureBatchDescriptor *bd) { if (bd != NULL) { printf("batch index: \t %i \n", bd -> batchIdx); printf("hash: \t %u \n", bd -> hash); printf("textures: \t %i\n", bd -> texNumber); } } // get texture pack descriptors void gettbd (struct TextureBatchDescriptor **descriptors, const char *filedata, unsigned int filesize) { if (descriptors == NULL || filedata == NULL || filesize <= 0) { return; } struct TexturePack *tp = NULL; tp = (struct TexturePack*)filedata; if (filesize <= (sizeof(struct TextureBatchDescriptor) * tp -> batchNumber + sizeof(struct TexturePack))){ fprintf(stderr, "File Error: file size to struct sizes ratio.\n"); return; } unsigned int index = sizeof(struct TexturePack); // Batch Descriptors are structured one after another. // therefore the next one is at // current index + sizeof(TextureBatchDescriptor) unsigned int i = 0; do { index = sizeof(struct TextureBatchDescriptor) * i + sizeof(struct TexturePack); printf("batch descriptor start: %x\n", index); descriptors[i] = (struct TextureBatchDescriptor*) (filedata + index); i++; } while(i < (tp -> batchNumber)); return; } // returns total count of textures in the file. unsigned int gettexturebatch( struct TextureBatch **tb, struct TextureBatchDescriptor **bds, const char *filedata, unsigned int filesize) { struct TexturePack *tp = (struct TexturePack*)filedata; unsigned int offset = tp -> firstBatchOffset; unsigned int i; unsigned int j; unsigned int totaltextures = 0; // TextureBatch shares a starting address with the first texture // and shares the ending address with the last texture. for (i = 0; i < tp -> batchNumber; i++) { tb[i] = (struct TextureBatch*)filedata + offset; // the next texture batch is TextureSize * number of textures away. offset += bds[i] -> textureSize * (bds[i] -> texNumber); totaltextures += bds[i] -> texNumber; } return totaltextures; } void locatetextures(unsigned int *t, struct TexturePack *tp, struct TextureBatchDescriptor **bds) { unsigned int i; unsigned int j; // k is access to index of textures. unsigned int k = 0; unsigned int offset = tp -> firstBatchOffset; for (i = 0; i < tp -> batchNumber; i++) { for (j = 0; j < bds[i] -> texNumber; j++) { t[k] = offset; offset += bds[i] -> textureSize; k++; } } } // -------------------------------------------------------+ // Revision Functions // -------------------------------------------------------+ // ** = 'pass by reference' of a pointer to struct bool gettexdescriptor(struct TextureBatchDescriptor **descriptor, unsigned int i, const char *filedata, unsigned int filesize) { // starts after the pack header. bool done = false; unsigned int offset = sizeof(struct TexturePack); offset += sizeof(struct TextureBatchDescriptor) * i; if (filedata != NULL) { *descriptor = (struct TextureBatchDescriptor*)(filedata + offset); done = true; } // printf("%x %x", *descriptor, filedata); return done; } // ** = 'pass by reference' of a pointer to struct bool gettexbatch(struct TextureBatch **batch, unsigned int i, const char *filedata, unsigned int filesize) { struct TexturePack *p = NULL; if (filedata == NULL) { // no data to get batch from. return false; } p = (struct TexturePack*)filedata; if (i > p -> batchNumber) { // no such batch in texture pack return false; } if (i == 0) { *batch = (struct TextureBatch*)(filedata + (p -> firstBatchOffset)); return true; } struct TextureBatchDescriptor *d = NULL; // find how large are previous batches in total // in order to jump to specified texture batch unsigned int pastbatchsize = p -> firstBatchOffset; unsigned int j; for (j = 0; j < i; j++) { gettexdescriptor(&d, j, filedata, filesize); pastbatchsize += (d -> textureSize * d -> texNumber); } *batch = (struct TextureBatch*)(filedata + pastbatchsize); //printf("batch offset: %x i: %d\n" , (p -> firstBatchOffset) + pastbatchsize, i); return true; } bool unpacktexbatch(struct Texture *t, unsigned int i, const char *filedata, const unsigned int filesize) { if (filedata == NULL) { return false; } struct TextureBatch *b = NULL; struct TextureBatchDescriptor *d = NULL; gettexbatch(&b, i, filedata, filesize); gettexdescriptor(&d, i, filedata, filesize); // first texture is at the start of the batch // second texture is right after. unsigned int j; for (j = 0; j < d -> texNumber; j++) { t[j].data = (unsigned char*)b + (d -> textureSize * j); //printf("unpack relative batch offset %x i= %i t.data= %x\n" , ((d -> textureSize * j)), i, t[j].data); } return true; }