summarylogtreecommitdiffstats
path: root/nethack-3.4.3-gray-1.diff
blob: b48448540cc460eb82c7ca7ccf63f7b808007e08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
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 <michael@talamasca.ocis.net>
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, FALSE, 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,123 @@ 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;
+	}
+
+	hilites[CLR_WHITE] = MD;
+	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]);
+	/* CLR_WHITE is the common variable MD, do not free */
+}
+
 # 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,