Support pet and tile decals in 16 color mode
This commit is contained in:
+147
-26
@@ -121,6 +121,7 @@ static void vga_scrollmap(boolean);
|
|||||||
static void vga_redrawmap(boolean);
|
static void vga_redrawmap(boolean);
|
||||||
static void vga_cliparound(int, int);
|
static void vga_cliparound(int, int);
|
||||||
static void decal_planar(struct planar_cell_struct *, unsigned);
|
static void decal_planar(struct planar_cell_struct *, unsigned);
|
||||||
|
static void decal_oview_planar(struct overview_planar_cell_struct *, unsigned);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef POSITIONBAR
|
#ifdef POSITIONBAR
|
||||||
@@ -141,6 +142,7 @@ static void vga_WriteStr(char *, int, int, int, int);
|
|||||||
static char __far *vga_FontPtrs(void);
|
static char __far *vga_FontPtrs(void);
|
||||||
|
|
||||||
#ifdef TILES_IN_GLYPHMAP
|
#ifdef TILES_IN_GLYPHMAP
|
||||||
|
static int glyph_to_tilenum(unsigned);
|
||||||
static void read_planar_tile(unsigned, struct planar_cell_struct *);
|
static void read_planar_tile(unsigned, struct planar_cell_struct *);
|
||||||
static void read_planar_tile_O(unsigned,
|
static void read_planar_tile_O(unsigned,
|
||||||
struct overview_planar_cell_struct *);
|
struct overview_planar_cell_struct *);
|
||||||
@@ -243,6 +245,10 @@ static int vp[SCREENPLANES] = { 8, 4, 2, 1 };
|
|||||||
#ifdef TILES_IN_GLYPHMAP
|
#ifdef TILES_IN_GLYPHMAP
|
||||||
static struct planar_cell_struct **cell_cache;
|
static struct planar_cell_struct **cell_cache;
|
||||||
static struct overview_planar_cell_struct **cell_cache_O;
|
static struct overview_planar_cell_struct **cell_cache_O;
|
||||||
|
|
||||||
|
enum { delimdecal, petdecal, piledecal, NUMDECALS };
|
||||||
|
static struct cellplane *decal_alpha[NUMDECALS] = { 0 };
|
||||||
|
static struct overview_cellplane *decal_oview_alpha[NUMDECALS] = { 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* static int g_attribute; */ /* Current attribute to use */
|
/* static int g_attribute; */ /* Current attribute to use */
|
||||||
@@ -442,8 +448,8 @@ vga_xputg(const glyph_info *glyphinfo,
|
|||||||
} else if (!iflags.over_view) {
|
} else if (!iflags.over_view) {
|
||||||
if ((col >= clipx) && (col <= clipxmax)) {
|
if ((col >= clipx) && (col <= clipxmax)) {
|
||||||
struct planar_cell_struct planecell;
|
struct planar_cell_struct planecell;
|
||||||
read_planar_tile(glyphnum, &planecell);
|
read_planar_tile(glyph_to_tilenum(glyphnum), &planecell);
|
||||||
if (map[ry][col].special)
|
if (special)
|
||||||
decal_planar(&planecell, special);
|
decal_planar(&planecell, special);
|
||||||
vga_DisplayCell(&planecell, col - clipx, row);
|
vga_DisplayCell(&planecell, col - clipx, row);
|
||||||
if (bkglyphinfo->framecolor != NO_COLOR) {
|
if (bkglyphinfo->framecolor != NO_COLOR) {
|
||||||
@@ -459,7 +465,9 @@ vga_xputg(const glyph_info *glyphinfo,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct overview_planar_cell_struct planecell_O;
|
struct overview_planar_cell_struct planecell_O;
|
||||||
read_planar_tile_O(glyphnum, &planecell_O);
|
read_planar_tile_O(glyph_to_tilenum(glyphnum), &planecell_O);
|
||||||
|
if (special)
|
||||||
|
decal_oview_planar(&planecell_O, special);
|
||||||
vga_DisplayCell_O(&planecell_O, col, row);
|
vga_DisplayCell_O(&planecell_O, col, row);
|
||||||
}
|
}
|
||||||
if (col < (CO - 1))
|
if (col < (CO - 1))
|
||||||
@@ -546,13 +554,15 @@ vga_redrawmap(boolean clearfirst)
|
|||||||
t = map[y][x].glyph;
|
t = map[y][x].glyph;
|
||||||
if (!iflags.over_view) {
|
if (!iflags.over_view) {
|
||||||
struct planar_cell_struct planecell;
|
struct planar_cell_struct planecell;
|
||||||
read_planar_tile(t, &planecell);
|
read_planar_tile(glyph_to_tilenum(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 {
|
||||||
struct overview_planar_cell_struct planecell_O;
|
struct overview_planar_cell_struct planecell_O;
|
||||||
read_planar_tile_O(t, &planecell_O);
|
read_planar_tile_O(glyph_to_tilenum(t), &planecell_O);
|
||||||
|
if (map[y][x].special)
|
||||||
|
decal_oview_planar(&planecell_O, map[y][x].special);
|
||||||
vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW);
|
vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -684,7 +694,7 @@ boolean left;
|
|||||||
for (x = i; x < j; x += 2) {
|
for (x = i; x < j; x += 2) {
|
||||||
struct planar_cell_struct planecell;
|
struct planar_cell_struct planecell;
|
||||||
t = map[y][x].glyph;
|
t = map[y][x].glyph;
|
||||||
read_planar_tile(t, &planecell);
|
read_planar_tile(glyph_to_tilenum(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);
|
||||||
@@ -693,13 +703,23 @@ boolean left;
|
|||||||
}
|
}
|
||||||
#endif /* SCROLLMAP */
|
#endif /* SCROLLMAP */
|
||||||
|
|
||||||
|
static int
|
||||||
|
glyph_to_tilenum(unsigned glyph)
|
||||||
|
{
|
||||||
|
/* We don't have enough colors to show the statues */
|
||||||
|
if (glyph_is_statue(glyph)) {
|
||||||
|
glyph = GLYPH_OBJ_OFF + STATUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return glyphmap[glyph].tileidx;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_planar_tile(unsigned glyph, struct planar_cell_struct *cell)
|
read_planar_tile(unsigned tilenum, struct planar_cell_struct *cell)
|
||||||
{
|
{
|
||||||
struct planar_cell_struct *pcell;
|
struct planar_cell_struct *pcell;
|
||||||
unsigned char indexes[TILE_Y][TILE_X];
|
unsigned char indexes[TILE_Y][TILE_X];
|
||||||
unsigned plane, y, byte, bit;
|
unsigned plane, y, byte, bit;
|
||||||
int tilenum = glyphmap[glyph].tileidx;
|
|
||||||
|
|
||||||
/* Get the processed tile from the cache if we can */
|
/* Get the processed tile from the cache if we can */
|
||||||
pcell = cell_cache[tilenum];
|
pcell = cell_cache[tilenum];
|
||||||
@@ -707,7 +727,7 @@ read_planar_tile(unsigned glyph, struct planar_cell_struct *cell)
|
|||||||
/* Process the tile */
|
/* Process the tile */
|
||||||
pcell = (struct planar_cell_struct *) alloc(sizeof(*pcell));
|
pcell = (struct planar_cell_struct *) alloc(sizeof(*pcell));
|
||||||
cell_cache[tilenum] = pcell;
|
cell_cache[tilenum] = pcell;
|
||||||
read_tile_indexes(glyph, indexes);
|
read_tile_indexes(tilenum, indexes);
|
||||||
/* pcell->plane[0..3].image[0..15][0..1] */
|
/* pcell->plane[0..3].image[0..15][0..1] */
|
||||||
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
||||||
for (y = 0; y < TILE_Y; ++y) {
|
for (y = 0; y < TILE_Y; ++y) {
|
||||||
@@ -729,12 +749,11 @@ read_planar_tile(unsigned glyph, struct planar_cell_struct *cell)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell)
|
read_planar_tile_O(unsigned tilenum, struct overview_planar_cell_struct *cell)
|
||||||
{
|
{
|
||||||
struct overview_planar_cell_struct *pcell;
|
struct overview_planar_cell_struct *pcell;
|
||||||
unsigned char indexes[TILE_Y][TILE_X];
|
unsigned char indexes[TILE_Y][TILE_X];
|
||||||
unsigned plane, y, bit;
|
unsigned plane, y, bit;
|
||||||
int tilenum = glyphmap[glyph].tileidx;
|
|
||||||
|
|
||||||
/* Get the processed tile from the cache if we can */
|
/* Get the processed tile from the cache if we can */
|
||||||
pcell = cell_cache_O[tilenum];
|
pcell = cell_cache_O[tilenum];
|
||||||
@@ -742,7 +761,7 @@ read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell)
|
|||||||
/* Process the tile */
|
/* Process the tile */
|
||||||
pcell = (struct overview_planar_cell_struct *) alloc(sizeof(*pcell));
|
pcell = (struct overview_planar_cell_struct *) alloc(sizeof(*pcell));
|
||||||
cell_cache_O[tilenum] = pcell;
|
cell_cache_O[tilenum] = pcell;
|
||||||
read_tile_indexes(glyph, indexes);
|
read_tile_indexes(tilenum, indexes);
|
||||||
/* pcell->plane[0..3].image[0..15][0..0] */
|
/* pcell->plane[0..3].image[0..15][0..0] */
|
||||||
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
for (plane = 0; plane < SCREENPLANES; ++plane) {
|
||||||
for (y = 0; y < TILE_Y; ++y) {
|
for (y = 0; y < TILE_Y; ++y) {
|
||||||
@@ -762,19 +781,12 @@ read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_tile_indexes(unsigned glyph, unsigned char (*indexes)[TILE_X])
|
read_tile_indexes(unsigned tilenum, unsigned char (*indexes)[TILE_X])
|
||||||
{
|
{
|
||||||
const struct TileImage *tile;
|
const struct TileImage *tile;
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
int tilenum;
|
|
||||||
|
|
||||||
/* We don't have enough colors to show the statues */
|
|
||||||
if (glyph_is_statue(glyph)) {
|
|
||||||
glyph = GLYPH_OBJ_OFF + STATUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the tile from the image */
|
/* Get the tile from the image */
|
||||||
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 */
|
||||||
@@ -792,13 +804,122 @@ read_tile_indexes(unsigned glyph, unsigned char (*indexes)[TILE_X])
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
decal_planar(struct planar_cell_struct *gpcs UNUSED, unsigned special)
|
decal_planar(struct planar_cell_struct *gpcs, unsigned special)
|
||||||
{
|
{
|
||||||
if (special & MG_CORPSE) {
|
int decalnum; /* indexes decal_alpha */
|
||||||
} else if (special & MG_INVIS) {
|
int decal_tile; /* tile index of decal */
|
||||||
} else if (special & MG_DETECT) {
|
|
||||||
} else if (special & MG_PET) {
|
/* Which decal do we use? */
|
||||||
} else if (special & MG_RIDDEN) {
|
if ((special & MG_PET) != 0 && iflags.hilite_pet) {
|
||||||
|
decalnum = petdecal;
|
||||||
|
decal_tile = Tile_petmark;
|
||||||
|
} else if ((special & MG_OBJPILE) != 0 && iflags.hilite_pile) {
|
||||||
|
decalnum = piledecal;
|
||||||
|
decal_tile = Tile_pilemark;
|
||||||
|
} else {
|
||||||
|
/* No decal */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the decal */
|
||||||
|
struct planar_cell_struct decal;
|
||||||
|
read_planar_tile(decal_tile, &decal);
|
||||||
|
|
||||||
|
/* Build the alpha channel for the decal */
|
||||||
|
struct cellplane *alpha = decal_alpha[decalnum];
|
||||||
|
|
||||||
|
if (alpha == NULL) {
|
||||||
|
/* Read the delimiter to get the background color */
|
||||||
|
struct planar_cell_struct delim;
|
||||||
|
read_planar_tile(Tile_delimiter, &delim);
|
||||||
|
|
||||||
|
/* Allocate space for the alpha channel */
|
||||||
|
alpha = (struct cellplane *) alloc(sizeof(*alpha));
|
||||||
|
decal_alpha[decalnum] = alpha;
|
||||||
|
memset(alpha, 0x00, sizeof(*alpha));
|
||||||
|
|
||||||
|
/* Alpha channel is 0 where all planes of the decal match the
|
||||||
|
background, and 1 otherwise */
|
||||||
|
for (unsigned i = 0; i < SCREENPLANES; ++i) {
|
||||||
|
uint8_t background = (delim.plane[i].image[0][0] & 0x80) ? 0xFF : 0x00;
|
||||||
|
for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) {
|
||||||
|
for (unsigned k = 0; k < MAX_BYTES_PER_CELL; ++k) {
|
||||||
|
/* Set alpha to 1 wherever the decal doesn't match the
|
||||||
|
background */
|
||||||
|
alpha->image[j][k] |= decal.plane[i].image[j][k] ^ background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply the decal to the tile */
|
||||||
|
for (unsigned i = 0; i < SCREENPLANES; ++i) {
|
||||||
|
for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) {
|
||||||
|
for (unsigned k = 0; k < MAX_BYTES_PER_CELL; ++k) {
|
||||||
|
uint8_t b1 = gpcs->plane[i].image[j][k];
|
||||||
|
uint8_t b2 = decal.plane[i].image[j][k];
|
||||||
|
uint8_t a = alpha->image[j][k];
|
||||||
|
gpcs->plane[i].image[j][k] = (b1 & ~a) | (b2 & a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
decal_oview_planar(struct overview_planar_cell_struct *gpcs, unsigned special)
|
||||||
|
{
|
||||||
|
int decalnum; /* indexes decal_alpha */
|
||||||
|
int decal_tile; /* tile index of decal */
|
||||||
|
|
||||||
|
/* Which decal do we use? */
|
||||||
|
if ((special & MG_PET) != 0 && iflags.hilite_pet) {
|
||||||
|
decalnum = petdecal;
|
||||||
|
decal_tile = Tile_petmark;
|
||||||
|
} else if ((special & MG_OBJPILE) != 0 && iflags.hilite_pile) {
|
||||||
|
decalnum = piledecal;
|
||||||
|
decal_tile = Tile_pilemark;
|
||||||
|
} else {
|
||||||
|
/* No decal */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the decal */
|
||||||
|
struct overview_planar_cell_struct decal;
|
||||||
|
read_planar_tile_O(decal_tile, &decal);
|
||||||
|
|
||||||
|
/* Build the alpha channel for the decal */
|
||||||
|
struct overview_cellplane *alpha = decal_oview_alpha[decalnum];
|
||||||
|
|
||||||
|
if (alpha == NULL) {
|
||||||
|
/* Read the delimiter to get the background color */
|
||||||
|
struct planar_cell_struct delim; /* not overview_planar_cell_struct */
|
||||||
|
read_planar_tile(Tile_delimiter, &delim);
|
||||||
|
|
||||||
|
/* Allocate space for the alpha channel */
|
||||||
|
alpha = (struct overview_cellplane *) alloc(sizeof(*alpha));
|
||||||
|
decal_oview_alpha[decalnum] = alpha;
|
||||||
|
memset(alpha, 0x00, sizeof(*alpha));
|
||||||
|
|
||||||
|
/* Alpha channel is 0 where all planes of the decal match the
|
||||||
|
background, and 1 otherwise */
|
||||||
|
for (unsigned i = 0; i < SCREENPLANES; ++i) {
|
||||||
|
uint8_t background = (delim.plane[i].image[0][0] & 0x80) ? 0xFF : 0x00;
|
||||||
|
for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) {
|
||||||
|
/* Set alpha to 1 wherever the decal doesn't match the
|
||||||
|
background */
|
||||||
|
alpha->image[j][0] |= decal.plane[i].image[j][0] ^ background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply the decal to the tile */
|
||||||
|
for (unsigned i = 0; i < SCREENPLANES; ++i) {
|
||||||
|
for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) {
|
||||||
|
uint8_t b1 = gpcs->plane[i].image[j][0];
|
||||||
|
uint8_t b2 = decal.plane[i].image[j][0];
|
||||||
|
uint8_t a = alpha->image[j][0];
|
||||||
|
gpcs->plane[i].image[j][0] = (b1 & ~a) | (b2 & a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* TILES_IN_GLYPHMAP */
|
#endif /* TILES_IN_GLYPHMAP */
|
||||||
|
|||||||
Reference in New Issue
Block a user