/* * --- public domain, no warranty. */ #include #include #include #include /* FONTX2 header */ #define CODETYPE_ASCII 0 #define CODETYPE_KANJI 1 /* common */ typedef struct { uint8_t identifier[6]; uint8_t fontname[8]; uint8_t xsize; uint8_t ysize; uint8_t codetype; } __attribute__((packed)) FONTX2_HEADER; /* sjis */ typedef struct { FONTX2_HEADER h; uint8_t tnum; uint8_t d[1]; } __attribute__((packed)) FONTX2_KANJI; typedef struct { uint16_t start; uint16_t end; } __attribute__((packed)) FONTX2_CODETABLE; static FONTX2_CODETABLE CodeTable_SJIS1[] = { {0x8140, 0x817e}, {0x8180, 0x81ac}, /* symbol */ {0x81b8, 0x81bf}, {0x81c8, 0x81ce}, {0x81da, 0x81e8}, {0x81f0, 0x81fc}, {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) */ {0x8440, 0x8460}, /* russian (large) */ {0x8470, 0x847e}, {0x8480, 0x8491}, /* russian (small) */ {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}, }; /* font data buffer */ #define BUFFERSIZE (65536) static uint8_t Buf[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; } /* 24bit(12x2) -> 32bit(16x2) */ static void decode_kanji(uint8_t *outbuf, uint8_t *inbuf) { int i, n; for (i = 0; i < 6; i++) { n = (inbuf[0] << 16) | (inbuf[1] << 8) | inbuf[2]; outbuf[0] = (n >> 16) & 0xff; outbuf[1] = (n >> 8) & 0xf0; outbuf[2] = (n >> 4) & 0xff; outbuf[3] = (n << 4) & 0xf0; inbuf += 3; outbuf += 4; } return; } /* 24bit(6x4) -> 32bit(8x4) */ static void decode_ank(uint8_t *outbuf, uint8_t *inbuf) { int i; uint32_t n; for (i = 0; i < 3; i++) { n = (inbuf[0] << 16) | (inbuf[1] << 8) | inbuf[2]; outbuf[0] = (n >> 16) & 0xfc; outbuf[1] = (n >> 10) & 0xfc; outbuf[2] = (n >> 4) & 0xfc; outbuf[3] = (n << 2) & 0xfc; inbuf += 3; outbuf += 4; } return; } static void convert_kanji(uint8_t *buf) { int i, j, jis, ku, ten, ix; uint8_t n, d[24]; FILE *fp; FONTX2_HEADER h; fp = fopen("mfan12x12.fnt", "wb"); if (fp == NULL) goto fin0; /* header */ strncpy(h.identifier, "FONTX2", sizeof(h.identifier)); strncpy(h.fontname, "MSXFAN ", sizeof(h.fontname)); h.xsize = 12; h.ysize = 12; h.codetype = CODETYPE_KANJI; fwrite(&h, sizeof(h), 1, fp); n = sizeof(CodeTable_SJIS1) / sizeof(FONTX2_CODETABLE); fputc(n, fp); fwrite(CodeTable_SJIS1, sizeof(CodeTable_SJIS1), 1, fp); for (i = 0; i < n; i++) { for (j = CodeTable_SJIS1[i].start; j <= CodeTable_SJIS1[i].end; j++) { jis = _mbcjmstojis(j); ku = ((jis >> 8) & 0xff) - 0x20; ten = (jis & 0xff) - 0x20; if (ku >= 16) ku -= 8; ix = (ku - 1) * 94 + (ten - 1); decode_kanji(d, &buf[ix * 18]); fwrite(d, sizeof(d), 1, fp); } } fclose(fp); fin0: return; } static void convert_ank(uint8_t *buf) { int i; uint8_t d[12]; FILE *fp; FONTX2_HEADER h; fp = fopen("mfan6x12.fnt", "wb"); if (fp == NULL) goto fin0; /* header */ strncpy(h.identifier, "FONTX2", sizeof(h.identifier)); strncpy(h.fontname, "MSXFAN ", sizeof(h.fontname)); h.xsize = 6; h.ysize = 12; h.codetype = CODETYPE_ASCII; fwrite(&h, sizeof(h), 1, fp); /* 0x00-0x1f: blank */ memset(d, 0, sizeof(d)); for (i = 0x00; i < 0x20; i++) fwrite(d, sizeof(d), 1, fp); /* 0x20-0x7f */ for (i = 0x20; i < 0x80; i++) { decode_ank(d, &buf[(i - 0x20) * 9]); fwrite(d, sizeof(d), 1, fp); } /* 0x80-0x9f: blank */ memset(d, 0, sizeof(d)); for (i = 0x80; i < 0xa0; i++) fwrite(d, sizeof(d), 1, fp); /* 0xa0-0xdf */ for (i = 0xa0; i < 0xe0; i++) { decode_ank(d, &buf[(i - 0xa0 + 0x60) * 9]); fwrite(d, sizeof(d), 1, fp); } /* 0xe0-ff: blank */ memset(d, 0, sizeof(d)); for (i = 0xe0; i < 0x100; i++) fwrite(d, sizeof(d), 1, fp); fclose(fp); fin0: return; } static int bload(char *filename, uint8_t *buf, int size) { int result; FILE *fp; fp = fopen(filename, "rb"); if (fp == NULL) { result = -1; goto fin0; } fread(buf, 1, 7, fp); /* discard BSAVE header */ fread(buf, 1, size, fp); fclose(fp); result = 0; fin0: return result; } int main(int argc, char *argv[]) { if (bload("FONT0612.BIN", Buf, 1440) < 0) { printf("FONT0612.BIN not found\n"); goto fin0; } convert_ank(Buf); if (bload("font12-0.sc7", Buf, 32768) < 0) { printf("font12-0.sc7 not found\n"); goto fin0; } if (bload("font12-1.sc7", Buf + 32768, 32768) < 0) { printf("font12-1.sc7 not found\n"); goto fin0; } convert_kanji(Buf); fin0: return 0; }