#include #include #include #include "txd.h" unsigned char *rawindices; int getint(int size, FILE *file) { int i; fread(&i, size, 1, file); return i; } void writeint(int i, int size, FILE *file) { fwrite(&i, size, 1, file); } int skipheader(FILE *file) { int i; fseek(file, 4, SEEK_CUR); i = getint(4, file); fseek(file, 4, SEEK_CUR); return i; } void unswizzle8(unsigned char *indices, unsigned char *rawindices, int width, int height) { int y, x; for (y = 0; y < height; y++) for (x = 0; x < width; x++) { int block_loc = (y&(~0x0F))*width + (x&(~0x0F))*2; unsigned int swap_sel = (((y+2)>>2)&0x01)*4; int ypos = (((y&(~3))>>1) + (y&1))&0x07; int column_loc = ypos*width*2 + ((x+swap_sel)&0x07)*4; int byte_sum = ((y>>1)&1) + ((x>>2)&2); int swizzled = block_loc + column_loc + byte_sum; indices[y*width+x] = rawindices[swizzled]; } } void correctindices(int width, int height) { int i; char temp; char map[4] = {0, 16, 8, 24}; for (i = 0; i < width*height; i++) { temp = indices[i]; indices[i] = (temp & ~24) | map[(temp & 24) >> 3]; } } int main(int argc, char *argv[]) { int i, j; int vers; short texturecount; int sectionsize; FILE *txd; FILE *texture, *alpha; char texturename[32], alphaname[32]; int width, height, bpp, psize; int hasalpha; unsigned char doubleindex; if ((txd = fopen(argv[1], "r")) == NULL) { printf("Usage: %s txd\n", argv[0]); exit(1); } fseek(txd, 8, 0); fread(&vers, 4, 1, txd); skipheader(txd); texturecount = getint(2, txd); fseek(txd, 2, SEEK_CUR); /* unknown */ printf("%d textures in file\n", texturecount); for (i = 0; i < texturecount; i++) { fseek(txd, 32, SEEK_CUR); /* skip TextureNative, Struct and */ /* irrelevant data */ sectionsize = skipheader(txd); fread(&texturename, 1, sectionsize, txd); sectionsize = skipheader(txd); fread(&alphaname, 1, sectionsize, txd); hasalpha = 0; skipheader(txd); skipheader(txd); width = getint(4, txd); height = getint(4, txd); bpp = getint(4, txd); if (alphaname[0] != '\0' || bpp == 32 && vers == 0x310) { if (bpp == 32) { memcpy(alphaname, texturename, strlen(texturename)); strcat(alphaname, "a"); } strcat(alphaname, ".bmp"); hasalpha = 1; if ((alpha = fopen(alphaname, "w")) == NULL) { printf("Couldn't open file: %s\n", alphaname); exit(1); } printf("Alphafile is: %s\n", alphaname); } strcat(texturename, ".bmp"); if ((texture = fopen(texturename, "w")) == NULL) { printf("Couldn't open file: %s\n", texturename); exit(1); } printf("Texturefile is: %s\n", texturename); fseek(txd, 52, SEEK_CUR); skipheader(txd); fseek(txd, 80, SEEK_CUR); /* Here start the pixel/indices */ if (bpp == 8) { rawindices = (unsigned char *) malloc(width*height); indices = (unsigned char *) malloc(width*height); for (j = 0; j < width*height; j++) rawindices[j] = getc(txd); unswizzle8(indices, rawindices, width, height); correctindices(width, height); free(rawindices); } else if (bpp == 4) { rawindices = (unsigned char *) malloc(width*height); indices = (unsigned char *) malloc(width*height); for (j = 0; j < width*height; j+=2) { doubleindex = getc(txd); rawindices[j+1] = doubleindex >> 4; rawindices[j] = doubleindex & 0x0F; } if (vers != 0x0310) unswizzle8(indices, rawindices, width, height); else memcpy(indices, rawindices, width*height); free(rawindices); } else if (bpp == 16) { pixel = (unsigned char **) malloc(width*height*4); for (j = 0; j < width*height; j++) { short temppixel; pixel[j] = (unsigned char *) malloc(4); temppixel = getint(2, txd); /* *8 because we covert 16 to 32 bit */ pixel[j] [2] = (temppixel & 0x1F) * 8; temppixel >>= 5; pixel[j] [1] = (temppixel & 0x1F) * 8; temppixel >>= 5; pixel[j] [0] = (temppixel & 0x1F) * 8; temppixel >>= 5; pixel[j] [3] = (temppixel & 0x01) * 8; } /* Now we have a real 32 bit image */ bpp = 32; } else if (bpp == 32) { pixel = (unsigned char **) malloc(width*height*4); for (j = 0; j < width*height; j++) { pixel[j] = (unsigned char *) malloc(4); pixel[j] [0] = getc(txd); pixel[j] [1] = getc(txd); pixel[j] [2] = getc(txd); pixel[j] [3] = getc(txd); } } else exit(1); if (bpp == 8 || bpp == 4) { fseek(txd, 80, SEEK_CUR); if (bpp == 4 && width == 16) fseek(txd, 132, SEEK_CUR); /* Here starts the palette */ if (bpp == 8) psize = 256; else if (bpp == 4) psize = 16; palette = (unsigned char **) malloc(psize*4); for (j = 0; j < psize; j++) { palette[j] = (unsigned char *) malloc(4); palette[j] [0] = getc(txd); palette[j] [1] = getc(txd); palette[j] [2] = getc(txd); palette[j] [3] = getc(txd); } } if (vers != 0x0310 && bpp == 4) fseek(txd, 32, SEEK_CUR); if (vers != 0x0310 && bpp == 4 && width == 16) fseek(txd, -4, SEEK_CUR); printf("After palette: %X\n", ftell(txd)); fseek(txd, 28, SEEK_CUR); /* irrelevant */ /* Now make a bitmap for texture and alpha */ makebitmaps(width, height, bpp, hasalpha, texture, alpha); fclose(texture); if (hasalpha) fclose(alpha); if (bpp == 4 || bpp == 8) { for (j = 0; j < psize; j++) free(palette[j]); free(palette); free(indices); } if (bpp == 32) { for (j = 0; j < width*height; j++) free(pixel[j]); free(pixel); } memset(alphaname, 0, 32); memset(texturename, 0, 32); } return 0; }