#include #include #include #include typedef unsigned char byte; static ggi_visual_t vis; static ggi_color pal[256]; static void Init(void) { ggiInit(); vis = ggiOpen(NULL); if(!vis || ggiSetGraphMode(vis, 320,200, 320,200, GT_8BIT)) exit(-1); } static void Done(void) { ggiClose(vis); ggiExit(); } static void SetPal(void) { int a; for(a=0; a<15; a++) pal[a].r = pal[a].g = pal[a].b = (15-a) * 0xFFFF / 15; pal[254].r=0x0400; pal[254].g=0x2000;pal[254].b=0x7FFF; pal[255].r=0xFFFF; pal[255].g=0x3000;pal[255].b=0xFFFF; ggiSetPalette(vis, 0,256, pal); } static void Disp(const char *s) { FILE *fp = fopen(s, "rb"); int posi, swap=1, bits=16, nes=0; if(!fp)return; ggiSetGCForeground(vis, 255); for(posi=0; ; ) { int sx, sy; fseek(fp, posi, SEEK_SET); for(sy=0; sy<25; sy++) for(sx=0; sx<32; sx++) { unsigned char Buf[64]; unsigned x, y; int bx,by; switch(swap) { case 0: bx = sx; by = sy; break; case 1: bx = (sx&1) | ((sy&1)<<1) | (sx&~3); by = ((sx&2)>>1) | (sy&~1); break; case 2: bx = (sx&15) | ((sy&1)<<4); by = ((sx&16)>>4) | (sy&~1); break; case 3: bx = (sx&7) | ((sy&3)<<3) | (sx&~31); by = ((sx&24)>>3) | (sy&~3); break; } /* 1256 */ /* 3478 */ bx*=8; by*=8; if(fread(Buf, 1, bits, fp) != bits) for(y=0; y<8; y++) for(x=0; x<8; x++) ggiPutPixel(vis, bx+x, by+y, 254); else for(y=0; y<8; y++) { unsigned char b1, b2, b3, b4; if(bits==32) { b1 = Buf[y*2]; b2 = Buf[y*2+1]; b3 = Buf[y*2+16]; b4 = Buf[y*2+17]; } else { b1 = Buf[nes?y:y*bits/8]; b2 = Buf[nes?y+8:y*bits/8+1]; } switch(bits) { case 16: for(x=0; x<8; x++) { ggiPutPixel(vis, bx+x, by+y, (((b1 >> (7-x))&1) | (((b2 >> (7-x))&1)<<1)) * 15 / 3 ); } break; case 32: for(x=0; x<8; x++) { ggiPutPixel(vis, bx+x, by+y, ((b1 >> (7-x))&1) | (((b2 >> (7-x))&1)<<1) | (((b3 >> (7-x))&1)<<2) | (((b4 >> (7-x))&1)<<3) ); } break; case 8: for(x=0; x<8; x++) ggiPutPixel(vis, bx+x, by+y, 15*((b1 >> (7-x))&1)); } } } ggiPutc(vis,320-48+ 0,0, 'P'); ggiPutc(vis,320-48+ 8,0, swap+'0'); ggiPutc(vis,320-48+16,0, 'B'); ggiPutc(vis,320-48+24,0, bits==8?'1':bits==16?'2':'4'); ggiPutc(vis,320-48+32,0, 'N'); ggiPutc(vis,320-48+40,0, nes+'0'); ggiPuts(vis,256+6,16, "a,d ="); ggiPuts(vis,256+6,24, " shift"); ggiPuts(vis,256+6,32, "w,s ="); ggiPuts(vis,256+3,40, " up,down"); ggiPuts(vis,256+6,48, "e,q ="); ggiPuts(vis,256+6,56, " posi-+"); ggiPuts(vis,256+3,64, "p=toggle"); ggiPuts(vis,256+6,72, " swap"); ggiPuts(vis,256+3,80, "b=toggle"); ggiPuts(vis,256+6,88, " bits"); ggiPuts(vis,256+3,96, "n=toggle"); ggiPuts(vis,256+6,104," nes/gb"); ggiPuts(vis,256+6,112,"esc="); ggiPuts(vis,256+6,120," quit"); switch(ggiGetc(vis)) { case 27: return; case 'a': if(posi>0)posi--; break; case 'd': posi++; break; case 's': posi+=2*32*bits; break; case 'w': posi-=2*32*bits; if(posi<0)posi=0; break; case 'e': posi+=4*bits; break; case 'q': posi-=4*bits; if(posi<0)posi=0; break; case 'p': swap=(swap+1)%4; break; case 'b': bits=bits==8?16:bits==16?32:8; break; case 'n': nes^=1; break; } } } int main(int argc, const char *const *argv) { if(argc<2 || access(argv[argc-1], O_RDONLY)) { printf( "Designed for Game Boy and NES files, but can be used on others as well\n" "Copyright (C) 1992,2000 Bisqwit (http://iki.fi/bisqwit/)\n" "Usage: xray \n"); return 0; } Init(); SetPal(); Disp(argv[argc-1]); Done(); return 0; }