#include "compiler.h"
#include "common.h"
#include "dosio.h"
#include "fontdata.h"
#include "font.h"
typedef struct {
int adrs;
int data;
int size;
} FONTPATCH;
static FONTPATCH patchx1[] = {
{0x00, 0x20, 0x1b},
{0x1b, 0x1b, 0x05},
{0x7f, 0x79, 0x01},
{0x80, 0x40, 0x0f},
{0x8f, 0x6e, 0x01},
{0x90, 0x85, 0x0f},
{0x9f, 0x6f, 0x01},
{0xe0, 0x6c, 0x02},
{0xe2, 0x68, 0x04},
{0xe6, 0x64, 0x02},
{0xe8, 0x70, 0x01},
{0xe9, 0x7a, 0x08},
{0xf1, 0x3b, 0x05},
{0xf6, 0x73, 0x05},
{0xfb, 0x72, 0x01},
{0xfc, 0x71, 0x01},
{0xfd, 0x82, 0x03}};
static FONTPATCH patchx68[] = {
{0x00, 0x00, 0x20},
{0x0b, 0x94, 0x02},
{0x80, 0x96, 0x03}};
static FONTPATCH patchx68h[] = {
{0x86, 0x99, 0x0a},
{0x91, 0xa3, 0x0f},
{0xe0, 0xb2, 0x1e}};
static BYTE jis90_83[] = "ιΛιςεyβ}σζ|θςαζεAθΥζΛβαθ·ηε’wΤεMβΔ";
static BYTE jis90_90[] = "±§ahΑΠz{ΗxGΩvτOχU";
static BYTE jis83_78[] = "Δy";
static BYTE jis83_83[] = "κκ κ‘κ’"; // © PC-98ΕJ΅Δι©ηΗίρc
static char *str_x68k[15] = {
"@@@@@@@@@@@@¨©ͺ«",
"@Ihfij{C|D^",
"OPQRSTUVWXGFH",
"`abcdefghijklmn",
"opqrstuvwxymnOQ",
"e
",
"obpP@",
"@@@@@@π‘£₯§αγεΑ",
"@ ’€¦¨©«―±³΅·Ή»",
"@BuvAE@BDFH
b",
"[ACEGIJLNPRTVXZ\",
"^`cegijklmnqtwz}",
"~JK",
"½ΏΒΔΖΘΙΚΛΜΝΠΣΦΩά",
"έήίΰβδζηθικλνρ@@"};
// ------------------------------------------------------------------------
static int getmonobmpsize(int x, int y) {
return(sizeof(BITMAPINFOHEADER) + 4*2 +
(((x + 31) / 8) & ~3) * y);
}
static void setmonobmphead(BITMAPINFO *bi, int x, int y) {
BYTE i;
ZeroMemory(&bi->bmiHeader, sizeof(BITMAPINFOHEADER));
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi->bmiHeader.biWidth = x;
bi->bmiHeader.biHeight = y;
bi->bmiHeader.biPlanes = 1;
bi->bmiHeader.biBitCount = 1;
bi->bmiHeader.biCompression = BI_RGB;
bi->bmiHeader.biSizeImage = (((x + 31) / 8) & ~3) * y;
bi->bmiHeader.biXPelsPerMeter = 0;
bi->bmiHeader.biYPelsPerMeter = 0;
bi->bmiHeader.biClrUsed = 2;
bi->bmiHeader.biClrImportant = 2;
for (i=0; i<2; i++) {
bi->bmiColors[i].rgbRed = (i ^ 1) - 1;
bi->bmiColors[i].rgbGreen = (i ^ 1) - 1;
bi->bmiColors[i].rgbBlue = (i ^ 1) - 1;
bi->bmiColors[i].rgbReserved = PC_RESERVED;
}
}
// ---------------------------------------------------------------------------
static LABEL WORD __fastcall jis2sjisex(WORD jis) {
__asm {
mov ax, cx
xor dl, dl
add ah, 21h
test ah, 1
je short jis2sjis1a
mov dl, 5eh
jis2sjis1a: sar ah, 1
add al, dl
xor ah, 20h
or ah, 80h
cmp al, 60h
jb short jis2sjis1b
inc al
jis2sjis1b: add al, 1fh
xchg al, ah
ret
}
}
static WORD jis2sjis(WORD jis, BYTE jistype) {
if (jis < 0x2121) {
return(0x4081);
}
else if (jis < 0x3021) {
BYTE jisl = (BYTE)jis;
switch(jis & 0xff00) {
case 0x2100:
break;
case 0x2200:
if (jisl < 0x2f) {
break;
}
if ((jistype & FONT_JIS78) || (jisl < 0x3a)) {
return(0x4081);
}
else if (jisl < 0x42) {
break;
}
else if (jisl < 0x4a) {
return(0x4081);
}
else if (jisl < 0x51) {
break;
}
else if (jisl < 0x5c) {
return(0x4081);
}
else if (jisl < 0x6b) {
break;
}
else if (jisl < 0x72) {
return(0x4081);
}
else if (jisl < 0x7a) {
break;
}
else if (jisl < 0x7e) {
return(0x4081);
}
break;
case 0x2300:
if (jisl < 0x30) {
return(0x4081);
}
else if (jisl < 0x3a) {
break;
}
else if (jisl < 0x41) {
return(0x4081);
}
else if (jisl < 0x5b) {
break;
}
else if ((jisl < 0x61) || (jisl > 0x7a)) {
return(0x4081);
}
break;
case 0x2400:
if (jisl > 0x73) {
return(0x4081);
}
break;
case 0x2500:
if (jisl > 0x76) {
return(0x4081);
}
break;
case 0x2600:
if (((jisl > 0x38) && (jisl < 0x41)) || (jisl > 0x58)) {
return(0x4081);
}
break;
case 0x2700:
if (((jisl > 0x41) && (jisl < 0x51)) || (jisl > 0x71)) {
return(0x4081);
}
break;
case 0x2800:
return(0x4081);
case 0x2d00:
if ((jisl == 0x3f) || (jisl > 0x7c) ||
((jisl > 0x56) && (jisl < 0x5f))) {
return(0x4081);
}
break;
default:
return(0x4081);
}
return(jis2sjisex(jis));
}
else if (jis < 0x4f54) {
return(jis2sjisex(jis));
}
else if (jis < 0x5021) {
return(0x4081);
}
else if (jis < 0x737f) {
return(jis2sjisex(jis));
}
else if (jis < 0x7921) {
if ((jistype & (FONT_JIS83 | FONT_JIS90)) &&
(jis >= 0x7421) && (jis <= 0x7424)) {
return(jis2sjisex(jis));
}
return(0x4081);
}
else if (jis < 0x7c6f) {
return(jis2sjisex(jis));
}
else if (jis < 0x7c71) {
return(0x4081);
}
else if (jis < 0x7c7f) {
return(jis2sjisex(jis));
}
return(0x4081);
}
static void cnvjis78_83(char *str) {
int i;
while((*str) && (*(str+1))) {
// jis78¨jis83
for (i=0; jis83_78[i]; i+=2) {
if (*(WORD *)str == *(WORD *)(&jis83_78[i])) {
*(WORD *)str = *(WORD *)(&jis83_83[i]);
break;
}
}
str += 2;
}
}
static void cnvjis83_90(char *str) {
int i;
while((*str) && (*(str+1))) {
// jis83©¨jis90
for (i=0; jis90_83[i]; i+=2) {
if (*(WORD *)str == *(WORD *)(&jis90_83[i])) {
*(WORD *)str = *(WORD *)(&jis90_90[i]);
break;
}
if (*(WORD *)str == *(WORD *)(&jis90_90[i])) {
*(WORD *)str = *(WORD *)(&jis90_83[i]);
break;
}
}
str += 2;
}
}
// ---------------------------------------------------------------------------
static BOOL getfont_sub(BYTE *dest, char *str, char *fontname,
int fntx, int fnty, int bmpx, int bmpy) {
HDC hdc;
HDC hdcimage;
HANDLE hwork;
BITMAPINFO *work;
HBITMAP hBitmap;
HBITMAP hBitmapbak;
BYTE *image;
HFONT hfont;
HFONT hfontbak;
RECT rect;
SetRect(&rect, 0, 0, bmpx, bmpy);
if ((hwork = GlobalAlloc(GPTR, getmonobmpsize(bmpx, bmpy))) == NULL) {
return(FAILURE);
}
if ((work = (BITMAPINFO *)GlobalLock(hwork)) == NULL) {
GlobalFree(hwork);
return(FAILURE);
}
setmonobmphead(work, bmpx, bmpy);
hdc = GetDC(NULL);
hBitmap = CreateDIBSection(hdc, work, DIB_RGB_COLORS,
(void **)&image, NULL, 0);
hdcimage = CreateCompatibleDC(hdc);
ReleaseDC(NULL, hdc);
hBitmapbak = (HBITMAP)SelectObject(hdcimage, hBitmap);
SetDIBColorTable(hdcimage, 0, 2, work->bmiColors);
hfont = CreateFont(fnty, fntx, FW_DONTCARE, FW_DONTCARE, FW_REGULAR,
FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
NONANTIALIASED_QUALITY, FIXED_PITCH, fontname);
hfontbak = (HFONT)SelectObject(hdcimage, hfont);
SetTextColor(hdcimage, RGB(255, 255, 255));
SetBkColor(hdcimage, RGB(0, 0, 0));
FillRect(hdcimage, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
TextOut(hdcimage, 0, 0, str, strlen(str));
CopyMemory(dest, image, (((bmpx + 31) / 8) & ~3) * bmpy);
SelectObject(hdcimage, hBitmapbak);
DeleteObject(hBitmap);
DeleteDC(hdcimage);
GlobalUnlock(hwork);
GlobalFree(hwork);
return(SUCCESS);
}
static BOOL getfont(BYTE *dest, char *fontname, int base,
int size, BYTE jistype) {
int i;
char textbuf[256];
if (!base) {
for (i=0; i<0x5f; i++) {
textbuf[i] = (BYTE)(i + 0x20);
}
textbuf[0x5f] = ' ';
textbuf[0x60] = ' ';
for (i=0x01; i<0x40; i++) {
textbuf[i+0x60] = (BYTE)(i + 0xa0);
}
textbuf[0xa0] = '\0';
}
else {
*(WORD *)textbuf = 0x4081;
for (i=1; i<0x5f; i++) {
((WORD *)textbuf)[i] = jis2sjis((base << 8) + i + 0x20, jistype);
}
textbuf[i*2] = '\0';
if (jistype & FONT_JIS78) {
cnvjis78_83(textbuf);
}
if (jistype & (FONT_JIS78 | FONT_JIS83)) {
cnvjis83_90(textbuf);
}
}
return(getfont_sub(dest, textbuf, fontname,
size, size*2, size*256, size*2));
}
// --------------------------------------------------------------------------
static void patchext2dat(BYTE *dst, FONTPATCH *src, int length) {
BYTE *p, *q;
int i;
int size;
length /= sizeof(FONTPATCH);
for (i=0; i<length; i++) {
p = ext8 + (src[i].data * 8);
q = dst + (src[i].adrs * 8);
size = src[i].size * 8;
CopyMemory(q, p, size);
}
}
static void patchank2dat(BYTE *dst, FONTPATCH *src, int length) {
BYTE *p, *q;
int i;
int size;
length /= sizeof(FONTPATCH);
for (i=0; i<length; i++) {
p = (BYTE *)(&ext16[src[i].data * 8]);
q = dst + (src[i].adrs * 16);
size = src[i].size * 16;
CopyMemory(q, p, size);
}
}
// --------------------------------------------------------------------------
#if 0
static LABEL WORD __fastcall jis2sjisx(WORD jis) {
__asm {
mov ax, cx
xor dl, dl
add ah, 21h
test ah, 1
je short jis2sjis1a
mov dl, 5eh
jis2sjis1a: sar ah, 1
add al, dl
xor ah, 20h
or ah, 80h
cmp al, 60h
jb short jis2sjis1b
inc al
jis2sjis1b: add al, 1fh
ret
}
}
static void cpyknj2x1fnt(BYTE *dst, BYTE *src, int jish) {
BYTE *q;
WORD sjis;
int i, j;
jish <<= 8;
for (i=0x01; i<0x5f; i++) {
src += 2;
q = NULL;
sjis = jis2sjisx((WORD)(jish + i + 0x20));
if (sjis >= 0x8140 && sjis < 0x84c0) {
q = dst + 0x00000 + ((DWORD)(sjis - 0x8140) << 5);
}
else if (sjis >= 0x8890 && sjis < 0xa000) {
q = dst + 0x07000 + ((DWORD)(sjis - 0x8890) << 5);
}
else if (sjis >= 0xe040 && sjis < 0xeab0) {
q = dst + 0x35e00 + ((DWORD)(sjis - 0xe040) << 5);
}
if (q) {
for (j=0; j<16; j++) {
*(WORD *)q = *(WORD *)(&src[(15-j)*256]);
q += 2;
}
}
}
}
BOOL makex1font(char *dirname, char *fontface) {
HANDLE hwork;
BYTE *work;
FILEH fh;
BYTE fnt[256*16];
int i, j;
BYTE *p;
BYTE *q;
int jish;
if ((hwork = GlobalAlloc(GPTR, 306176)) == NULL) {
return(FAILURE);
}
if ((work = (BYTE *)GlobalLock(hwork)) == NULL) {
GlobalFree(hwork);
return(FAILURE);
}
ZeroMemory(work, 0x800);
CopyMemory(work + 0x20*8, ank8, 0x60*8);
CopyMemory(work + 0xa0*8, ank8+0x60*8, 0x40*8);
patchext2dat(work, patchx1, sizeof(patchx1));
strcpy((char *)fnt, dirname);
strcat((char *)fnt, "FNT0808.X1");
if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
file_write(fh, work, 0x800);
file_close(fh);
}
ZeroMemory(work, 0x1000);
getfont(fnt, fontface, 0, 8, FONT_JIS78);
p = fnt;
q = work + 0x20*16;
for (j=0x20; j<0x7f; j++, p++) {
for (i=0; i<16; i++) {
*q++ = p[(15-i)*256];
}
}
p = fnt + 0x61;
q = work + 0xa1*16;
for (j=0xa1; j<0xe0; j++, p++) {
for (i=0; i<16; i++) {
*q++ = p[(15-i)*256];
}
}
patchank2dat(work, patchx1, sizeof(patchx1));
strcpy((char *)fnt, dirname);
strcat((char *)fnt, "FNT0816.X1");
if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
file_write(fh, work, 0x1000);
file_close(fh);
}
ZeroMemory(work, 306176);
for (jish=0x01; jish<0x74; jish++) {
getfont(fnt, fontface, jish+0x20, 8, FONT_JIS78);
cpyknj2x1fnt(work, fnt, jish+0x20);
}
strcpy((char *)fnt, dirname);
strcat((char *)fnt, "FNT1616.X1");
if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
file_write(fh, work, 306176);
file_close(fh);
}
GlobalUnlock(hwork);
GlobalFree(hwork);
return(SUCCESS);
}
#endif
// --------------------------------------------------------------------------
static void cpysmall2cgrom(BYTE *dst, BYTE *src, int line) {
int i, j;
dst += 0x5e * 32 * line;
for (i=0; i<0x5e; i++) {
src += 2;
for (j=16; j--;) {
*(WORD *)dst = *(WORD *)(src + j * 256);
dst += 2;
}
}
}
static void cpybig2cgrom(BYTE *dst, BYTE *src, int line) {
int i, j;
dst += 0x5e * 72 * line;
for (i=0; i<0x5e; i++) {
src += 3;
for (j=24; j--;) {
*dst++ = *(src + j * 384 + 0);
*dst++ = *(src + j * 384 + 1);
*dst++ = *(src + j * 384 + 2);
}
}
}
static void cpy12fnt2cgrom(BYTE *dst, BYTE *src, int y) {
int i, j;
for (i=0; i<8; i++) {
for (j=0; j<y; j++) {
*(WORD *)dst = (*(WORD *)(&src[(23-j)*32])) & 0xf0ff;
dst += 2;
}
for (j=0; j<y; j++) {
*dst++ = (src[(23-j)*32+1] << 4) | (src[(23-j)*32+2] >> 4);
*dst++ = (src[(23-j)*32+2] << 4);
}
src += 3;
}
}
BOOL makecgromdat(char *dirname, char *fontface) {
HANDLE hwork;
BYTE *work;
FILEH fh;
BYTE fnt[24*256*24/8];
int i, j;
BYTE *p;
BYTE *q;
int jish;
if ((hwork = GlobalAlloc(GPTR, 0xc0000)) == NULL) {
return(FAILURE);
}
if ((work = (BYTE *)GlobalLock(hwork)) == NULL) {
GlobalFree(hwork);
return(FAILURE);
}
ZeroMemory(work, 0xc0000);
// 8x8
CopyMemory(work + 0x3a000 + 0x20*8, ank8, 0x60*8);
CopyMemory(work + 0x3a000 + 0xa0*8, ank8+0x60*8, 0x40*8);
patchext2dat(work + 0x3a000, patchx68, sizeof(patchx68));
patchext2dat(work + 0x3a000, patchx68h, sizeof(patchx68h));
// 8x16
getfont(fnt, fontface, 0, 8, FONT_JIS90);
p = fnt;
q = work + 0x3a800 + 0x20*16;
for (j=0x20; j<0x7f; j++, p++) {
for (i=0; i<16; i++) {
*q++ = p[(15-i)*256];
}
}
p = fnt + 0x61;
q = work + 0x3a800 + 0xa1*16;
for (j=0xa1; j<0xe0; j++, p++) {
for (i=0; i<16; i++) {
*q++ = p[(15-i)*256];
}
}
patchank2dat(work + 0x3a800, patchx68, sizeof(patchx68));
patchank2dat(work + 0x3a800, patchx68h, sizeof(patchx68h));
// 16x16
for (jish=0; jish<7; jish++) {
getfont(fnt, fontface, jish+0x21, 8, FONT_JIS90);
cpysmall2cgrom(work, fnt, jish);
}
for (jish=0; jish<0x45; jish++) {
getfont(fnt, fontface, jish+0x30, 8, FONT_JIS90);
cpysmall2cgrom(work, fnt, jish+8);
}
CopyMemory(work + 0x5e*32*7, x68k16, 32*32);
// 24x24
for (jish=0; jish<7; jish++) {
getfont(fnt, fontface, jish+0x21, 12, FONT_JIS90);
cpybig2cgrom(work + 0x40000, fnt, jish);
}
for (jish=0; jish<0x45; jish++) {
getfont(fnt, fontface, jish+0x30, 12, FONT_JIS90);
cpybig2cgrom(work + 0x40000, fnt, jish+8);
}
CopyMemory(work + 0x40000 + 0x5e*72*7, x68k24, 72*32);
// 12x12
for (i=0; i<0x0f; i++) {
getfont_sub(fnt, str_x68k[i], fontface, 6, 12, 256, 24);
cpy12fnt2cgrom(work + 0x3b800 + (i+1)*24*16, fnt, 12);
}
CopyMemory(work + 0x3b800 + 24*1, x68c12, 24*0x1b);
CopyMemory(work + 0x3b800 + 24*0x80, &x68c12[0x1b*24/2], 24*0x03);
// 12x24
for (i=0; i<0x0f; i++) {
getfont_sub(fnt, str_x68k[i], fontface, 6, 24, 256, 24);
cpy12fnt2cgrom(work + 0x3d000 + (i+1)*16*2*24, fnt, 24);
}
CopyMemory(work + 0x3d000 + 48*1, x68c24, 48*0x1b);
CopyMemory(work + 0x3d000 + 48*0x80, &x68c24[0x1b*48/2], 48*0x03);
strcpy((char *)fnt, dirname);
strcat((char *)fnt, "CGROM.DAT");
if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
file_write(fh, work, 0xc0000);
file_close(fh);
}
GlobalUnlock(hwork);
GlobalFree(hwork);
return(SUCCESS);
}
RetroPC.NET-CVS <cvs@retropc.net>