Merge branch 'msdos-tile-processing' of https://github.com/chasonr/NetHack into NetHack-5.0
This commit is contained in:
+59
-24
@@ -60,6 +60,8 @@ static unsigned long vesa_DoublePixels(unsigned long);
|
||||
static unsigned long vesa_TriplePixels(unsigned long);
|
||||
static void vesa_WriteStr(const char *, int, int, int, int);
|
||||
static unsigned char __far *vesa_FontPtrs(void);
|
||||
static unsigned char *vesa_tile(unsigned);
|
||||
static unsigned char *vesa_oview_tile(unsigned);
|
||||
/* static void vesa_process_tile(struct TileImage *tile); */
|
||||
|
||||
#ifdef POSITIONBAR
|
||||
@@ -849,7 +851,7 @@ vesa_redrawmap(void)
|
||||
for (cy = 0; cy < ROWNO; ++cy) {
|
||||
for (py = 0; py < vesa_oview_height; ++py) {
|
||||
for (cx = 0; cx < COLNO; ++cx) {
|
||||
tile = vesa_oview_tiles[map[cy][cx].tileidx];
|
||||
tile = vesa_oview_tile(map[cy][cx].tileidx);
|
||||
vesa_WritePixelRow(offset + p_row_width * cx, tile + p_row_width * py, p_row_width);
|
||||
}
|
||||
x = COLNO * vesa_oview_width;
|
||||
@@ -869,7 +871,7 @@ vesa_redrawmap(void)
|
||||
for (cy = clipy; cy <= (unsigned) clipymax && cy < ROWNO; ++cy) {
|
||||
for (py = 0; py < (unsigned) iflags.wc_tile_height; ++py) {
|
||||
for (cx = clipx; cx <= (unsigned) clipxmax && cx < COLNO; ++cx) {
|
||||
tile = vesa_tiles[map[cy][cx].tileidx];
|
||||
tile = vesa_tile(map[cy][cx].tileidx);
|
||||
vesa_WritePixelRow(offset + p_row_width * (cx - clipx), tile + p_row_width * py, p_row_width);
|
||||
}
|
||||
x = (cx - clipx) * iflags.wc_tile_width;
|
||||
@@ -1053,8 +1055,6 @@ vesa_Init(void)
|
||||
{
|
||||
static boolean inited = FALSE;
|
||||
const struct Pixel *paletteptr;
|
||||
unsigned i;
|
||||
unsigned num_pixels, num_oview_pixels;
|
||||
const char *tile_file;
|
||||
const char *font_name;
|
||||
int tilefailure = 0;
|
||||
@@ -1186,31 +1186,33 @@ vesa_Init(void)
|
||||
|
||||
/* Process tiles for the current video mode */
|
||||
vesa_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *));
|
||||
memset(vesa_tiles, 0, total_tiles_used * sizeof(void *));
|
||||
vesa_oview_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *));
|
||||
num_pixels = iflags.wc_tile_width * iflags.wc_tile_height;
|
||||
num_oview_pixels = vesa_oview_width * vesa_oview_height;
|
||||
memset(vesa_oview_tiles, 0, total_tiles_used * sizeof(void *));
|
||||
set_tile_type(vesa_pixel_size > 8);
|
||||
for (i = 0; i < (unsigned) total_tiles_used; ++i) {
|
||||
const struct TileImage *tile = get_tile(i);
|
||||
struct TileImage *ov_tile = stretch_tile(tile, vesa_oview_width, vesa_oview_height);
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/* Return processed pixels for a normal tile */
|
||||
static unsigned char *
|
||||
vesa_tile(unsigned index)
|
||||
{
|
||||
if (vesa_tiles[index] == NULL) {
|
||||
unsigned num_pixels = iflags.wc_tile_width * iflags.wc_tile_height;
|
||||
const struct TileImage *tile = get_tile(index);
|
||||
unsigned j;
|
||||
unsigned char *t_img = (unsigned char *) alloc(num_pixels * vesa_pixel_bytes);
|
||||
unsigned char *ot_img = (unsigned char *) alloc(num_oview_pixels * vesa_pixel_bytes);
|
||||
vesa_tiles[i] = t_img;
|
||||
vesa_oview_tiles[i] = ot_img;
|
||||
vesa_tiles[index] = t_img;
|
||||
switch (vesa_pixel_bytes) {
|
||||
case 1:
|
||||
memcpy(t_img, tile->indexes, num_pixels);
|
||||
memcpy(ot_img, ov_tile->indexes, num_oview_pixels);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (j = 0; j < num_pixels; ++j) {
|
||||
((uint16_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]);
|
||||
}
|
||||
for (j = 0; j < num_oview_pixels; ++j) {
|
||||
((uint16_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@@ -1220,6 +1222,42 @@ vesa_Init(void)
|
||||
t_img[3*j + 1] = (color >> 8) & 0xFF;
|
||||
t_img[3*j + 2] = (color >> 16) & 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for (j = 0; j < num_pixels; ++j) {
|
||||
((uint32_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return vesa_tiles[index];
|
||||
}
|
||||
|
||||
/* Return processed pixels for an overview tile */
|
||||
static unsigned char *
|
||||
vesa_oview_tile(unsigned index)
|
||||
{
|
||||
if (vesa_oview_tiles[index] == NULL) {
|
||||
unsigned num_oview_pixels = vesa_oview_width * vesa_oview_height;
|
||||
const struct TileImage *tile = get_tile(index);
|
||||
struct TileImage *ov_tile = stretch_tile(tile, vesa_oview_width, vesa_oview_height);
|
||||
unsigned j;
|
||||
unsigned char *ot_img = (unsigned char *) alloc(num_oview_pixels * vesa_pixel_bytes);
|
||||
vesa_oview_tiles[index] = ot_img;
|
||||
switch (vesa_pixel_bytes) {
|
||||
case 1:
|
||||
memcpy(ot_img, ov_tile->indexes, num_oview_pixels);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (j = 0; j < num_oview_pixels; ++j) {
|
||||
((uint16_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
for (j = 0; j < num_oview_pixels; ++j) {
|
||||
unsigned long color = vesa_MakeColor(ov_tile->pixels[j]);
|
||||
ot_img[3*j + 0] = color & 0xFF;
|
||||
@@ -1229,9 +1267,6 @@ vesa_Init(void)
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for (j = 0; j < num_pixels; ++j) {
|
||||
((uint32_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]);
|
||||
}
|
||||
for (j = 0; j < num_oview_pixels; ++j) {
|
||||
((uint32_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]);
|
||||
}
|
||||
@@ -1239,10 +1274,9 @@ vesa_Init(void)
|
||||
}
|
||||
free_tile(ov_tile);
|
||||
}
|
||||
free_tiles();
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
return vesa_oview_tiles[index];
|
||||
}
|
||||
|
||||
/* Set the size of the map viewport */
|
||||
static void
|
||||
@@ -1314,6 +1348,7 @@ vesa_Finish(void)
|
||||
}
|
||||
free(vesa_tiles);
|
||||
free(vesa_oview_tiles);
|
||||
free_tiles();
|
||||
vesa_SwitchMode(MODETEXT);
|
||||
windowprocs.win_cliparound = tty_cliparound;
|
||||
g_attribute = attrib_text_normal;
|
||||
@@ -1873,11 +1908,11 @@ vesa_DisplayCell(int tilenum, int col, int row)
|
||||
unsigned p_row_width;
|
||||
|
||||
if (iflags.over_view) {
|
||||
tile = vesa_oview_tiles[tilenum];
|
||||
tile = vesa_oview_tile(tilenum);
|
||||
t_width = vesa_oview_width;
|
||||
t_height = vesa_oview_height;
|
||||
} else {
|
||||
tile = vesa_tiles[tilenum];
|
||||
tile = vesa_tile(tilenum);
|
||||
t_width = iflags.wc_tile_width;
|
||||
t_height = iflags.wc_tile_height;
|
||||
}
|
||||
|
||||
+71
-25
@@ -213,8 +213,8 @@ int vp[SCREENPLANES] = { 8, 4, 2, 1 };
|
||||
#endif
|
||||
int vp2[SCREENPLANES] = { 1, 2, 4, 8 };
|
||||
|
||||
static struct planar_cell_struct planecell;
|
||||
static struct overview_planar_cell_struct planecell_O;
|
||||
static struct planar_cell_struct **cell_cache;
|
||||
static struct overview_planar_cell_struct **cell_cache_O;
|
||||
|
||||
/* static int g_attribute; */ /* Current attribute to use */
|
||||
|
||||
@@ -410,6 +410,7 @@ vga_xputg(const glyph_info *glyphinfo,
|
||||
vga_WriteChar(ch, col, row, attr);
|
||||
} else if (!iflags.over_view) {
|
||||
if ((col >= clipx) && (col <= clipxmax)) {
|
||||
struct planar_cell_struct planecell;
|
||||
read_planar_tile(glyphnum, &planecell);
|
||||
if (map[ry][col].special)
|
||||
decal_planar(&planecell, special);
|
||||
@@ -426,6 +427,7 @@ vga_xputg(const glyph_info *glyphinfo,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct overview_planar_cell_struct planecell_O;
|
||||
read_planar_tile_O(glyphnum, &planecell_O);
|
||||
vga_DisplayCell_O(&planecell_O, col, row);
|
||||
}
|
||||
@@ -512,11 +514,13 @@ vga_redrawmap(boolean clearfirst)
|
||||
} else {
|
||||
t = map[y][x].glyph;
|
||||
if (!iflags.over_view) {
|
||||
struct planar_cell_struct planecell;
|
||||
read_planar_tile(t, &planecell);
|
||||
if (map[y][x].special)
|
||||
decal_planar(&planecell, map[y][x].special);
|
||||
vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW);
|
||||
} else {
|
||||
struct overview_planar_cell_struct planecell_O;
|
||||
read_planar_tile_O(t, &planecell_O);
|
||||
vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW);
|
||||
}
|
||||
@@ -643,6 +647,7 @@ boolean left;
|
||||
}
|
||||
for (y = 0; y < ROWNO; ++y) {
|
||||
for (x = i; x < j; x += 2) {
|
||||
struct planar_cell_struct planecell;
|
||||
t = map[y][x].glyph;
|
||||
read_planar_tile(t, &planecell);
|
||||
if (map[y][x].special)
|
||||
@@ -656,47 +661,69 @@ boolean left;
|
||||
static void
|
||||
read_planar_tile(unsigned glyph, struct planar_cell_struct *cell)
|
||||
{
|
||||
struct planar_cell_struct *pcell;
|
||||
unsigned char indexes[TILE_Y][TILE_X];
|
||||
unsigned plane, y, byte, bit;
|
||||
int tilenum = glyphmap[glyph].tileidx;
|
||||
|
||||
read_tile_indexes(glyph, indexes);
|
||||
/* cell->plane[0..3].image[0..15][0..1] */
|
||||
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
||||
for (y = 0; y < TILE_Y; ++y) {
|
||||
for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) {
|
||||
unsigned char b = 0;
|
||||
for (bit = 0; bit < 8; ++bit) {
|
||||
unsigned char x = byte * 8 + bit;
|
||||
unsigned char i = indexes[y][x];
|
||||
b <<= 1;
|
||||
if (i & (0x8 >> plane)) b |= 1;
|
||||
/* Get the processed tile from the cache if we can */
|
||||
pcell = cell_cache[tilenum];
|
||||
if (pcell == NULL) {
|
||||
/* Process the tile */
|
||||
pcell = (struct planar_cell_struct *) alloc(sizeof(*pcell));
|
||||
cell_cache[tilenum] = pcell;
|
||||
read_tile_indexes(glyph, indexes);
|
||||
/* pcell->plane[0..3].image[0..15][0..1] */
|
||||
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
||||
for (y = 0; y < TILE_Y; ++y) {
|
||||
for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) {
|
||||
unsigned char b = 0;
|
||||
for (bit = 0; bit < 8; ++bit) {
|
||||
unsigned char x = byte * 8 + bit;
|
||||
unsigned char i = indexes[y][x];
|
||||
b <<= 1;
|
||||
if (i & (0x8 >> plane)) b |= 1;
|
||||
}
|
||||
pcell->plane[plane].image[y][byte] = b;
|
||||
}
|
||||
cell->plane[plane].image[y][byte] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*cell = *pcell;
|
||||
}
|
||||
|
||||
static void
|
||||
read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell)
|
||||
{
|
||||
struct overview_planar_cell_struct *pcell;
|
||||
unsigned char indexes[TILE_Y][TILE_X];
|
||||
unsigned plane, y, bit;
|
||||
int tilenum = glyphmap[glyph].tileidx;
|
||||
|
||||
read_tile_indexes(glyph, indexes);
|
||||
/* cell->plane[0..3].image[0..15][0..0] */
|
||||
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
||||
for (y = 0; y < TILE_Y; ++y) {
|
||||
unsigned char b = 0;
|
||||
for (bit = 0; bit < 8; ++bit) {
|
||||
unsigned char x = bit * 2;
|
||||
unsigned char i = indexes[y][x];
|
||||
b <<= 1;
|
||||
if (i & (0x8 >> plane)) b |= 1;
|
||||
/* Get the processed tile from the cache if we can */
|
||||
pcell = cell_cache_O[tilenum];
|
||||
if (pcell == NULL) {
|
||||
/* Process the tile */
|
||||
pcell = (struct overview_planar_cell_struct *) alloc(sizeof(*pcell));
|
||||
cell_cache_O[tilenum] = pcell;
|
||||
read_tile_indexes(glyph, indexes);
|
||||
/* pcell->plane[0..3].image[0..15][0..0] */
|
||||
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
||||
for (y = 0; y < TILE_Y; ++y) {
|
||||
unsigned char b = 0;
|
||||
for (bit = 0; bit < 8; ++bit) {
|
||||
unsigned char x = bit * 2;
|
||||
unsigned char i = indexes[y][x];
|
||||
b <<= 1;
|
||||
if (i & (0x8 >> plane)) b |= 1;
|
||||
}
|
||||
pcell->plane[plane].image[y][0] = b;
|
||||
}
|
||||
cell->plane[plane].image[y][0] = b;
|
||||
}
|
||||
}
|
||||
|
||||
*cell = *pcell;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -782,6 +809,15 @@ vga_Init(void)
|
||||
/* term_clear_screen() */ /* not vga_clear_screen() */
|
||||
return;
|
||||
}
|
||||
|
||||
if (cell_cache == NULL) {
|
||||
cell_cache = (struct planar_cell_struct **) alloc(
|
||||
total_tiles_used * sizeof(cell_cache[0]));
|
||||
memset(cell_cache, 0, total_tiles_used * sizeof(cell_cache[0]));
|
||||
cell_cache_O = (struct overview_planar_cell_struct **) alloc(
|
||||
total_tiles_used * sizeof(cell_cache_O[0]));
|
||||
memset(cell_cache_O, 0, total_tiles_used * sizeof(cell_cache_O[0]));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (iflags.usevga) {
|
||||
@@ -860,7 +896,17 @@ vga_SwitchMode(unsigned int mode)
|
||||
void
|
||||
vga_Finish(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
free_tiles();
|
||||
for (i = 0; i < total_tiles_used; ++i) {
|
||||
free(cell_cache[i]);
|
||||
free(cell_cache_O[i]);
|
||||
}
|
||||
free(cell_cache);
|
||||
cell_cache = NULL;
|
||||
free(cell_cache_O);
|
||||
cell_cache_O = NULL;
|
||||
vga_SwitchMode(MODETEXT);
|
||||
windowprocs.win_cliparound = tty_cliparound;
|
||||
g_attribute = attrib_text_normal;
|
||||
|
||||
+13
-11
@@ -30,6 +30,9 @@ read_tiles(const char *filename, boolean true_color)
|
||||
char header[16];
|
||||
boolean ok;
|
||||
|
||||
if (tiles != NULL)
|
||||
return TRUE;
|
||||
|
||||
/* Fill the image structure with known values */
|
||||
image.width = 0;
|
||||
image.height = 0;
|
||||
@@ -283,7 +286,7 @@ split_tiles(const struct TileSetImage *image)
|
||||
{
|
||||
unsigned tile_rows, tile_cols;
|
||||
size_t tile_size, i, j;
|
||||
unsigned x1, y1, x2, y2;
|
||||
unsigned x1, y1, y2;
|
||||
|
||||
/* Get the number of tiles */
|
||||
tile_rows = image->height / iflags.wc_tile_height;
|
||||
@@ -308,16 +311,15 @@ split_tiles(const struct TileSetImage *image)
|
||||
tile->indexes = (unsigned char *) alloc(tile_size);
|
||||
}
|
||||
for (y2 = 0; y2 < (unsigned) iflags.wc_tile_height; ++y2) {
|
||||
for (x2 = 0; x2 < (unsigned) iflags.wc_tile_width; ++x2) {
|
||||
unsigned x = x1 * iflags.wc_tile_width + x2;
|
||||
unsigned y = y1 * iflags.wc_tile_height + y2;
|
||||
|
||||
i = y * image->width + x;
|
||||
j = y2 * tile->width + x2;
|
||||
tile->pixels[j] = image->pixels[i];
|
||||
if (image->indexes != NULL) {
|
||||
tile->indexes[j] = image->indexes[i];
|
||||
}
|
||||
unsigned y = y1 * iflags.wc_tile_height + y2;
|
||||
unsigned x = x1 * iflags.wc_tile_width;
|
||||
i = y * image->width;
|
||||
j = y2 * tile->width;
|
||||
memcpy(tile->pixels + j, image->pixels + i + x,
|
||||
sizeof(tile->pixels[0]) * iflags.wc_tile_width);
|
||||
if (image->indexes != NULL) {
|
||||
memcpy(tile->indexes + j, image->indexes + i + x,
|
||||
iflags.wc_tile_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user