Support Unicode symbols in VESA modes

This commit is contained in:
Ray Chason
2022-10-08 18:50:38 -04:00
parent 334fd76ab4
commit fb88488583
5 changed files with 419 additions and 44 deletions

View File

@@ -16,13 +16,14 @@
#include "vesa.h"
#include "wintty.h"
#include "tileset.h"
#include "font.h"
#define FIRST_TEXT_COLOR 240
extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */
struct VesaCharacter {
int colour;
int chr;
uint32 chr;
};
static unsigned long vesa_SetWindow(int window, unsigned long offset);
@@ -47,13 +48,13 @@ static boolean vesa_SetHardPalette(const struct Pixel *);
static boolean vesa_SetSoftPalette(const struct Pixel *);
static void vesa_DisplayCell(int, int, int);
static unsigned vesa_FindMode(unsigned long mode_addr, unsigned bits);
static void vesa_WriteChar(int, int, int, int);
static void vesa_WriteCharXY(int, int, int, int);
static void vesa_WriteChar(uint32, int, int, int);
static void vesa_WriteCharXY(uint32, int, int, int);
static void vesa_WriteCharTransparent(int, int, int, int);
static void vesa_WriteTextRow(int pixx, int pixy,
struct VesaCharacter const *t_row, unsigned t_row_width);
static boolean vesa_GetCharPixel(int, unsigned, unsigned);
static unsigned char vesa_GetCharPixelRow(int, unsigned, unsigned);
static unsigned char vesa_GetCharPixelRow(uint32, unsigned, unsigned);
static unsigned long vesa_DoublePixels(unsigned long);
static unsigned long vesa_TriplePixels(unsigned long);
static void vesa_WriteStr(const char *, int, int, int, int);
@@ -81,7 +82,7 @@ static unsigned char __far *font;
static struct map_struct {
int glyph;
int ch;
uint32 ch;
int attr;
unsigned special;
short int tileidx;
@@ -151,6 +152,7 @@ static unsigned vesa_char_width = 8, vesa_char_height = 16;
static unsigned vesa_oview_width, vesa_oview_height;
static unsigned char **vesa_tiles;
static unsigned char **vesa_oview_tiles;
static struct BitmapFont *vesa_font;
#ifdef SIMULATE_CURSOR
static unsigned long *undercursor;
@@ -670,12 +672,17 @@ vesa_xputc(char ch, int attr)
void
vesa_xputg(const glyph_info *glyphinfo)
{
int glyphnum = glyphinfo->glyph, ch = glyphinfo->ttychar;
int glyphnum = glyphinfo->glyph;
uint32 ch = (uchar) glyphinfo->ttychar;
unsigned special = glyphinfo->gm.glyphflags;
int col, row;
int attr;
int ry;
if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) {
ch = glyphinfo->gm.u->utf32ch;
}
row = currow;
col = curcol;
if ((col < 0 || col >= COLNO)
@@ -689,7 +696,7 @@ vesa_xputg(const glyph_info *glyphinfo)
attr = (g_attribute == 0) ? attrib_gr_normal : g_attribute;
map[ry][col].attr = attr;
if (iflags.traditional_view) {
vesa_WriteChar((unsigned char) ch, col, row, attr);
vesa_WriteChar(ch, col, row, attr);
} else {
if ((col >= clipx) && (col <= clipxmax)
&& (ry >= clipy) && (ry <= clipymax)) {
@@ -1011,6 +1018,7 @@ vesa_Init(void)
unsigned i;
unsigned num_pixels, num_oview_pixels;
const char *tile_file;
const char *font_name;
int tilefailure = 0;
if (inited) return;
@@ -1090,22 +1098,48 @@ vesa_Init(void)
vesa_oview_height = (unsigned) iflags.wc_tile_height;
}
/* Use the map font size to set the font size */
/* Supported sizes are 8x16, 16x32, 24x48 and 32x64 */
vesa_char_height = iflags.wc_fontsiz_map;
if (vesa_char_height <= 0 || vesa_char_height > vesa_y_res / 30) {
vesa_char_height = vesa_y_res / 30;
}
if (vesa_char_height < 32) {
vesa_char_height = 16;
} else if (vesa_char_height < 48) {
vesa_char_height = 32;
} else if (vesa_char_height < 64) {
vesa_char_height = 48;
/* Load a font of size appropriate to the screen size */
if (vesa_x_res >= 1280 && vesa_y_res >= 960)
font_name = "ter-u32b.psf";
else if (vesa_x_res >= 1120 && vesa_y_res >= 840)
font_name = "ter-u28b.psf";
else if (vesa_x_res >= 960 && vesa_y_res >= 720)
font_name = "ter-u24b.psf";
else if (vesa_x_res >= 880 && vesa_y_res >= 660)
font_name = "ter-u22b.psf";
else if (vesa_x_res >= 800 && vesa_y_res >= 600)
font_name = "ter-u20b.psf";
else if (vesa_x_res >= 720 && vesa_y_res >= 540)
font_name = "ter-u18b.psf";
else
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(vesa_font);
vesa_font = load_font(font_name);
/* if load_font fails, vesa_font is NULL and we'll fall back to the font
defined in ROM */
if (vesa_font != NULL) {
vesa_char_width = vesa_font->width;
vesa_char_height = vesa_font->height;
} else {
vesa_char_height = 64;
/* Use the map font size to set the font size */
/* Supported sizes are 8x16, 16x32, 24x48 and 32x64 */
vesa_char_height = iflags.wc_fontsiz_map;
if (vesa_char_height <= 0 || vesa_char_height > vesa_y_res / 30) {
vesa_char_height = vesa_y_res / 30;
}
if (vesa_char_height < 32) {
vesa_char_height = 16;
} else if (vesa_char_height < 48) {
vesa_char_height = 32;
} else if (vesa_char_height < 64) {
vesa_char_height = 48;
} else {
vesa_char_height = 64;
}
vesa_char_width = vesa_char_height / 2;
}
vesa_char_width = vesa_char_height / 2;
/* Process tiles for the current video mode */
vesa_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *));
@@ -1508,7 +1542,7 @@ vesa_FindMode(unsigned long mode_addr, unsigned bits)
*
*/
static void
vesa_WriteChar(int chr, int col, int row, int colour)
vesa_WriteChar(uint32 chr, int col, int row, int colour)
{
int pixx, pixy;
@@ -1527,7 +1561,7 @@ vesa_WriteChar(int chr, int col, int row, int colour)
* transparency
*/
static void
vesa_WriteCharXY(int chr, int pixx, int pixy, int colour)
vesa_WriteCharXY(uint32 chr, int pixx, int pixy, int colour)
{
/* Flush if cache is full or if not contiguous to the last character */
if (chr_cache_size >= SIZE(chr_cache)) {
@@ -1604,7 +1638,7 @@ vesa_WriteTextRow(int pixx, int pixy, struct VesaCharacter const *t_row,
/* Second loop: draw one raster line of one character */
x = 0;
for (i = 0; i < t_row_width; ++i) {
int chr = t_row[i].chr;
uint32 chr = t_row[i].chr;
int colour = t_row[i].colour + FIRST_TEXT_COLOR;
/* Preprocess the foreground color */
if (vesa_pixel_bytes == 1) {
@@ -1655,8 +1689,9 @@ vesa_GetCharPixel(int ch, unsigned x, unsigned y)
}
static unsigned char
vesa_GetCharPixelRow(int ch, unsigned x, unsigned y)
vesa_GetCharPixelRow(uint32 ch, unsigned x, unsigned y)
{
unsigned fnt_width;
unsigned x1;
unsigned char fnt;
size_t offset;
@@ -1664,30 +1699,38 @@ vesa_GetCharPixelRow(int ch, unsigned x, unsigned y)
if (x >= vesa_char_width) return 0;
if (y >= vesa_char_height) return 0;
fnt_width = (vesa_char_width + 7) / 8;
x1 = x / 8;
const unsigned char __far *fp;
if (vesa_font != NULL) {
const unsigned char *fp;
if (ch < 0 || 255 < ch) return FALSE;
offset = ch * 16 + (y * 16 / vesa_char_height);
fp = font;
fnt = READ_ABSOLUTE((fp + offset));
offset = y * fnt_width + x1;
fp = get_font_glyph(vesa_font, ch, SYMHANDLING(H_UTF8));
fnt = fp[offset];
} else {
const unsigned char __far *fp;
if (vesa_char_width != 8) {
unsigned long fnt2 = fnt;
unsigned width = vesa_char_width;
if (width % 3 == 0) {
fnt2 = vesa_TriplePixels(fnt2);
width /= 3;
if (255 < ch) return 0;
offset = (ch * vesa_char_height + y) * fnt_width + x1;
fp = font;
fnt = READ_ABSOLUTE((fp + offset));
if (vesa_char_width != 8) {
unsigned long fnt2 = fnt;
unsigned width = vesa_char_width;
if (width % 3 == 0) {
fnt2 = vesa_TriplePixels(fnt2);
width /= 3;
}
while (width > 8) {
fnt2 = vesa_DoublePixels(fnt2);
width /= 2;
}
fnt2 <<= 32 - vesa_char_width;
fnt = (unsigned char)(fnt2 >> (24 - 8 * x1));
}
while (width > 8) {
fnt2 = vesa_DoublePixels(fnt2);
width /= 2;
}
fnt2 <<= 32 - vesa_char_width;
fnt = (unsigned char)(fnt2 >> (24 - 8 * x1));
}
return fnt;
}