/* jwr50ffontx.c code: SASANO Takayoshi ---- CC-BY, no warranty. [charset=UTF-8] ●概要 省略。 */ #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; static FONTX2_CODETABLE CodeTable_SJIS[] = { {0x8140, 0x817e}, {0x8180, 0x81ac}, /* symbol */ {0x81d8, 0x81d9}, {0x81e3, 0x81e3}, {0x81e7, 0x81e7}, {0x824f, 0x8258}, /* number */ {0x8260, 0x8279}, /* alphabet (large) */ {0x8281, 0x829a}, /* alphabet (small) */ {0x829f, 0x82f1}, /* hiragana */ {0x8340, 0x837e}, {0x8380, 0x8396}, /* katakana */ {0x839f, 0x83b6}, /* greek (large) */ {0x83bf, 0x83d6}, /* greek (small) */ {0x83e4, 0x83e5}, /* symbol (3) */ {0x8440, 0x8460}, /* russian (large) */ {0x8470, 0x847e}, {0x8480, 0x8491}, /* russian (small) */ {0x849f, 0x84b4}, /* keisen */ {0x8740, 0x8749}, /* symbol (2) */ {0x8754, 0x875d}, {0x875f, 0x8768}, {0x876c, 0x876c}, {0x876e, 0x8773}, {0x8775, 0x8775}, {0x8782, 0x8784}, {0x878a, 0x878c}, {0x889f, 0x88fc}, /* kanji (JIS1) */ {0x8940, 0x897e}, {0x8980, 0x89fc}, {0x8a40, 0x8a7e}, {0x8a80, 0x8afc}, {0x8b40, 0x8b7e}, {0x8b80, 0x8bfc}, {0x8c40, 0x8c7e}, {0x8c80, 0x8cfc}, {0x8d40, 0x8d7e}, {0x8d80, 0x8dfc}, {0x8e40, 0x8e7e}, {0x8e80, 0x8efc}, {0x8f40, 0x8f7e}, {0x8f80, 0x8ffc}, {0x9040, 0x907e}, {0x9080, 0x90fc}, {0x9140, 0x917e}, {0x9180, 0x91fc}, {0x9240, 0x927e}, {0x9280, 0x92fc}, {0x9340, 0x937e}, {0x9380, 0x93fc}, {0x9440, 0x947e}, {0x9480, 0x94fc}, {0x9540, 0x957e}, {0x9580, 0x95fc}, {0x9640, 0x967e}, {0x9680, 0x96fc}, {0x9740, 0x977e}, {0x9780, 0x97fc}, {0x9840, 0x9872}, {0x989f, 0x98fc}, /* kanji (JIS2) */ {0x9940, 0x997e}, {0x9980, 0x99fc}, {0x9a40, 0x9a7e}, {0x9a80, 0x9afc}, {0x9b40, 0x9b7e}, {0x9b80, 0x9bfc}, {0x9c40, 0x9c7e}, {0x9c80, 0x9cfc}, {0x9d40, 0x9d7e}, {0x9d80, 0x9dfc}, {0x9e40, 0x9e7e}, {0x9e80, 0x9efc}, {0x9f40, 0x9f7e}, {0x9f80, 0x9ffc}, {0xe040, 0xe07e}, {0xe080, 0xe0fc}, {0xe140, 0xe17e}, {0xe180, 0xe1fc}, {0xe240, 0xe27e}, {0xe280, 0xe2fc}, {0xe340, 0xe37e}, {0xe380, 0xe3fc}, {0xe440, 0xe47e}, {0xe480, 0xe4fc}, {0xe540, 0xe57e}, {0xe580, 0xe5fc}, {0xe640, 0xe67e}, {0xe680, 0xe6fc}, {0xe740, 0xe77e}, {0xe780, 0xe7fc}, {0xe840, 0xe87e}, {0xe880, 0xe8fc}, {0xe940, 0xe97e}, {0xe980, 0xe9fc}, #if 0 {0xea40, 0xea7e}, {0xea80, 0xeaa2}, #else {0xea40, 0xea7e}, {0xea80, 0xea9e}, #endif }; static unsigned short table_8ku[] = { 0x0722, 0x0723, 0x0725, 0x0726, 0x0727, 0x0724, 0x0729, 0x072a, //01-08 0x072b, 0x0728, 0x072c, 0x0851, 0x0852, 0x0854, 0x0855, 0x0856, //09-10 0x0853, 0x0858, 0x0859, 0x085a, 0x0857, 0x085b, //11-16 }; static unsigned short table_13ku[] = { 0x023d, 0x023e, 0x023f, 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, //01-08 0x0245, 0x0246, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, //09-10 0x0101, 0x0101, 0x0101, 0x0101, 0x0211, 0x0212, 0x0213, 0x0214, //11-18 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, 0x0101, 0x022f, //19-20 0x0234, 0x022e, 0x022d, 0x022c, 0x0233, 0x0231, 0x0230, 0x0238, //21-28 0x0237, 0x0101, 0x022b, 0x0101, 0x0239, 0x0101, 0x023a, 0x021e, //29-30 0x021d, 0x021f, 0x0223, 0x0224, 0x0101, 0x0221, 0x0101, 0x0101, //31-38 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, //39-40 0x0101, 0x0229, 0x0227, 0x0228, 0x0101, 0x0101, 0x0101, 0x0101, //41-48 0x0101, 0x020f, 0x0210, 0x0226, //49-4c }; /* data buffer (in/out) */ #define BUFFERSIZE (2048 * 1024) static unsigned char *InData; static unsigned char *InData2; static unsigned char OutData[BUFFERSIZE]; static int machine_id; /* fetch 24x24 */ static void fetch24x24(unsigned char *in, unsigned long *out, int index) { int i; for (i = 0; i < 8; i++) { out[i + 0] = (in[index * 8 + i + 0x58000] << 16) | (in[index * 8 + i + 0x10000] << 8) | (in[index * 8 + i + 0x28000] << 0); out[i + 8] = (in[index * 8 + i + 0x00000] << 16) | (in[index * 8 + i + 0x18000] << 8) | (in[index * 8 + i + 0x30000] << 0); out[i + 16] = (in[index * 8 + i + 0x08000] << 16) | (in[index * 8 + i + 0x20000] << 8) | (in[index * 8 + i + 0x38000] << 0); } return; } /* fetch 24x24 (JIS2) */ static void fetch24x24_2(unsigned char *in, unsigned long *out, int index) { int i; in += index * 72; for (i = 0; i < 24; i++) { out[i] = ((in[i + 0] << 16) | (in[i + 24] << 8) | (in[i + 48] << 0)); } return; } /* 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 index */ static int get_kanji_index(int sjis) { int kuten, ku, ten, idx; kuten = _mbcjmstojis(sjis) - 0x2020; switch (kuten) { case 0x023a ... 0x023b: kuten = 0x0247 + (kuten - 0x023a); break; case 0x0245: kuten = 0x024d; break; case 0x0249: kuten = 0x024c; break; case 0x0646 ... 0x0647: kuten = 0x0249 + (kuten - 0x0646); break; case 0x0801 ... 0x0816: kuten = table_8ku[kuten - 0x0801]; break; case 0x0d01 ... 0x0d4c: kuten = table_13ku[kuten - 0x0d01]; default: break; } ku = (kuten >> 8) & 0xff; ten = kuten & 0xff; idx = ku * 96 + ten - (ku >= 16) * 512; return idx; } /* get kanji font index (JIS2) */ static int get_kanji_index2(int sjis) { int kuten, ku, ten, idx; kuten = _mbcjmstojis(sjis) - 0x5020; ku = (kuten >> 8) & 0xff; ten = kuten & 0xff; idx = ku * 96 + ten; return idx; } /* copy CodeTable */ static char *copy_table(char *dst, FONTX2_CODETABLE *src, int entry) { int i; /* table must be little-endian */ for (i = 0; i < entry; i++) { *dst++ = src[i].start & 0xff; *dst++ = (src[i].start >> 8) & 0xff; *dst++ = src[i].end & 0xff; *dst++ = (src[i].end >> 8) & 0xff; } return dst; } /* convert (Kanji) */ static void convert_kanji(void) { int i, j, tnum, sjis, chr; unsigned char *d; FILE *fp; FONTX2_KANJI *f; unsigned long t[24]; char s[16]; memset(OutData, 0, sizeof(OutData)); f = (FONTX2_KANJI *)OutData; tnum = sizeof(CodeTable_SJIS) / sizeof(FONTX2_CODETABLE); /* create header */ strncpy(f->h.identifier, "FONTX2", sizeof(f->h.identifier)); snprintf(s, sizeof(s), "JWR%dF", machine_id); strncpy(f->h.fontname, s, sizeof(f->h.fontname)); for (i = 0; i < sizeof(f->h.fontname); i++) { if (f->h.fontname[i] < 0x20) f->h.fontname[i] = 0x20; } f->h.xsize = 24; f->h.ysize = 24; f->h.codetype = CODETYPE_KANJI; f->tnum = tnum; /* make CodeTable */ d = f->d; d = copy_table(d, CodeTable_SJIS, tnum); chr = 0; /* convert font */ for (i = 0; i < tnum; i++) { for (sjis = CodeTable_SJIS[i].start; sjis <= CodeTable_SJIS[i].end; sjis++, chr++) { if (sjis < 0x989f) { fetch24x24(InData, t, get_kanji_index(sjis)); } else { fetch24x24_2(InData2 + 0x400 - 72, t, get_kanji_index2(sjis)); } for (j = 0; j < 24; j++) { *d++ = (t[j] >> 16) & 0xff; *d++ = (t[j] >> 8) & 0xff; *d++ = (t[j] >> 0) & 0xff; } } } /* save result */ snprintf(s, sizeof(s), "jpnzn24x.r%d", machine_id); fp = fopen(s, "w"); if (fp != NULL) { fwrite(OutData, 1, (sizeof(FONTX2_HEADER) + tnum * sizeof(FONTX2_CODETABLE) + 72 * chr + 1), fp); } fclose(fp); return; } /* convert (ASCII) */ static void convert_ascii(void) { int i, j; FILE *fp; FONTX2_ASCII *f; unsigned long t[24]; char s[16]; memset(OutData, 0, sizeof(OutData)); f = (FONTX2_ASCII *)OutData; /* create header */ strncpy(f->h.identifier, "FONTX2", sizeof(f->h.identifier)); snprintf(s, sizeof(s), "JWR%dF", machine_id); strncpy(f->h.fontname, s, sizeof(f->h.fontname)); for (i = 0; i < sizeof(f->h.fontname); i++) { if (f->h.fontname[i] < 0x20) f->h.fontname[i] = 0x20; } f->h.xsize = 24 / 2; f->h.ysize = 24; f->h.codetype = CODETYPE_ASCII; /* converrt font (ASCII, 0x20-0x7e) */ for (i = 0x020; i < 0x7f; i++) { fetch24x24(InData, t, i - 0x20); for (j = 0; j < 24; j++) { f->d[48 * i + j * 2 + 0] = (t[j] >> 16) & 0xff; f->d[48 * i + j * 2 + 1] = (t[j] >> 8) & 0xf0; } } /* convert font (Kana, 0xa0-0xdf) */ for (i = 0x0a0; i < 0xe0; i++) { fetch24x24(InData, t, i - 0xa0 + 9 * 96); for (j = 0; j < 24; j++) { f->d[48 * i + j * 2 + 0] = (t[j] >> 16) & 0xff; f->d[48 * i + j * 2 + 1] = (t[j] >> 8) & 0xf0; } } /* save result */ snprintf(s, sizeof(s), "jpnhn24x.r%d", machine_id); fp = fopen(s, "w"); if (fp != NULL) { fwrite(OutData, 1, sizeof(FONTX2_HEADER) + 256 * 48, fp); } fclose(fp); return; } unsigned char *loadfile(char *filename) { FILE *fp; unsigned char *buf; off_t filesize; fp = fopen(filename, "r"); if (fp == NULL) { // fprintf(stderr, "loadfile: %s open error\n", filename); buf = NULL; goto fin0; } fseek(fp, 0, SEEK_END); filesize = ftello(fp); fseek(fp, 0, SEEK_SET); buf = calloc(filesize, 1); if (buf == NULL) goto fin1; fread(buf, filesize, 1, fp); fin1: fclose(fp); fin0: return buf; } /* entry */ int main(int argc, char *argv[]) { InData = loadfile("0314_0315_0317.bin"); if (InData == NULL) { InData = loadfile("0319_0320_0323.bin"); InData2 = loadfile("jw-r55f-jis2.img"); machine_id = 55; } else { InData2 = loadfile("jw-r50f-jis2.img"); machine_id = 50; } if (InData == NULL || InData2 == NULL) { fprintf(stderr, "file not found\n"); goto fin0; } convert_ascii(); convert_kanji(); fin0: free(InData2); free(InData); return 0; }