#include "devil1tex.h" #include #include // Print Texture Pack Header. static void printtph(struct TexturePack*); // Print Texture Batch Descriptor. static void printtbd(struct TextureBatchDescriptor*); // Get Texture Pack Header static inline bool getpackheader(struct TexturePack**, const char*); // Get Texture Batch Descriptor. static bool gettexdescriptor(struct TextureBatchDescriptor**, unsigned int, const char *, unsigned int); // Get Texture Batch. static bool gettexbatch(struct TextureBatch**, unsigned int, const char*, unsigned int); // Unpack Texture Batch static bool unpacktexbatch(struct Texture*, unsigned int, const char*, const unsigned int); fn_devil1tex const DEVIL1TEX = {printtph, printtbd, getpackheader, gettexdescriptor, gettexbatch, unpacktexbatch}; static 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; } static 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); } } inline static bool getpackheader(struct TexturePack** p, const char *filedata) { if (filedata == NULL) { return false; } (*p) = (struct TexturePack*)filedata; return true; } static 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 && offset <= filesize) { *descriptor = (struct TextureBatchDescriptor*)(filedata + offset); done = true; } return done; } static bool gettexbatch(struct TextureBatch **batch, unsigned int i, const char *filedata, unsigned int filesize) { struct TexturePack *p = NULL; if (!(getpackheader(&p, filedata))) { return false; } 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); return true; } static 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); } return true; }