Line 1: |
Line 1: |
− | // DSi icon2ppm - #dsidev
| + | <source lang="c"> |
− | // written by remark
| + | // DSi icon2ppm - #dsidev |
− | // thanks to loopy_, bLASTY
| + | // written by remark |
| + | // thanks to loopy_, bLASTY |
| + | |
| + | // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org> |
| + | // Licensed under the terms of the GNU GPL, version 2 |
| + | // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt |
| + | |
| + | #include <stdio.h> |
| + | #include <unistd.h> |
| + | typedef unsigned long u32; |
| + | typedef unsigned short u16; |
| + | typedef unsigned char u8; |
| + | |
| + | u16 be16(const u8 *p) |
| + | { |
| + | return (p[0] << 8) | p[1]; |
| + | } |
| + | u32 be32(const u8 *p) |
| + | { |
| + | return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; |
| + | } |
| | | |
− | // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org> | + | #define BNR_VER 0x0301 |
− | // Licensed under the terms of the GNU GPL, version 2 | + | #define FLAG_FLIPV 0x80 |
− | // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt | + | #define FLAG_FLIPH 0x40 |
| + | typedef struct { |
| + | u16 version; |
| + | u16 crcs[4]; |
| + | u8 padding[0x16]; |
| + | u8 bitmap[0x200]; |
| + | u16 palette[0x10]; |
| + | u8 title_jap[0x100]; |
| + | u8 title_eng[0x100]; |
| + | u8 title_fr[0x100]; |
| + | u8 title_ger[0x100]; |
| + | u8 title_ita[0x100]; |
| + | u8 title_spa[0x100]; |
| + | u8 title_unk[0x100]; |
| + | u8 title_unk2[0x100]; |
| + | u8 padding2[0x800]; |
| + | u8 bitmaps[8][0x200]; |
| + | u16 palettes[8][0x10]; |
| + | u16 sequence[0x40]; |
| + | } bannerstruct; |
| + | |
| + | int flength(FILE *f) |
| + | { |
| + | int pos,end; |
| + | pos = ftell (f); |
| + | fseek (f, 0, SEEK_END); |
| + | end = ftell (f); |
| + | fseek (f, pos, SEEK_SET); |
| + | return end; |
| + | } |
| + | |
| + | void do_bitmap(u8* bitmap, u16* palette, char* fname) |
| + | { |
| + | FILE *fp = fopen(fname, "wb"); |
| + | if (fp == NULL) |
| + | { |
| + | fprintf(stderr, "file cannot be opened: %s\n", fname); |
| + | exit(1); |
| + | } |
| + | fprintf(fp, "P6 %d %d 255\n", 32, 32); |
| | | |
− | #include <stdio.h> | + | // fix 8x8 tiling |
− | #include <unistd.h> | + | u8 tilebuf[0x204]; |
− | typedef unsigned long u32; | + | int x,y,z; |
− | typedef unsigned short u16; | + | for(x=0; x<4; x++) |
− | typedef unsigned char u8; | + | { |
| + | for(y=0; y<8; y++) |
| + | { |
| + | for(z=0; z<8; z++) |
| + | { |
| + | memcpy(tilebuf+(x*128)+(16*y)+(4*z), |
| + | bitmap+(x*128)+(32*z)+(4*y), 4); |
| + | } |
| + | } |
| + | } |
| | | |
− | u16 be16(const u8 *p) | + | // convert to rgb888 |
| + | int i,j; |
| + | u8 pixeldata[32*32][3]; |
| + | for(i=0; i<0x200; i++) |
| { | | { |
− | return (p[0] << 8) | p[1]; | + | u8 off = tilebuf[i]; |
| + | int offs[2]; |
| + | offs[0] = off&0x0F; |
| + | offs[1] = (off&0xF0)>>4; |
| + | |
| + | u16 colors[2]; |
| + | colors[0] = *(palette+offs[0]); |
| + | colors[1] = *(palette+offs[1]); |
| + | |
| + | for(j=0; j<2; j++) |
| + | { |
| + | u8 r = (colors[j] ) & 0x1f; |
| + | u8 g = (colors[j] >> 5) & 0x1f; |
| + | u8 b = (colors[j] >> 10) & 0x1f; |
| + | pixeldata[i*2+j][0] = (r << 3); |
| + | pixeldata[i*2+j][1] = (g << 3); |
| + | pixeldata[i*2+j][2] = (b << 3); |
| + | } |
| } | | } |
− | u32 be32(const u8 *p) | + | |
| + | if(fwrite(pixeldata, sizeof(pixeldata), 1, fp) != 1) |
| { | | { |
− | return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; | + | fprintf(stderr, "writing output-file failed\n"); |
| + | exit(1); |
| } | | } |
| + | |
| + | fclose(fp); |
| + | } |
| | | |
− | #define BNR_VER 0x0301
| + | int main(int argc, char* argv[]) |
− | #define FLAG_FLIPV 0x80
| + | { |
− | #define FLAG_FLIPH 0x40 | + | if(argc != 2) |
− | typedef struct { | + | { |
− | u16 version; | + | fprintf(stderr, "usage: %s <icon.bin>\n", argv[0]); |
− | u16 crcs[4];
| + | exit(0); |
− | u8 padding[0x16];
| + | } |
− | u8 bitmap[0x200]; | |
− | u16 palette[0x10];
| |
− | u8 title_jap[0x100];
| |
− | u8 title_eng[0x100];
| |
− | u8 title_fr[0x100];
| |
− | u8 title_ger[0x100];
| |
− | u8 title_ita[0x100];
| |
− | u8 title_spa[0x100];
| |
− | u8 title_unk[0x100];
| |
− | u8 title_unk2[0x100];
| |
− | u8 padding2[0x800];
| |
− | u8 bitmaps[8][0x200];
| |
− | u16 palettes[8][0x10];
| |
− | u16 sequence[0x40];
| |
− | } bannerstruct; | |
| | | |
− | int flength(FILE *f) | + | FILE* fp = fopen(argv[1], "rb"); |
| + | if(fp == NULL) |
| { | | { |
− | int pos,end; | + | fprintf(stderr, "input file not found\n"); |
− | pos = ftell (f);
| + | exit(1); |
− | fseek (f, 0, SEEK_END);
| |
− | end = ftell (f);
| |
− | fseek (f, pos, SEEK_SET); | |
− | return end;
| |
| } | | } |
| | | |
− | void do_bitmap(u8* bitmap, u16* palette, char* fname) | + | int f_len = flength(fp); |
| + | char* f_buf = malloc(f_len); |
| + | if(f_buf == NULL) |
| { | | { |
− | FILE *fp = fopen(fname, "wb"); | + | fprintf(stderr, "not enough memory\n"); |
− | if (fp == NULL)
| + | exit(1); |
− | {
| + | } |
− | fprintf(stderr, "file cannot be opened: %s\n", fname);
| + | if(fread(f_buf, f_len, 1, fp) != 1) |
− | exit(1);
| + | { |
− | }
| + | fprintf(stderr, "file read failure\n"); |
− | fprintf(fp, "P6 %d %d 255\n", 32, 32);
| + | exit(1); |
− |
| + | } |
− | // fix 8x8 tiling
| + | |
− | u8 tilebuf[0x204];
| + | char dirname[256]; |
− | int x,y,z;
| + | snprintf(dirname, sizeof(dirname), "%s.out", argv[1]); |
− | for(x=0; x<4; x++)
| + | mkdir(dirname, 0777); |
− | {
| + | chdir(dirname); |
− | for(y=0; y<8; y++)
| + | |
− | {
| + | bannerstruct* bnr = (bannerstruct*) f_buf; |
− | for(z=0; z<8; z++)
| + | // check magic |
− | {
| + | if(be16((u8*)&bnr->version) != BNR_VER) |
− | memcpy(tilebuf+(x*128)+(16*y)+(4*z),
| + | { |
− | bitmap+(x*128)+(32*z)+(4*y), 4);
| + | fprintf(stderr, "invalid banner icon (magic mismatch)\n"); |
− | }
| + | exit(1); |
− | }
| |
− | } | |
− |
| |
− | // convert to rgb888
| |
− | int i,j;
| |
− | u8 pixeldata[32*32][3];
| |
− | for(i=0; i<0x200; i++)
| |
− | {
| |
− | u8 off = tilebuf[i];
| |
− | int offs[2];
| |
− | offs[0] = off&0x0F;
| |
− | offs[1] = (off&0xF0)>>4;
| |
− |
| |
− | u16 colors[2];
| |
− | colors[0] = *(palette+offs[0]);
| |
− | colors[1] = *(palette+offs[1]);
| |
− |
| |
− | for(j=0; j<2; j++)
| |
− | {
| |
− | u8 r = (colors[j] ) & 0x1f;
| |
− | u8 g = (colors[j] >> 5) & 0x1f;
| |
− | u8 b = (colors[j] >> 10) & 0x1f;
| |
− | pixeldata[i*2+j][0] = (r << 3);
| |
− | pixeldata[i*2+j][1] = (g << 3);
| |
− | pixeldata[i*2+j][2] = (b << 3);
| |
− | }
| |
− | }
| |
− |
| |
− | if(fwrite(pixeldata, sizeof(pixeldata), 1, fp) != 1)
| |
− | {
| |
− | fprintf(stderr, "writing output-file failed\n");
| |
− | exit(1);
| |
− | }
| |
− | fclose(fp);
| |
| } | | } |
| | | |
− | int main(int argc, char* argv[]) | + | // extract default bitmap |
| + | do_bitmap(bnr->bitmap, bnr->palette, "default.ppm"); |
| + | |
| + | // loop through all sequences |
| + | u16* pseq = bnr->sequence; |
| + | u16 seq, i; |
| + | for(i=0; (seq = be16((u8*) pseq+i)) != 0; i++) |
| { | | { |
− | if(argc != 2) | + | // masking out |
− | { | + | int bid = (seq&0x7); |
− | fprintf(stderr, "usage: %s <icon.bin>\n", argv[0]);
| + | int pid = (seq&0x38)>>3; |
− | exit(0);
| |
− | }
| |
− |
| |
− | FILE* fp = fopen(argv[1], "rb");
| |
− | if(fp == NULL)
| |
− | {
| |
− | fprintf(stderr, "input file not found\n");
| |
− | exit(1);
| |
− | }
| |
− |
| |
− | int f_len = flength(fp); | |
− | char* f_buf = malloc(f_len);
| |
− | if(f_buf == NULL)
| |
− | {
| |
− | fprintf(stderr, "not enough memory\n");
| |
− | exit(1);
| |
− | }
| |
− | if(fread(f_buf, f_len, 1, fp) != 1)
| |
− | {
| |
− | fprintf(stderr, "file read failure\n");
| |
− | exit(1);
| |
− | }
| |
| | | |
− | char dirname[256]; | + | // write to logfile |
− | snprintf(dirname, sizeof(dirname), "%s.out", argv[1]); | + | char fname[256]; |
− | mkdir(dirname, 0777);
| + | snprintf(fname, sizeof(fname), "seq#%d.txt", i); |
− | chdir(dirname);
| |
| | | |
− | bannerstruct* bnr = (bannerstruct*) f_buf; | + | FILE* flog = fopen(fname, "w+"); |
− | // check magic
| + | if(flog == NULL) |
− | if(be16((u8*)&bnr->version) != BNR_VER) | |
| { | | { |
− | fprintf(stderr, "invalid banner icon (magic mismatch)\n"); | + | fprintf(stderr, "log-file couldn't be created\n"); |
| exit(1); | | exit(1); |
| } | | } |
| | | |
− | // extract default bitmap | + | fprintf(flog, "duration : %d frames\n", (seq&0xFF00)>>8); |
− | do_bitmap(bnr->bitmap, bnr->palette, "default.ppm"); | + | fprintf(flog, "bitmap : #%d\n", bid); |
| + | fprintf(flog, "palette : #%d\n", pid); |
| + | fclose(flog); |
| | | |
− | // loop through all sequences | + | // todo: flipz! |
− | u16* pseq = bnr->sequence;
| + | if((seq & FLAG_FLIPV) == FLAG_FLIPV) |
− | u16 seq, i;
| + | fprintf(stderr, "warning: vertical flip ignored on sequence #%d\n", i); |
− | for(i=0; (seq = be16((u8*) pseq+i)) != 0; i++)
| + | if((seq & FLAG_FLIPH) == FLAG_FLIPH) |
− | {
| + | fprintf(stderr, "warning: horizontal flip ignored on sequence #%d\n", i); |
− | // masking out
| |
− | int bid = (seq&0x7);
| |
− | int pid = (seq&0x38)>>3;
| |
− |
| |
− | // write to logfile
| |
− | char fname[256];
| |
− | snprintf(fname, sizeof(fname), "seq#%d.txt", i);
| |
− |
| |
− | FILE* flog = fopen(fname, "w+");
| |
− | if(flog == NULL)
| |
− | {
| |
− | fprintf(stderr, "log-file couldn't be created\n");
| |
− | exit(1);
| |
− | }
| |
− |
| |
− | fprintf(flog, "duration : %d frames\n", (seq&0xFF00)>>8);
| |
− | fprintf(flog, "bitmap : #%d\n", bid);
| |
− | fprintf(flog, "palette : #%d\n", pid);
| |
− | fclose(flog);
| |
− |
| |
− | // todo: flipz!
| |
− | if((seq & FLAG_FLIPV) == FLAG_FLIPV)
| |
− | fprintf(stderr, "warning: vertical flip ignored on sequence #%d\n", i);
| |
− | if((seq & FLAG_FLIPH) == FLAG_FLIPH)
| |
− | fprintf(stderr, "warning: horizontal flip ignored on sequence #%d\n", i);
| |
− |
| |
− | // change extension to .ppm
| |
− | char* dot_pos = strchr(fname, '.');
| |
− | strcpy(dot_pos, ".ppm");
| |
− |
| |
− | // extract bitmap to file
| |
− | do_bitmap(bnr->bitmaps[bid], bnr->palettes[pid], fname);
| |
− | }
| |
| | | |
− | fclose(fp); | + | // change extension to .ppm |
− | free(f_buf); | + | char* dot_pos = strchr(fname, '.'); |
| + | strcpy(dot_pos, ".ppm"); |
| | | |
− | return 0; | + | // extract bitmap to file |
| + | do_bitmap(bnr->bitmaps[bid], bnr->palettes[pid], fname); |
| } | | } |
| + | |
| + | fclose(fp); |
| + | free(f_buf); |
| + | |
| + | return 0; |
| + | } |
| + | </source> |