From 81af655f35b6944c0bd50fab3fe0136ab246e9cb Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 5 Apr 2018 21:52:56 -0700 Subject: [PATCH] Added revised functions for handling texture files --- include/devil1tex.h | 17 +++++++++- src/devil1tex.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ test/main.c | 36 +++++++++++++++++++-- 3 files changed, 126 insertions(+), 4 deletions(-) diff --git a/include/devil1tex.h b/include/devil1tex.h index 117ee29..3dddbdd 100644 --- a/include/devil1tex.h +++ b/include/devil1tex.h @@ -2,7 +2,7 @@ #define DEVIL1TEX_H #include - +#include #pragma pack(push, 1) // disable struct padding // to easily impose struct on plain data. @@ -56,4 +56,19 @@ void locatetextures(unsigned int*, struct TexturePack*, struct TextureBatchDescriptor**); +bool gettexdescriptor(struct TextureBatchDescriptor**, + unsigned int, + const char *, + unsigned int); + +bool gettexbatch(struct TextureBatch**, + unsigned int, + const char*, + unsigned int); + +bool unpacktexbatch(struct Texture*, + unsigned int, + const char*, + const unsigned int); + #endif diff --git a/src/devil1tex.c b/src/devil1tex.c index dd22cd5..d9d0db6 100644 --- a/src/devil1tex.c +++ b/src/devil1tex.c @@ -2,6 +2,7 @@ #include #include #include +#include void printtph (struct TexturePack *tp) { if (tp != NULL) { @@ -94,4 +95,80 @@ void locatetextures(unsigned int *t, } } } +// -------------------------------------------------------+ +// 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; +} + + + diff --git a/test/main.c b/test/main.c index bb45c5a..6aa2cc0 100644 --- a/test/main.c +++ b/test/main.c @@ -91,7 +91,6 @@ bool unpackpld (const char *filedata, } void write(const char *filename, - unsigned int id, const char* t, unsigned int size) { if (filename == NULL) { @@ -132,7 +131,7 @@ void unpacktextures(const char *filedata, for (i = 0; i < texturecount; i++) { texsize = descripts[i/(tp -> batchNumber)] -> textureSize; sprintf(fmt, "%s_%d.dds", filename, i); - write(fmt, i, filedata + tloc[i], texsize); + write(fmt, filedata + tloc[i], texsize); } free(fmt); free(tloc); @@ -140,12 +139,43 @@ void unpacktextures(const char *filedata, free(batches); } +void exporttextures(const char *filedata, + unsigned int filesize, + const char *filename) { + struct TexturePack *p = NULL; + struct Texture *t = NULL; + struct TextureBatchDescriptor *d = NULL; + char * fmt = NULL; + if (filename == NULL || filesize == 0) { + return; + } + p = (struct TexturePack*)filedata; + fmt = (char*)malloc(strlen(filename) + 3 + 4); + unsigned int i; + unsigned int j; + unsigned int id = 0; + for (i = 0; i < p -> batchNumber; i++) { + gettexdescriptor(&d, i, filedata, filesize); + t = (struct Texture*) + malloc(sizeof(struct Texture) * (d -> texNumber)); + unpacktexbatch(t, i, filedata, filesize); + for (j = 0; j < d -> texNumber; j++) { + sprintf(fmt, "%s_%d.dds", filename, id); + write(fmt, t[j].data, d -> textureSize); + id++; + } + free(t); + } + free(fmt); + return; +} + 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, f); + exporttextures(buffer, bufsize, f); free(buffer); return 0; }