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 "tile.h"
#include "tileset.h"
#include "font.h"
#include <dos.h>
#include <ctype.h>
@@ -123,7 +124,8 @@ static void vga_DisplayCell_O(struct overview_planar_cell_struct *, int,
int);
static void vga_SwitchMode(unsigned int);
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 read_planar_tile(unsigned, struct planar_cell_struct *);
@@ -149,13 +151,14 @@ extern glyph_map glyphmap[MAX_GLYPH];
* Global Variables
*/
static unsigned char __far *font;
static unsigned char __far *rom_font;
static struct BitmapFont *psf_font;
static char *screentable[SCREENHEIGHT];
static const struct Pixel *paletteptr;
static struct map_struct {
int glyph;
int ch;
uint32 ch;
int attr;
unsigned special;
short int tileidx;
@@ -363,12 +366,18 @@ void vga_xputc(char ch, int attr)
void
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;
int col, row;
int attr;
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 0
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].tileidx = glyphinfo->gm.tileidx;
if (iflags.traditional_view) {
vga_WriteChar((unsigned char) ch, col, row, attr);
vga_WriteChar(ch, col, row, attr);
} else if (!iflags.over_view) {
if ((col >= clipx) && (col <= clipxmax)) {
read_planar_tile(glyphnum, &planecell);
@@ -479,7 +488,7 @@ vga_redrawmap(boolean clearfirst)
#endif
if (iflags.traditional_view) {
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);
} else {
t = map[y][x].glyph;
@@ -723,6 +732,7 @@ void
vga_Init(void)
{
int i;
const char *font_name;
#ifdef USE_TILES
const char *tile_file;
@@ -773,7 +783,21 @@ vga_Init(void)
#endif
vga_SetPalette(paletteptr);
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();
clipx = 0;
clipxmax = clipx + (viewport_size - 1);
@@ -910,22 +934,23 @@ vga_detect(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 x, pixy;
char __far *cp;
unsigned char __far *fp = font;
unsigned char fnt;
int actual_colour = vgacmap[colour];
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 */
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;
if (vplane != 0) {
egawriteplane(vplane);
@@ -939,7 +964,7 @@ vga_WriteChar(int chr, int col, int row, int colour)
egawriteplane(vplane);
for (i = 0; i < MAX_ROWS_PER_CELL; ++i) {
cp = screentable[pixy + i] + x;
fnt = READ_ABSOLUTE((fp + chr + i));
fnt = bitmap[i];
WRITE_ABSOLUTE(cp, (char) fnt);
}
}
@@ -948,7 +973,7 @@ vga_WriteChar(int chr, int col, int row, int colour)
egawriteplane(vplane);
for (i = 0; i < MAX_ROWS_PER_CELL; ++i) {
cp = screentable[pixy + i] + x;
fnt = ~READ_ABSOLUTE((fp + chr + i));
fnt = ~bitmap[i];
WRITE_ABSOLUTE(cp, (char) fnt);
}
}
@@ -963,6 +988,28 @@ vga_WriteChar(int chr, int col, int row, int colour)
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'
* at the desired location (col,row).
@@ -1045,7 +1092,7 @@ vga_WriteStr(char *s, int len, int col, int row, int colour)
i = 0;
us = (unsigned char *) s;
while ((*us != 0) && (i < len) && (col < (CO - 1))) {
vga_WriteChar(*us, col, row, colour);
vga_WriteChar((uchar) *us, col, row, colour);
++us;
++i;
++col;
@@ -1221,6 +1268,9 @@ vga_special(int chr, int col, int color)
int vplane;
char fnt;
char bits[SCREENPLANES][ROWS_PER_CELL];
unsigned char bitmap[ROWS_PER_CELL];
vga_GetBitmap(chr, bitmap);
pixy = PBAR_ROW * MAX_ROWS_PER_CELL;
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) {
tmp_d = screentable[y++] + col;
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)
bits[vplane][i] |= fnt;
else