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);