Support Unicode symbols in 16 color mode

This commit is contained in:
Ray Chason
2022-10-08 19:41:22 -04:00
parent fb88488583
commit 6400ce073a

View File

@@ -11,6 +11,7 @@
#include "pcvideo.h" #include "pcvideo.h"
#include "tile.h" #include "tile.h"
#include "tileset.h" #include "tileset.h"
#include "font.h"
#include <dos.h> #include <dos.h>
#include <ctype.h> #include <ctype.h>
@@ -123,7 +124,8 @@ static void vga_DisplayCell_O(struct overview_planar_cell_struct *, int,
int); int);
static void vga_SwitchMode(unsigned int); static void vga_SwitchMode(unsigned int);
static void vga_SetPalette(const struct Pixel *); static void vga_SetPalette(const struct Pixel *);
static void vga_WriteChar(int, int, int, int); static void vga_WriteChar(uint32, int, int, int);
static void vga_GetBitmap(uint32, unsigned char *);
static void vga_WriteStr(char *, int, int, int, int); static void vga_WriteStr(char *, int, int, int, int);
static void read_planar_tile(unsigned, struct planar_cell_struct *); static void read_planar_tile(unsigned, struct planar_cell_struct *);
@@ -149,13 +151,14 @@ extern glyph_map glyphmap[MAX_GLYPH];
* Global Variables * Global Variables
*/ */
static unsigned char __far *font; static unsigned char __far *rom_font;
static struct BitmapFont *psf_font;
static char *screentable[SCREENHEIGHT]; static char *screentable[SCREENHEIGHT];
static const struct Pixel *paletteptr; static const struct Pixel *paletteptr;
static struct map_struct { static struct map_struct {
int glyph; int glyph;
int ch; uint32 ch;
int attr; int attr;
unsigned special; unsigned special;
short int tileidx; short int tileidx;
@@ -363,12 +366,18 @@ void vga_xputc(char ch, int attr)
void void
vga_xputg(const glyph_info *glyphinfo) vga_xputg(const glyph_info *glyphinfo)
{ {
int glyphnum = glyphinfo->glyph, ch = glyphinfo->ttychar; int glyphnum = glyphinfo->glyph;
uint32 ch = glyphinfo->ttychar;
unsigned special = glyphinfo->gm.glyphflags; unsigned special = glyphinfo->gm.glyphflags;
int col, row; int col, row;
int attr; int attr;
int ry; int ry;
if (psf_font != NULL && SYMHANDLING(H_UTF8) && glyphinfo->gm.u
&& glyphinfo->gm.u->utf8str) {
ch = glyphinfo->gm.u->utf32ch;
}
/* If statue glyph, map to the generic statue */ /* If statue glyph, map to the generic statue */
#if 0 #if 0
if (GLYPH_STATUE_OFF <= glyphnum && glyphnum < GLYPH_STATUE_OFF + NUMMONS) { if (GLYPH_STATUE_OFF <= glyphnum && glyphnum < GLYPH_STATUE_OFF + NUMMONS) {
@@ -389,7 +398,7 @@ vga_xputg(const glyph_info *glyphinfo)
map[ry][col].attr = attr; map[ry][col].attr = attr;
map[ry][col].tileidx = glyphinfo->gm.tileidx; map[ry][col].tileidx = glyphinfo->gm.tileidx;
if (iflags.traditional_view) { if (iflags.traditional_view) {
vga_WriteChar((unsigned char) ch, col, row, attr); vga_WriteChar(ch, col, row, attr);
} else if (!iflags.over_view) { } else if (!iflags.over_view) {
if ((col >= clipx) && (col <= clipxmax)) { if ((col >= clipx) && (col <= clipxmax)) {
read_planar_tile(glyphnum, &planecell); read_planar_tile(glyphnum, &planecell);
@@ -479,7 +488,7 @@ vga_redrawmap(boolean clearfirst)
#endif #endif
if (iflags.traditional_view) { if (iflags.traditional_view) {
if (!(clearfirst && map[y][x].ch == S_stone)) if (!(clearfirst && map[y][x].ch == S_stone))
vga_WriteChar((unsigned char) map[y][x].ch, x, vga_WriteChar(map[y][x].ch, x,
y + TOP_MAP_ROW, map[y][x].attr); y + TOP_MAP_ROW, map[y][x].attr);
} else { } else {
t = map[y][x].glyph; t = map[y][x].glyph;
@@ -723,6 +732,7 @@ void
vga_Init(void) vga_Init(void)
{ {
int i; int i;
const char *font_name;
#ifdef USE_TILES #ifdef USE_TILES
const char *tile_file; const char *tile_file;
@@ -773,7 +783,21 @@ vga_Init(void)
#endif #endif
vga_SetPalette(paletteptr); vga_SetPalette(paletteptr);
g_attribute = attrib_gr_normal; g_attribute = attrib_gr_normal;
font = (unsigned char __far *) vga_FontPtrs(); rom_font = (unsigned char __far *) vga_FontPtrs();
/* Load an external font if requested */
font_name = "ter-u16v.psf";
if (iflags.wc_font_map != NULL && iflags.wc_font_map[0] != '\0') {
font_name = iflags.wc_font_map;
}
free_font(psf_font);
psf_font = load_font(font_name);
if (psf_font->width != 8 || psf_font->height != 16) {
raw_printf("VGA mode only supports 8x16 fonts");
free_font(psf_font);
psf_font = NULL;
}
clear_screen(); clear_screen();
clipx = 0; clipx = 0;
clipxmax = clipx + (viewport_size - 1); clipxmax = clipx + (viewport_size - 1);
@@ -910,22 +934,23 @@ vga_detect(void)
* *
*/ */
static void static void
vga_WriteChar(int chr, int col, int row, int colour) vga_WriteChar(uint32 chr, int col, int row, int colour)
{ {
int i; int i;
int x, pixy; int x, pixy;
char __far *cp; char __far *cp;
unsigned char __far *fp = font;
unsigned char fnt; unsigned char fnt;
int actual_colour = vgacmap[colour]; int actual_colour = vgacmap[colour];
int vplane; int vplane;
unsigned char bitmap[ROWS_PER_CELL];
/* if (chr < ' ') chr = ' '; */ /* assumes ASCII set */
vga_GetBitmap(chr, bitmap);
x = min(col, (CO - 1)); /* min() used protection from callers */ x = min(col, (CO - 1)); /* min() used protection from callers */
pixy = min(row, (LI - 1)) * 16; /* assumes 8 x 16 char set */ pixy = min(row, (LI - 1)) * 16; /* assumes 8 x 16 char set */
/* if (chr < ' ') chr = ' '; */ /* assumes ASCII set */
chr = chr << 4;
vplane = ~actual_colour & ~BACKGROUND_VGA_COLOR & 0xF; vplane = ~actual_colour & ~BACKGROUND_VGA_COLOR & 0xF;
if (vplane != 0) { if (vplane != 0) {
egawriteplane(vplane); egawriteplane(vplane);
@@ -939,7 +964,7 @@ vga_WriteChar(int chr, int col, int row, int colour)
egawriteplane(vplane); egawriteplane(vplane);
for (i = 0; i < MAX_ROWS_PER_CELL; ++i) { for (i = 0; i < MAX_ROWS_PER_CELL; ++i) {
cp = screentable[pixy + i] + x; cp = screentable[pixy + i] + x;
fnt = READ_ABSOLUTE((fp + chr + i)); fnt = bitmap[i];
WRITE_ABSOLUTE(cp, (char) fnt); WRITE_ABSOLUTE(cp, (char) fnt);
} }
} }
@@ -948,7 +973,7 @@ vga_WriteChar(int chr, int col, int row, int colour)
egawriteplane(vplane); egawriteplane(vplane);
for (i = 0; i < MAX_ROWS_PER_CELL; ++i) { for (i = 0; i < MAX_ROWS_PER_CELL; ++i) {
cp = screentable[pixy + i] + x; cp = screentable[pixy + i] + x;
fnt = ~READ_ABSOLUTE((fp + chr + i)); fnt = ~bitmap[i];
WRITE_ABSOLUTE(cp, (char) fnt); WRITE_ABSOLUTE(cp, (char) fnt);
} }
} }
@@ -963,6 +988,28 @@ vga_WriteChar(int chr, int col, int row, int colour)
egawriteplane(15); egawriteplane(15);
} }
/*
* Given the character, return the bitmap that displays that character
*/
static void
vga_GetBitmap(uint32 chr, unsigned char *bitmap)
{
unsigned i;
if (psf_font) {
unsigned char const *fp = get_font_glyph(psf_font, chr,
SYMHANDLING(H_UTF8));
for (i = 0; i < ROWS_PER_CELL; ++i) {
bitmap[i] = fp[i];
}
} else {
unsigned char const __far *fp = rom_font + chr * ROWS_PER_CELL;
for (i = 0; i < ROWS_PER_CELL; ++i) {
bitmap[i] = READ_ABSOLUTE((fp + i));
}
}
}
/* /*
* This is the routine that displays a high-res "cell" pointed to by 'gp' * This is the routine that displays a high-res "cell" pointed to by 'gp'
* at the desired location (col,row). * at the desired location (col,row).
@@ -1045,7 +1092,7 @@ vga_WriteStr(char *s, int len, int col, int row, int colour)
i = 0; i = 0;
us = (unsigned char *) s; us = (unsigned char *) s;
while ((*us != 0) && (i < len) && (col < (CO - 1))) { while ((*us != 0) && (i < len) && (col < (CO - 1))) {
vga_WriteChar(*us, col, row, colour); vga_WriteChar((uchar) *us, col, row, colour);
++us; ++us;
++i; ++i;
++col; ++col;
@@ -1221,6 +1268,9 @@ vga_special(int chr, int col, int color)
int vplane; int vplane;
char fnt; char fnt;
char bits[SCREENPLANES][ROWS_PER_CELL]; char bits[SCREENPLANES][ROWS_PER_CELL];
unsigned char bitmap[ROWS_PER_CELL];
vga_GetBitmap(chr, bitmap);
pixy = PBAR_ROW * MAX_ROWS_PER_CELL; pixy = PBAR_ROW * MAX_ROWS_PER_CELL;
for (vplane = 0; vplane < SCREENPLANES; ++vplane) { for (vplane = 0; vplane < SCREENPLANES; ++vplane) {
@@ -1229,7 +1279,7 @@ vga_special(int chr, int col, int color)
for (i = 0; i < ROWS_PER_CELL; ++i) { for (i = 0; i < ROWS_PER_CELL; ++i) {
tmp_d = screentable[y++] + col; tmp_d = screentable[y++] + col;
bits[vplane][i] = READ_ABSOLUTE(tmp_d); bits[vplane][i] = READ_ABSOLUTE(tmp_d);
fnt = READ_ABSOLUTE((font + ((chr << 4) + i))); fnt = READ_ABSOLUTE((rom_font + ((chr << 4) + i)));
if (colorbits[vplane] & color) if (colorbits[vplane] & color)
bits[vplane][i] |= fnt; bits[vplane][i] |= fnt;
else else