diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 0c0f4627f..0733a28a1 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -2117,6 +2117,9 @@ NetHack should display inverse when the game specifies it. .lp vary_msgcount NetHack should display this number of messages at a time in the message window. +.lp windowcolors +NetHack should display windows with the specified foreground/background +colors if it can. .hn 2 Configuring NetHack for Play by the Blind .pg diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 78dde0db6..354d9c53a 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -2608,6 +2608,10 @@ NetHack should display inverse when the game specifies it. %.lp \item[\ib{vary\_msgcount}] NetHack should display this number of messages at a time in the message window. +%.lp +\item[\ib{windowcolors}] +NetHack should display windows with the specified foreground/background +colors if it can. \elist %.hn 2 diff --git a/doc/window.doc b/doc/window.doc index 3a827fbac..96d665555 100644 --- a/doc/window.doc +++ b/doc/window.doc @@ -456,38 +456,46 @@ iflags.wc_* fields are: Here are the wincap preference settings that your port can choose to support: - +-------------------+--------------------+-------------------+--------+ - | | | iflags field | data | - | player option | bit in wincap mask | for value | type | - |-------------------+--------------------+-------------------+--------+ - | align_message | WC_ALIGN_MESSAGE | wc_align_message |int | - | align_status | WC_ALIGN_STATUS | wc_align_status |int | - | ascii_map | WC_ASCII_MAP | wc_ascii_map |boolean | - | color | WC_COLOR | wc_color |boolean | - | eight_bit_tty | WC_EIGHT_BIT_IN | wc_eight_bit_input|boolean | - | font_map | WC_FONT_MAP | wc_font_map |char * | - | font_menu | WC_FONT_MENU | wc_font_menu |char * | - | font_message | WC_FONT_MESSAGE | wc_font_message |char * | - | font_status | WC_FONT_STATUS | wc_font_status |char * | - | font_text | WC_FONT_TEXT | wc_font_text |char * | - | font_size_map | WC_FONTSIZ_MAP | wc_fontsiz_map |int | - | font_size_menu | WC_FONTSIZ_MENU | wc_fontsiz_menu |int | - | font_size_message| WC_FONTSIZ_MESSAGE | wc_fontsiz_message|int | - | font_size_status | WC_FONTSIZ_STATUS | wc_fontsiz_status |int | - | font_size_text | WC_FONTSIZ_TEXT | wc_fontsiz_text |int | - | hilite_pet | WC_HILITE_PET | wc_hilite_pet |boolean | - | large_font | WC_LARGE_FONT | wc_large_font |boolean | - | map_mode | WC_MAP_MODE | wc_map_mode |int | - | popup_dialog | WC_POPUP_DIALOG | wc_popup_dialog |boolean | - | preload_tiles | WC_PRELOAD_TILES | wc_preload_tiles |boolean | - | scroll_margin | WC_SCROLL_MARGIN | wc_scroll_margin |int | - | tiled_map | WC_TILED_MAP | wc_tiled_map |boolean | - | tile_width | WC_TILE_WIDTH | wc_tile_width |int | - | tile_height | WC_TILE_HEIGHT | wc_tile_height |int | - | tile_file | WC_TILE_FILE | wc_tile_file |char * | - | use_inverse | WC_INVERSE | wc_inverse |boolean | - | vary_msgcount | WC_VARY_MSGCOUNT | wc_vary_msgcount |int | - +-------------------+--------------------+-------------------+--------+ + +--------------------+--------------------+--------------------+--------+ + | | | iflags field | data | + | player option | bit in wincap mask | for value | type | + |--------------------+--------------------+--------------------+--------+ + | align_message | WC_ALIGN_MESSAGE | wc_align_message |int | + | align_status | WC_ALIGN_STATUS | wc_align_status |int | + | ascii_map | WC_ASCII_MAP | wc_ascii_map |boolean | + | color | WC_COLOR | wc_color |boolean | + | eight_bit_tty | WC_EIGHT_BIT_IN | wc_eight_bit_input |boolean | + | font_map | WC_FONT_MAP | wc_font_map |char * | + | font_menu | WC_FONT_MENU | wc_font_menu |char * | + | font_message | WC_FONT_MESSAGE | wc_font_message |char * | + | font_status | WC_FONT_STATUS | wc_font_status |char * | + | font_text | WC_FONT_TEXT | wc_font_text |char * | + | font_size_map | WC_FONTSIZ_MAP | wc_fontsiz_map |int | + | font_size_menu | WC_FONTSIZ_MENU | wc_fontsiz_menu |int | + | font_size_message | WC_FONTSIZ_MESSAGE | wc_fontsiz_message |int | + | font_size_status | WC_FONTSIZ_STATUS | wc_fontsiz_status |int | + | font_size_text | WC_FONTSIZ_TEXT | wc_fontsiz_text |int | + | hilite_pet | WC_HILITE_PET | wc_hilite_pet |boolean | + | large_font | WC_LARGE_FONT | wc_large_font |boolean | + | map_mode | WC_MAP_MODE | wc_map_mode |int | + | popup_dialog | WC_POPUP_DIALOG | wc_popup_dialog |boolean | + | preload_tiles | WC_PRELOAD_TILES | wc_preload_tiles |boolean | + | scroll_margin | WC_SCROLL_MARGIN | wc_scroll_margin |int | + | tiled_map | WC_TILED_MAP | wc_tiled_map |boolean | + | tile_width | WC_TILE_WIDTH | wc_tile_width |int | + | tile_height | WC_TILE_HEIGHT | wc_tile_height |int | + | tile_file | WC_TILE_FILE | wc_tile_file |char * | + | use_inverse | WC_INVERSE | wc_inverse |boolean | + | vary_msgcount | WC_VARY_MSGCOUNT | wc_vary_msgcount |int | + | windowcolors | WC_WINDOWCOLORS | wc_foregrnd_menu |char * | + | | | wc_backgrnd_menu |char * | + | | | wc_foregrnd_message|char * | + | | | wc_backgrnd_message|char * | + | | | wc_foregrnd_status |char * | + | | | wc_backgrnd_status |char * | + | | | wc_foregrnd_text |char * | + | | | wc_backgrnd_text |char * | + +--------------------+--------------------+--------------------+--------+ align_message -- where to place message window (top, bottom, left, right) align_status -- where to place status window (top, bottom, left, right). @@ -522,6 +530,10 @@ tile_file -- open this alternative tile file. The file name is likely to be use_inverse -- port should display inverse when NetHack asks for it. vary_msgcount -- port should display this number of messages at a time in the message window. +windowcolors + -- port should use these colors for window foreground/background + colors. Syntax: + menu fore/back message fore/back status fore/back text fore/back Whenever one of these settings is adjusted, the port is notified of a change to the setting by calling the port's preference_update() routine. The port @@ -544,6 +556,19 @@ set_wc_option_mod_status(optmask, status) is completely hidden during the game). +Adding a new wincap option: + +To add a new wincap option, please follow all these steps: + 1. Add the option to the wincap preference settings table above. + 2. Add the description to the paragraph below the chart. + 3. Add the WC_ to the bit list in include/winprocs.h (if there is room). + 4. Add the wc_ field(s) to the iflags structure in flag.h. + 5. Add an appropriate parser to parseoptions() in options.c. + 6. Add code to display current value to get_compopt_value() in options.c. + 7. Document the option in Guidebook.mn and Guidebook.tex. + 8. Add the bit name to the OR'd values in your window port's winprocs struct + wincap mask if your port supports the option. + V. New or respecified common, high level routines These are not part of the interface, but mentioned here for your information. diff --git a/include/flag.h b/include/flag.h index 2c850f30c..0f9f7cbfd 100644 --- a/include/flag.h +++ b/include/flag.h @@ -223,6 +223,14 @@ struct instance_flags { int wc_align_status; /* status win at top|bot|right|left */ int wc_align_message; /* message win at top|bot|right|left */ int wc_vary_msgcount; /* show more old messages at a time */ + char *wc_foregrnd_menu; /* points to foregrnd color name for menu win */ + char *wc_backgrnd_menu; /* points to backgrnd color name for menu win */ + char *wc_foregrnd_message; /* points to foregrnd color name for msg win */ + char *wc_backgrnd_message; /* points to backgrnd color name for msg win */ + char *wc_foregrnd_status; /* points to foregrnd color name for status win */ + char *wc_backgrnd_status; /* points to backgrnd color name for status win */ + char *wc_foregrnd_text; /* points to foregrnd color name for text win */ + char *wc_backgrnd_text; /* points to backgrnd color name for text win */ char *wc_font_map; /* points to font name for the map win */ char *wc_font_message; /* points to font name for message win */ char *wc_font_status; /* points to font name for status win */ diff --git a/include/winprocs.h b/include/winprocs.h index e01ad988b..ac7d056c4 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -162,7 +162,9 @@ extern NEARDATA struct window_procs windowprocs; #define WC_EIGHT_BIT_IN 0x2000000L /* 26 8-bit character input */ #define WC_PERM_INVENT 0x4000000L /* 27 8-bit character input */ #define WC_MAP_MODE 0x8000000L /* 28 map_mode option */ - /* 4 free bits */ +#define WC_WINDOWCOLORS 0x10000000L /* 29 background color for message window */ + /* 3 free bits */ + #define ALIGN_LEFT 1 #define ALIGN_RIGHT 2 #define ALIGN_TOP 3 diff --git a/src/options.c b/src/options.c index 97d2af29b..e459423c6 100644 --- a/src/options.c +++ b/src/options.c @@ -302,6 +302,8 @@ static struct Comp_Opt { "videoshades", "gray shades to map to black/gray/white", 32, DISP_IN_GAME }, #endif + { "windowcolors", "the foreground/background colors of windows", /*WC*/ + 80, DISP_IN_GAME }, { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, { (char *)0, (char *)0, 0, 0 } }; @@ -404,6 +406,7 @@ STATIC_DCL void FDECL(warning_opts, (char *,const char *)); STATIC_DCL void FDECL(duplicate_opt_detection, (const char *, int)); STATIC_OVL void FDECL(wc_set_font_name, (int, char *)); +STATIC_OVL int FDECL(wc_set_window_colors, (char *)); STATIC_OVL boolean FDECL(is_wc_option, (const char *)); STATIC_OVL boolean FDECL(wc_supported, (const char *)); @@ -1858,6 +1861,19 @@ goodfruit: return; } + /* WINCAP + * setting window colors + * syntax: windowcolors=menu foregrnd/backgrnd text foregrnd/backgrnd + */ + fullname = "windowcolors"; + if (match_optname(opts, fullname, 7, TRUE)) { + if ((op = string_for_opt(opts, FALSE)) != 0) { + if (!wc_set_window_colors(op)) + badoption(opts); + } else if (negated) bad_negation(fullname, TRUE); + return; + } + /* menustyle:traditional or combo or full or partial */ if (match_optname(opts, "menustyle", 4, TRUE)) { int tmp; @@ -2437,7 +2453,8 @@ char *buf; char ocl[MAXOCLASSES+1]; static const char none[] = "(none)", randomrole[] = "random", to_be_done[] = "(to be done)", - defopt[] = "default"; + defopt[] = "default", + defbrief[] = "def"; int i; buf[0] = '\0'; @@ -2638,6 +2655,16 @@ char *buf; #endif /* VIDEOSHADES */ else if (!strcmp(optname, "windowtype")) Sprintf(buf, "%s", windowprocs.name); + else if (!strcmp(optname, "windowcolors")) + Sprintf(buf, "%s/%s %s/%s %s/%s %s/%s", + iflags.wc_foregrnd_menu ? iflags.wc_foregrnd_menu : defbrief, + iflags.wc_backgrnd_menu ? iflags.wc_backgrnd_menu : defbrief, + iflags.wc_foregrnd_message ? iflags.wc_foregrnd_message : defbrief, + iflags.wc_backgrnd_message ? iflags.wc_backgrnd_message : defbrief, + iflags.wc_foregrnd_status ? iflags.wc_foregrnd_status : defbrief, + iflags.wc_backgrnd_status ? iflags.wc_backgrnd_status : defbrief, + iflags.wc_foregrnd_text ? iflags.wc_foregrnd_text : defbrief, + iflags.wc_backgrnd_text ? iflags.wc_backgrnd_text : defbrief); #ifdef PREFIXES_IN_USE else { for (i = 0; i < PREFIX_COUNT; ++i) @@ -3108,6 +3135,88 @@ char *fontname; return; } +STATIC_OVL int +wc_set_window_colors(op) +char *op; +{ + /* syntax: + * menu white/black message green/yellow status white/blue text white/black + */ + + int j; + char buf[BUFSZ]; + char *wn, *tfg, *tbg, *newop; + char *wnames[] = {"menu", "message", "status", "text"}; + char *shortnames[] = {"mnu", "msg", "sts", "txt"}; + char **fgp[] = { + &iflags.wc_foregrnd_menu, + &iflags.wc_foregrnd_message, + &iflags.wc_foregrnd_status, + &iflags.wc_foregrnd_text + }; + char **bgp[] = { + &iflags.wc_backgrnd_menu, + &iflags.wc_backgrnd_message, + &iflags.wc_backgrnd_status, + &iflags.wc_backgrnd_text + }; + + Strcpy(buf, op); + newop = mungspaces(buf); + while (newop && *newop) { + + wn = tfg = tbg = (char *)0; + + /* until first non-space in case there's leading spaces*/ + while(*newop && isspace(*newop)) newop++; + if (*newop) wn = newop; + else return 0; + + /* until first space */ + while(*newop && !isspace(*newop)) newop++; + if (*newop) *newop = '\0'; + newop++; + + /* until first non-space */ + while(*newop && isspace(*newop)) newop++; + if (*newop) tfg = newop; + else return 0; + + /* until slash */ + while(*newop && *newop != '/') newop++; + if (*newop) *newop = '\0'; + else return 0; + newop++; + + /* until first non-space (in case there's leading space after slash) */ + while(*newop && isspace(*newop)) newop++; + if (*newop) tbg = newop; + else return 0; + + /* until first space */ + while(*newop && !isspace(*newop)) newop++; + if (*newop) *newop = '\0'; + newop++; + for (j = 0; j < 4; ++j) { + if (!strcmpi(wn, wnames[j]) || + !strcmpi(wn, shortnames[j])) { + if (tfg && !strstri(tfg, " ")) { + if (*fgp[j]) free(*fgp[j]); + *fgp[j] = (char *)alloc(strlen(tfg) + 1); + Strcpy(*fgp[j], tfg); + } + if (tbg && !strstri(tbg, " ")) { + if (*bgp[j]) free(*bgp[j]); + *bgp[j] = (char *)alloc(strlen(tbg) + 1); + Strcpy(*bgp[j], tbg); + } + break; + } + } + } + return 1; +} + #endif /* OPTION_LISTS_ONLY */ /*options.c*/