/* * fontx2xm7.c * * original code by SASANO Takayoshi * --- public domain, no warranty. */ #include #include #include /* FONTX2 header */ #define CODETYPE_ASCII 0 #define CODETYPE_KANJI 1 /* common */ typedef struct { unsigned char identifier[6]; unsigned char fontname[8]; unsigned char xsize; unsigned char ysize; unsigned char codetype; } __attribute__((packed)) FONTX2_HEADER; /* ascii */ typedef struct { FONTX2_HEADER h; unsigned char d[1]; } __attribute__((packed)) FONTX2_ASCII; /* sjis */ typedef struct { FONTX2_HEADER h; unsigned char tnum; unsigned char d[1]; } __attribute__((packed)) FONTX2_KANJI; typedef struct { unsigned short start; unsigned short end; } __attribute__((packed)) FONTX2_CODETABLE; /* ROM data buffer */ #define BUFFERSIZE 131072 static unsigned char RomData[BUFFERSIZE]; /* SJIS -> JIS */ static int _mbcjmstojis(int jms) { int low, high; high = (jms >> 8) & 0xff; low = jms & 0xff; if (low < 0x9f) { if (high < 0xa0) { high -= 0x81; high *= 2; high += 0x21; } else { high -= 0xe0; high *= 2; high += 0x5f; } if (low > 0x7f) low--; low -= 0x1f; } else { if (high < 0xa0) { high -= 0x81; high *= 2; high += 0x22; } else { high -= 0xe0; high *= 2; high += 0x60; } low -= 0x7e; } return (high << 8) | low; } /* get kanji font pointer */ static unsigned char *get_kanji_pointer(int sjis) { int kuten, ku, ten, n, ix; kuten = _mbcjmstojis(sjis) - 0x2020; ku = (kuten >> 8) & 0xff; ten = kuten & 0xff; ix = ten / 32; if (ku < 8) { /* 0区〜7区 */ switch (ix) { case 1: ix = 2; break; case 2: ix = 1; break; } n = (ku + ix * 8) * 32 + (ten % 32); } else if (ku < 16) { /* 8区〜15区 (未定義) */ n = -1; } else if (ku < 32) { /* 16区〜31区 */ n = (ku + 16 + ix * 16) * 32 + (ten % 32); } else if (ku < 48) { /* 32区〜47区 */ n = (ku + 48 + ix * 16) * 32 + (ten % 32); } else { /* 48区以降 (未定義) */ n = -1; } return (n < 0) ? NULL : (RomData + n * 32); } /* convert kanji font */ void convert_kanji_font(void *buf) { int i, j; FONTX2_KANJI *k = buf; FONTX2_CODETABLE *c = (FONTX2_CODETABLE *)&k->d[0]; unsigned char *d = &k->d[sizeof(FONTX2_CODETABLE) * k->tnum]; unsigned char *p; if (k->h.codetype != CODETYPE_KANJI || (k->h.xsize + 7) / 8 != 2 || k->h.ysize != 16) { printf("invalid font data (kanji)\n"); return; } for (i = 0; i < k->tnum; i++) { for (j = c[i].start; j <= c[i].end; j++) { p = get_kanji_pointer(j); if (p != NULL) memcpy(p, d, 32); d += 32; } } return; } /* load file */ unsigned char *loadfile(char *filename) { FILE *fp; int size; unsigned char *buf = NULL; fp = fopen(filename, "r"); if (fp == NULL) { printf("loadfile: file open error (%s)\n", filename); goto fin0; } fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); buf = malloc(size); if (buf == NULL) { printf("loadfile: memory allocation error (%s)\n", filename); goto fin0; } if (fread(buf, size, 1, fp) < 1) { printf("loadfile: file read error (%s)\n", filename); free(buf); buf = NULL; } fclose(fp); fin0: return buf; } /* save file */ void savefile(char *filename, char *buf, int size) { FILE *fp; fp = fopen(filename, "w"); if (fp == NULL) { printf("savefile: file open error (%s)\n", filename); goto fin0; } if (fwrite(buf, size, 1, fp) < 1) { printf("savefile: file write error (%s)\n", filename); } fclose(fp); fin0: return; } /* entry */ int main(int argc, char *argv[]) { int i, result; unsigned char *buf; if (argc < 3) { printf("usage: %s [kanji] [romfile]\n", argv[0]); result = EXIT_FAILURE; goto fin0; } for (i = 0; i < sizeof(RomData); i++) RomData[i] = i & 1; buf = loadfile(argv[1]); if (buf != NULL) { convert_kanji_font(buf); free(buf); } savefile(argv[2], RomData, sizeof(RomData)); result = EXIT_SUCCESS; fin0: return result; }