/* RIPFONT.C by John Elliott, November 2003. This program is public domain, please copy! Note: Must be compiled by a large-model compiler (I used Pacific C). */ #include #include #include #include #include typedef void (*DRAWFUNC)(int row, int col, unsigned char c); void drawch_cga(int row, int col, unsigned char c); void drawch_herc(int row, int col, unsigned char c); void drawch_3270(int row, int col, unsigned char c); void putscr(unsigned char *buf, int len); void getscr(unsigned char *buf, int len); typedef struct vid_data { int text_originx; int text_originy; int gfx_offsetx; int gfx_offsety; int char_height; int char_width; char *filename; int textmode; int gfxmode; int tscrlen; int char_wb; unsigned int vid_seg; unsigned int vid_len; DRAWFUNC drawc; } VID_DATA; VID_DATA vd_pc3270 = { 6, 6, 8, 13, 14, 9, "3270font.psf", 2, 6, 2048, 2, 0xB800, 0x4000, drawch_3270 }; VID_DATA vd_cga = { 0, 0, 0, 0, 8, 8, "cgafont.psf", 0, 5, 1024, 1, 0xB800, 0x4000, drawch_cga }; VID_DATA vd_mda = { 0, 0, 0, 0, 14, 9, "mdafont.psf", 7,-7, 2048, 2, 0xB000, 0x8000, drawch_herc }; VID_DATA *gl_vd; int gl_herc = 1; typedef struct psf2_header { long magic; long version; long hdrlen; long flags; long nchars; long charlen; long height; long width; } PSF2_HEADER; PSF2_HEADER psf2; #define PSF2_MAGIC (0x864ab572L) unsigned char textscr[2048]; unsigned char gfxscr[32768]; unsigned char fontbuf[8192]; typedef unsigned char far *PBYTE; PBYTE cdata; PBYTE graftabl; PBYTE *int1f; void sleep(int secs) { long t, t1; time(&t); while (secs) { time(&t1); if (t != t1) { --secs; t = t1; } } } void setcurpos(int row, int col) { union REGS rg; rg.x.ax = 0x200; rg.x.bx = 0x000; rg.h.dl = col; rg.h.dh = row; int86(0x10, &rg, &rg); } void drawch(int row, int col, unsigned char c) { union REGS rg; rg.x.ax = 0x200; rg.x.bx = 0x000; rg.h.dl = col; rg.h.dh = row; int86(0x10, &rg, &rg); rg.h.ah = 9; rg.h.al = c; rg.x.bx = 15; rg.x.cx = 1; int86(0x10, &rg, &rg); } void drawch_cga(int row, int col, unsigned char c) { *int1f = fontbuf + c * gl_vd->char_height * gl_vd->char_wb; drawch(row, col, 0x80); } void drawch_3270(int row, int col, unsigned char c) { int nr, nc; unsigned char smask, dmask, *chr, *chrbase; PBYTE scr; union REGS rgi; rgi.x.ax = 0x0C01; rgi.x.dx = row * gl_vd->char_height + gl_vd->gfx_offsety; chrbase = fontbuf + (c * gl_vd->char_wb * gl_vd->char_height); for (nr = 0; nr < gl_vd->char_height; nr++) { chr = chrbase + nr * gl_vd->char_wb; rgi.x.cx = col * gl_vd->char_width + gl_vd->gfx_offsetx; scr = MK_FP(gl_vd->vid_seg, 0); scr += (80 * (rgi.x.dx/2)); if (rgi.x.dx & 1) scr += 0x2000; scr += (rgi.x.cx / 8); smask = 0x80; dmask = 0x80>> (rgi.x.cx % 8); for (nc = 0; nc < gl_vd->char_width; nc++) { if (chr[0] & smask) scr[0] |= dmask; smask = smask>> 1; if (smask == 0) { smask = 0x80; chr++; } dmask = dmask>> 1; if (dmask == 0) { dmask = 0x80; scr++; } rgi.x.cx++; } rgi.x.dx++; } } void drawch_herc(int row, int col, unsigned char c) { int nr, nc; unsigned char smask, dmask, *chr, *chrbase; PBYTE scr; union REGS rgi; rgi.x.ax = 0x0C01; rgi.x.dx = row * gl_vd->char_height + gl_vd->gfx_offsety; chrbase = fontbuf + (c * gl_vd->char_wb * gl_vd->char_height); for (nr = 0; nr < gl_vd->char_height; nr++) { chr = chrbase + nr * gl_vd->char_wb; rgi.x.cx = col * gl_vd->char_width + gl_vd->gfx_offsetx; scr = MK_FP(gl_vd->vid_seg, 0); scr += (90 * (rgi.x.dx/4)) + (0x2000 * (rgi.x.dx % 4)); scr += (rgi.x.cx / 8); smask = 0x80; dmask = 0x80>> (rgi.x.cx % 8); for (nc = 0; nc < gl_vd->char_width; nc++) { if (chr[0] & smask) scr[0] |= dmask; smask = smask>> 1; if (smask == 0) { smask = 0x80; chr++; } dmask = dmask>> 1; if (dmask == 0) { dmask = 0x80; scr++; } rgi.x.cx++; } rgi.x.dx++; } } void drawstr(int r, int c, char *s) { while (*s) { drawch(r,c,*s); ++s; ++c; if (c == 40) { c = 0; ++r; } } } void mkdisp(int gfx) { int r,c,n; unsigned char ch = 0; if (gfx) { memset(gfxscr, 0, gl_vd->vid_len); putscr(gfxscr, gl_vd->vid_len); } for (r=c=n=0; n < 256; n++) { if (gfx) (*gl_vd->drawc)(r,c,ch); else drawch(gl_vd->text_originy + r, gl_vd->text_originx +c, ch); ++c; if (c == 40) { c=0; ++r; } ++ch; } } /* Using CGA mode 6, get the current ROS+GRAFTABL font combination. * Not very suitable for 9x14 fonts, but the best we can do. */ void getfont() { int n; unsigned char *pch; unsigned char *scr = MK_FP(gl_vd->vid_seg, 0); for (n = 0; n < 256; n++) { pch = fontbuf + n * gl_vd->char_wb * gl_vd->char_height; drawch(0, 0, n); pch[0*gl_vd->char_wb] = scr[0x0000]; pch[1*gl_vd->char_wb] = scr[0x2000]; pch[2*gl_vd->char_wb] = scr[0x0050]; pch[3*gl_vd->char_wb] = scr[0x2050]; pch[4*gl_vd->char_wb] = scr[0x00A0]; pch[5*gl_vd->char_wb] = scr[0x20A0]; pch[6*gl_vd->char_wb] = scr[0x00F0]; pch[7*gl_vd->char_wb] = scr[0x20F0]; } } static unsigned char herc_gfx_init[] = { 0x38, 0x2d, 0x30, 0x08, 0x5a, 0x00, 0x57, 0x57, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static unsigned char herc_txt_init[] = { 0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* static void herc_cls() { unsigned char * screen = MK_FP(0xB000, 0); memset(&screen[0], 0, 0x1eef); memset(&screen[0x2000], 0, 0x1eef); memset(&screen[0x4000], 0, 0x1eef); memset(&screen[0x6000], 0, 0x1eef); }*/ static void herc_gfxmode() { int i; union REGS regs; regs.x.ax = 7; int86(0x10, ®s, ®s); outp(0x3b8,0); outp(0x3bf,3); for (i=0; i<18; i++) { outp(0x3b4,i); outp(0x3b5,herc_gfx_init[i]); } outp(0x3b8,6); // herc_cls(); outp(0x3b8,14); } static void herc_txtmode() { int i; union REGS regs; regs.x.ax = 7; int86(0x10, ®s, ®s); outp(0x3bf,0); outp(0x3b8,0x28); for (i=0; i<18; i++) { outp(0x3b4,i); outp(0x3b5,herc_txt_init[i]); } } void setmode(int m) { union REGS rg; if (m == -7 && gl_herc) /* Herc graphics mode */ { herc_gfxmode(); return; } if (m == 7 && gl_herc) { herc_txtmode(); return; } if (m < 0) m = -m; rg.x.ax = m & 0xFF; int86(0x10, &rg, &rg); } unsigned char getmode() { union REGS rg; rg.x.ax = 0x0F00; int86(0x10, &rg, &rg); return rg.h.al; } void putscr(unsigned char *buf, int len) { void *scr = MK_FP(gl_vd->vid_seg, 0); memcpy(scr, buf, len); } void getscr(unsigned char *buf, int len) { void *scr = MK_FP(gl_vd->vid_seg, 0); memcpy(buf, scr, len); } void dotest(int slow) { setmode(gl_vd->textmode); mkdisp(0); getscr(textscr, gl_vd->tscrlen); setmode(gl_vd->gfxmode); mkdisp(1); getscr(gfxscr, gl_vd->vid_len); while (1) { setmode(gl_vd->textmode); putscr(textscr, gl_vd->tscrlen); if (slow) sleep(1); if (kbhit()) break; setmode(gl_vd->gfxmode); putscr(gfxscr, gl_vd->vid_len); if (kbhit()) break; if (slow) sleep(1); } getch(); /* Swallow the kbhit() */ setmode(gl_vd->textmode); } void draw_editor() { int n; setmode(gl_vd->textmode); drawstr(0,0, "Character editor"); drawch(2, 2,0xC9); drawch(2, 3+gl_vd->char_width,0xBB); drawch(3+gl_vd->char_height, 2,0xC8); drawch(3+gl_vd->char_height,3+gl_vd->char_width,0xBC); for (n = 0; n < gl_vd->char_height; n++) { if (n < gl_vd->char_width) { drawch(2, 3+n,0xCD); drawch(gl_vd->char_height+3, 3+n,0xCD); } drawch(3+n,2, 0xC7); drawch(3+n,gl_vd->char_width+3, 0xC7); } drawstr(gl_vd->char_height+4,0,"Cursors and SPACE to edit"); drawstr(gl_vd->char_height+5,0, "S/T to test with ROM font, ESC to exit"); } void draw_edchar(int nc) { int r,c; unsigned char mask; PBYTE pdata; drawch(8, 20, nc); for (r = 0; r < gl_vd->char_height; r++) { mask = 0x80; pdata = cdata + r*gl_vd->char_wb; for (c = 0; c < gl_vd->char_width; c++) { if ((*pdata) & mask) drawch(3+r,3+c,10); else drawch(3+r,3+c,7); mask = mask>> 1; if (mask == 0) { mask = 0x80; ++pdata; } } } } void edit_char(unsigned nc) { static int cx=0,cy=0, mask = 0x80; int n; PBYTE pdata; cdata = fontbuf + gl_vd->char_height * gl_vd->char_wb * nc; draw_editor(); draw_edchar(nc); while (1) { setcurpos(3+cy,3+cx); pdata = cdata + cy * gl_vd->char_wb + (cx/8); switch(getch()) { case '\r': case '\n': case 27: return; case ' ' : pdata[0] ^= mask; if (pdata[0] & mask) drawch(3+cy,3+cx,10); else drawch(3+cy,3+cx,7); break; case 'T': case 't': dotest(0); draw_editor(); draw_edchar(nc); break; case 'S': case 's': dotest(1); draw_editor(); draw_edchar(nc); break; case 'R': case 'r': for (n = 0; n < gl_vd->char_height * gl_vd->char_wb; n++) cdata[n] = cdata[n]>> 1; draw_edchar(nc); break; case 'L': case 'l': for (n = 0; n < gl_vd->char_height * gl_vd->char_wb; n++) cdata[n] = cdata[n] << 1; draw_edchar(nc); break; case 'U': case 'u': for (n = 0; n < (gl_vd->char_height-1) * gl_vd->char_wb; n++) { cdata[n] = cdata[n+gl_vd->char_wb]; } draw_edchar(nc); break; case 'D': case 'd': for (n = (gl_vd->char_height-1) * gl_vd->char_wb; n>= gl_vd->char_wb; n--) { cdata[n] = cdata[n-gl_vd->char_wb]; } draw_edchar(nc); break; case 0: switch(getch()) { case 0x4B: if (cx) { --cx; mask = mask << 1; if (mask>= 0x100) mask = 0x01; } break; case 0x4D: if (cx < (gl_vd->char_width-1)) { ++cx; mask = mask>> 1; if (mask == 0) mask = 0x80; } break; case 0x48: if (cy) --cy; break; case 0x50: if (cychar_height-1) ++cy; break; } } } } void draw_chooser() { setmode(gl_vd->textmode); drawstr(0, 0, "Choose character to edit"); /* 1...5...10...15...20...25...30...35...40 */ drawstr(gl_vd->char_height+2, 0, "Cursor keys to select, ENTER to edit"); drawstr(gl_vd->char_height+3, 0, "W to write font dump to disc"); drawstr(gl_vd->char_height+4, 0, "R to read previous font dump"); drawstr(gl_vd->char_height+5, 0, "S/T to test with ROM font, ESC to exit"); } void rdfont() { char fail[80]; PSF2_HEADER psfh; FILE *fp = fopen(gl_vd->filename, "rb"); int okay = 0; // This "do ... break ... break ... while (0)" construct is a fun // way of jumping to the end of the function if there's an error, // without doing anything so crass as a goto. do { sprintf(fail, "Could not open file %s", gl_vd->filename); if (!fp) break; sprintf(fail, "Read error on file %s", gl_vd->filename); if (fread(&psfh, 1, sizeof(psfh), fp) < (int)sizeof(psfh)) break; if (psfh.magic != PSF2_MAGIC) { sprintf(fail, "%s is not PSF2 ", gl_vd->filename); break; } if (psfh.version != 0) { sprintf(fail, "%s is version %ld", gl_vd->filename, psfh.version); break; } if (psfh.hdrlen != sizeof(PSF2_HEADER)) { sprintf(fail, "%s header not 32", gl_vd->filename); break; } if (psfh.height != gl_vd->char_height || psfh.width != gl_vd->char_width) { sprintf(fail, "%s is %ldx%ld not %dx%d", gl_vd->filename, psfh.width, psfh.height, gl_vd->char_width, gl_vd->char_height); break; } if ( psfh.charlen != gl_vd->char_height * gl_vd->char_wb) { sprintf(fail, "%s is %ld not %d", gl_vd->filename, psfh.charlen, gl_vd->char_height * gl_vd->char_wb); break; } if (psfh.nchars> 256) psfh.nchars = 256; if (fread(fontbuf, psfh.charlen, psfh.nchars, fp) < psfh.nchars) { strcpy(fail, "Unexpected EOF"); break; } fclose(fp); sprintf(fail, "%s has been read.", gl_vd->filename); okay = 1; } while (0); drawstr(gl_vd->char_height+6, 0, fail); drawstr(gl_vd->char_height+6, 32, " [SPACE]"); getch(); drawstr(gl_vd->char_height+6, 0, " "); } void wrfont() { int okay = 1; char fail[80]; FILE *fp = fopen(gl_vd->filename, "rb"); if (fp) { char c; fclose(fp); sprintf(fail, "%s exists - delete (Y/N)?", gl_vd->filename); drawstr(gl_vd->char_height+6, 0, fail); do { c = getch(); if (c == 'N' || c == 'n') { drawstr(gl_vd->char_height+6, 0, " "); return; } } while (c != 'y' && c != 'Y'); drawstr(gl_vd->char_height+6, 0, " "); remove(gl_vd->filename); } fp = fopen(gl_vd->filename, "wb"); if (fp) { /* Emit a PSF header */ psf2.magic = PSF2_MAGIC; psf2.version = 0; psf2.hdrlen = sizeof(PSF2_HEADER); psf2.flags = 0; psf2.nchars = 256; psf2.charlen = gl_vd->char_height * gl_vd->char_wb; psf2.height = gl_vd->char_height; psf2.width = gl_vd->char_width; okay = (fwrite(&psf2, 1, sizeof(psf2), fp) == sizeof(psf2)); if (okay) okay = (fwrite(fontbuf, psf2.charlen, 256, fp) == 256); fclose(fp); } else okay = 0; if (okay) sprintf(fail, "%s was saved.", gl_vd->filename); else sprintf(fail, "%s was not saved.", gl_vd->filename); drawstr(gl_vd->char_height+6, 0, fail); drawstr(gl_vd->char_height+6, 32, " [SPACE]"); getch(); drawstr(gl_vd->char_height+6, 0, " "); } int choose_char() { static unsigned int nchar = 0; char buf[8]; draw_chooser(); while (1) { sprintf(buf, "%03d: %c", nchar, nchar); drawstr(5, 5, buf); switch(getch()) { case 'T': case 't': dotest(0); draw_chooser(); break; case 'S': case 's': dotest(1); draw_chooser(); break; case 'R': case 'r': rdfont(); break; case 'W': case 'w': wrfont(); break; case 27: return -1; case '\n': case '\r': return nchar; case 0: switch(getch()) { case 0x4D: if (nchar < 255) ++nchar; break; case 0x4B: if (nchar> 0) --nchar; break; } } } return -1; } void probe_video() { union REGS rg; if (getmode() == 7) { gl_vd = &vd_mda; return; } rg.x.ax = 0x3000; rg.x.cx = 0; rg.x.dx = 0; int86(0x10, &rg, &rg); if (rg.x.cx || rg.x.dx) { gl_vd = &vd_pc3270; return; } gl_vd = &vd_cga; return; } int main(int argc, char **argv) { int n, nc; unsigned char mode = getmode(); for (n = 1; n < argc; n++) { if (!strcmp(argv[n], "+h")) gl_herc = 1; if (!strcmp(argv[n], "-h")) gl_herc = 0; if (!strcmp(argv[n], "+H")) gl_herc = 1; if (!strcmp(argv[n], "-H")) gl_herc = 0; } probe_video(); int1f = MK_FP(0, 0x7C); setmode(6); /* Deliberately not gl_vd->gfxmode */ graftabl = *int1f; getfont(); setmode(gl_vd->textmode); while ((nc = choose_char()) != -1) { edit_char(nc); } setmode(6); *int1f = graftabl; setmode(mode); return 0; }

AltStyle によって変換されたページ (->オリジナル) /