Fix: NH001 Problem: Colours don't work properly under Linux. Specifically red and blue are swapped over on xterm based terminals. The basic problem is that the terminfo code assumes that the Sf and AF codes to set the foreground colour are equivalent. At least under version 4.2 of ncurses (which Linux uses), this is not the case. AF sets the colours according to a RGB model and Sf according to a BGR model. curses.h defines the COLOR_FOO macros according to the RGB model regardless causing reds and blues to be switched around. We solve this by manually swapping red and blue if we decide to use Sf under ncurses. Secondly, I believe AF should be preferred over Sf, because other curses packages may have similar characteristics to ncurses and the swapping code is only active for an ncurses implementation. This patch is based on a fix for Slash'EM (SE031), which a number of people helped me in testing my theories and/or for providing patches to address the problem: Matt Reishus David Damerell Peter Makholm Kalle Sandstroem Kresimir Kukulj Compatible with: NetHack 3.3.0 Author: J. Ali Harlow, ali@avrc.city.ac.uk Date: 14 Dec 1999 *** win/tty/termcap.c.orig Sat Dec 11 05:21:07 1999 --- win/tty/termcap.c Tue Dec 14 17:12:42 1999 *************** *** 813,819 **** # 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 }; --- 813,822 ---- # endif #define COLOR_BLACK COLOR_BLUE ! #ifndef NCURSES_VERSION ! const ! #endif ! int ti_map[8] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; *************** *** 821,837 **** init_hilite() { register int c; ! char *setf, *scratch; extern char *tparm(); for (c = 0; c < SIZE(hilites); c++) hilites[c] = HI; hilites[CLR_GRAY] = hilites[NO_COLOR] = (char *)0; ! if (tgetnum("Co") < 8 ! || ((setf = tgetstr("Sf", (char **)0)) == (char *)0 ! && (setf = tgetstr("AF", (char **)0)) == (char *)0)) return; for (c = 0; c < CLR_MAX / 2; c++) { scratch = tparm(setf, ti_map[c]); --- 824,866 ---- init_hilite() { register int c; ! char *setf, *setaf, *scratch; ! #ifndef NCURSES_VERSION extern char *tparm(); + #endif for (c = 0; c < SIZE(hilites); c++) hilites[c] = HI; hilites[CLR_GRAY] = hilites[NO_COLOR] = (char *)0; ! setf = tgetstr("Sf", (char **)0); ! setaf = tgetstr("AF", (char **)0); ! if (tgetnum("Co") < 8 || !setf && !setaf) return; + /* + * Prefer ANSI version if defined in case other curses packages + * do similar colour re-mappings to ncurses. + */ + if (setaf) + setf=setaf; + #ifdef NCURSES_VERSION + else + { + /* + * ALI + * + * ncurses seems to switch from RGB to BGR if + * you use setf rather than setaf. This is despite + * the values for COLOR_FOO in curses.h which + * always remain RGB. Tested against ncurses v4.2 + */ + #define SWAP_COLOR(c1,c2) (c=ti_map[c1],ti_map[c1]=ti_map[c2],ti_map[c2]=c) + SWAP_COLOR(CLR_RED,CLR_BLUE); + SWAP_COLOR(CLR_CYAN,CLR_YELLOW); + ti_map[CLR_BLACK]=ti_map[CLR_BLUE]; + #undef SWAP_COLOR + } + #endif for (c = 0; c < CLR_MAX / 2; c++) { scratch = tparm(setf, ti_map[c]);