#include #include #include #include char pokecap[191][17]; char pokenam[191][17]; char pokespec[191][17]; char pokedesc[191][110]; char Learns[191][70]; unsigned char pokenum[191]; unsigned char anchestor[191]; unsigned char evolveitem[191]; unsigned char poketype[191][2]; unsigned char internalnum[191]; int evolvelevel[191]; int IniSkill[191][4]; char poketypes[16][10]; char Skills[256][64]; char Items[256][64]; int cm[191]; int g[191]; static const char poketrans[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ();:[]" // 0x80 "abcdefghijklmnopqrstuvwxyzé " // 0xA0 " " // 0xC0 "' -''?!. -$*./,+0123456789"; // 0xE0 int main(void) { FILE *fp; int flag; fp = fopen("pokeblue.gb", "rb"); printf("enum Items\n{\n"); fseek(fp, 0x472B, SEEK_SET); /* 8C,80,92,93 */ for(flag=1;flag<84;flag++) { char Buf[64], *s; int a; for(s=Buf; (a=fgetc(fp))!=0x50; ) { switch(a) { case 0x4E: *s++=' '; break; case 0x5F: *s++='.'; break; case 0xBB: *s++='\''; *s++='d'; break; case 0xBC: *s++='\''; *s++='l'; break; case 0xBD: *s++='\''; *s++='s'; break; case 0xBE: *s++='\''; *s++='t'; break; case 0xBF: *s++='\''; *s++='v'; break; default: *s++ = a<0x80 ? ' ' : poketrans[a&0x7F]; } } *s=0; for(s=Buf; *s; s++) if(*s=='é')*s='e'; else if(!isalpha(*s)) *s='_'; printf(" %s=%d,\n", Buf,flag); strcat(s, ","); strcpy(Items[flag], Buf); } printf(" ITEMCOUNT\n};\n"); fseek(fp, 0x41023, SEEK_SET); fread(pokenum, 1, 191, fp); for(flag=1; flag<191; flag++) internalnum[pokenum[flag]] = flag; fseek(fp, 0x383DE, SEEK_SET); /* 01,2D,31,31,2D */ printf( "/*_pokeskills|grep '\\/\\* '|sort -t_ +0.6|less\n\n" "/* pid # HP ATK DEF SPD SPC Unknown IMG1 IMG2 Unknown*/\n" "/* --- -- -------------------- -------- ---- ---- -------*/\n"); /* 123 FF 2D 31 31 2D 41 xx xx xx 1234 1234 xx xx */ for(flag=1; flag<151; flag++) { char *s = Learns[flag]; int a; printf("/*%4d %02X ", fgetc(fp), internalnum[flag]); printf(" %02X ", fgetc(fp)); printf(" %02X ", fgetc(fp)); printf(" %02X ", fgetc(fp)); printf(" %02X ", fgetc(fp)); printf(" %02X ", fgetc(fp)); a = fgetc(fp); poketype[flag][1] = a==26?15:a>=20?a-16:a>4?a+6:a; a = fgetc(fp); poketype[flag][2] = a==26?15:a>=20?a-16:a>4?a+6:a; for(a=0; a<3; a++) printf(" %02X", fgetc(fp)); a = fgetc(fp); printf(" %02X%02X", fgetc(fp), a); /* pokédex image offset */ a = fgetc(fp); printf(" %02X%02X", fgetc(fp), a); /* behind-image (battle) offset */ for(a=0; a<4; a++) IniSkill[flag][a] = fgetc(fp); printf(" %02X ", fgetc(fp)); for(a=0; a<7; a++) { int c, n = fgetc(fp); for(c=1; c<256; c+=c) *s++ = (n&c) ? 'x': ' '; } Learns[flag][55] = 0; printf("%02X */\n", fgetc(fp)); } memset(Learns[0], '-', 55); /* missingno */ memset(Learns[151], 'x', 55); /* Mew */ printf("enum PokeNames\n{\n"); fseek(fp, 0x1C21E, SEEK_SET); for(flag=1; flag<191; flag++) { char Buf[11], *s; int a; fread(Buf, 1, 10, fp); Buf[10]=0; for(a=0; a<10; a++) Buf[a] = Buf[a]==0x50 ? 0 : poketrans[Buf[a]&0x7F]; sprintf(pokecap[flag], "\"%s\",", Buf); for(s=Buf, a=1; *s; s++) { if(*s=='.')a=0; if(*s=='-')*s='m'; else if(*s=='+')*s='f'; else if(!isalpha(*s))*s='_'; } sprintf(pokenam[flag], "%s,", Buf); if(a) printf(" %s=%d,\n", Buf, flag); } printf(" POKECOUNT\n};\n"); printf("enum Skills\n{\n"); fseek(fp, 0xB0000, SEEK_SET); for(flag=1;;) { char Buf[128], *s=Buf; int a, b=0; while((a=fgetc(fp)) != 0x50) { if(!a)break; b=1; *s=a<0x80?' ':poketrans[a&0x7F]; if(!isalpha(*s))*s='_'; s++; } if(!b)break; *s=0; printf(" %s=%d,\n", Buf, flag); strcpy(Skills[flag++], Buf); } printf(" SKILLCOUNT\n};\n"); fseek(fp, 0xAC000, SEEK_SET); for(flag=1; flag<191; flag++) if(pokenum[flag]) { char Buf[128], *s=Buf; int a; fgetc(fp); /* 0 */ *s++='"'; while((a=fgetc(fp)) != 0x50) { switch(a) { case 0x54: *s++='P'; *s++='O'; *s++='K'; *s++='é'; break; case 0xE3: { int b=fgetc(fp); if(b!=0x4E) /* newline */ { ungetc(b, fp); goto RedoDef; } break; } case 0x4E: *s++=' '; break; case 0x5F: *s++='.'; break; case 0x49: *s++='\\'; *s++='n'; break; case 0xBB: *s++='\''; *s++='d'; break; case 0xBC: *s++='\''; *s++='l'; break; case 0xBD: *s++='\''; *s++='s'; break; case 0xBE: *s++='\''; *s++='t'; break; case 0xBF: *s++='\''; *s++='v'; break; default: RedoDef: *s++ = a<0x80 ? ' ' : poketrans[a&0x7F]; } } strcpy(s, "\","); strcpy(pokedesc[flag], Buf); } printf("enum PokeTypes\n{\n"); fseek(fp, 0x27DE4, SEEK_SET); /* 8D,8E,91,8C */ for(flag=0;flag>=0;) { int a, b=0; char *s = poketypes[flag]; while((a=fgetc(fp)) != 0x50) { if(a == 0x21){printf("=%d,\n POKETYPECOUNT\n};\n", flag-1); flag=-1;break;} if(!b){b=1;if(flag)printf("=%d,\n", flag-1);flag++;printf(" ");} printf("%c", *s++=poketrans[a&0x7F]); } strcpy(s,","); } fseek(fp, 0x405FA, SEEK_SET); for(flag=1; flag<191; flag++) if(pokenum[flag]) { char Buf[17]; double n; int a, b; for(b=0; (a=fgetc(fp)) != 0x50; b++) Buf[b]=a<0x80?' ':poketrans[a&0x7F]; Buf[b]=0; sprintf(pokespec[flag], "\"%s\",", Buf); n = fgetc(fp)*30.48; /* ' */ n += fgetc(fp)*3.048 /*2.34*/; /* " */ cm[flag] = n; b = fgetc(fp); b += fgetc(fp)*256; /* lbs */ n = b * 45.359; g[flag] = n; for(a=0; a<5; a++) fgetc(fp); } fseek(fp, 0x3B1DF, SEEK_SET); /* 30,20,37 */ for(flag=2; flag<191; flag++) /* 2 because the first doesn't have evolve info */ { int a; while(fgetc(fp) != 0); /* skillit */ while((a=fgetc(fp)) != 0) switch(a) { case 1: /* level */ { int lev = fgetc(fp); int become = fgetc(fp); anchestor[become] = flag; evolvelevel[become] = lev; break; } case 2: /* item */ { int item = fgetc(fp); int lev = fgetc(fp); int become = fgetc(fp); anchestor[become] = flag; evolvelevel[become] = lev; evolveitem[become] = item; break; } case 3: /* trade only */ { int lev = fgetc(fp); int become = fgetc(fp); anchestor[become] = flag; evolvelevel[become] = -lev; break; } } } fseek(fp, 0x3B1DF, SEEK_SET); /* 30,20,37 */ printf( "static struct pokemon\n" "{\n" " unsigned char num; /* index in pokédex */\n" " const char *name;\n" " const char *specie;\n" " unsigned char type1, type2;\n" " const char *tmhm; /* space=can't learn, x=can learn */\n" " int evolve_level; /* or -1 for trade only */\n" " unsigned char evolve_item; /* item[] or 0 */\n" " unsigned char evolved; /* pokemon[] or 0 (replaces that pokemon) */\n" " int cm, g; /* the game uses ' and \" and lbs but I like SI more */\n" " const char *descr;\n" " struct {unsigned char level, skill;} skillsperlevel[20];\n" "} pokemon[POKEMONCOUNT] = " " /*_TM 00000000011111111112222222222333333333344444444445HHHHH */\n" "/* The list is in the same order as it is internally in the game itself */\n" ); for(flag=1; flag<191; flag++) { int a, n; /* missing: Abilities (struct) */ printf( "{%3d,%-13s%-13s%-9s%-9s\"%s\",%2d,%-13s%-12s%4d,%6d,%-107s/*%02X*/{", pokenum[flag], pokecap[flag], pokespec[flag], poketypes[poketype[pokenum[flag]][1]], poketypes[poketype[pokenum[flag]][2]], Learns[pokenum[flag]], evolvelevel[flag], evolveitem[flag]?Items[evolveitem[flag]]:"0,", anchestor[flag]?pokenam[anchestor[flag]]:"0,", cm[flag], g[flag], pokedesc[flag], flag); for(n=a=0; a<4; a++) { if(IniSkill[pokenum[flag]][a]) { if(n)printf(","); printf("{%d,%s}", 0, Skills[IniSkill[pokenum[flag]][a]]); n++; } } for(;;) { int lev=fgetc(fp), skill; if(!lev)break; skill = fgetc(fp); if(n)printf(","); printf("{%d,%s}", lev, Skills[skill]); n++; } while(fgetc(fp) != 0); printf("},\n"); } fclose(fp); return 0; }