diff options
| author | Alex Marshall <SquidMan72@gmail.com> | 2009-03-21 01:15:00 -0700 |
|---|---|---|
| committer | Alex Marshall <SquidMan72@gmail.com> | 2009-03-21 01:15:00 -0700 |
| commit | 41f312b1a3e703edd56627342fdd358c22890480 (patch) | |
| tree | efea223fd1df1395add826c0765af2f6c22649a1 | |
| parent | 33dbada8f9c9fc97222ee3b0bfa0defc1f554c9f (diff) | |
Updated Zetsubou a lot. Now has CMP support (waiting on segher's approval), output to PNG (BUGGY. COLOR IS WASHED OUT, BUT WHEN WRITING TO BMP, STILL LOOKS FINE), and probably more stuff.
| -rw-r--r-- | zetsubou/Makefile | 2 | ||||
| -rw-r--r-- | zetsubou/main.c | 36 | ||||
| -rw-r--r-- | zetsubou/tpl.c | 557 | ||||
| -rw-r--r-- | zetsubou/tpl.h | 81 |
4 files changed, 506 insertions, 170 deletions
diff --git a/zetsubou/Makefile b/zetsubou/Makefile index eb5230f..1e49245 100644 --- a/zetsubou/Makefile +++ b/zetsubou/Makefile @@ -1,7 +1,7 @@ GENERICOBJECTS = main.o endian.o MAINOBJECTS = tpl.o OBJECTS = $(GENERICOBJECTS) $(MAINOBJECTS) -LIBS = +LIBS = -lgd OUTPUT = zetsubou main: $(OBJECTS) gcc -o $(OUTPUT) $(LIBS) $(OBJECTS) diff --git a/zetsubou/main.c b/zetsubou/main.c index 87b5dad..26baf71 100644 --- a/zetsubou/main.c +++ b/zetsubou/main.c @@ -17,16 +17,17 @@ void bad_args(char progname[]) { - printf("Invalid usage. Usage:\n\t%s r <file.tpl>\nOr:\n\t%s w <type> <file1.bmp> [file2.bmp...] <out.tpl>\n", progname, progname); + printf("Invalid usage. Usage:\n\t%s r[bmp|png] <file.tpl>\nOr:\n\t%s w[bmp|png] <type> <file1.bmp> [file2.bmp...] <out.tpl>\n", progname, progname); exit(1); } int main(int argc, char *argv[]) { - printf("Zetsubou v0.1. Written by SquidMan (Alex Marshall)\nRGB5A3 code was contributed by booto.\nBased off of gentpl.\n\n"); + printf("Zetsubou v0.1. Written by SquidMan (Alex Marshall)\nFormat information from YAGCD. RGB5A3 code by booto. CMP code by segher.\nBased off of gentpl by comex.\n\n"); if(argc < 3) bad_args(argv[0]); char type = toupper(argv[1][0]); + char fmt = toupper(argv[1][1]); if(type == 'R') { // Read TPL. if(argc != 3) bad_args(argv[0]); @@ -38,16 +39,28 @@ int main(int argc, char *argv[]) char *basename = (char*)calloc(strlen(argv[2]) + 1, 1); int arg1strlen = strlen(argv[2]); int i; - for(i = 0; (i < arg1strlen) && (argv[2][i] != '.'); i++) basename[i] = argv[2][i]; + for(i = 0; (i < arg1strlen); i++) { + if((argv[2][i] == '.') && ((argv[2][i + 1] != '.') && (argv[2][i + 1] != '/'))) + break; + basename[i] = argv[2][i]; + } fseek(fp, 0, SEEK_END); u32 tplsize = ftell(fp); u8* tplbuf = (u8*)malloc(tplsize); fseek(fp, 0, SEEK_SET); fread(tplbuf, tplsize, 1, fp); fclose(fp); - int ret = TPL_ConvertToBMP(tplbuf, tplsize, basename); + int ret; + int outfmt; + if(fmt == 'B') + outfmt = 0; + else if(fmt == 'P') + outfmt = 1; + else + bad_args(argv[0]); + ret = TPL_ConvertToGD(tplbuf, tplsize, basename, outfmt); if(ret < 0) { - printf("Error converting to BMP.\n"); + printf("Error converting from TPL.\n"); exit(1); } }else if(type == 'W') { // Write TPL. @@ -57,7 +70,6 @@ int main(int argc, char *argv[]) int i; for(i = 0; i < argc - 4; i++) names[i] = argv[i + 3]; - printf("%d\n", argc); int format; char formatstr[256]; memset(formatstr, 0, 256); @@ -73,9 +85,17 @@ int main(int argc, char *argv[]) else if(strcmp(formatstr, "CI8") == 0) format = TPL_FORMAT_CI8; else if(strcmp(formatstr, "CI14X2") == 0) format = TPL_FORMAT_CI14X2; else if(strcmp(formatstr, "CMP") == 0) format = TPL_FORMAT_CMP; - int ret = TPL_ConvertFromBMPs(argc - 4, names, argv[argc - 1], format); + int ret; + int outfmt; + if(fmt == 'B') + outfmt = 0; + else if(fmt == 'P') + outfmt = 1; + else + bad_args(argv[0]); + ret = TPL_ConvertFromGDs(argc - 4, names, argv[argc - 1], format, outfmt); if(ret < 0) { - printf("Error converting BMPs.\n"); + printf("Error converting to TPL.\n"); exit(1); } } diff --git a/zetsubou/tpl.c b/zetsubou/tpl.c index af2ef32..af0bff1 100644 --- a/zetsubou/tpl.c +++ b/zetsubou/tpl.c @@ -10,6 +10,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <GD.h> #include "tpl.h" #include "endian.h" @@ -23,9 +24,6 @@ int TPL_ConvertRGB565ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmap *bitmapdata = (u8*)calloc(width * height, 4); if(*bitmapdata == NULL) return -1; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - if(subbitmapdata == NULL) - return -1; u32 outsz = width * height * 4; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 4) { @@ -38,15 +36,11 @@ int TPL_ConvertRGB565ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmap u8 r = ((oldpixel >> 0) & 0x1F) << 3; u8 a = 255; u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + (y * width)] = rgba; } } } } - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - *((*(u32**)bitmapdata) + ((x + (y * width)))) = ((u32*)subbitmapdata)[x + (iv * width)]; - free(subbitmapdata); return outsz; } @@ -55,19 +49,13 @@ int TPL_ConvertBitMapToRGB565(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 w s32 x, y; s32 x1, y1; u32 iv; - u8* subbitmapdata = (u8*)calloc(width * height, 4); -// u8* subbitmapdata = bitmapdata; + u8* subbitmapdata = bitmapdata; if(subbitmapdata == NULL) return -1; *tplbuf = (u8*)calloc(width * height, 2); if(*tplbuf == NULL) return -1; - int i; u8* writebuf = *tplbuf; - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - for(i = 0; i < 4; i++) - subbitmapdata[((x + (y * width)) * 4) + i] = bitmapdata[((x + (iv * width)) * 4) + i]; u32 outsz = width * height * 2; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 4) { @@ -196,9 +184,6 @@ int TPL_ConvertRGB5A3ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmap *bitmapdata = (u8*)calloc(width * height, 4); if(*bitmapdata == NULL) return -1; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - if(subbitmapdata == NULL) - return -1; u32 outsz = width * height * 4; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 4) { @@ -213,7 +198,7 @@ int TPL_ConvertRGB5A3ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmap u8 b = (((oldpixel >> 0) & 0x1F) * 255) / 31; u8 a = 255; u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + (y * width)] = rgba; }else{ // RGB4A3 u8 r = (((oldpixel >> 11) & 0xF) * 255) / 15; @@ -221,16 +206,12 @@ int TPL_ConvertRGB5A3ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmap u8 b = (((oldpixel >> 3) & 0xF) * 255) / 15; u8 a = (((oldpixel >> 0) & 0x7) * 255) / 7; u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + (y * width)] = rgba; } } } } } - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - *((*(u32**)bitmapdata) + ((x + (y * width)))) = ((u32*)subbitmapdata)[x + (iv * width)]; - free(subbitmapdata); return outsz; } @@ -239,19 +220,13 @@ int TPL_ConvertBitMapToRGB5A3(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 w s32 x, y; s32 x1, y1; u32 iv; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - // u8* subbitmapdata = bitmapdata; + u8* subbitmapdata = bitmapdata; if(subbitmapdata == NULL) return -1; *tplbuf = (u8*)calloc(width * height, 2); if(*tplbuf == NULL) return -1; - int i; u8* writebuf = *tplbuf; - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - for(i = 0; i < 4; i++) - subbitmapdata[((x + (y * width)) * 4) + i] = bitmapdata[((x + (iv * width)) * 4) + i]; u32 outsz = width * height * 2; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 4) { @@ -304,9 +279,6 @@ int TPL_ConvertI4ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdata *bitmapdata = (u8*)calloc(width * height, 8); if(*bitmapdata == NULL) return -1; - u8* subbitmapdata = (u8*)calloc(width * height, 8); - if(subbitmapdata == NULL) - return -1; u32 outsz = width * height * 4; for(iv = 0, y1 = 0; y1 < height; y1 += 8) { for(x1 = 0; x1 < width; x1 += 8) { @@ -318,22 +290,18 @@ int TPL_ConvertI4ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdata u8 r = (oldpixel >> 4) * 255 / 15; u8 a = 255; u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + (y * width)] = rgba; b = (oldpixel & 0xF) * 255 / 15; g = (oldpixel & 0xF) * 255 / 15; r = (oldpixel & 0xF) * 255 / 15; a = 255; rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + 1 + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + 1 + (y * width)] = rgba; iv++; } } } } - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - *((*(u32**)bitmapdata) + ((x + (y * width)))) = ((u32*)subbitmapdata)[x + (iv * width)]; - free(subbitmapdata); return outsz; } @@ -342,19 +310,13 @@ int TPL_ConvertBitMapToI4(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width s32 x, y; s32 x1, y1; u32 iv; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - // u8* subbitmapdata = bitmapdata; + u8* subbitmapdata = bitmapdata; if(subbitmapdata == NULL) return -1; *tplbuf = (u8*)calloc(width * height / 2, 1); if(*tplbuf == NULL) return -1; - int i; u8* writebuf = *tplbuf; - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - for(i = 0; i < 4; i++) - subbitmapdata[((x + (y * width)) * 4) + i] = bitmapdata[((x + (iv * width)) * 4) + i]; u32 outsz = width * height / 2; for(iv = 0, y1 = 0; y1 < height; y1 += 8) { for(x1 = 0; x1 < width; x1 += 8) { @@ -386,9 +348,6 @@ int TPL_ConvertIA4ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdat *bitmapdata = (u8*)calloc(width * height, 4); if(*bitmapdata == NULL) return -1; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - if(subbitmapdata == NULL) - return -1; u32 outsz = width * height * 4; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 8) { @@ -400,15 +359,11 @@ int TPL_ConvertIA4ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdat u8 r = ((oldpixel >> 4) * 255) / 15; u8 a = ((oldpixel & 0xF) * 255) / 15; u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + (y * width)] = rgba; } } } } - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - *((*(u32**)bitmapdata) + ((x + (y * width)))) = ((u32*)subbitmapdata)[x + (iv * width)]; - free(subbitmapdata); return outsz; } @@ -417,19 +372,13 @@ int TPL_ConvertBitMapToIA4(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 widt s32 x, y; s32 x1, y1; u32 iv; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - // u8* subbitmapdata = bitmapdata; + u8* subbitmapdata = bitmapdata; if(subbitmapdata == NULL) return -1; *tplbuf = (u8*)calloc(width * height, 1); if(*tplbuf == NULL) return -1; - int i; u8* writebuf = *tplbuf; - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - for(i = 0; i < 4; i++) - subbitmapdata[((x + (y * width)) * 4) + i] = bitmapdata[((x + (iv * width)) * 4) + i]; u32 outsz = width * height; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 8) { @@ -460,9 +409,6 @@ int TPL_ConvertI8ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdata *bitmapdata = (u8*)calloc(width * height, 4); if(*bitmapdata == NULL) return -1; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - if(subbitmapdata == NULL) - return -1; u32 outsz = width * height * 4; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 8) { @@ -474,15 +420,11 @@ int TPL_ConvertI8ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdata u8 r = oldpixel; u8 a = 255; u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + (y * width)] = rgba; } } } } - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - *((*(u32**)bitmapdata) + ((x + (y * width)))) = ((u32*)subbitmapdata)[x + (iv * width)]; - free(subbitmapdata); return outsz; } @@ -491,19 +433,13 @@ int TPL_ConvertBitMapToI8(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 width s32 x, y; s32 x1, y1; u32 iv; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - // u8* subbitmapdata = bitmapdata; + u8* subbitmapdata = bitmapdata; if(subbitmapdata == NULL) return -1; *tplbuf = (u8*)calloc(width * height, 1); if(*tplbuf == NULL) return -1; - int i; u8* writebuf = *tplbuf; - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - for(i = 0; i < 4; i++) - subbitmapdata[((x + (y * width)) * 4) + i] = bitmapdata[((x + (iv * width)) * 4) + i]; u32 outsz = width * height; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 8) { @@ -530,9 +466,6 @@ int TPL_ConvertIA8ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdat *bitmapdata = (u8*)calloc(width * height, 4); if(*bitmapdata == NULL) return -1; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - if(subbitmapdata == NULL) - return -1; u32 outsz = width * height * 4; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 4) { @@ -544,15 +477,11 @@ int TPL_ConvertIA8ToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdat u8 r = oldpixel >> 8; u8 a = oldpixel & 0xFF; u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); - ((u32*)subbitmapdata)[x + (y * width)] = rgba; + (*(u32**)bitmapdata)[x + (y * width)] = rgba; } } } } - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - *((*(u32**)bitmapdata) + ((x + (y * width)))) = ((u32*)subbitmapdata)[x + (iv * width)]; - free(subbitmapdata); return outsz; } @@ -561,19 +490,13 @@ int TPL_ConvertBitMapToIA8(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 widt s32 x, y; s32 x1, y1; u32 iv; - u8* subbitmapdata = (u8*)calloc(width * height, 4); - // u8* subbitmapdata = bitmapdata; + u8* subbitmapdata = bitmapdata; if(subbitmapdata == NULL) return -1; *tplbuf = (u8*)calloc(width * height, 2); if(*tplbuf == NULL) return -1; - int i; u8* writebuf = *tplbuf; - for(iv = height - 1, y = 0; y < height; y++, iv--) - for(x = 0; x < width; x++) - for(i = 0; i < 4; i++) - subbitmapdata[((x + (y * width)) * 4) + i] = bitmapdata[((x + (iv * width)) * 4) + i]; u32 outsz = width * height * 2; for(iv = 0, y1 = 0; y1 < height; y1 += 4) { for(x1 = 0; x1 < width; x1 += 4) { @@ -595,6 +518,386 @@ int TPL_ConvertBitMapToIA8(u8* bitmapdata, u32 bitmapsize, u8** tplbuf, u32 widt return outsz; } +#define round_up(x,n) (-(-(x) & -(n))) + +static u16 avg(u16 w0, u16 w1, u16 c0, u16 c1) +{ + u16 a0, a1; + u16 a, c; + + a0 = c0 >> 11; + a1 = c1 >> 11; + a = (w0*a0 + w1*a1) / (w0 + w1); + c = a << 11; + + a0 = (c0 >> 5) & 63; + a1 = (c1 >> 5) & 63; + a = (w0*a0 + w1*a1) / (w0 + w1); + c |= a << 5; + + a0 = c0 & 31; + a1 = c1 & 31; + a = (w0*a0 + w1*a1) / (w0 + w1); + c |= a; + + return c; +} + +int TPL_ConvertCMPToBitMap(u8* tplbuf, u32 tplsize, u32 tplpoint, u8** bitmapdata, u32 width, u32 height) +{ + s32 x, y; + u32 iv = 0; + //tplpoint -= width; + *bitmapdata = (u8*)calloc(width * height, 4); + if(*bitmapdata == NULL) + return -1; + u32 outsz = width * height * 4; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++) { + u8 pix[3]; + u16 raw; + u16 c[4]; + int x0, x1, x2, y0, y1, y2, off; + int ww = round_up(width, 8); + int ix; + u32 px; + + x0 = x & 3; + x1 = (x >> 2) & 1; + x2 = x >> 3; + y0 = y & 3; + y1 = (y >> 2) & 1; + y2 = y >> 3; + off = (8 * x1) + (16 * y1) + (32 * x2) + (4 * ww * y2); + + c[0] = be16(*(u16*)(tplbuf + tplpoint + off)); + c[1] = be16(*(u16*)(tplbuf + tplpoint + off + 2)); + if (c[0] > c[1]) { + c[2] = avg(2, 1, c[0], c[1]); + c[3] = avg(1, 2, c[0], c[1]); + } else { + c[2] = avg(1, 1, c[0], c[1]); + c[3] = 0; + } + + px = be32(*(u32*)(tplbuf + tplpoint + off + 4)); + ix = x0 + (4 * y0); + raw = c[(px >> (30 - (2 * ix))) & 3]; + + pix[0] = (raw >> 8) & 0xf8; + pix[1] = (raw >> 3) & 0xf8; + pix[2] = (raw << 3) & 0xf8; + + u32 rgba = (pix[0] << 0) | (pix[1] << 8) | (pix[2] << 16) | (255 << 24); + (*(u32**)bitmapdata)[iv++] = rgba; + } + return outsz; +} + +int TPL_ConvertToGD(u8* tplbuf, u32 tplsize, char basename[], u32 format) +{ + char formatstr[4]; + switch(format) { + case 0: // BMP + return TPL_ConvertToBMP(tplbuf, tplsize, basename); + case 1: // PNG + strcpy(formatstr, "png"); + break; + default: + printf("Unknown output format %d.\n", format); + return -1; + } + u32 tplpoint = 0; + u32 header[3]; + u32 goodmagic = be32(0x0020af30); + memcpy(header, tplbuf + tplpoint, 12); + tplpoint += 12; + if(memcmp(&(header[0]), &goodmagic, 4) != 0) { + printf("Not a valid TPL file. %08x\n", header[0]); + return -1; + } + if(header[2] != be32(0x0000000c)) { + printf("TPL Header is malformed. %08x\n", header[2]); + return -1; + } + u32 TPLTextures[256][2]; // Who's gonna use more than 256 textures per TPL? Nobody. + u32 texcount = 0; + int i; + for(i = 0; i < be32(header[1]); i++) { + memcpy(TPLTextures[i], tplbuf + tplpoint, 8); + tplpoint += 8; + texcount++; + } + char *outname = (char*)malloc(strlen(basename) + 3); + for(i = 0; i < texcount; i++) { + printf("Converting file %d.\n", i); + memset(outname, 0, strlen(basename) + 6); + sprintf(outname, "%s%02x.%s", basename, i, formatstr); + printf("Output to %s.\n", outname); + tplpoint = be32(TPLTextures[i][0]); + TPL_header h; + memcpy(&h.height, tplbuf + tplpoint, 2); + tplpoint += 2; + memcpy(&h.width, tplbuf + tplpoint, 2); + tplpoint += 2; + memcpy(&h.format, tplbuf + tplpoint, 4); + tplpoint += 4; + memcpy(&h.offs, tplbuf + tplpoint, 4); + tplpoint += 4; + memcpy(&h.wrap_s, tplbuf + tplpoint, 4); + tplpoint += 4; + memcpy(&h.wrap_t, tplbuf + tplpoint, 4); + tplpoint += 4; + memcpy(&h.min, tplbuf + tplpoint, 4); + tplpoint += 4; + memcpy(&h.mag, tplbuf + tplpoint, 4); + tplpoint += 4; + memcpy(&h.lod_bias, tplbuf + tplpoint, 4); + tplpoint += 4; + memcpy(&h.edge_lod, tplbuf + tplpoint, 1); + tplpoint++; + memcpy(&h.min_lod, tplbuf + tplpoint, 1); + tplpoint++; + memcpy(&h.max_lod, tplbuf + tplpoint, 1); + tplpoint++; + memcpy(&h.unpacked, tplbuf + tplpoint, 1); + tplpoint++; + /* if((be16(h.width) % 4) != 0) { + printf("TPL width is not a multiple of four! BAD! %d\n", be16(h.width)); + return -1; + } + if((be16(h.height) % 4) != 0) { + printf("TPL height is not a multiple of four! BAD! %d\n", be16(h.height)); + return -1; + }*/ + printf("Dimensions: %dx%d\n", be16(h.width), be16(h.height)); + gdImagePtr im = gdImageCreateTrueColor(be16(h.width), be16(h.height)); + gdImageAlphaBlending(im, 0); + gdImageSaveAlpha(im, 1); + FILE *fileout = fopen(outname, "wb"); + tplpoint = be32(h.offs); + int ret = 0; + u8* bitmapdata; + printf("Format: "); + switch(be32(h.format)) { + case TPL_FORMAT_RGB565: + printf("RGB565\n"); + ret = TPL_ConvertRGB565ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, be16(h.width), be16(h.height)); + break; + case TPL_FORMAT_RGB5A3: + printf("RGB5A3\n"); + ret = TPL_ConvertRGB5A3ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, be16(h.width), be16(h.height)); + break; + case TPL_FORMAT_RGBA8: + printf("RGBA8\n"); + ret = TPL_ConvertRGBA8ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, be16(h.width), be16(h.height)); + break; + case TPL_FORMAT_I4: + printf("I4\n"); + ret = TPL_ConvertI4ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, be16(h.width), be16(h.height)); + break; + case TPL_FORMAT_I8: + printf("I8\n"); + ret = TPL_ConvertI8ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, be16(h.width), be16(h.height)); + break; + case TPL_FORMAT_IA4: + printf("IA4\n"); + ret = TPL_ConvertIA4ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, be16(h.width), be16(h.height)); + break; + case TPL_FORMAT_IA8: + printf("IA8\n"); + ret = TPL_ConvertIA8ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, be16(h.width), be16(h.height)); + break; + default: + printf("Unsupported: %d.\n", be32(h.format)); + ret = -1; + } + if(ret == -1) { + printf("Error converting file.\n"); + return -1; + } + int x, y; + for(y = 0; y < be16(h.height); y++) { + for(x = 0; x < be16(h.width); x++) { + u32 rgba = ((u32*)bitmapdata)[x + (y * be16(h.width))]; + rgba = be32(rgba); + u8 r = (rgba >> 0) & 0xFF; + u8 g = (rgba >> 8) & 0xFF; + u8 b = (rgba >> 16) & 0xFF; + u8 a = 254 - 2*((rgba >> 24) & 0xFF); + if(a == 254) a++; + int clr = gdTrueColorAlpha(r, g, b, a); + gdImageSetPixel(im, x, y, clr); + } + } + gdImagePng(im, fileout); + fclose(fileout); + memset(outname, 0, strlen(basename) + 6); + sprintf(outname, "%s%02x.%s", basename, i, "met"); + FILE* tplmeta = fopen(outname, "wb"); + char tplheadstartmagic[] = {'T', 'P', 'L', 'M'}; + fwrite(tplheadstartmagic, 4, 1, tplmeta); + fwrite(&h.height, 2, 1, tplmeta); + fwrite(&h.width, 2, 1, tplmeta); + fwrite(&h.format, 4, 1, tplmeta); + fwrite(&h.offs, 4, 1, tplmeta); + fwrite(&h.wrap_s, 4, 1, tplmeta); + fwrite(&h.wrap_t, 4, 1, tplmeta); + fwrite(&h.min, 4, 1, tplmeta); + fwrite(&h.mag, 4, 1, tplmeta); + fwrite(&h.lod_bias, 4, 1, tplmeta); + fwrite(&h.edge_lod, 1, 1, tplmeta); + fwrite(&h.min_lod, 1, 1, tplmeta); + fwrite(&h.max_lod, 1, 1, tplmeta); + fwrite(&h.unpacked, 1, 1, tplmeta); + fclose(tplmeta); + } + return 0; +} + +int TPL_ConvertFromGDs(const u32 count, char *gds[], char outname[], u32 format, u32 typeformat) +{ + switch(typeformat) { + case 0: // BMP + return TPL_ConvertFromBMPs(count, gds, outname, format); + case 1: // PNG + break; + } + FILE *out = fopen(outname, "wb"); + if(out == NULL) { + printf("Unable to open %s\n", outname); + return -1; + } + fflush(stdout); + u32 magic = be32(0x0020af30); + u32 header[] = { magic, be32(count), be32(0xc) }; + fwrite(header, 4, 3, out); + + int i; + for(i = 0; i < count; i++) { + u32 offsets[] = { be32(12 + (8 * count) + (36 * i)), be32(0) }; + fwrite(offsets, 4, 2, out); + } + u8* imagedatas[256]; + u32 imagesizes[256]; + for(i = 0; i < count; i++) { + printf("Handling %d/%d\n", i + 1, count); + FILE* gdfp = fopen(gds[i], "rb"); + gdImagePtr im; + switch(typeformat) { + case 0: // BMP + return TPL_ConvertFromBMPs(count, gds, outname, format); + case 1: // PNG + im = gdImageCreateFromPng(gdfp); + break; + } + gdImageAlphaBlending(im, 0); + gdImageSaveAlpha(im, 1); + fclose(gdfp); + u32 width = gdImageSX(im); + u32 height = gdImageSY(im); + u32 bitmapsize = width * height * 4; + u8* bitmapdata = (u8*)malloc(width * height * 4); + memset(bitmapdata, 0, width * height * 4); + u8* tplbuf; + u32 iv, x, y, z; + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + u32 p; + if(x >= width || y >= height) + p = 0; + else + p = gdImageGetPixel(im, x, y); + u8 a = 254 - 2*((u8)gdImageAlpha(im, p)); + if(a == 254) a++; + u8 r = (u8)gdImageRed(im, p); + u8 g = (u8)gdImageGreen(im, p); + u8 b = (u8)gdImageBlue(im, p); + u32 rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24); + rgba = be32(rgba); + ((u32*)bitmapdata)[x + (y * width)] = rgba; + } + } + int ret; + switch(format) { + case TPL_FORMAT_RGB565: + printf("RGB565\n"); + ret = TPL_ConvertBitMapToRGB565(bitmapdata, bitmapsize, &tplbuf, width, height); + break; + case TPL_FORMAT_RGB5A3: + printf("RGB5A3\n"); + ret = TPL_ConvertBitMapToRGB5A3(bitmapdata, bitmapsize, &tplbuf, width, height); + break; + case TPL_FORMAT_RGBA8: + printf("RGBA8\n"); + ret = TPL_ConvertBitMapToRGBA8(bitmapdata, bitmapsize, &tplbuf, width, height); + break; + case TPL_FORMAT_I4: + printf("I4\n"); + ret = TPL_ConvertBitMapToI4(bitmapdata, bitmapsize, &tplbuf, width, height); + break; + case TPL_FORMAT_I8: + printf("I8\n"); + ret = TPL_ConvertBitMapToI8(bitmapdata, bitmapsize, &tplbuf, width, height); + break; + case TPL_FORMAT_IA4: + printf("IA4\n"); + ret = TPL_ConvertBitMapToIA4(bitmapdata, bitmapsize, &tplbuf, width, height); + break; + case TPL_FORMAT_IA8: + printf("IA8\n"); + ret = TPL_ConvertBitMapToIA8(bitmapdata, bitmapsize, &tplbuf, width, height); + break; + case TPL_FORMAT_CMP: + printf("CMP\n"); + printf("CMP is not supported as a writable format.\nPlease choose a different format.\n"); + return -1; + default: + printf("Unsupported: %d.\n", format); + ret = -1; + } + if(ret == -1) { + printf("Error converting file.\n"); + return -1; + } + imagedatas[i] = tplbuf; + imagesizes[i] = ret; + TPL_header h; + fflush(stdout); + memset(&h, 0, sizeof(TPL_header)); + fflush(stdout); + h.format = be32(format); + h.offs = be32(12 + (8 * count) + (36 * count)); + printf("Dimensions: %dx%d\n", width, height); + h.width = be16(width); + h.height = be16(height); + h.min = be32(TPL_MIN_FILTER_NORMAL); + h.mag = be32(TPL_MAG_FILTER_NORMAL); + fwrite(&h.height, 2, 1, out); + fwrite(&h.width, 2, 1, out); + fwrite(&h.format, 4, 1, out); + fwrite(&h.offs, 4, 1, out); + fwrite(&h.wrap_s, 4, 1, out); + fwrite(&h.wrap_t, 4, 1, out); + fwrite(&h.min, 4, 1, out); + fwrite(&h.mag, 4, 1, out); + fwrite(&h.lod_bias, 4, 1, out); + fwrite(&h.edge_lod, 1, 1, out); + fwrite(&h.min_lod, 1, 1, out); + fwrite(&h.max_lod, 1, 1, out); + fwrite(&h.unpacked, 1, 1, out); + fflush(out); + } + for(i = 0; i < count; i++) { + fflush(stdout); + fwrite(imagedatas[i], imagesizes[i], 1, out); + fflush(out); + free(imagedatas[i]); + } + fclose(out); + return 0; +} + int TPL_ConvertToBMP(u8* tplbuf, u32 tplsize, char basename[]) { u32 tplpoint = 0; @@ -621,7 +924,7 @@ int TPL_ConvertToBMP(u8* tplbuf, u32 tplsize, char basename[]) char *outname = (char*)malloc(strlen(basename) + 3); for(i = 0; i < texcount; i++) { printf("Converting file %d.\n", i); - memset(outname, 0, strlen(basename) + 3); + memset(outname, 0, strlen(basename) + 6); sprintf(outname, "%s%02x.bmp", basename, i); printf("Output to %s.\n", outname); tplpoint = be32(TPLTextures[i][0]); @@ -652,14 +955,14 @@ int TPL_ConvertToBMP(u8* tplbuf, u32 tplsize, char basename[]) tplpoint++; memcpy(&h.unpacked, tplbuf + tplpoint, 1); tplpoint++; - if((be16(h.width) % 4) != 0) { - printf("TPL width is not a multiple of four! BAD!\n"); +/* if((be16(h.width) % 4) != 0) { + printf("TPL width is not a multiple of four! BAD! %d\n", be16(h.width)); return -1; } if((be16(h.height) % 4) != 0) { - printf("TPL height is not a multiple of four! BAD!\n"); + printf("TPL height is not a multiple of four! BAD! %d\n", be16(h.height)); return -1; - } + }*/ printf("Dimensions: %dx%d\n", be16(h.width), be16(h.height)); TPL_BMPHeader b; memset(&b, 0, sizeof(TPL_BMPHeader)); @@ -714,6 +1017,10 @@ int TPL_ConvertToBMP(u8* tplbuf, u32 tplsize, char basename[]) printf("IA8\n"); ret = TPL_ConvertIA8ToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, bi.width, bi.height); break; + case TPL_FORMAT_CMP: + printf("CMP\n"); + ret = TPL_ConvertCMPToBitMap(tplbuf, tplsize, tplpoint, &bitmapdata, bi.width, bi.height); + break; default: printf("Unsupported: %d.\n", be32(h.format)); ret = -1; @@ -722,6 +1029,12 @@ int TPL_ConvertToBMP(u8* tplbuf, u32 tplsize, char basename[]) printf("Error converting file.\n"); return -1; } + u8* subbitmapdata = (u8*)malloc(ret); + u32 iv, x, y; + for(iv = bi.height - 1, y = 0; y < bi.height; y++, iv--) + for(x = 0; x < bi.width; x++) + ((u32*)subbitmapdata)[x + (y * bi.width)] = ((u32*)bitmapdata)[x + (iv * bi.width)]; + free(bitmapdata); bi.bitmapsize = ret; b.size = b.offset + bi.bitmapsize + 38; FILE* out = fopen(outname, "wb"); @@ -742,7 +1055,7 @@ int TPL_ConvertToBMP(u8* tplbuf, u32 tplsize, char basename[]) fwrite(&(bi.vres), 4, 1, out); fwrite(&(bi.colorpalette), 4, 1, out); fwrite(&(bi.importantcolors), 4, 1, out); - fwrite(bitmapdata, bi.bitmapsize, 1, out); + fwrite(subbitmapdata, bi.bitmapsize, 1, out); char tplheadstartmagic[] = {'T', 'P', 'L', 'M'}; fwrite(tplheadstartmagic, 4, 1, out); fwrite(&h.height, 2, 1, out); @@ -770,7 +1083,6 @@ int TPL_ConvertFromBMPs(const u32 count, char *bmps[], char outname[], u32 forma printf("Unable to open %s\n", outname); return -1; } - printf("%d\n", count); fflush(stdout); u32 magic = be32(0x0020af30); u32 header[] = { magic, be32(count), be32(0xc) }; @@ -784,33 +1096,8 @@ int TPL_ConvertFromBMPs(const u32 count, char *bmps[], char outname[], u32 forma u8* imagedatas[256]; u32 imagesizes[256]; for(i = 0; i < count; i++) { - printf("Handling %d/%d\n", i, count); + printf("Handling %d/%d\n", i + 1, count); FILE* bmpfp = fopen(bmps[i], "rb"); -/* fseek(bmpfp, 38, SEEK_END); - char goodtplheadstartmagic[] = {'T', 'P', 'L', 'M'}; - char tplheadstartmagic[4]; - fread(tplheadstartmagic, 4, 1, bmpfp); - if(memcmp(goodtplheadstartmagic, tplheadstartmagic, 4) != 0) { - printf("Bad TPL Header magic in file %s! %02x%02x%02x%02x\n", \ - bmps[i], \ - tplheadstartmagic[0], tplheadstartmagic[1], \ - tplheadstartmagic[2], tplheadstartmagic[3]); - return -1; - } - TPL_header h; - fread(&h.height, 2, 1, bmpfp); - fread(&h.width, 2, 1, bmpfp); - fread(&h.format, 4, 1, bmpfp); - fread(&h.offs, 4, 1, bmpfp); - fread(&h.wrap_s, 4, 1, bmpfp); - fread(&h.wrap_t, 4, 1, bmpfp); - fread(&h.min, 4, 1, bmpfp); - fread(&h.mag, 4, 1, bmpfp); - fread(&h.lod_bias, 4, 1, bmpfp); - fread(&h.edge_lod, 1, 1, bmpfp); - fread(&h.min_lod, 1, 1, bmpfp); - fread(&h.max_lod, 1, 1, bmpfp); - fread(&h.unpacked, 1, 1, bmpfp);*/ fseek(bmpfp, 0, SEEK_END); fseek(bmpfp, 0, SEEK_SET); TPL_BMPHeader b; @@ -869,8 +1156,15 @@ int TPL_ConvertFromBMPs(const u32 count, char *bmps[], char outname[], u32 forma fread(&bi.importantcolors, 4, 1, bmpfp); fseek(bmpfp, b.offset, SEEK_SET); u8* bitmapdata = (u8*)malloc(bi.bitmapsize); - fread(bitmapdata, bi.bitmapsize, 1, bmpfp); + u8* subbitmapdata = (u8*)malloc(bi.bitmapsize); + fread(subbitmapdata, bi.bitmapsize, 1, bmpfp); u8* tplbuf; + u32 iv, x, y, z; + for(iv = bi.height - 1, y = 0; y < bi.height; y++, iv--) + for(x = 0; x < bi.width; x++) + for(z = 0; z < 4; z++) + bitmapdata[((x + (y * bi.width)) * 4) + z] = subbitmapdata[((x + (iv * bi.width)) * 4) + z]; + free(subbitmapdata); int ret; switch(format) { case TPL_FORMAT_RGB565: @@ -901,6 +1195,10 @@ int TPL_ConvertFromBMPs(const u32 count, char *bmps[], char outname[], u32 forma printf("IA8\n"); ret = TPL_ConvertBitMapToIA8(bitmapdata, bi.bitmapsize, &tplbuf, bi.width, bi.height); break; + case TPL_FORMAT_CMP: + printf("CMP\n"); + printf("CMP is not supported as a writable format.\nPlease choose a different format.\n"); + return -1; default: printf("Unsupported: %d.\n", format); ret = -1; @@ -912,14 +1210,12 @@ int TPL_ConvertFromBMPs(const u32 count, char *bmps[], char outname[], u32 forma imagedatas[i] = tplbuf; imagesizes[i] = ret; TPL_header h; - printf("Nulling h\n"); fflush(stdout); memset(&h, 0, sizeof(TPL_header)); - printf("Nulled h\n"); fflush(stdout); h.format = be32(format); h.offs = be32(12 + (8 * count) + (36 * count)); - printf("%dx%d\n", bi.width, bi.height); + printf("Dimensions: %dx%d\n", bi.width, bi.height); h.width = be16(bi.width); h.height = be16(bi.height); h.min = be32(TPL_MIN_FILTER_NORMAL); @@ -937,16 +1233,13 @@ int TPL_ConvertFromBMPs(const u32 count, char *bmps[], char outname[], u32 forma fwrite(&h.min_lod, 1, 1, out); fwrite(&h.max_lod, 1, 1, out); fwrite(&h.unpacked, 1, 1, out); - printf("Closing bmpfp\n"); fflush(stdout); fflush(out); fflush(bmpfp); fclose(bmpfp); - printf("Closed bmpfp\n"); fflush(stdout); } for(i = 0; i < count; i++) { - printf("Writing %d. 0x%08x, 0x%08x\n", i, imagedatas[i], imagesizes[i]); fflush(stdout); fwrite(imagedatas[i], imagesizes[i], 1, out); fflush(out); diff --git a/zetsubou/tpl.h b/zetsubou/tpl.h index 633e60e..0398888 100644 --- a/zetsubou/tpl.h +++ b/zetsubou/tpl.h @@ -50,46 +50,69 @@ typedef struct texthead { - u16 height; // Height of the TPL image. - u16 width; // Width of the TPL image. - u32 format; // Format of the TPL image. (Use #defines pl0x.) - u32 offs; // Offset to actual image data. - u32 wrap_s; // Wrap S. - u32 wrap_t; // Wrap T. - u32 min; // Min filter. - u32 mag; // Mag filter. - f32 lod_bias; // LOD Bias? - u8 edge_lod; // Edge LOD? - u8 min_lod; // Minimum LOD? - u8 max_lod; // Maximum LOD? - u8 unpacked; // Unpacked? + u16 height; // Height of the TPL image. + u16 width; // Width of the TPL image. + u32 format; // Format of the TPL image. (Use #defines pl0x.) + u32 offs; // Offset to actual image data. + u32 wrap_s; // Wrap S. + u32 wrap_t; // Wrap T. + u32 min; // Min filter. + u32 mag; // Mag filter. + f32 lod_bias; // LOD Bias? + u8 edge_lod; // Edge LOD? + u8 min_lod; // Minimum LOD? + u8 max_lod; // Maximum LOD? + u8 unpacked; // Unpacked? } TPL_header; typedef struct bmphead { - u16 magic; // 0x42 0x4D (ASCII for `BM') - u32 size; // The size of the file - u16 reserved1; // Reserved. (We'll stuff `TP' here) - u16 reserved2; // Reserved. (We'll stuff `LB' here) - u32 offset; // Offset to actual bitmap. + u16 magic; // 0x42 0x4D (ASCII for `BM') + u32 size; // The size of the file + u16 reserved1; // Reserved. (We'll stuff `TP' here) + u16 reserved2; // Reserved. (We'll stuff `LB' here) + u32 offset; // Offset to actual bitmap. } TPL_BMPHeader; typedef struct bmpv3infohead { - u32 headersize; // Size of this header (40 bytes) - s32 width; // Width in pixels. - s32 height; // Height in pixels. - u16 colorplanes; // Number of color planes. Always 1. - u16 bpp; // Bits per pixel. - u32 compression; // Compression method. Just use 0, kthx. - u32 bitmapsize; // Size of the bitmap itself. - u32 hres; // Horizontal resolution. Just use 0, kthx. - u32 vres; // Vertical resolution. Just use 0, kthx. - u32 colorpalette; // Number of colors in palette. Just use 0, kthx. - u32 importantcolors; // Number of important colors. Just use 0, kthx. + u32 headersize; // Size of this header (40 bytes) + s32 width; // Width in pixels. + s32 height; // Height in pixels. + u16 colorplanes; // Number of color planes. Always 1. + u16 bpp; // Bits per pixel. + u32 compression; // Compression method. Just use 0, kthx. + u32 bitmapsize; // Size of the bitmap itself. + u32 hres; // Horizontal resolution. Just use 0, kthx. + u32 vres; // Vertical resolution. Just use 0, kthx. + u32 colorpalette; // Number of colors in palette. Just use 0, kthx. + u32 importantcolors; // Number of important colors. Just use 0, kthx. } TPL_BMPInfoHeaderV3; int TPL_ConvertToBMP(u8* tplbuf, u32 tplsize, char basename[]); +int TPL_ConvertToGD(u8* tplbuf, u32 tplsize, char basename[], u32 format); int TPL_ConvertFromBMPs(const u32 count, char *bmps[], char outname[], u32 format); +int TPL_ConvertFromGDs(const u32 count, char *gds[], char outname[], u32 format, u32 typeformat); #endif //_TPL_H_ + + + + + + + + + + + + + + + + + + + + + |
