Add menucolors
-Add a boolean option menucolors to toggle menu color -Add MENUCOLOR -config file option TODO: -Better support for win32 -Support more windowports -Update Guidebook -Allow changing menucolor lines in-game
This commit is contained in:
@@ -219,6 +219,8 @@ NEARDATA struct c_color_names c_color_names = {
|
||||
"white"
|
||||
};
|
||||
|
||||
struct menucoloring *menu_colorings = NULL;
|
||||
|
||||
const char *c_obj_colors[] = {
|
||||
"black", /* CLR_BLACK */
|
||||
"red", /* CLR_RED */
|
||||
|
||||
@@ -2290,6 +2290,8 @@ int src;
|
||||
} else if (match_varname(buf, "BOULDER", 3)) {
|
||||
(void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
|
||||
1, "BOULDER");
|
||||
} else if (match_varname(buf, "MENUCOLOR", 9)) {
|
||||
(void) add_menu_coloring(bufp);
|
||||
} else if (match_varname(buf, "WARNINGS", 5)) {
|
||||
(void) get_uchars(fp, buf, bufp, translate, FALSE,
|
||||
WARNCOUNT, "WARNINGS");
|
||||
|
||||
179
src/options.c
179
src/options.c
@@ -141,6 +141,7 @@ static struct Bool_Opt
|
||||
{"mail", (boolean *)0, TRUE, SET_IN_FILE},
|
||||
#endif
|
||||
{"mention_walls", &iflags.mention_walls, FALSE, SET_IN_GAME},
|
||||
{"menucolors", &iflags.use_menu_color, FALSE, SET_IN_GAME},
|
||||
/* for menu debugging only*/
|
||||
{"menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_GAME},
|
||||
{"menu_objsyms", &iflags.menu_head_objsym, FALSE, SET_IN_GAME},
|
||||
@@ -1090,6 +1091,174 @@ STATIC_VAR const struct paranoia_opts {
|
||||
{ ~0, "all", 3, 0, 0, 0 }, /* ditto */
|
||||
};
|
||||
|
||||
|
||||
extern struct menucoloring *menu_colorings;
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
const int color;
|
||||
} colornames[] = {
|
||||
{"black", CLR_BLACK},
|
||||
{"red", CLR_RED},
|
||||
{"green", CLR_GREEN},
|
||||
{"brown", CLR_BROWN},
|
||||
{"blue", CLR_BLUE},
|
||||
{"magenta", CLR_MAGENTA},
|
||||
{"cyan", CLR_CYAN},
|
||||
{"gray", CLR_GRAY},
|
||||
{"grey", CLR_GRAY},
|
||||
{"orange", CLR_ORANGE},
|
||||
{"lightgreen", CLR_BRIGHT_GREEN},
|
||||
{"yellow", CLR_YELLOW},
|
||||
{"lightblue", CLR_BRIGHT_BLUE},
|
||||
{"lightmagenta", CLR_BRIGHT_MAGENTA},
|
||||
{"lightcyan", CLR_BRIGHT_CYAN},
|
||||
{"white", CLR_WHITE}
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
const int attr;
|
||||
} attrnames[] = {
|
||||
{"none", ATR_NONE},
|
||||
{"bold", ATR_BOLD},
|
||||
{"dim", ATR_DIM},
|
||||
{"underline", ATR_ULINE},
|
||||
{"blink", ATR_BLINK},
|
||||
{"inverse", ATR_INVERSE}
|
||||
};
|
||||
|
||||
/* parse '"regex_string"=color&attr' and add it to menucoloring */
|
||||
boolean
|
||||
add_menu_coloring(str)
|
||||
char *str;
|
||||
{
|
||||
int i, c = NO_COLOR, a = ATR_NONE;
|
||||
struct menucoloring *tmp;
|
||||
char *tmps, *cs = strchr(str, '=');
|
||||
#ifdef MENU_COLOR_REGEX_POSIX
|
||||
int errnum;
|
||||
char errbuf[80];
|
||||
#endif
|
||||
const char *err = (char *)0;
|
||||
|
||||
if (!cs || !str) return FALSE;
|
||||
|
||||
tmps = cs;
|
||||
tmps++;
|
||||
while (*tmps && isspace(*tmps)) tmps++;
|
||||
|
||||
for (i = 0; i < SIZE(colornames); i++)
|
||||
if (strstri(tmps, colornames[i].name) == tmps) {
|
||||
c = colornames[i].color;
|
||||
break;
|
||||
}
|
||||
if ((i == SIZE(colornames)) && (*tmps >= '0' && *tmps <='9'))
|
||||
c = atoi(tmps);
|
||||
|
||||
if (c > 15) return FALSE;
|
||||
|
||||
tmps = strchr(str, '&');
|
||||
if (tmps) {
|
||||
tmps++;
|
||||
while (*tmps && isspace(*tmps)) tmps++;
|
||||
for (i = 0; i < SIZE(attrnames); i++)
|
||||
if (strstri(tmps, attrnames[i].name) == tmps) {
|
||||
a = attrnames[i].attr;
|
||||
break;
|
||||
}
|
||||
if ((i == SIZE(attrnames)) && (*tmps >= '0' && *tmps <='9'))
|
||||
a = atoi(tmps);
|
||||
}
|
||||
|
||||
*cs = '\0';
|
||||
tmps = str;
|
||||
if ((*tmps == '"') || (*tmps == '\'')) {
|
||||
cs--;
|
||||
while (isspace(*cs)) cs--;
|
||||
if (*cs == *tmps) {
|
||||
*cs = '\0';
|
||||
tmps++;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = (struct menucoloring *)alloc(sizeof(struct menucoloring));
|
||||
#ifdef MENU_COLOR_REGEX
|
||||
#ifdef MENU_COLOR_REGEX_POSIX
|
||||
errnum = regcomp(&tmp->match, tmps, REG_EXTENDED | REG_NOSUB);
|
||||
if (errnum != 0)
|
||||
{
|
||||
regerror(errnum, &tmp->match, errbuf, sizeof(errbuf));
|
||||
err = errbuf;
|
||||
}
|
||||
#else
|
||||
tmp->match.translate = 0;
|
||||
tmp->match.fastmap = 0;
|
||||
tmp->match.buffer = 0;
|
||||
tmp->match.allocated = 0;
|
||||
tmp->match.regs_allocated = REGS_FIXED;
|
||||
err = re_compile_pattern(tmps, strlen(tmps), &tmp->match);
|
||||
#endif
|
||||
#else
|
||||
tmp->match = (char *)alloc(strlen(tmps)+1);
|
||||
(void) memcpy((genericptr_t)tmp->match, (genericptr_t)tmps, strlen(tmps)+1);
|
||||
#endif
|
||||
if (err) {
|
||||
raw_printf("\nMenucolor regex error: %s\n", err);
|
||||
wait_synch();
|
||||
free(tmp);
|
||||
return FALSE;
|
||||
} else {
|
||||
tmp->next = menu_colorings;
|
||||
tmp->color = c;
|
||||
tmp->attr = a;
|
||||
menu_colorings = tmp;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
boolean
|
||||
get_menu_coloring(str, color, attr)
|
||||
char *str;
|
||||
int *color, *attr;
|
||||
{
|
||||
struct menucoloring *tmpmc;
|
||||
if (iflags.use_menu_color)
|
||||
for (tmpmc = menu_colorings; tmpmc; tmpmc = tmpmc->next)
|
||||
#ifdef MENU_COLOR_REGEX
|
||||
# ifdef MENU_COLOR_REGEX_POSIX
|
||||
if (regexec(&tmpmc->match, str, 0, NULL, 0) == 0) {
|
||||
# else
|
||||
if (re_search(&tmpmc->match, str, strlen(str), 0, 9999, 0) >= 0) {
|
||||
# endif
|
||||
#else
|
||||
if (pmatch(tmpmc->match, str)) {
|
||||
#endif
|
||||
*color = tmpmc->color;
|
||||
*attr = tmpmc->attr;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
free_menu_coloring()
|
||||
{
|
||||
struct menucoloring *tmp = menu_colorings;
|
||||
|
||||
while (tmp) {
|
||||
struct menucoloring *tmp2 = tmp->next;
|
||||
#ifdef MENU_COLOR_REGEX
|
||||
(void) regfree(&tmp->match);
|
||||
#else
|
||||
free(tmp->match);
|
||||
#endif
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
parseoptions(opts, tinitial, tfrom_file)
|
||||
register char *opts;
|
||||
@@ -1431,6 +1600,16 @@ boolean tinitial, tfrom_file;
|
||||
return;
|
||||
}
|
||||
|
||||
/* menucolor:"regex_string"=color */
|
||||
fullname = "menucolor";
|
||||
if (match_optname(opts, fullname, 9, TRUE)) {
|
||||
if (negated) bad_negation(fullname, FALSE);
|
||||
else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
|
||||
if (!add_menu_coloring(op))
|
||||
badoption(opts);
|
||||
return;
|
||||
}
|
||||
|
||||
fullname = "msghistory";
|
||||
if (match_optname(opts, fullname, 3, TRUE)) {
|
||||
if (duplicate) complain_about_duplicate(opts,1);
|
||||
|
||||
@@ -1296,6 +1296,7 @@ void
|
||||
freedynamicdata()
|
||||
{
|
||||
unload_qtlist();
|
||||
free_menu_coloring();
|
||||
free_invbuf(); /* let_to_name (invent.c) */
|
||||
free_youbuf(); /* You_buf,&c (pline.c) */
|
||||
tmp_at(DISP_FREEMEM, 0); /* temporary display effects */
|
||||
|
||||
Reference in New Issue
Block a user