diff -durpN nethack-3.4.3/README.gray nethack-gray/README.gray --- nethack-3.4.3/README.gray 1969-12-31 16:00:00.000000000 -0800 +++ nethack-gray/README.gray 2003-12-09 18:37:21.000000000 -0800 @@ -0,0 +1,42 @@ +This copy of the nethack source includes a patch to allow black objects +(orcish daggers, ravens, pits, etc.) to be represented using a dark shade +of gray on some terminals. Normally, nethack shows them as blue to avoid +printing unreadable black-on-black text, but this confuses them with with +objects that are actually blue (cornuthaums, sapphires, soldier ants, +etc.). + +The patch works by specifying "black foreground" and "boldface" at the +same time. On terminals that simulate bold with brighter colors, this +produces a distinct color. Terminal emulators based on PC CGA/EGA/VGA +textmode generally have this property. + +However, on terminals that implement actual bolding -- thickening the +font without changing the color, it will result in invisible text. So, +the feature is not enabled by default. It must be activated with the new +option "use_darkgray". + +Notes: + * This patch is only effective in when TERMINFO is defined in unixconf.h + + * Highlights added by the existing "use_inverse" and/or "hilite_pet" +options will probably not be visible when applied to black objects. + + * nethack doesn't properly follow the rules for using the tputs() +function of termcap/curses. The first argument is supposed to be a string +obtained from the termcap/terminfo functions. Nethack assumes it can +provide a null pointer to do nothing, and can string-concatenate two codes +(boldface and a color select) and use them as one. + My code does not fix this -- although it uses "" instead of a null +pointer, which is less likely to crash on a less permissive +termcap/terminfo implementation. + + * I'm aware of a seperate patch to add darkgray support -- but it was +unconditional at runtime, and had to change the color numbers in +includes/color.h to work. My patch makes the TTY code independent of the +actual value of the CLR_* defines. + + * I personally believe the correct spelling of the color involved is +"grey", however I have adopted the popular misspelling "gray" throughout +to be consistent with the rest of nethack. :) + +---- Michael Deutschmann diff -durpN nethack-3.4.3/include/flag.h nethack-gray/include/flag.h --- nethack-3.4.3/include/flag.h 2003-12-07 15:39:13.000000000 -0800 +++ nethack-gray/include/flag.h 2003-12-09 18:37:21.000000000 -0800 @@ -263,6 +263,8 @@ struct instance_flags { boolean wc2_fullscreen; /* run fullscreen */ boolean wc2_softkeyboard; /* use software keyboard */ boolean wc2_wraptext; /* wrap text */ + boolean wc2_darkgray; /* try to use PC dark-gray color + * to represent black object */ boolean cmdassist; /* provide detailed assistance for some commands */ boolean obsolete; /* obsolete options can point at this, it isn't used */ diff -durpN nethack-3.4.3/include/winprocs.h nethack-gray/include/winprocs.h --- nethack-3.4.3/include/winprocs.h 2003-12-07 15:39:13.000000000 -0800 +++ nethack-gray/include/winprocs.h 2003-12-09 18:37:21.000000000 -0800 @@ -176,8 +176,9 @@ extern NEARDATA struct window_procs wind #define WC2_FULLSCREEN 0x01L /* 01 display full screen */ #define WC2_SOFTKEYBOARD 0x02L /* 02 software keyboard */ -#define WC2_WRAPTEXT 0x04L /* 04 wrap long lines of text */ - /* 29 free bits */ +#define WC2_WRAPTEXT 0x04L /* 03 wrap long lines of text */ +#define WC2_DARKGRAY 0x08L /* 04 try to use "bright black" color */ + /* 28 free bits */ #define ALIGN_LEFT 1 #define ALIGN_RIGHT 2 diff -durpN nethack-3.4.3/src/options.c nethack-gray/src/options.c --- nethack-3.4.3/src/options.c 2003-12-07 15:39:13.000000000 -0800 +++ nethack-gray/src/options.c 2003-12-09 18:37:21.000000000 -0800 @@ -188,6 +188,7 @@ static struct Bool_Opt {"tombstone",&flags.tombstone, TRUE, SET_IN_GAME}, {"toptenwin",&flags.toptenwin, FALSE, SET_IN_GAME}, {"travel", &iflags.travelcmd, TRUE, SET_IN_GAME}, + {"use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE}, #ifdef WIN32CON {"use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME}, /*WC*/ #else @@ -3593,6 +3594,7 @@ struct wc_Opt wc2_options[] = { {"fullscreen", WC2_FULLSCREEN}, {"softkeyboard", WC2_SOFTKEYBOARD}, {"wraptext", WC2_WRAPTEXT}, + {"use_darkgray", WC2_DARKGRAY}, {(char *)0, 0L} }; diff -durpN nethack-3.4.3/win/tty/termcap.c nethack-gray/win/tty/termcap.c --- nethack-3.4.3/win/tty/termcap.c 2003-12-07 15:39:14.000000000 -0800 +++ nethack-gray/win/tty/termcap.c 2003-12-09 18:37:21.000000000 -0800 @@ -839,10 +839,9 @@ cl_eos() /* free after Robert Viduya * extern char *tparm(); #endif -# ifdef COLOR_BLACK /* trust include file */ -#undef COLOR_BLACK -# else +# ifndef COLOR_BLACK /* trust include file */ # ifndef _M_UNIX /* guess BGR */ +#define COLOR_BLACK 0 #define COLOR_BLUE 1 #define COLOR_GREEN 2 #define COLOR_CYAN 3 @@ -851,6 +850,7 @@ extern char *tparm(); #define COLOR_YELLOW 6 #define COLOR_WHITE 7 # else /* guess RGB */ +#define COLOR_BLACK 0 #define COLOR_RED 1 #define COLOR_GREEN 2 #define COLOR_YELLOW 3 @@ -860,42 +860,127 @@ extern char *tparm(); #define COLOR_WHITE 7 # endif # endif -#define COLOR_BLACK COLOR_BLUE -const int ti_map[8] = { - COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, - COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; +/* Mapping data for the six terminfo colors that resolve to pairs of nethack + * colors. Black and white are handled specially. + */ +const struct {int ti_color, nh_color, nh_bright_color;} ti_map[6] = +{ + {COLOR_RED,CLR_RED,CLR_ORANGE}, + {COLOR_GREEN,CLR_GREEN,CLR_BRIGHT_GREEN}, + {COLOR_YELLOW,CLR_BROWN,CLR_YELLOW}, + {COLOR_BLUE,CLR_BLUE,CLR_BRIGHT_BLUE}, + {COLOR_MAGENTA,CLR_MAGENTA,CLR_BRIGHT_MAGENTA}, + {COLOR_CYAN,CLR_CYAN,CLR_BRIGHT_CYAN} +}; static void init_hilite() { register int c; char *setf, *scratch; - - for (c = 0; c < SIZE(hilites); c++) - hilites[c] = nh_HI; - hilites[CLR_GRAY] = hilites[NO_COLOR] = (char *)0; + int length_md; if (tgetnum("Co") < 8 || ((setf = tgetstr("AF", (char **)0)) == (char *)0 && (setf = tgetstr("Sf", (char **)0)) == (char *)0)) + { + /* Fallback when colors not available + * It's arbitrary to collapse all colors except gray + * together, but that's what the previous code did. + */ + hilites[CLR_BLACK] = nh_HI; + hilites[CLR_RED] = nh_HI; + hilites[CLR_GREEN] = nh_HI; + hilites[CLR_BROWN] = nh_HI; + hilites[CLR_BLUE] = nh_HI; + hilites[CLR_MAGENTA] = nh_HI; + hilites[CLR_CYAN] = nh_HI; + hilites[CLR_GRAY] = ""; + hilites[NO_COLOR] = ""; + hilites[CLR_ORANGE] = nh_HI; + hilites[CLR_BRIGHT_GREEN] = nh_HI; + hilites[CLR_YELLOW] = nh_HI; + hilites[CLR_BRIGHT_BLUE] = nh_HI; + hilites[CLR_BRIGHT_MAGENTA] = nh_HI; + hilites[CLR_BRIGHT_CYAN] = nh_HI; + hilites[CLR_WHITE] = nh_HI; return; + } - for (c = 0; c < CLR_MAX / 2; c++) { - scratch = tparm(setf, ti_map[c]); - if (c != CLR_GRAY) { - hilites[c] = (char *) alloc(strlen(scratch) + 1); - Strcpy(hilites[c], scratch); - } - if (c != CLR_BLACK) { - hilites[c|BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1); - Strcpy(hilites[c|BRIGHT], MD); - Strcat(hilites[c|BRIGHT], scratch); - } + length_md = strlen(MD); + c = 6; + while (c--) + { + char *work; + + scratch = tparm(setf,ti_map[c].ti_color); + work = (char *) alloc(strlen(scratch) + length_md + 1); + Strcpy(work,MD); + hilites[ti_map[c].nh_bright_color] = work; + work += length_md; + Strcpy(work,scratch); + hilites[ti_map[c].nh_color] = work; + } + + scratch = tparm(setf,COLOR_WHITE); + hilites[CLR_WHITE] = (char *) alloc(strlen(scratch) + length_md + 1); + Strcpy(hilites[CLR_WHITE],MD); + Strcat(hilites[CLR_WHITE],scratch); + + hilites[CLR_GRAY] = ""; + hilites[NO_COLOR] = ""; + + if (iflags.wc2_darkgray) + { + /* On many terminals, esp. those using classic PC CGA/EGA/VGA + * textmode, specifying "hilight" and "black" simultaneously + * produces a dark shade of gray that is visible against a + * black background. We can use it to represent black objects. + */ + scratch = tparm(setf,COLOR_BLACK); + hilites[CLR_BLACK] = (char *) alloc(strlen(scratch) + length_md + 1); + Strcpy(hilites[CLR_BLACK],MD); + Strcat(hilites[CLR_BLACK],scratch); + } + else + { + /* But it's concievable that hilighted black-on-black could + * still be invisible on many others. We substitute blue for + * black. + */ + hilites[CLR_BLACK] = hilites[CLR_BLUE]; } } +static void +kill_hilite() +{ + /* if colors weren't usable, no freeing needed */ + if (hilites[CLR_BLACK] == nh_HI) + return; + + if (hilites[CLR_BLACK] != hilites[CLR_BLUE]) + free(hilites[CLR_BLACK]); + + /* CLR_BLUE overlaps CLR_BRIGHT_BLUE, do not free */ + /* CLR_GREEN overlaps CLR_BRIGHT_GREEN, do not free */ + /* CLR_CYAN overlaps CLR_BRIGHT_CYAN, do not free */ + /* CLR_RED overlaps CLR_ORANGE, do not free */ + /* CLR_MAGENTA overlaps CLR_BRIGHT_MAGENTA, do not free */ + /* CLR_BROWN overlaps CLR_YELLOW, do not free */ + /* CLR_GRAY is a constant "", do not free */ + /* NO_COLOR is a constant "", do not free */ + free(hilites[CLR_BRIGHT_BLUE]); + free(hilites[CLR_BRIGHT_GREEN]); + free(hilites[CLR_BRIGHT_CYAN]); + free(hilites[CLR_YELLOW]); + free(hilites[CLR_ORANGE]); + free(hilites[CLR_BRIGHT_MAGENTA]); + free(hilites[CLR_WHITE]); +} + # else /* UNIX && TERMINFO */ # ifndef TOS @@ -1040,7 +1121,6 @@ init_hilite() # endif # endif /* TOS */ } -# endif /* UNIX */ static void kill_hilite() @@ -1058,6 +1138,7 @@ kill_hilite() # endif return; } +# endif /* UNIX */ #endif /* TEXTCOLOR */ diff -durpN nethack-3.4.3/win/tty/wintty.c nethack-gray/win/tty/wintty.c --- nethack-3.4.3/win/tty/wintty.c 2003-12-07 15:39:14.000000000 -0800 +++ nethack-gray/win/tty/wintty.c 2003-12-09 18:37:21.000000000 -0800 @@ -50,7 +50,11 @@ struct window_procs tty_procs = { WC_MOUSE_SUPPORT| #endif WC_COLOR|WC_HILITE_PET|WC_INVERSE|WC_EIGHT_BIT_IN, +#ifdef TERMINFO + WC2_DARKGRAY, +#else 0L, +#endif tty_init_nhwindows, tty_player_selection, tty_askname,