mirror of
				https://notabug.org/scuti/lib3ddevil1
				synced 2025-05-31 14:11:42 +05:30 
			
		
		
		
	Merge branch 'scuti/texture' of scuti/lib3ddevil1 into master
This commit is contained in:
		
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							| @@ -4,11 +4,14 @@ CFLAGS= -I"include" | ||||
|  | ||||
| all: main | ||||
|  | ||||
| main: devil1pld.o | ||||
| main: devil1pld.o devil1tex.o | ||||
| 	$(CC) $^ test/main.c $(CFLAGS) -o $(EX)  | ||||
|  | ||||
| devil1pld.o: src/devil1pld.c | ||||
| 	$(CC) -c $^ $(CFLAGS) | ||||
|  | ||||
| devil1tex.o: src/devil1tex.c | ||||
| 	$(CC) -c $^ $(CFLAGS) | ||||
|  | ||||
| clean: | ||||
| 	rm *.o $(EX) | ||||
|   | ||||
							
								
								
									
										71
									
								
								include/devil1tex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								include/devil1tex.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| #ifndef DEVIL1TEX_H | ||||
| #define DEVIL1TEX_H | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
|  | ||||
| // disable struct padding | ||||
| // to easily impose struct on plain data. | ||||
| #pragma pack(push, 1) | ||||
|  | ||||
| struct TexturePack { | ||||
|     char    id[4]; | ||||
|     int32_t   batchNumber; | ||||
|     uint32_t  firstBatchOffset; // <format=hex> | ||||
|     uint32_t  unknownA; | ||||
| }; | ||||
|  | ||||
| struct TextureBatchDescriptor{ | ||||
|     int32_t batchIdx; | ||||
|     uint32_t hash;        // <format=hex> | ||||
|     uint32_t texNumber; | ||||
|     uint32_t unknownA[8]; // <format=hex> | ||||
|     uint32_t textureSize; // <format=hex> | ||||
|     uint32_t unknownB[30]; | ||||
| }; | ||||
|  | ||||
| struct Texture { | ||||
|     // size of array is defined by descriptor | ||||
|     // textureSize | ||||
|     unsigned char *data; | ||||
| }; | ||||
|  | ||||
| struct TextureBatch { | ||||
|     // quantity of textures are defined by descriptor | ||||
|     // texNumber | ||||
|     struct Texture *batch; | ||||
| }; | ||||
|  | ||||
| #pragma pack(pop) | ||||
|  | ||||
| // -------------------------------------------------------+ | ||||
| //                  Functions | ||||
| // -------------------------------------------------------+ | ||||
|  | ||||
| // Print Texture Pack Header. | ||||
| void printtph(struct TexturePack*); | ||||
|  | ||||
| // Print Texture Batch Descriptor. | ||||
| void printtbd(struct TextureBatchDescriptor*); | ||||
|  | ||||
| // Get Texture Batch Descriptor. | ||||
| // ** = 'pass by reference' of a pointer to struct | ||||
| bool gettexdescriptor(struct TextureBatchDescriptor**, | ||||
|                       unsigned int, | ||||
|                       const char *, | ||||
|                       unsigned int); | ||||
|  | ||||
| // Get Texture Batch. | ||||
| // ** = 'pass by reference' of a pointer to struct | ||||
| bool gettexbatch(struct TextureBatch**,  | ||||
|                  unsigned int,  | ||||
|                  const char*, | ||||
|                  unsigned int); | ||||
|  | ||||
| // Unpack Texture Batch | ||||
| bool unpacktexbatch(struct Texture*, | ||||
|                     unsigned int, | ||||
|                     const char*,  | ||||
|                     const unsigned int); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										93
									
								
								src/devil1tex.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/devil1tex.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| #include "devil1tex.h" | ||||
| #include <stdio.h> | ||||
| #include <stdbool.h> | ||||
|  | ||||
| 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); | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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; | ||||
|     } | ||||
|     return done; | ||||
| } | ||||
|  | ||||
| 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); | ||||
|     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); | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										55
									
								
								test/main.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								test/main.c
									
									
									
									
									
								
							| @@ -1,9 +1,11 @@ | ||||
| #include "devil1pld.h" | ||||
| #include <stdbool.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "devil1pld.h" | ||||
| #include "devil1tex.h" | ||||
|  | ||||
| bool writedata(const char *basename,  | ||||
|                unsigned int id,  | ||||
|                const char *data, | ||||
| @@ -88,11 +90,60 @@ bool unpackpld (const char *filedata, | ||||
|     return status; | ||||
| } | ||||
|  | ||||
| void write(const char *filename,  | ||||
|            const char* t,  | ||||
|            unsigned int size) { | ||||
|     if (filename == NULL) { | ||||
|         return; | ||||
|     } | ||||
|     unsigned int written = 0; | ||||
|     FILE *out = fopen(filename, "wb"); | ||||
|     if (out != NULL) { | ||||
|         written = fwrite(t, sizeof(unsigned char), size, out); | ||||
|         fclose(out); | ||||
|         if (written == 0) { | ||||
|             perror("texture write error"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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); | ||||
| //    unpackpld(buffer, bufsize, f); | ||||
|     exporttextures(buffer, bufsize, f); | ||||
|     free(buffer); | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user