Sundry fixes for DOS 16-color VGA mode

To test 16-color mode, specify OPTIONS=video:vga explicitly;
autodetect will choose a VESA mode if it can.

* Draw tiles correctly when redrawing from panning or from changing
  the map mode among text, tiles and overview. Previously, this would
  draw everything with the tile at the hero's position.

* Draw corridor walls with the stone tile.

* Map the statue colors to the nearest neutral tone among the main
  16 colors. This mainly affects altars and female cats.

* Fix the code that shows statues as the generic statue tile. This
  code could be deleted, but the statues don't draw with the full
  range of gray tones.

* Document the option OPTIONS=video:vesa.
This commit is contained in:
Ray Chason
2022-09-13 19:49:56 -04:00
parent 356e3176bc
commit 686153f6cb
2 changed files with 23 additions and 27 deletions
+4 -1
View File
@@ -47,7 +47,7 @@ OPTIONS=VIDEO
ie: OPTIONS=video:autodetect ie: OPTIONS=video:autodetect
Possible values are: AUTODETECT, DEFAULT, VGA Possible values are: AUTODETECT, DEFAULT, VGA, VESA
AUTODETECT Checks for a supported hi-res video AUTODETECT Checks for a supported hi-res video
adaptor, and if it detects one, NetHack adaptor, and if it detects one, NetHack
@@ -62,6 +62,9 @@ OPTIONS=VIDEO
potential to cause machine lock-ups if potential to cause machine lock-ups if
the specified video hardware is not present. the specified video hardware is not present.
VESA Forces use of VESA specific video routines.
Reverts to TTY mode if no VESA BIOS is found.
OPTIONS=VIDEOSHADES OPTIONS=VIDEOSHADES
(defaults.nh only) (defaults.nh only)
Players may wish to add this option because one of their Players may wish to add this option because one of their
+19 -26
View File
@@ -141,6 +141,9 @@ extern int attrib_gr_normal; /* graphics mode normal attribute */
extern int attrib_text_intense; /* text mode intense attribute */ extern int attrib_text_intense; /* text mode intense attribute */
extern int attrib_gr_intense; /* graphics mode intense attribute */ extern int attrib_gr_intense; /* graphics mode intense attribute */
extern boolean inmap; /* in the map window */ extern boolean inmap; /* in the map window */
#ifdef USE_TILES
extern glyph_map glyphmap[MAX_GLYPH];
#endif
/* /*
* Global Variables * Global Variables
@@ -480,16 +483,14 @@ vga_redrawmap(boolean clearfirst)
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;
if (!(clearfirst && t == cmap_to_glyph(S_stone))) { if (!iflags.over_view) {
if (!iflags.over_view) { read_planar_tile(t, &planecell);
read_planar_tile(t, &planecell); if (map[y][x].special)
if (map[y][x].special) decal_planar(&planecell, map[y][x].special);
decal_planar(&planecell, map[y][x].special); vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW);
vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); } else {
} else { read_planar_tile_O(t, &planecell_O);
read_planar_tile_O(t, &planecell_O); vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW);
vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW);
}
} }
} }
} }
@@ -675,34 +676,26 @@ read_tile_indexes(unsigned glyph, unsigned char (*indexes)[TILE_X])
{ {
const struct TileImage *tile; const struct TileImage *tile;
unsigned x, y; unsigned x, y;
int row, col, ry, tilenum = 0; int tilenum;
/* We don't have enough colors to show the statues */ /* We don't have enough colors to show the statues */
if (glyph >= GLYPH_STATUE_OFF) { if (glyph_is_statue(glyph)) {
glyph = GLYPH_OBJ_OFF + STATUE; glyph = GLYPH_OBJ_OFF + STATUE;
} }
row = currow;
col = curcol;
if ((col < 0 || col >= COLNO)
|| (row < TOP_MAP_ROW || row >= (ROWNO + TOP_MAP_ROW)))
return;
ry = row - TOP_MAP_ROW;
/* Get the tile from the image */ /* Get the tile from the image */
tilenum = map[ry][col].tileidx; tilenum = glyphmap[glyph].tileidx;
tile = get_tile(tilenum); tile = get_tile(tilenum);
/* Map to a 16 bit palette; assume colors laid out as in default tileset */ /* Map to a 16 bit palette; assume colors laid out as in default tileset */
for (y = 0; y < TILE_Y && y < tile->height; ++y) { for (y = 0; y < TILE_Y && y < tile->height; ++y) {
for (x = 0; x < TILE_X && x < tile->width; ++x) { for (x = 0; x < TILE_X && x < tile->width; ++x) {
static const unsigned char color_to_16[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 14, 15,
13, 1, 1, 1, 1, 15, 1, 15, 15, 15, 15, 1, 0
};
unsigned i = tile->indexes[y * tile->width + x]; unsigned i = tile->indexes[y * tile->width + x];
if (i == 28) { i = (i < SIZE(color_to_16)) ? color_to_16[i] : 15;
i = 0;
} else if (i == 16) {
i = 13;
} else if (i > 15) {
i = 15;
}
indexes[y][x] = i; indexes[y][x] = i;
} }
} }