#include <stdio.h>
#include "bitswap.h"
// cthd, matrimbl, svcboot
void DoPerm(unsigned char *src, int g, int ed, int size)
{
unsigned int idx[2][ 0x10 ] = {
{0,1,2,3,3,4,4,5,0,1,2,3,3,4,4,5}, // cthd2003/matrimbl
{0,1,0,1,2,3,2,3,3,4,3,4,4,5,4,5}, // svcboot
};
unsigned int tbl[ 6 ][ 4 ] = {
{ 3, 0, 1, 2 },
{ 2, 3, 0, 1 },
{ 1, 2, 3, 0 },
{ 0, 1, 2, 3 },
{ 3, 2, 1, 0 },
{ 3, 0, 2, 1 },
};
unsigned char dst[0x400];
int i, j;
for(i = 0; i < size/0x400; i++)
{
for(j = 0; j < 16; j++)
{
unsigned int *b = tbl[ idx[g][(i>>(5-g))&0xF] ];
int ofst = BITSWAP08(j, 7, 6, 5, 4, b[3], b[2], b[1], b[0] );
if (ed==0)memcpy( dst + j * 0x40, src + (i * 0x400) + ofst * 0x40, 0x40 ); // decrypt
if (ed==1)memcpy( dst + ofst * 0x40, src + (i * 0x400) + j * 0x40, 0x40 ); // encrypt
}
memcpy (src + i * 0x400, dst, 0x400);
}
}
// kof2002b
void kof2k2b(unsigned char* rom, int ed, int size)
{
int t[8][10] = {
{ 0, 8, 7, 3, 4, 5, 6, 2, 1 },
{ 1, 0, 8, 4, 5, 3, 7, 6, 2 },
{ 2, 1, 0, 3, 4, 5, 8, 7, 6 },
{ 6, 2, 1, 5, 3, 4, 0, 8, 7 },
{ 7, 6, 2, 5, 3, 4, 1, 0, 8 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 },
{ 2, 1, 0, 4, 5, 3, 6, 7, 8 },
{ 8, 0, 7, 3, 4, 5, 6, 2, 1 },
};
int i,j;
unsigned char* tmp = (unsigned char*)malloc(0x8000);
for (i = 0; i < size; i += 0x8000) {
memcpy(tmp, rom + i, 0x8000);
for (j = 0; j < 0x200; j++) {
int *n = t[ (j >> 3) & 7];
int ofst = BITSWAP16(j, 15, 14, 13, 12, 11, 10, 9, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]);
if (ed==0)memcpy( rom + i + ofst * 64, tmp + j * 64, 64 ); // decrypt
if (ed==1)memcpy( rom + i + j * 64, tmp + ofst * 64, 64 ); // encrypt
}
}
free(tmp);
}
void usage()
{
printf("Converts between encrypted and decrypted (Bootleg) C (graphics) roms\n\n");
printf("Usage: BootCEn [type] [command] [source file] [output file]\n\n");
printf("[type]: 0 for kog/lans2004 | 1 for matrimbl/cthd2003\n");
printf(" 2 for svcboot | 3 for kof2002b\n");
printf("[command]: e (for encryption) | d (for decryption)\n");
printf("[source file]: the file name of the rom you wish to work with\n");
printf("[output file]: the file name of the rom you wish to create\n");
}
int main(int argc, char **argv)
{
int type = 0;
int ed = 0;
if (argc < 5)
{
usage();
return (1);
}
sscanf(argv[1],"%d",&type);
if ((strcmp(argv[2],"d"))&&(strcmp(argv[2],"D"))) ed = 1;
if ((strcmp(argv[2],"e"))&&(strcmp(argv[2],"E"))) ed = 0;
int i;
int size = 0;
FILE *rom_out, *rom_in;
if ((rom_in=fopen(argv[3],"rb"))==NULL)
{
fprintf(stderr,"Error: cannot read %s.", argv[3]); return(1);
}
fseek (rom_in , 0 , SEEK_END); size += ftell (rom_in); rewind (rom_in);
if ((rom_out=fopen(argv[4],"wb"))==NULL)
{
fprintf(stderr,"Error: cannot write to %s.", argv[4]); return(1);
}
unsigned char *src = (unsigned char*)malloc(size);
if (type == 0) // kog, samsh5bl, lans2004
{
for (i = 0; i < size; i+=0x40)
{
fread (src + i + 0x20, 1, 0x20, rom_in);
fread (src + i + 0x00, 1, 0x20, rom_in);
}
} else {
fread (src, 1, size, rom_in);
if (type == 1) DoPerm(src, 0, ed, size); // cthd2003/matrimbl
if (type == 2) DoPerm(src, 1, ed, size); // svcboot
if (type == 3) kof2k2b(src, ed, size); // kof2002b
}
fwrite (src, 1, size, rom_out);
fclose(rom_out);
free (src);
}