introduce support for coloring the frame behind a map location

Also includes support by paxed for polearm targeting using the
frame color.

Also renames USE_TILES to TILES_IN_GLYPHMAP which is a more
accurate description.

Not all window interfaces have full support for the color framing
of the background square yet.

MS-DOS needs further work (to bring it to both VESA and VGA, with
and without tiles.

Windows GUI is missing support.

X11 and Qt have been started, but may require further refinement.
This commit is contained in:
nhmall
2023-01-01 19:55:02 -05:00
parent 1972c8447f
commit 2fc0d25d45
38 changed files with 365 additions and 133 deletions

View File

@@ -360,6 +360,7 @@ const struct instance_globals_g g_init_g = {
{ { { 0 } } }, /* gbuf */
UNDEFINED_VALUES, /* gbuf_start */
UNDEFINED_VALUES, /* gbug_stop */
/* do_name.c */
UNDEFINED_PTR, /* gloc_filter_map */
UNDEFINED_VALUE, /* gloc_filter_floodfill_match_glyph */
@@ -834,6 +835,9 @@ const struct instance_globals_w g_init_w = {
UNDEFINED_VALUE, /* wc */
/* mkmaze.c */
UNDEFINED_PTR, /* wportal */
/* new */
{ wdmode_traditional, NO_COLOR }, /* wsettings */
TRUE, /* havestate*/
IVMAGIC /* w_magic used to validate that structure layout has been preserved */
};

View File

@@ -129,7 +129,7 @@ static int swallow_to_glyph(int, int);
static void display_warning(struct monst *);
static int check_pos(coordxy, coordxy, int);
static int get_bk_glyph(coordxy x, coordxy y);
static void get_bkglyph_and_framecolor(coordxy x, coordxy y, int *, uint32 *);
static int tether_glyph(coordxy, coordxy);
static void mimic_light_blocking(struct monst *);
#ifdef UNBUFFERED_GLYPHINFO
@@ -1444,7 +1444,7 @@ see_traps(void)
/* glyph, ttychar, { glyphflags, { sym.color, sym.symidx },
tileidx, u } */
static glyph_info no_ginfo = {
NO_GLYPH, ' ', { MG_BADXY, { NO_COLOR, 0 }, 0
NO_GLYPH, ' ', NO_COLOR, { MG_BADXY, { NO_COLOR, 0 }, 0
#ifdef ENHANCED_SYMBOLS
, 0
#endif
@@ -1459,13 +1459,13 @@ static glyph_info ginfo;
#define Glyphinfo_at(x, y, glyph) glyphinfo_at(x, y, glyph)
#endif
#ifdef USE_TILES
#ifdef TILES_IN_GLYPHMAP
extern const glyph_info nul_glyphinfo; /* tile.c */
#else
/* glyph, ttychar, { glyphflags, { sym.color, sym.symidx },
tileidx, 0} */
const glyph_info nul_glyphinfo = {
NO_GLYPH, ' ',
NO_GLYPH, ' ', NO_COLOR,
{ /* glyph_map */
MG_UNEXPL,
{ NO_COLOR, SYM_UNEXPLORED + SYM_OFF_X },
@@ -1477,7 +1477,7 @@ const glyph_info nul_glyphinfo = {
};
#endif
#ifdef USE_TILES
#ifdef TILES_IN_GLYPHMAP
extern glyph_map glyphmap[MAX_GLYPH]; /* from tile.c */
#else
glyph_map glyphmap[MAX_GLYPH] = {
@@ -1590,7 +1590,7 @@ redraw_map(void)
for (y = 0; y < ROWNO; ++y)
for (x = 1; x < COLNO; ++x) {
glyph = glyph_at(x, y); /* not levl[x][y].glyph */
bkglyphinfo.glyph = get_bk_glyph(x, y);
get_bkglyph_and_framecolor(x, y, &bkglyphinfo.glyph, &bkglyphinfo.framecolor);
print_glyph(WIN_MAP, x, y,
Glyphinfo_at(x, y, glyph), &bkglyphinfo);
}
@@ -1826,7 +1826,7 @@ show_glyph(coordxy x, coordxy y, int glyph)
static gbuf_entry nul_gbuf = {
0, /* gnew */
{ GLYPH_UNEXPLORED, (unsigned) ' ', /* glyphinfo.glyph */
{ GLYPH_UNEXPLORED, (unsigned) ' ', NO_COLOR, /* glyphinfo.glyph */
/* glyphinfo.gm */
{ MG_UNEXPL, { (unsigned) NO_COLOR, 0 }, 0
#ifdef ENHANCED_SYMBOLS
@@ -1906,8 +1906,10 @@ row_refresh(coordxy start, coordxy stop, coordxy y)
for (x = start; x <= stop; x++) {
gptr = &gg.gbuf[y][x];
glyph = gptr->glyphinfo.glyph;
if (force || glyph != GLYPH_UNEXPLORED) {
bkglyphinfo.glyph = get_bk_glyph(x, y);
get_bkglyph_and_framecolor(x, y, &bkglyphinfo.glyph,
&bkglyphinfo.framecolor);
if (force || glyph != GLYPH_UNEXPLORED
|| bkglyphinfo.framecolor != NO_COLOR) {
print_glyph(WIN_MAP, x, y,
Glyphinfo_at(x, y, glyph), &bkglyphinfo);
}
@@ -1943,6 +1945,7 @@ flush_screen(int cursor_on_u)
static int delay_flushing = 0;
register coordxy x, y;
glyph_info bkglyphinfo = nul_glyphinfo;
int bkglyph;
/* 3.7: don't update map, status, or perm_invent during save/restore */
if (suppress_map_output())
@@ -1969,13 +1972,16 @@ flush_screen(int cursor_on_u)
for (y = 0; y < ROWNO; y++) {
register gbuf_entry *gptr = &gg.gbuf[y][x = gg.gbuf_start[y]];
for (; x <= gg.gbuf_stop[y]; gptr++, x++)
if (gptr->gnew) {
map_glyphinfo(x, y, get_bk_glyph(x, y), 0, &bkglyphinfo);
for (; x <= gg.gbuf_stop[y]; gptr++, x++) {
get_bkglyph_and_framecolor(x, y, &bkglyph, &bkglyphinfo.framecolor);
if (gptr->gnew
|| (gw.wsettings.map_frame_color != NO_COLOR && bkglyphinfo.framecolor != NO_COLOR)) {
map_glyphinfo(x, y, bkglyph, 0, &bkglyphinfo); /* won't touch framecolor */
print_glyph(WIN_MAP, x, y,
Glyphinfo_at(x, y, gptr->glyph), &bkglyphinfo);
gptr->gnew = 0;
}
}
}
reset_glyph_bbox();
@@ -2204,22 +2210,21 @@ glyphinfo_at(coordxy x, coordxy y, int glyph)
#endif
/*
* This will be used to get the glyph for the background so that
* it can potentially be merged into graphical window ports to
* improve the appearance of stuff on dark room squares and the
* plane of air etc.
*
* Until that is working correctly in the branch, however, for now
* we just return NO_GLYPH as an indicator to ignore it.
*
* Get the glyph for the background so that it can potentially
* be merged into graphical window ports to improve the appearance
* of stuff on dark room squares and the plane of air etc.
* [This should be using background as recorded for #overview rather
* than current data from the map.]
*
* Also get the frame color to use for highlighting the map location
* for some purpose.
*
*/
static int
get_bk_glyph(coordxy x, coordxy y)
static void
get_bkglyph_and_framecolor(coordxy x, coordxy y, int *bkglyph, uint32 *framecolor)
{
int idx, bkglyph = GLYPH_UNEXPLORED;
int idx, tmp_bkglyph = GLYPH_UNEXPLORED;
struct rm *lev = &levl[x][y];
if (iflags.use_background_glyph && lev->seenv != 0
@@ -2267,14 +2272,18 @@ get_bk_glyph(coordxy x, coordxy y)
idx = (flags.dark_room && iflags.use_color)
? DARKROOMSYM : S_stone;
}
if (idx != S_room)
bkglyph = cmap_to_glyph(idx);
tmp_bkglyph = cmap_to_glyph(idx);
}
return bkglyph;
if (gw.wsettings.map_frame_color != NO_COLOR && framecolor && mapxy_valid(x, y))
*framecolor = gw.wsettings.map_frame_color;
else
*framecolor = NO_COLOR;
*bkglyph = tmp_bkglyph;
}
#if defined(USE_TILES) && defined(MSDOS)
#if defined(TILES_IN_GLYPHMAP) && defined(MSDOS)
#define HAS_ROGUE_IBM_GRAPHICS \
(gc.currentgraphics == ROGUESET && SYMHANDLING(H_IBM) && !iflags.grmode)
#else

View File

@@ -6,6 +6,8 @@
#include "hack.h"
static char *nextmbuf(void);
static void getpos_getvalids_selection(struct selectionvar *, boolean (*)(coordxy, coordxy));
static void selection_force_newsyms(struct selectionvar *);
static void getpos_help_keyxhelp(winid, const char *, const char *, int);
static void getpos_help(boolean, const char *);
static int QSORTCALLBACK cmp_coord_distu(const void *, const void *);
@@ -50,8 +52,50 @@ getpos_sethilite(
void (*gp_hilitef)(int),
boolean (*gp_getvalidf)(coordxy, coordxy))
{
boolean was_valid = (getpos_getvalid != NULL);
struct selectionvar *sel = selection_new();
getpos_getvalids_selection(sel, getpos_getvalid);
getpos_hilitefunc = gp_hilitef;
getpos_getvalid = gp_getvalidf;
getpos_getvalids_selection(sel, getpos_getvalid);
gw.wsettings.map_frame_color = (getpos_getvalid != NULL) ? CLR_BLUE : NO_COLOR;
if ((boolean) (getpos_getvalid != NULL) != was_valid)
selection_force_newsyms(sel);
selection_free(sel, TRUE);
}
boolean
mapxy_valid(coordxy x, coordxy y)
{
if (getpos_getvalid)
return (*getpos_getvalid)(x, y);
return FALSE;
}
static void
getpos_getvalids_selection(struct selectionvar *sel, boolean (*validf)(coordxy, coordxy))
{
coordxy x, y;
if (!sel || !validf)
return;
for (x = 1; x < sel->wid; x++)
for (y = 0; y < sel->hei; y++)
if ((*validf)(x, y))
selection_setpoint(x, y, sel, 1);
}
static void
selection_force_newsyms(struct selectionvar *sel)
{
coordxy x, y;
for (x = 1; x < sel->wid; x++)
for (y = 0; y < sel->hei; y++)
if (selection_getpoint(x, y, sel))
newsym_force(x, y);
}
static const char *const gloc_descr[NUM_GLOCS][4] = {
@@ -1058,8 +1102,7 @@ getpos(coord *ccp, boolean force, const char *goal)
for (i = 0; i < NUM_GLOCS; i++)
if (garr[i])
free((genericptr_t) garr[i]);
getpos_hilitefunc = (void (*)(int)) 0;
getpos_getvalid = (boolean (*)(coordxy, coordxy)) 0;
getpos_sethilite(NULL, NULL);
u.dx = udx, u.dy = udy, u.dz = udz;
return result;
}

View File

@@ -107,7 +107,7 @@ struct win_information {
static struct win_information window_opts[] = {
#ifdef TTY_GRAPHICS
{ "tty",
/* testing 'USE_TILES' here would bring confusion because it could
/* testing 'TILES_IN_GLYPHMAP' here would bring confusion because it could
apply to another interface such as X11, so check MSDOS explicitly
instead; even checking TTY_TILES_ESCCODES would probably be
confusing to most users (and it will already be listed separately

View File

@@ -11,7 +11,7 @@ static void shuffle_all(void);
static int QSORTCALLBACK discovered_cmp(const genericptr, const genericptr);
static char *oclass_to_name(char, char *);
#ifdef USE_TILES
#ifdef TILES_IN_GLYPHMAP
extern glyph_map glyphmap[MAX_GLYPH];
static void shuffle_tiles(void);
@@ -39,7 +39,7 @@ shuffle_tiles(void)
glyphmap[i + GLYPH_OBJ_PILETOP_OFF].tileidx = tmp_tilemap[1][i];
}
}
#endif /* USE_TILES */
#endif /* TILES_IN_GLYPHMAP */
static void
setgemprobs(d_level* dlev)
@@ -208,7 +208,7 @@ init_objects(void)
/* shuffle descriptions */
shuffle_all();
#ifdef USE_TILES
#ifdef TILES_IN_GLYPHMAP
shuffle_tiles();
#endif
objects[WAN_NOTHING].oc_dir = rn2(2) ? NODIR : IMMEDIATE;
@@ -403,7 +403,7 @@ restnames(NHFILE* nhfp)
}
}
}
#ifdef USE_TILES
#ifdef TILES_IN_GLYPHMAP
shuffle_tiles();
#endif
}

View File

@@ -229,7 +229,7 @@ assign_graphics(int whichset)
gs.showsyms[i] = go.ov_rogue_syms[i] ? go.ov_rogue_syms[i]
: gr.rogue_syms[i];
#if defined(MSDOS) && defined(USE_TILES)
#if defined(MSDOS) && defined(TILES_IN_GLYPHMAP)
if (iflags.grmode)
tileview(FALSE);
#endif
@@ -242,7 +242,7 @@ assign_graphics(int whichset)
gs.showsyms[i] = go.ov_primary_syms[i] ? go.ov_primary_syms[i]
: gp.primary_syms[i];
#if defined(MSDOS) && defined(USE_TILES)
#if defined(MSDOS) && defined(TILES_IN_GLYPHMAP)
if (iflags.grmode)
tileview(TRUE);
#endif