From 749f2ffb0e443411d1dcf189c852b9001e1a14b0 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 12 Apr 2024 11:52:26 -0700 Subject: [PATCH 1/4] update 'hitpointbar' documentation --- doc/Guidebook.mn | 27 ++++++++++++++++++++++++--- doc/Guidebook.tex | 29 ++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 1df677b4e..0d0232850 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -46,7 +46,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 DATE(%B %-d, %Y) -.ds f2 March 21, 2024 +.ds f2 April 12, 2024 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4057,8 +4057,29 @@ In text windowing, text highlighting or inverse video is often used; with tiles, generally displays a small plus-symbol beside the object on the top of the pile. .lp hitpointbar -Show a hit point bar graph behind your name and title. -Only available for TTY, Curses, and Windows GUI, and only when statushilites is on. +Show a hit point bar graph behind your name and title in the status +display (default off). +.lp "" +The \(lqcurses\(rq interface supports it even if the status highlighting +feature has been disabled when building the program. +The \(lqtty\(rq and \(lqmswin\(rq (aka \(lqWindows GUI\(rq) interfaces +support it only if status highlighting is left enabled when building. +You don't need to set up any highlighting rules in order to display +the bar. +If there is one for hitpoints in effect and it specifies color, that +color will be used for the bar. +However if it specifies video attributes, they will be ignored in +favor of \fIinverse\fP. +For tty and curses, \fIblink\fP will also be used if the current +hitpoint value is at or below the \fIcritical HP\fP threshold. +.lp "" +The \(lqQt\(rq interface also supports hitpointbar, by drawing +a solid bar above the name and title with a hard-coded color scheme. +(As of this writing, having the bar enabled unintentionally inhibits +resizing the status panel. +To resize that, use the \f(CR#optionsfull\fP command to toggle the +\fIhitpointbar\fP option off, perform the resize while it's off, then +use the same command to toggle it back on.) .lp horsename Name your starting horse (for example \(lqhorsename:Trigger\(rq). Cannot be set with the \(oq\f(CRO\fP\(cq command. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 1d90e5203..57d69e381 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -48,7 +48,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)} -\date{March 21, 2024} +\date{April 12, 2024} \maketitle @@ -4433,8 +4433,31 @@ with tiles, generally displays a small plus-symbol beside the object on the top of the pile. %.lp \item[\ib{hitpointbar}] -Show a hit point bar graph behind your name and title. -Only available for TTY, Curses, and Windows GUI, and only when statushilites is on. +Show a hit point bar graph behind your name and title in the status +display (default off). +\\ +%.lp +The ``curses'' interface supports it even if the status highlighting +feature has been disabled when building the program. +The ``tty'' and ``mswin'' (aka ``Windows GUI'') interfaces +support it only if status highlighting is left enabled when building. +You don't need to set up any highlighting rules in order to display +the bar. +If there is one for hitpoints in effect and it specifies color, that +color will be used for the bar. +However if it specifies video attributes, they will be ignored in +favor of {\it inverse}. +For tty and curses, {\it blink\/} will also be used if the current +hitpoint value is at or below the {\it critical HP\/} threshold. +\\ +%.lp +The ``Qt'' interface also supports hitpointbar, by drawing +a solid bar above the name and title with a hard-coded color scheme. +(As of this writing, having the bar enabled unintentionally inhibits +resizing the status panel. +To resize that, use the {\tt \#optionsfull} command to toggle the +{\it hitpointbar\/} option off, perform the resize while it's off, then +use the same command to toggle it back on.) %.lp \item[\ib{horsename}] Name your starting horse (for example, ``{\tt horsename:Trigger}''). From 15db874f71468ce18a7deac5de4a312e2798841a Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 12 Apr 2024 21:57:27 -0400 Subject: [PATCH 2/4] CHANGE_COLOR palette option adjustments It was too early to call the windowport change_color() routine while processing the config file. The windowport was not yet fully operational. Now the palette option processing will just place the rgb value into the appropriate ga.altpalette[CLR_MAX] entry. init_sound_disp_gamewindows(void) [allmain.c] calls change_palette() [coloratt.c] and it will call the windowport change_color() function for each ga.altpalette[] entry that has been set. Notes: The rgb values stored in ga.altpalette[] have the NH_ALTPALETTE bit set so that the rgb value of 0 can be stored and be distinguishable from a "not set" entry. The NH_ALTPALETTE bit is cleared from the rgb value in change_palette() prior to calling the windowport change_color() function. The syntax for palette is colorname/r-g-b. For example: palette:black/12-12-12 colorname must be one of the NH_BASIC_COLOR names or a suitable alias for one of those 16 entries. Some of the windowport CHANGE_COLOR functions had the wrong parameters, perhaps due to bitrot. Those have been corrected to match the prototype. --- include/color.h | 1 + include/decl.h | 6 ++ include/extern.h | 4 ++ include/optlist.h | 10 +-- src/allmain.c | 7 +++ src/coloratt.c | 76 +++++++++++++++++++++++ src/decl.c | 6 ++ src/options.c | 130 ++++++++++++++++++++++++--------------- src/windows.c | 2 +- sys/windows/consoletty.c | 37 ++++++++++- win/share/safeproc.c | 14 +++++ win/win32/mswproc.c | 6 +- win/win32/winMS.h | 2 +- 13 files changed, 239 insertions(+), 62 deletions(-) diff --git a/include/color.h b/include/color.h index 25dc27b2f..a1fa5327b 100644 --- a/include/color.h +++ b/include/color.h @@ -55,6 +55,7 @@ #define HI_ZAP CLR_BRIGHT_BLUE #define NH_BASIC_COLOR 0x1000000 +#define NH_ALTPALETTE 0x2000000 #define COLORVAL(x) ((x) & 0xFFFFFF) enum nhcolortype { no_color, nh_color, rgb_color }; diff --git a/include/decl.h b/include/decl.h index 62d21c33f..27b9e384c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -157,6 +157,11 @@ struct instance_globals_a { short *animal_list; /* list of PM values for animal monsters */ int animal_list_count; +#ifdef CHANGE_COLOR + /* options.c */ + uint32 altpalette[CLR_MAX]; +#endif + /* pickup.c */ int A_first_hint; /* menustyle:Full plus 'A' response + !paranoid:A */ int A_second_hint; /* menustyle:Full plus 'A' response + paranoid:A */ @@ -759,6 +764,7 @@ struct instance_globals_o { boolean opt_need_promptstyle; boolean opt_reset_customcolors; boolean opt_reset_customsymbols; + boolean opt_update_basic_palette; /* pickup.c */ int oldcap; /* last encumbrance */ diff --git a/include/extern.h b/include/extern.h index 18cfc4e6b..87c1d3547 100644 --- a/include/extern.h +++ b/include/extern.h @@ -325,6 +325,10 @@ extern boolean closest_color(uint32_t lcolor, uint32_t *closecolor, uint16 *clri extern int color_distance(uint32_t, uint32_t); extern boolean onlyhexdigits(const char *buf); extern uint32 get_nhcolor_from_256_index(int idx); +#ifdef CHANGE_COLOR +extern int count_alt_palette(void); +extern void change_palette(void); +#endif /* ### cmd.c ### */ diff --git a/include/optlist.h b/include/optlist.h index efcf34650..e7009ae68 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -534,14 +534,14 @@ static int optfn_##a(int, int, boolean, char *, char *); No, Yes, No, No, NoAlias, "the inventory order of the items in your pack") #ifdef CHANGE_COLOR -#ifndef WIN32 +#ifndef MAC /* not old Mac OS9 */ + NHOPTC(palette, Advanced, 15, opt_in, set_gameview, + No, Yes, No, No, "hicolor", + "palette (adjust an RGB color in palette (color/R-G-B)") +#else NHOPTC(palette, Advanced, 15, opt_in, set_in_game, No, Yes, No, No, "hicolor", "palette (00c/880/-fff is blue/yellow/reverse white)") -#else - NHOPTC(palette, Advanced, 15, opt_in, set_in_config, - No, Yes, No, No, "hicolor", - "palette (adjust an RGB color in palette (color-R-G-B)") #endif #endif /* prior to paranoid_confirmation, 'prayconfirm' was a distinct option */ diff --git a/src/allmain.c b/src/allmain.c index c2ee0c115..3ce39ad38 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -667,6 +667,13 @@ init_sound_disp_gamewindows(void) SoundAchievement(0, sa2_newgame_nosplash, 0); } +#ifdef CHANGE_COLOR + /* init_nhwindows() has already been called, so before + creating the windows, check to see if there are any + palette entries to alter */ + change_palette(); +#endif + WIN_MESSAGE = create_nhwindow(NHW_MESSAGE); if (VIA_WINDOWPORT()) { status_initialize(0); diff --git a/src/coloratt.c b/src/coloratt.c index 90e316ab7..762a80bec 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -1016,4 +1016,80 @@ get_nhcolor_from_256_index(int idx) retcolor = color_256_definitions[idx].value; return retcolor; } + +#ifdef CHANGE_COLOR + +int +count_alt_palette(void) +{ + int clr, clrcount = 0; + + for (clr = 0; clr < CLR_MAX; ++clr) { + if (ga.altpalette[clr] != 0U) + clrcount++; + } + return clrcount; +} + +int +alternative_palette(char *op) +{ + char buf[BUFSZ], *c_colorid, *c_colorval, *cp; + int reslt = 0, coloridx = CLR_MAX; + long rgb = 0L; + boolean slash = FALSE; + + if (!op) + return 0; + + Snprintf(buf, sizeof buf, "%s", op); + c_colorval = (char *) 0; + c_colorid = cp = buf; + while (*cp) { + if (*cp == ':' || *cp == '/') { + if (*cp == '/') { + slash = TRUE; + *cp = '\0'; + } + } + cp++; + if (slash) { + c_colorval = cp; + slash = FALSE; + } + } + /* some sanity checks */ + if (c_colorid && *c_colorid == ' ') + c_colorid++; + if (c_colorval && *c_colorval == ' ') + c_colorval++; + if (c_colorid) + coloridx = match_str2clr(c_colorid, TRUE); + + if (c_colorval && coloridx >= 0 && coloridx < CLR_MAX) { + rgb = rgbstr_to_int32(c_colorval); + if (rgb != -1) { + ga.altpalette[coloridx] = (uint32) rgb | NH_ALTPALETTE; + /* use COLORVAL(ga.altpalette[coloridx]) to get + the actual rgb value out of ga.altpalette[] */ + reslt = 1; + } + } + return reslt; +} + +void +change_palette(void) +{ + int clridx; + + for (clridx = 0; clridx < CLR_MAX; ++clridx) { + if (ga.altpalette[clridx] != 0) { + long rgb = (long) (ga.altpalette[clridx] & ~NH_ALTPALETTE); + (*windowprocs.win_change_color)(clridx, rgb, 0); + } + } +} +#endif /* CHANGE_COLOR */ + /*coloratt.c*/ diff --git a/src/decl.c b/src/decl.c index c3e36aa78..d3d0ea8c2 100644 --- a/src/decl.c +++ b/src/decl.c @@ -210,6 +210,11 @@ static const struct instance_globals_a g_init_a = { /* mon.c */ UNDEFINED_PTR, /* animal_list */ UNDEFINED_VALUE, /* animal_list_count */ +#ifdef CHANGE_COLOR + /* options.c */ + { 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U }, /* altpalette[CLR_MAX] */ +#endif /* pickup.c */ 0, /* A_first_hint */ 0, /* A_second_hint */ @@ -661,6 +666,7 @@ static const struct instance_globals_o g_init_o = { FALSE, /* opt_need_promptstyle */ FALSE, /* opt_reset_customcolors */ FALSE, /* opt_reset_customsymbols */ + FALSE, /* opt_update_basic_palette */ /* pickup.c */ 0, /* oldcap */ /* restore.c */ diff --git a/src/options.c b/src/options.c index 7912afafc..5042d7fbb 100644 --- a/src/options.c +++ b/src/options.c @@ -315,6 +315,8 @@ static const menu_cmd_t default_menu_cmd_info[] = { { (char *) 0, '\0', (char *) 0 } }; +static const char n_currently_set[] = "(%d currently set)"; + staticfn void nmcpy(char *, const char *, int); staticfn void escapes(const char *, char *); staticfn void rejectoption(const char *); @@ -2575,57 +2577,78 @@ optfn_packorder( } #ifdef CHANGE_COLOR + +DISABLE_WARNING_FORMAT_NONLITERAL + staticfn int optfn_palette( int optidx UNUSED, int req, boolean negated UNUSED, char *opts, char *op) { -#ifndef WIN32 - int cnt, tmp, reverse; - char *pt = op; - long rgb; -#endif - if (req == do_init) { return optn_ok; } if (req == do_set) { if (op == empty_optstr) return optn_err; - /* - Non-WIN32 variant - palette (00c/880/-fff is blue/yellow/reverse white) - WIN32 variant - palette (adjust an RGB color in palette (color-R-G-B) - */ - if (match_optname(opts, "palette", 3, TRUE) -#ifdef MAC - || match_optname(opts, "hicolor", 3, TRUE) -#endif - ) { - int color_number, color_incr; - -#ifndef WIN32 - if (duplicate) - complain_about_duplicate(optidx); -#endif -#ifdef MAC - if (match_optname(opts, "hicolor", 3, TRUE)) { - color_number = CLR_MAX + 4; /* HARDCODED inverse number */ - color_incr = -1; - } else -#endif - { - color_number = 0; - color_incr = 1; - } -#ifdef WIN32 + if (match_optname(opts, "palette", 3, TRUE)) { + /* + * palette (adjust an RGB color in palette (color/R-G-B) + */ if (!alternative_palette(op)) { config_error_add("Error in palette parameter '%s'", op); return optn_err; } -#else + if (!go.opt_initial) + go.opt_update_basic_palette = TRUE; + } + return optn_ok; + } + if (req == get_val || req == get_cnf_val) { + if (!opts) + return optn_err; + Sprintf(opts, n_currently_set, count_alt_palette()); + return optn_ok; + } + return optn_ok; +} + +#if 0 +/* old MAC OS9 code */ +staticfn int +optfn_palette( + int optidx UNUSED, int req, boolean negated UNUSED, + char *opts, char *op) +{ + int cnt, tmp, reverse; + char *pt = op; + long rgb; + + * Mac OS9 variant + * palette (00c/880/-fff is blue/yellow/reverse white) + */ + if (req == do_init) { + return optn_ok; + } + if (req == do_set) { + if (op == empty_optstr) + return optn_err; + + if (match_optname(opts, "palette", 3, TRUE) + || match_optname(opts, "hicolor", 3, TRUE)) { + int color_number, color_incr; + + if (duplicate) + complain_about_duplicate(optidx); + if (match_optname(opts, "hicolor", 3, TRUE)) { + color_number = CLR_MAX + 4; /* HARDCODED inverse number */ + color_incr = -1; + } else { + color_number = 0; + color_incr = 1; + } + /* ----------- Mac OS 9 code -------------------------*/ while (*pt && color_number >= 0) { cnt = 3; rgb = 0L; @@ -2637,21 +2660,15 @@ optfn_palette( } while (cnt-- > 0) { if (*pt && *pt != '/') { -#ifdef AMIGA - rgb <<= 4; -#else rgb <<= 8; -#endif tmp = *pt++; if (isalpha((uchar) tmp)) { tmp = (tmp + 9) & 0xf; /* Assumes ASCII... */ } else { tmp &= 0xf; /* Digits in ASCII too... */ } -#ifndef AMIGA /* Add an extra so we fill f -> ff and 0 -> 00 */ rgb += tmp << 4; -#endif rgb += tmp; } } @@ -2660,20 +2677,25 @@ optfn_palette( change_color(color_number, rgb, reverse); color_number += color_incr; } -#endif /* !WIN32 */ - if (!go.opt_initial) { - go.opt_need_redraw = TRUE; - } + + if (!go.opt_initial) + go.opt_update_basic_palette = TRUE; } return optn_ok; } if (req == get_val || req == get_cnf_val) { - opts[0] = '\0'; - Sprintf(opts, "%s", get_color_string()); + if (!opts) + return optn_err; + Sprintf(opts, n_currently_set, count_alt_palette()); return optn_ok; } return optn_ok; + } +#endif /* 0 */ + +RESTORE_WARNING_FORMAT_NONLITERAL + #endif /* CHANGE_COLOR */ /* for "paranoid_confirmation:foo" and alias "[!]prayconfirm" */ @@ -6333,7 +6355,6 @@ handler_msgtype(void) return optn_ok; } - staticfn int handler_versinfo(void) { @@ -8071,8 +8092,6 @@ fruitadd(char *str, struct fruit *replace_fruit) */ -static const char n_currently_set[] = "(%d currently set)"; - DISABLE_WARNING_FORMAT_NONLITERAL /* RESTORE is after show_menucontrols() */ staticfn int @@ -8400,6 +8419,7 @@ doset_simple_menu(void) go.opt_need_glyph_reset = FALSE; go.opt_reset_customcolors = FALSE; go.opt_reset_customsymbols = FALSE; + go.opt_update_basic_palette = FALSE; pick_cnt = select_menu(tmpwin, PICK_ONE, &pick_list); /* note: without the complication of a preselected entry, a PICK_ONE menu returning pick_cnt > 0 implies exactly 1 */ @@ -8490,6 +8510,10 @@ doset_simple(void) } if (go.opt_need_promptstyle) adjust_menu_promptstyle(WIN_INVEN, &iflags.menu_headings); + if (go.opt_update_basic_palette) { + change_palette(); + go.opt_update_basic_palette = FALSE; + } if (go.opt_reset_customcolors || go.opt_reset_customsymbols) { if (go.opt_reset_customcolors) reset_customcolors(); @@ -8745,8 +8769,12 @@ doset(void) /* changing options via menu by Per Liboriussen */ if (go.opt_need_glyph_reset) { reset_glyphmap(gm_optionchange); } - if (go.opt_reset_customcolors + if (go.opt_reset_customcolors || go.opt_update_basic_palette || go.opt_reset_customsymbols || go.opt_need_redraw) { + if (go.opt_update_basic_palette) { + change_palette(); + go.opt_update_basic_palette = FALSE; + } if (go.opt_reset_customcolors) reset_customcolors(); if (go.opt_reset_customsymbols) diff --git a/src/windows.c b/src/windows.c index 33084c819..3af946b96 100644 --- a/src/windows.c +++ b/src/windows.c @@ -790,7 +790,7 @@ hup_cliparound(int x UNUSED, int y UNUSED) #ifdef CHANGE_COLOR /*ARGSUSED*/ staticfn void -hup_change_color(int color, int reverse, long rgb) +hup_change_color(int color, long rgb, int reverse) { return; } diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 2c1e88037..55f89dee6 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -293,6 +293,27 @@ char erase_char, kill_char; #define DEFTEXTCOLOR ttycolors[7] static INPUT_RECORD bogus_key; +/* +Windows console palette: +Color Name Console Legacy RGB Values New Default RGB Values +BLACK 0,0,0 12,12,12 +DARK_BLUE 0,0,128 0,55,218 +DARK_GREEN 0,128,0 19,161,14 +DARK_CYAN 0,128,128 58,150,221 +DARK_RED 128,0,0 197,15,31 +DARK_MAGENTA 128,0,128 136,23,152 +DARK_YELLOW 128,128,0 193,156,0 +DARK_WHITE 192,192,192 204,204,204 +BRIGHT_BLACK 128,128,128 118,118,118 +BRIGHT_BLUE 0,0,255 59,120,255 +BRIGHT_GREEN 0,255,0 22,198,12 +BRIGHT_CYAN 0,255,255 97,214,214 +BRIGHT_RED 255,0,0 231,72,86 +BRIGHT_MAGENTA 255,0,255 180,0,158 +BRIGHT_YELLOW 255,255,0 249,241,165 +WHITE 255,255,255 242,242,242 +*/ + #ifdef VIRTUAL_TERMINAL_SEQUENCES long customcolors[CLR_MAX]; const char *esc_seq_colors[CLR_MAX]; @@ -1979,6 +2000,21 @@ tty_ibmgraphics_fixup(void) #endif /* VIRTUAL_TERMINAL_SEQUENCES */ } +#ifdef CHANGE_COLOR +#ifdef NO_TERMS +void +tty_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) +{ +} + +char * +tty_get_color_string(void) +{ + return (""); +} +#endif +#endif /* CHANGE_COLOR */ + #ifdef PORT_DEBUG void win32con_debug_keystrokes(void) @@ -3896,5 +3932,4 @@ nh340_checkinput( } return mode ? 0 : ch; } - #endif /* WIN32 */ diff --git a/win/share/safeproc.c b/win/share/safeproc.c index 3786fc0d4..32dec1a5b 100644 --- a/win/share/safeproc.c +++ b/win/share/safeproc.c @@ -550,5 +550,19 @@ stdio_nhgetch(void) return getchar(); } +#ifdef CHANGE_COLOR +void +safe_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) +{ +} + +char * +safe_get_color_string(void) +{ + return (""); +} + + +#endif /* safeprocs.c */ diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 0b95886a9..2b0df926c 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -115,7 +115,7 @@ struct window_procs mswin_procs = { mswin_nh_poskey, mswin_nhbell, mswin_doprev_message, mswin_yn_function, mswin_getlin, mswin_get_ext_cmd, mswin_number_pad, mswin_delay_output, #ifdef CHANGE_COLOR /* only a Mac option currently */ - mswin, mswin_change_background, + mswin_change_color, mswin_get_color_string, #endif /* other defs that really should go away (they're tty specific) */ mswin_start_screen, mswin_end_screen, mswin_outrip, @@ -1901,9 +1901,9 @@ mswin_delay_output(void) } void -mswin_change_color(void) +mswin_change_color(int color, long rgb, int reverse) { - logDebug("mswin_change_color()\n"); + logDebug("mswin_change_color(%d, %ld, %d)\n", color, rgb, reverse); } char * diff --git a/win/win32/winMS.h b/win/win32/winMS.h index 23d98b736..9e92d92ec 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -178,7 +178,7 @@ void mswin_getlin(const char *question, char *input); int mswin_get_ext_cmd(void); void mswin_number_pad(int state); void mswin_delay_output(void); -void mswin_change_color(void); +void mswin_change_color(int color, long rgb, int reverse); char *mswin_get_color_string(void); void mswin_start_screen(void); void mswin_end_screen(void); From ebd200ecc24e2210ef6c40f494b1e858dfeb7a78 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 12 Apr 2024 21:59:59 -0400 Subject: [PATCH 3/4] follow-up: preprocessor conditional --- src/options.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/options.c b/src/options.c index 5042d7fbb..6436a3306 100644 --- a/src/options.c +++ b/src/options.c @@ -8511,7 +8511,9 @@ doset_simple(void) if (go.opt_need_promptstyle) adjust_menu_promptstyle(WIN_INVEN, &iflags.menu_headings); if (go.opt_update_basic_palette) { - change_palette(); +#ifdef CHANGE_COLOR + change_palette(); +#endif go.opt_update_basic_palette = FALSE; } if (go.opt_reset_customcolors || go.opt_reset_customsymbols) { @@ -8772,7 +8774,9 @@ doset(void) /* changing options via menu by Per Liboriussen */ if (go.opt_reset_customcolors || go.opt_update_basic_palette || go.opt_reset_customsymbols || go.opt_need_redraw) { if (go.opt_update_basic_palette) { +#ifdef CHANGE_COLOR change_palette(); +#endif go.opt_update_basic_palette = FALSE; } if (go.opt_reset_customcolors) From a57d0e6f4fbb459e075ad193b493e6b2ac84f331 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 13 Apr 2024 12:01:40 +0300 Subject: [PATCH 4/4] Curses: add support for the palette config option Depends on CHANGE_COLOR compile-time option. Also allow multiple palette-definitions in the config file. --- doc/fixes3-7-0.txt | 2 ++ include/extern.h | 1 + include/optlist.h | 4 ++-- src/windows.c | 4 ++-- sys/unix/hints/linux.370 | 1 + win/curses/cursmain.c | 22 +++++++++++++++------- win/tty/termcap.c | 9 +++++++++ win/tty/wintty.c | 16 ++++++++++++++++ 8 files changed, 48 insertions(+), 11 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index f32e31730..39e1b9329 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2080,6 +2080,8 @@ curses: if user's terminal was set to 'application keypad mode' (DEC VTxxx "ESC SPC G"), nethack wasn't recognizing number pad keys curses: change petattr attributes, dropping support for curses-only ones curses: swap the grey and no-color color initialization +curses: allow changing default colors with the 'palette' config option + (only if compiled with CHANGE_COLOR) macOS: Xcode project was failing to build if the path to the NetHack source tree contained a space; the issue was within some shell script code contained within the project diff --git a/include/extern.h b/include/extern.h index 87c1d3547..85ec516c2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -327,6 +327,7 @@ extern boolean onlyhexdigits(const char *buf); extern uint32 get_nhcolor_from_256_index(int idx); #ifdef CHANGE_COLOR extern int count_alt_palette(void); +extern int alternative_palette(char *); extern void change_palette(void); #endif diff --git a/include/optlist.h b/include/optlist.h index e7009ae68..1a3235822 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -536,11 +536,11 @@ static int optfn_##a(int, int, boolean, char *, char *); #ifdef CHANGE_COLOR #ifndef MAC /* not old Mac OS9 */ NHOPTC(palette, Advanced, 15, opt_in, set_gameview, - No, Yes, No, No, "hicolor", + No, Yes, Yes, No, "hicolor", "palette (adjust an RGB color in palette (color/R-G-B)") #else NHOPTC(palette, Advanced, 15, opt_in, set_in_game, - No, Yes, No, No, "hicolor", + No, Yes, Yes, No, "hicolor", "palette (00c/880/-fff is blue/yellow/reverse white)") #endif #endif diff --git a/src/windows.c b/src/windows.c index 3af946b96..3bb8004b9 100644 --- a/src/windows.c +++ b/src/windows.c @@ -790,7 +790,7 @@ hup_cliparound(int x UNUSED, int y UNUSED) #ifdef CHANGE_COLOR /*ARGSUSED*/ staticfn void -hup_change_color(int color, long rgb, int reverse) +hup_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) { return; } @@ -798,7 +798,7 @@ hup_change_color(int color, long rgb, int reverse) #ifdef MAC /*ARGSUSED*/ staticfn short -hup_set_font_name(winid window, char *fontname) +hup_set_font_name(winid window UNUSED, char *fontname UNUSED) { return 0; } diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.370 index 06c69b7be..c46f271ef 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.370 @@ -141,6 +141,7 @@ NHCFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" #NHCFLAGS+=-DTTY_SOUND_ESCCODES #NHCFLAGS+=-DNO_CHRONICLE #NHCFLAGS+=-DLIVELOG +#NHCFLAGS+=-DCHANGE_COLOR NHCFLAGS+=-DSELF_RECOVER ifdef WANT_WIN_CURSES ifeq "$(HAVE_NCURSESW)" "1" diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 253bb3e75..b6af48ca5 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -44,8 +44,8 @@ extern glyph_info mesg_gi; static void dummy_update_position_bar(char *); #endif #ifdef CHANGE_COLOR -static void dummy_change_color(int, long, int); -static char *dummy_get_color_string(void); +static void curses_change_color(int, long, int); +static char *curses_get_color_string(void); #endif /* Public functions for curses NetHack interface */ @@ -119,12 +119,12 @@ struct window_procs curses_procs = { curses_number_pad, curses_delay_output, #ifdef CHANGE_COLOR - dummy_change_color, + curses_change_color, #ifdef MAC /* old OS 9, not OSX */ (void (*)(int)) 0, (short (*)(winid, char *)) 0, #endif - dummy_get_color_string, + curses_get_color_string, #endif curses_start_screen, curses_end_screen, @@ -1278,13 +1278,21 @@ dummy_update_position_bar(char *arg UNUSED) #ifdef CHANGE_COLOR static void -dummy_change_color(int a1 UNUSED, long a2 UNUSED, int a3 UNUSED) +curses_change_color(int color, long rgb, int reverse UNUSED) { - return; + short r, g, b; + + if (!can_change_color()) + return; + + r = (rgb >> 16) & 0xFF; + g = (rgb >> 8) & 0xFF; + b = rgb & 0xFF; + init_color(color % 16, r * 4, g * 4, b * 4); } static char * -dummy_get_color_string(void) +curses_get_color_string(void) { return (char *) 0; } diff --git a/win/tty/termcap.c b/win/tty/termcap.c index 1830fffad..b3b141881 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -1495,6 +1495,15 @@ term_curs_set(int visibility) xputs(nh_VE); } +#ifdef CHANGE_COLOR +void +tty_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) +{ + return; +} +#endif /* CHANGE_COLOR */ + + #ifndef SEP2 #define tcfmtstr "\033[38;2;%ld;%ld;%ldm" #ifdef UNIX diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 0ef7eb44d..f738fc46d 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -803,6 +803,14 @@ tty_resume_nhwindows(void) docrt(); } +#ifdef CHANGE_COLOR +char * +tty_get_color_string(void) +{ + return (char *) 0; +} +#endif /* CHANGE_COLOR */ + void tty_exit_nhwindows(const char *str) { @@ -3941,6 +3949,14 @@ term_curs_set(int visibility UNUSED) /* nothing */ } +#ifdef CHANGE_COLOR +void +tty_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) +{ + /* nothing */ +} +#endif /* CHANGE_COLOR */ + #endif /* NO_TERMS */ void