Merge branch 'dos-tty-unicode' of https://github.com/chasonr/NetHack into pr899
This commit is contained in:
@@ -202,7 +202,7 @@ U = $(UTIL)/
|
||||
# Utility Objects.
|
||||
#==========================================
|
||||
|
||||
VGAOBJ = $(O)vidvga.o $(O)vidvesa.o
|
||||
VGAOBJ = $(O)vidvga.o $(O)vidvesa.o $(O)font.o
|
||||
|
||||
MAKESRC = makedefs.c
|
||||
|
||||
@@ -601,9 +601,7 @@ ifdef CWSDPMI
|
||||
else
|
||||
@$(subst /,\,echo Could not find a copy of CWSDPMI.EXE to put into $(GAMEDIR))
|
||||
endif
|
||||
ifdef WANT_DOSVGA
|
||||
@$(subst /,\,copy $(MSYS)/fonts/*.psf $(GAMEDIR))
|
||||
endif
|
||||
@$(subst /,\,echo install done > $@)
|
||||
|
||||
#==========================================
|
||||
@@ -925,7 +923,6 @@ $(O)luac.o: $(LUASRC)/luac.c
|
||||
# Fonts for Unicode support
|
||||
#==========================================
|
||||
|
||||
ifdef WANT_DOSVGA
|
||||
$(O)fonts.tag: lua.exe $(MSYS)/fonts/makefont.lua
|
||||
lua $(MSYS)/fonts/makefont.lua $(FONTTOP)/ter-u16b.bdf $(MSYS)/fonts/ter-u16b.psf
|
||||
lua $(MSYS)/fonts/makefont.lua $(FONTTOP)/ter-u16v.bdf $(MSYS)/fonts/ter-u16v.psf
|
||||
@@ -936,10 +933,6 @@ $(O)fonts.tag: lua.exe $(MSYS)/fonts/makefont.lua
|
||||
lua $(MSYS)/fonts/makefont.lua $(FONTTOP)/ter-u28b.bdf $(MSYS)/fonts/ter-u28b.psf
|
||||
lua $(MSYS)/fonts/makefont.lua $(FONTTOP)/ter-u32b.bdf $(MSYS)/fonts/ter-u32b.psf
|
||||
@echo Fonts done >$(O)fonts.tag
|
||||
else
|
||||
$(O)fonts.tag:
|
||||
@echo Fonts not needed >$(O)fonts.tag
|
||||
endif
|
||||
|
||||
#==========================================
|
||||
# Housekeeping.
|
||||
@@ -1052,6 +1045,9 @@ $(O)vidvesa.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/
|
||||
$(O)vidtxt.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidtxt.c
|
||||
# $(CC) $(cflags) -o$@ -I$(MSYS) $(MSYS)/vidtxt.c
|
||||
|
||||
$(O)font.o : $(HACK_H) $(MSYS)/font.h $(MSYS)/font.c
|
||||
$(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/font.c
|
||||
|
||||
$(O)stubvid.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/video.c
|
||||
$(CC) $(cflags) -I$(MSYS) -DSTUBVIDEO -o$@ $(MSYS)/video.c
|
||||
|
||||
|
||||
276
sys/msdos/font.c
Executable file
276
sys/msdos/font.c
Executable file
@@ -0,0 +1,276 @@
|
||||
/* Maintain a data structure describing a monospaced bitmap font */
|
||||
|
||||
#include "hack.h"
|
||||
#include "integer.h"
|
||||
#include "font.h"
|
||||
|
||||
static uint32 read_u32(const unsigned char *);
|
||||
static void add_unicode_index(
|
||||
struct BitmapFont *font,
|
||||
uint32 ch,
|
||||
unsigned index);
|
||||
static uint32 *uni_8to32(const char *);
|
||||
|
||||
struct BitmapFont *
|
||||
load_font(const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
struct BitmapFont *font = NULL;
|
||||
unsigned char header[32];
|
||||
size_t size;
|
||||
uint32 magic;
|
||||
uint32 version;
|
||||
uint32 headersize;
|
||||
uint32 flags;
|
||||
uint32 length;
|
||||
uint32 charsize;
|
||||
uint32 height;
|
||||
uint32 width;
|
||||
uint32 bwidth, memsize;
|
||||
uint32 i;
|
||||
|
||||
fp = fopen(filename, "rb");
|
||||
if (fp == NULL) goto error;
|
||||
|
||||
/* Read the PSF header */
|
||||
size = fread(header, 1, sizeof(header), fp);
|
||||
if (size != sizeof(header)) goto error;
|
||||
|
||||
/* Convert from little endian order */
|
||||
magic = read_u32(header + 0);
|
||||
if (magic != 0x864AB572) goto error;
|
||||
version = read_u32(header + 4);
|
||||
if (version != 0) goto error;
|
||||
headersize = read_u32(header + 8);
|
||||
if (headersize < sizeof(header)) goto error;
|
||||
flags = read_u32(header + 12);
|
||||
length = read_u32(header + 16);
|
||||
charsize = read_u32(header + 20);
|
||||
height = read_u32(header + 24);
|
||||
width = read_u32(header + 28);
|
||||
|
||||
/* Check that the declared character size can hold the declared width
|
||||
and height */
|
||||
bwidth = (width + 7) / 8;
|
||||
memsize = bwidth * height;
|
||||
if (memsize > charsize) goto error;
|
||||
|
||||
/* Allocate a font structure */
|
||||
font = (struct BitmapFont *) alloc(sizeof(struct BitmapFont));
|
||||
memset(font, 0, sizeof(struct BitmapFont));
|
||||
|
||||
/* Dimensions of the font */
|
||||
font->width = width;
|
||||
font->height = height;
|
||||
font->num_glyphs = length;
|
||||
|
||||
/* The glyph array */
|
||||
font->glyphs = (unsigned char **) alloc(length * sizeof(unsigned char *));
|
||||
memset(font->glyphs, 0, length * sizeof(unsigned char *));
|
||||
|
||||
/* Read the glyphs */
|
||||
fseek(fp, headersize, SEEK_SET);
|
||||
for (i = 0; i < length; ++i) {
|
||||
font->glyphs[i] = (unsigned char *) alloc(memsize);
|
||||
size = fread(font->glyphs[i], 1, memsize, fp);
|
||||
if (size != memsize) goto error;
|
||||
fseek(fp, charsize - memsize, SEEK_CUR);
|
||||
}
|
||||
|
||||
if (flags & 0x01) {
|
||||
/* Read the Unicode table */
|
||||
char buf[128], buf2[128+1];
|
||||
unsigned bufsize, strsize;
|
||||
char *p;
|
||||
uint32 *codepoints;
|
||||
|
||||
bufsize = 0;
|
||||
i = 0;
|
||||
while (i < length) {
|
||||
unsigned j;
|
||||
|
||||
size = fread(buf + bufsize, 1, sizeof(buf) - bufsize, fp);
|
||||
if (ferror(fp)) goto error;
|
||||
bufsize += size;
|
||||
if (bufsize == 0) goto error; /* unexpected EOF */
|
||||
|
||||
p = memchr(buf, 0xFF, bufsize);
|
||||
if (p != NULL) { /* end marker found */
|
||||
strsize = p - buf;
|
||||
memcpy(buf2, buf, strsize);
|
||||
buf2[strsize] = '\0';
|
||||
bufsize -= strsize + 1;
|
||||
memmove(buf, buf + strsize + 1, bufsize);
|
||||
} else { /* partial string */
|
||||
strsize = bufsize - 1;
|
||||
/* Roll back to character boundary in case of partial character */
|
||||
while (strsize != 0 && (buf[strsize] & 0xC0) == 0x80)
|
||||
--strsize;
|
||||
if (strsize == 0) /* avoid infinite loop */
|
||||
strsize = (bufsize < 4) ? bufsize : 4;
|
||||
memcpy(buf2, buf, strsize);
|
||||
buf2[strsize] = '\0';
|
||||
bufsize -= strsize;
|
||||
memmove(buf, buf + strsize, bufsize);
|
||||
}
|
||||
codepoints = uni_8to32(buf2);
|
||||
for (j = 0; codepoints[j] != 0; ++j) {
|
||||
add_unicode_index(font, codepoints[j], i);
|
||||
}
|
||||
free(codepoints);
|
||||
if (p != NULL)
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
/* Fake a Unicode table, assuming that ASCII glyphs are in the
|
||||
expected places */
|
||||
for (i = 0x20; i <= 0x7E; ++i) {
|
||||
add_unicode_index(font, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return font;
|
||||
|
||||
error:
|
||||
if (fp != NULL) fclose(fp);
|
||||
free_font(font);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
free_font(struct BitmapFont *font)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
if (font == NULL) return;
|
||||
|
||||
if (font->glyphs != NULL) {
|
||||
for (i = 0; i < font->num_glyphs; ++i)
|
||||
free(font->glyphs[i]);
|
||||
free(font->glyphs);
|
||||
}
|
||||
|
||||
for (i = 0; i < SIZE(font->unicode); ++i) {
|
||||
if (font->unicode[i] == NULL) continue;
|
||||
for (j = 0; j < 256; ++j)
|
||||
free(font->unicode[i][j]);
|
||||
free(font->unicode[i]);
|
||||
}
|
||||
|
||||
free(font);
|
||||
}
|
||||
|
||||
const unsigned char *
|
||||
get_font_glyph(struct BitmapFont *font, uint32 ch, boolean unicode)
|
||||
{
|
||||
unsigned index;
|
||||
|
||||
if (unicode) {
|
||||
index = 0;
|
||||
if (ch <= 0x10FFFF && (ch & 0xFFFFD800) != 0xD800) {
|
||||
unsigned i, j, k;
|
||||
|
||||
i = (unsigned) (ch >> 16);
|
||||
j = (unsigned) ((ch >> 8) & 0xFF);
|
||||
k = (unsigned) (ch & 0xFF);
|
||||
if (font->unicode[i] != NULL
|
||||
&& font->unicode[i][j] != NULL) {
|
||||
index = font->unicode[i][j][k];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
index = ch;
|
||||
}
|
||||
|
||||
if (index >= font->num_glyphs)
|
||||
index = 0;
|
||||
|
||||
return font->glyphs[index];
|
||||
}
|
||||
|
||||
static void
|
||||
add_unicode_index(struct BitmapFont *font, uint32 ch, unsigned index)
|
||||
{
|
||||
unsigned i, j, k;
|
||||
|
||||
i = (unsigned) (ch >> 16);
|
||||
j = (unsigned) ((ch >> 8) & 0xFF);
|
||||
k = (unsigned) (ch & 0xFF);
|
||||
|
||||
if (font->unicode[i] == NULL) {
|
||||
/* Create the second level node */
|
||||
font->unicode[i] = (unsigned **) alloc(256 * sizeof(unsigned *));
|
||||
memset(font->unicode[i], 0, 256 * sizeof(unsigned *));
|
||||
}
|
||||
if (font->unicode[i][j] == NULL) {
|
||||
/* Create the third level node */
|
||||
font->unicode[i][j] = (unsigned *) alloc(256 * sizeof(unsigned));
|
||||
memset(font->unicode[i][j], 0, 256 * sizeof(unsigned));
|
||||
}
|
||||
font->unicode[i][j][k] = index;
|
||||
}
|
||||
|
||||
static uint32
|
||||
read_u32(const unsigned char *buf)
|
||||
{
|
||||
return ((uint32) buf[0] << 0)
|
||||
| ((uint32) buf[1] << 8)
|
||||
| ((uint32) buf[2] << 16)
|
||||
| ((uint32) buf[3] << 24);
|
||||
}
|
||||
|
||||
static uint32 *
|
||||
uni_8to32(const char *inp)
|
||||
{
|
||||
size_t i, j;
|
||||
uint32 *out;
|
||||
|
||||
/* Output string */
|
||||
out = (uint32 *) alloc((strlen(inp) + 1) * sizeof(out[0]));
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
while (inp[i] != 0) {
|
||||
unsigned char byte = inp[i++];
|
||||
uint32 ch32;
|
||||
uint32 min = 0;
|
||||
unsigned count = 0;
|
||||
|
||||
if (byte < 0x80) {
|
||||
ch32 = byte;
|
||||
} else if (byte < 0xC0) {
|
||||
ch32 = 0xFFFD;
|
||||
} else if (byte < 0xE0) {
|
||||
ch32 = byte & 0x1F;
|
||||
min = 0x80;
|
||||
count = 1;
|
||||
} else if (byte < 0xF0) {
|
||||
ch32 = byte & 0x0F;
|
||||
min = 0x800;
|
||||
count = 2;
|
||||
} else if (byte < 0xF5) {
|
||||
ch32 = byte & 0x07;
|
||||
min = 0x10000;
|
||||
count = 3;
|
||||
} else {
|
||||
ch32 = 0xFFFD;
|
||||
}
|
||||
|
||||
for (; count != 0; --count) {
|
||||
byte = inp[i];
|
||||
if ((byte & 0xC0) != 0x80) {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
ch32 = (ch32 << 6) | (byte & 0x3F);
|
||||
}
|
||||
if (count != 0 || ch32 < min || ((ch32 & 0xFFFFF800) == 0xD800)) {
|
||||
ch32 = 0xFFFD;
|
||||
}
|
||||
out[j++] = ch32;
|
||||
}
|
||||
|
||||
out[j] = 0;
|
||||
return out;
|
||||
}
|
||||
53
sys/msdos/font.h
Executable file
53
sys/msdos/font.h
Executable file
@@ -0,0 +1,53 @@
|
||||
/* Maintain a data structure describing a monospaced bitmap font */
|
||||
|
||||
#ifndef FONT_H
|
||||
#define FONT_H
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
/*
|
||||
* The file format is Linux PSF, version 2. Version 1 is not supported.
|
||||
* Actual Linux fonts are restricted to 256 or 512 glyphs; for NetHack, the
|
||||
* font can have any number of glyphs. The Unicode map is expected to be
|
||||
* present, but combining sequences are not supported.
|
||||
* The fonts supplied for use with this data structure have the first 256
|
||||
* glyphs arranged according to IBM code page 437, for simpler support of
|
||||
* the IBM handling mode for the map.
|
||||
*/
|
||||
|
||||
/* For Unicode lookup, a three level tree provides constant-time access to
|
||||
the glyphs without using an excessive amount of memory.
|
||||
The root has seventeen entries, one for each plane of Unicode. Most fonts
|
||||
will populate only plane 0, and Unicode defines only planes 0, 1, 2, 3, 15
|
||||
and 16.
|
||||
The second level has 256 entries, each pointing to a third level node with
|
||||
256 entries. Each third level entry has type unsigned, and gives the index
|
||||
of the glyph.
|
||||
Given the Unicode code point, we can use bits 20 through 16 to index the
|
||||
root, bits 15 through 8 for the second level and bits 7 through 0 for the
|
||||
third level. */
|
||||
|
||||
struct BitmapFont {
|
||||
/* Dimensions of a single glyph */
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
|
||||
/* The glyphs, in the order that they appear in the font */
|
||||
/* IBM handling will index the glyphs this way */
|
||||
/* glyph points to an allocated array, each element of which points to
|
||||
another allocated array */
|
||||
unsigned num_glyphs;
|
||||
unsigned char **glyphs;
|
||||
|
||||
/* The root node of the Unicode tree */
|
||||
unsigned **unicode[17];
|
||||
};
|
||||
|
||||
extern struct BitmapFont *load_font(const char *filename);
|
||||
extern void free_font(struct BitmapFont *font);
|
||||
extern const unsigned char *get_font_glyph(
|
||||
struct BitmapFont *font,
|
||||
uint32 ch,
|
||||
boolean unicode);
|
||||
|
||||
#endif
|
||||
@@ -476,6 +476,7 @@ tty_start_screen(void)
|
||||
void
|
||||
gr_init(void)
|
||||
{
|
||||
windowprocs.wincap2 &= ~WC2_U_24BITCOLOR;
|
||||
#ifdef SCREEN_VGA
|
||||
if (iflags.usevga) {
|
||||
vga_Init();
|
||||
|
||||
@@ -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 colour;
|
||||
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, uint32);
|
||||
static void vesa_WriteCharXY(uint32, int, int, uint32);
|
||||
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,8 +82,8 @@ static unsigned char __far *font;
|
||||
|
||||
static struct map_struct {
|
||||
int glyph;
|
||||
int ch;
|
||||
int attr;
|
||||
uint32 ch;
|
||||
uint32 attr;
|
||||
unsigned special;
|
||||
short int tileidx;
|
||||
} map[ROWNO][COLNO]; /* track the glyphs */
|
||||
@@ -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,24 @@ 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;
|
||||
uint32_t attr = (g_attribute == 0) ? attrib_gr_normal : g_attribute;
|
||||
int ry;
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) {
|
||||
ch = glyphinfo->gm.u->utf32ch;
|
||||
if (vesa_pixel_size > 8 && glyphinfo->gm.u->ucolor != 0) {
|
||||
/* FIXME: won't display black (0,0,0) correctly, but the background
|
||||
is usually black anyway */
|
||||
attr = glyphinfo->gm.u->ucolor | 0x80000000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
row = currow;
|
||||
col = curcol;
|
||||
if ((col < 0 || col >= COLNO)
|
||||
@@ -686,10 +700,9 @@ vesa_xputg(const glyph_info *glyphinfo)
|
||||
map[ry][col].ch = ch;
|
||||
map[ry][col].special = special;
|
||||
map[ry][col].tileidx = glyphinfo->gm.tileidx;
|
||||
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 +1024,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;
|
||||
@@ -1063,6 +1077,11 @@ vesa_Init(void)
|
||||
vesa_SwitchMode(vesa_mode);
|
||||
vesa_SetViewPort();
|
||||
windowprocs.win_cliparound = vesa_cliparound;
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (vesa_pixel_size > 8) {
|
||||
windowprocs.wincap2 |= WC2_U_24BITCOLOR;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_TILES
|
||||
paletteptr = get_palette();
|
||||
iflags.tile_view = TRUE;
|
||||
@@ -1090,22 +1109,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 *));
|
||||
@@ -1333,8 +1378,12 @@ vesa_detect(void)
|
||||
}
|
||||
|
||||
/* Scan the mode list for an acceptable mode */
|
||||
/* Choose the widest bit-width, even if the tile set can handle 8 bits,
|
||||
so that Unicode symbols can display in their colors */
|
||||
#ifndef ENHANCED_SYMBOLS
|
||||
if (get_palette() != NULL && vesa_mode == 0xFFFF)
|
||||
vesa_mode = vesa_FindMode(mode_addr, 8);
|
||||
#endif
|
||||
if (vesa_mode == 0xFFFF)
|
||||
vesa_mode = vesa_FindMode(mode_addr, 32);
|
||||
if (vesa_mode == 0xFFFF)
|
||||
@@ -1508,7 +1557,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, uint32 colour)
|
||||
{
|
||||
int pixx, pixy;
|
||||
|
||||
@@ -1527,7 +1576,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, uint32 colour)
|
||||
{
|
||||
/* Flush if cache is full or if not contiguous to the last character */
|
||||
if (chr_cache_size >= SIZE(chr_cache)) {
|
||||
@@ -1604,13 +1653,18 @@ 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;
|
||||
int colour = t_row[i].colour + FIRST_TEXT_COLOR;
|
||||
uint32 chr = t_row[i].chr;
|
||||
uint32 colour = t_row[i].colour;
|
||||
/* Preprocess the foreground color */
|
||||
if (vesa_pixel_bytes == 1) {
|
||||
fg[0] = colour;
|
||||
if (colour & 0x80000000) {
|
||||
fg[0] = colour & 0xFF;
|
||||
fg[1] = (colour >> 8) & 0xFF;
|
||||
fg[2] = (colour >> 16) & 0xFF;
|
||||
fg[3] = 0;
|
||||
} else if (vesa_pixel_bytes == 1) {
|
||||
fg[0] = colour + FIRST_TEXT_COLOR;
|
||||
} else {
|
||||
unsigned long pix = vesa_palette[colour];
|
||||
unsigned long pix = vesa_palette[colour + FIRST_TEXT_COLOR];
|
||||
fg[0] = pix & 0xFF;
|
||||
fg[1] = (pix >> 8) & 0xFF;
|
||||
fg[2] = (pix >> 16) & 0xFF;
|
||||
@@ -1655,8 +1709,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 +1719,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,20 @@ 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;
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (psf_font != NULL && SYMHANDLING(H_UTF8) && glyphinfo->gm.u
|
||||
&& glyphinfo->gm.u->utf8str) {
|
||||
ch = glyphinfo->gm.u->utf32ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If statue glyph, map to the generic statue */
|
||||
#if 0
|
||||
if (GLYPH_STATUE_OFF <= glyphnum && glyphnum < GLYPH_STATUE_OFF + NUMMONS) {
|
||||
@@ -389,7 +400,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 +490,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 +734,7 @@ void
|
||||
vga_Init(void)
|
||||
{
|
||||
int i;
|
||||
const char *font_name;
|
||||
|
||||
#ifdef USE_TILES
|
||||
const char *tile_file;
|
||||
@@ -773,7 +785,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 +936,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 +966,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 +975,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 +990,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 +1094,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 +1270,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 +1281,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
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
ifdef CROSS_TO_MSDOS
|
||||
#
|
||||
$(TARGETPFX)msdos.o : ../sys/msdos/msdos.c $(HACK_H)
|
||||
$(TARGETPFX)font.o : ../sys/msdos/font.c ../sys/msdos/font.h $(HACK_H)
|
||||
$(TARGETPFX)pckeys.o : ../sys/msdos/pckeys.c $(HACK_H)
|
||||
$(TARGETPFX)pctiles.o : ../sys/msdos/pctiles.c ../sys/msdos/portio.h $(HACK_H)
|
||||
$(TARGETPFX)video.o : ../sys/msdos/video.c ../sys/msdos/portio.h $(HACK_H)
|
||||
@@ -14,7 +15,7 @@ $(TARGETPFX)vidtxt.o : ../sys/msdos/vidtxt.c ../sys/msdos/portio.h \
|
||||
$(TARGETPFX)vidvga.o : ../sys/msdos/vidvga.c ../sys/msdos/portio.h \
|
||||
../win/share/tile.h ../include/tileset.h $(HACK_H)
|
||||
$(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \
|
||||
../win/share/tile.h ../include/tileset.h $(HACK_H)
|
||||
../win/share/tile.h ../include/tileset.h ../sys/msdos/font.h $(HACK_H)
|
||||
$(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \
|
||||
$(HACK_H)
|
||||
$(TARGETPFX)tile.o : tile.c
|
||||
@@ -42,11 +43,7 @@ $(FONTDIR)/ter-u32b.psf: $(FONTTOP)/ter-u32b.bdf $(FONTDIR)/makefont.lua $(LUABI
|
||||
$(LUABIN) $(FONTDIR)/makefont.lua $(FONTTOP)/ter-u32b.bdf $@
|
||||
#
|
||||
.PHONY: dodata dospkg dosfonts
|
||||
ifdef WANT_DOSVGA
|
||||
dosfonts: $(FONTTARGETS)
|
||||
else
|
||||
dosfonts:
|
||||
endif
|
||||
dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp
|
||||
$(TARGET_STUBEDIT) $(GAMEBIN) minstack=2048K
|
||||
mkdir -p $(TARGETPFX)pkg
|
||||
@@ -59,7 +56,6 @@ dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp
|
||||
cp ../sys/share/NetHack.cnf $(TARGETPFX)pkg/NETHACK.CNF
|
||||
cp ../sys/msdos/sysconf $(TARGETPFX)pkg/SYSCONF
|
||||
cp ../doc/nethack.txt $(TARGETPFX)pkg/NETHACK.TXT
|
||||
ifdef WANT_DOSVGA
|
||||
cp ../sys/msdos/fonts/ter-u16b.psf $(TARGETPFX)pkg/TER-U16B.PSF
|
||||
cp ../sys/msdos/fonts/ter-u16v.psf $(TARGETPFX)pkg/TER-U16V.PSF
|
||||
cp ../sys/msdos/fonts/ter-u18b.psf $(TARGETPFX)pkg/TER-U18B.PSF
|
||||
@@ -68,7 +64,6 @@ ifdef WANT_DOSVGA
|
||||
cp ../sys/msdos/fonts/ter-u24b.psf $(TARGETPFX)pkg/TER-U24B.PSF
|
||||
cp ../sys/msdos/fonts/ter-u28b.psf $(TARGETPFX)pkg/TER-U28B.PSF
|
||||
cp ../sys/msdos/fonts/ter-u32b.psf $(TARGETPFX)pkg/TER-U32B.PSF
|
||||
endif
|
||||
cp ../lib/djgpp/cwsdpmi/bin/CWSDPMI.EXE $(TARGETPFX)pkg/CWSDPMI.EXE
|
||||
-touch $(TARGETPFX)pkg/RECORD
|
||||
cd $(TARGETPFX)pkg ; zip -9 ../NH370DOS.ZIP * ; cd ../../..
|
||||
|
||||
@@ -185,6 +185,7 @@ override SYSSRC = ../sys/share/pcmain.c ../sys/msdos/msdos.c \
|
||||
../sys/share/pcunix.c ../sys/msdos/video.c \
|
||||
../sys/msdos/vidtxt.c ../sys/msdos/pckeys.c \
|
||||
../sys/msdos/vidvga.c ../sys/msdos/vidvesa.c \
|
||||
../sys/msdos/font.c \
|
||||
../win/share/bmptiles.c ../win/share/giftiles.c \
|
||||
../win/share/tileset.c
|
||||
override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \
|
||||
@@ -192,6 +193,7 @@ override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \
|
||||
$(TARGETPFX)pcunix.o $(TARGETPFX)video.o \
|
||||
$(TARGETPFX)vidtxt.o $(TARGETPFX)pckeys.o \
|
||||
$(TARGETPFX)vidvga.o $(TARGETPFX)vidvesa.o \
|
||||
$(TARGETPFX)font.o \
|
||||
$(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \
|
||||
$(TARGETPFX)tileset.o $(TARGETPFX)tile.o
|
||||
override WINLIB=
|
||||
|
||||
Reference in New Issue
Block a user