1 /*	SCCS Id: @(#)drawing.c	3.4	1999/12/02	*/
2 /* Copyright (c) NetHack Development Team 1992.			  */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #include "hack.h"
6 #include "tcap.h"
7 
8 /* Relevent header information in rm.h and objclass.h. */
9 
10 #ifdef C
11 #undef C
12 #endif
13 
14 #ifdef TEXTCOLOR
15 #define C(n) n
16 #else
17 #define C(n)
18 #endif
19 
20 #define g_FILLER(symbol) 0
21 
22 uchar oc_syms[MAXOCLASSES] = DUMMY; /* the current object  display symbols */
23 uchar showsyms[MAXPCHARS]  = DUMMY; /* the current feature display symbols */
24 uchar monsyms[MAXMCLASSES] = DUMMY; /* the current monster display symbols */
25 uchar warnsyms[WARNCOUNT]  = DUMMY;  /* the current warning display symbols */
26 
27 /* Default object class symbols.  See objclass.h. */
28 const char def_oc_syms[MAXOCLASSES] = {
29 /* 0*/	'\0',		/* placeholder for the "random class" */
30 	ILLOBJ_SYM,
31 	WEAPON_SYM,
32 	ARMOR_SYM,
33 	RING_SYM,
34 /* 5*/	AMULET_SYM,
35 	TOOL_SYM,
36 	FOOD_SYM,
37 	POTION_SYM,
38 	SCROLL_SYM,
39 /*10*/	SPBOOK_SYM,
40 	WAND_SYM,
41 	GOLD_SYM,
42 	GEM_SYM,
43 	ROCK_SYM,
44 /*15*/	BALL_SYM,
45 	CHAIN_SYM,
46 	VENOM_SYM
47 };
48 
49 const char invisexplain[] = "remembered, unseen, creature";
50 
51 /* Object descriptions.  Used in do_look(). */
52 const char * const objexplain[] = {	/* these match def_oc_syms, above */
53 /* 0*/	0,
54 	"strange object",
55 	"weapon",
56 	"suit or piece of armor",
57 	"ring",
58 /* 5*/	"amulet",
59 	"useful item (pick-axe, key, lamp...)",
60 	"piece of food",
61 	"potion",
62 	"scroll",
63 /*10*/	"spell book",
64 	"wand",
65 	"pile of coins",
66 	"gem or rock",
67 	"boulder or statue",
68 /*15*/	"iron ball",
69 	"iron chain",
70 	"splash of venom"
71 };
72 
73 /* Object class names.  Used in object_detect(). */
74 const char * const oclass_names[] = {
75 /* 0*/	0,
76 	"illegal objects",
77 	"weapons",
78 	"armor",
79 	"rings",
80 /* 5*/	"amulets",
81 	"tools",
82 	"food",
83 	"potions",
84 	"scrolls",
85 /*10*/	"spell books",
86 	"wands",
87 	"coins",
88 	"rocks",
89 	"large stones",
90 /*15*/	"iron balls",
91 	"chains",
92 	"venoms"
93 };
94 
95 /* Default monster class symbols.  See monsym.h. */
96 const char def_monsyms[MAXMCLASSES] = {
97 	'\0',		/* holder */
98 	DEF_ANT,
99 	DEF_BLOB,
100 	DEF_COCKATRICE,
101 	DEF_DOG,
102 	DEF_EYE,
103 	DEF_FELINE,
104 	DEF_GREMLIN,
105 	DEF_HUMANOID,
106 	DEF_IMP,
107 	DEF_JELLY,		/* 10 */
108 	DEF_KOBOLD,
109 	DEF_LEPRECHAUN,
110 	DEF_MIMIC,
111 	DEF_NYMPH,
112 	DEF_ORC,
113 	DEF_PIERCER,
114 	DEF_QUADRUPED,
115 	DEF_RODENT,
116 	DEF_SPIDER,
117 	DEF_TRAPPER,		/* 20 */
118 	DEF_UNICORN,
119 	DEF_VORTEX,
120 	DEF_WORM,
121 	DEF_XAN,
122 	DEF_LIGHT,
123 	DEF_ZRUTY,
124 	DEF_ANGEL,
125 	DEF_BAT,
126 	DEF_CENTAUR,
127 	DEF_DRAGON,		/* 30 */
128 	DEF_ELEMENTAL,
129 	DEF_FUNGUS,
130 	DEF_GNOME,
131 	DEF_GIANT,
132 	'\0',
133 	DEF_JABBERWOCK,
134 	DEF_KOP,
135 	DEF_LICH,
136 	DEF_MUMMY,
137 	DEF_NAGA,		/* 40 */
138 	DEF_OGRE,
139 	DEF_PUDDING,
140 	DEF_QUANTMECH,
141 	DEF_RUSTMONST,
142 	DEF_SNAKE,
143 	DEF_TROLL,
144 	DEF_UMBER,
145 	DEF_VAMPIRE,
146 	DEF_WRAITH,
147 	DEF_XORN,		/* 50 */
148 	DEF_YETI,
149 	DEF_ZOMBIE,
150 	DEF_HUMAN,
151 	DEF_GHOST,
152 	DEF_GOLEM,
153 	DEF_DEMON,
154 	DEF_EEL,
155 	DEF_LIZARD,
156 	DEF_BAD_FOOD,
157 	DEF_BAD_COINS,		/* 60 */
158 	DEF_WORM_TAIL,
159 	DEF_MIMIC_DEF,
160 };
161 
162 /* The explanations below are also used when the user gives a string
163  * for blessed genocide, so no text should wholly contain any later
164  * text.  They should also always contain obvious names (eg. cat/feline).
165  */
166 /* KMH -- changed u and z */
167 /* Robin Johnson -  changed Q */
168 const char * const monexplain[MAXMCLASSES] = {
169     0,
170     "ant or other insect",	"blob",			"cockatrice",
171     "dog or other canine",	"eye or sphere",	"cat or other feline",
172     "gremlin",			"humanoid",		"imp or minor demon",
173     "jelly",			"kobold",		"leprechaun",
174     "mimic",			"nymph",		"orc",
175     "piercer",			"quadruped",		"rodent",
176     "arachnid or centipede",	"trapper or lurker above", "unicorn or horse",
177     "vortex",		"worm", "xan or other mythical/fantastic insect",
178     "light",			"Zouthern animal",
179 #if 0
180     "light",			"zruty",
181 #endif
182     "angelic being",		"bat or bird",		"centaur",
183     "dragon",			"elemental",		"fungus or mold",
184     "gnome",			"giant humanoid",	0,
185     "jabberwock",		"Keystone Kop",		"lich",
186     "mummy",			"naga",			"ogre",
187     "pudding or ooze",  "quantum mechanic or other scientist",
188     "rust monster or disenchanter",
189     "snake",			"troll",		"umber hulk",
190     "vampire",			"wraith",		"xorn",
191     "apelike creature",		"zombie",
192 
193     "human or elf",		"ghost",		"golem",
194     "major demon",		"sea monster",		"lizard",
195     "piece of food",	"pile of coins",
196     "long worm tail",		"mimic"
197 };
198 
199 const struct symdef def_warnsyms[WARNCOUNT] = {
200 	{'0', "unknown creature causing you worry", C(CLR_WHITE)},  	/* white warning  */
201 	{'1', "unknown creature causing you concern", C(CLR_RED)},	/* pink warning   */
202 	{'2', "unknown creature causing you anxiety", C(CLR_RED)},	/* red warning    */
203 	{'3', "unknown creature causing you disquiet", C(CLR_RED)},	/* ruby warning   */
204 	{'4', "unknown creature causing you alarm",
205 						C(CLR_MAGENTA)},        /* purple warning */
206 	{'5', "unknown creature causing you dread",
207 						C(CLR_BRIGHT_MAGENTA)}	/* black warning  */
208 };
209 
210 /*
211  *  Default screen symbols with explanations and colors.
212  *  Note:  {ibm|dec|mac}_graphics[] arrays also depend on this symbol order.
213  */
214 const struct symdef defsyms[MAXPCHARS] = {
215 /* 0*/	{' ', "dark part of a room",C(NO_COLOR)},	/* stone */
216 	{'|', "wall",		C(CLR_GRAY)},	/* vwall */
217 	{'-', "wall",		C(CLR_GRAY)},	/* hwall */
218 	{'-', "wall",		C(CLR_GRAY)},	/* tlcorn */
219 	{'-', "wall",		C(CLR_GRAY)},	/* trcorn */
220 	{'-', "wall",		C(CLR_GRAY)},	/* blcorn */
221 	{'-', "wall",		C(CLR_GRAY)},	/* brcorn */
222 	{'-', "wall",		C(CLR_GRAY)},	/* crwall */
223 	{'-', "wall",		C(CLR_GRAY)},	/* tuwall */
224 	{'-', "wall",		C(CLR_GRAY)},	/* tdwall */
225 /*10*/	{'|', "wall",		C(CLR_GRAY)},	/* tlwall */
226 	{'|', "wall",		C(CLR_GRAY)},	/* trwall */
227 	{'.', "doorway",	C(CLR_GRAY)},	/* ndoor */
228 	{'-', "open door",	C(CLR_BROWN)},	/* vodoor */
229 	{'|', "open door",	C(CLR_BROWN)},	/* hodoor */
230 	{'+', "closed door",	C(CLR_BROWN)},	/* vcdoor */
231 	{'+', "closed door",	C(CLR_BROWN)},	/* hcdoor */
232 	{'#', "iron bars",	C(HI_METAL)},	/* bars */
233 	{'#', "tree",		C(CLR_GREEN)},	/* tree */
234 	{'.', "floor of a room",C(CLR_GRAY)},	/* room */
235 /*20*/	{'#', "corridor",	C(CLR_BLACK)},	/* dark corr */
236 	{'#', "lit corridor",	C(CLR_GRAY)},	/* lit corr (see mapglyph.c) */
237 	{'<', "staircase up",	C(CLR_WHITE)},	/* upstair */
238 	{'>', "staircase down",	C(CLR_WHITE)},	/* dnstair */
239 	{'<', "ladder up",	C(CLR_BROWN)},	/* upladder */
240 	{'>', "ladder down",	C(CLR_BROWN)},	/* dnladder */
241 	{'_', "altar",		C(CLR_GRAY)},	/* altar */
242 	{'|', "grave",      C(CLR_GRAY)},   /* grave */
243 	{'\\', "opulent throne",C(HI_GOLD)},	/* throne */
244 #ifdef SINKS
245 	{'#', "sink",		C(CLR_GRAY)},	/* sink */
246 /*30*/	{'#', "toilet",         C(CLR_WHITE)},  /* toilet */
247 #else
248 	{'#', "",		C(CLR_GRAY)},	/* sink */
249 /*30*/	{'\\', "",              C(CLR_WHITE)},  /* toilet */
250 #endif
251 	{'{', "fountain",       C(CLR_BLUE)},   /* fountain */
252 	{'}', "water",		C(CLR_BLUE)},	/* pool */
253 	{'.', "ice",		C(CLR_CYAN)},	/* ice */
254 	{'}', "molten lava",	C(CLR_RED)},	/* lava */
255 	{'.', "lowered drawbridge",C(CLR_BROWN)},	/* vodbridge */
256 	{'.', "lowered drawbridge",C(CLR_BROWN)},	/* hodbridge */
257 	{'#', "raised drawbridge",C(CLR_BROWN)},/* vcdbridge */
258 	{'#', "raised drawbridge",C(CLR_BROWN)},/* hcdbridge */
259 	{' ', "air",		C(CLR_CYAN)},	/* open air */
260 /*40*/	{'#', "cloud",		C(CLR_GRAY)},	/* [part of] a cloud */
261 	{'}', "water",		C(CLR_BLUE)},	/* under water */
262 	{'^', "arrow trap",	C(HI_METAL)},	/* trap */
263 	{'^', "dart trap",	C(HI_METAL)},	/* trap */
264 	{'^', "falling rock trap",C(CLR_GRAY)},	/* trap */
265 	{'^', "squeaky board",	C(CLR_BROWN)},	/* trap */
266 	{'^', "bear trap",	C(HI_METAL)},	/* trap */
267 	{'^', "land mine",	C(CLR_RED)},	/* trap */
268 	{'^', "rolling boulder trap",	C(CLR_GRAY)},	/* trap */
269 	{'^', "sleeping gas trap",C(HI_ZAP)},	/* trap */
270 /*50*/	{'^', "rust trap",	C(CLR_BLUE)},	/* trap */
271 	{'^', "fire trap",	C(CLR_ORANGE)},	/* trap */
272 	{'^', "pit",		C(CLR_BLACK)},	/* trap */
273 	{'^', "spiked pit",	C(CLR_BLACK)},	/* trap */
274 	{'^', "hole",	C(CLR_BROWN)},	/* trap */
275 	{'^', "trap door",	C(CLR_BROWN)},	/* trap */
276 	{'^', "teleportation trap", C(CLR_MAGENTA)},	/* trap */
277 	{'^', "level teleporter", C(CLR_MAGENTA)},	/* trap */
278 	{'^', "magic portal",	C(CLR_BRIGHT_MAGENTA)},	/* trap */
279 	{'"', "web",		C(CLR_GRAY)},	/* web */
280 /*60*/	{'^', "statue trap",	C(CLR_GRAY)},	/* trap */
281 	{'^', "magic trap",	C(HI_ZAP)},	/* trap */
282 	{'^', "anti-magic field", C(HI_ZAP)},	/* trap */
283 	{'^', "polymorph trap",	C(CLR_BRIGHT_GREEN)},	/* trap */
284 	{'|', "wall",		C(CLR_GRAY)},	/* vbeam */
285 	{'-', "wall",		C(CLR_GRAY)},	/* hbeam */
286 	{'\\',"wall",		C(CLR_GRAY)},	/* lslant */
287 	{'/', "wall",		C(CLR_GRAY)},	/* rslant */
288 	{'*', "",		C(CLR_WHITE)},	/* dig beam */
289 	{'!', "",		C(CLR_WHITE)},	/* camera flash beam */
290 /*70*/	{')', "",		C(HI_WOOD)},	/* boomerang open left */
291 	{'(', "",		C(HI_WOOD)},	/* boomerang open right */
292 	{'0', "",		C(HI_ZAP)},	/* 4 magic shield symbols */
293 	{'#', "",		C(HI_ZAP)},
294 	{'@', "",		C(HI_ZAP)},
295 	{'*', "",		C(HI_ZAP)},
296 	{'/', "",		C(CLR_GREEN)},	/* swallow top left	*/
297 	{'-', "",		C(CLR_GREEN)},	/* swallow top center	*/
298 	{'\\', "",		C(CLR_GREEN)},	/* swallow top right	*/
299 	{'|', "",		C(CLR_GREEN)},	/* swallow middle left	*/
300 /*80*/	{'|', "",		C(CLR_GREEN)},	/* swallow middle right	*/
301 	{'\\', "",		C(CLR_GREEN)},	/* swallow bottom left	*/
302 	{'-', "",		C(CLR_GREEN)},	/* swallow bottom center*/
303 	{'/', "",		C(CLR_GREEN)},	/* swallow bottom right	*/
304 	{'/', "",		C(CLR_ORANGE)},	/* explosion top left     */
305 	{'-', "",		C(CLR_ORANGE)},	/* explosion top center   */
306 	{'\\', "",		C(CLR_ORANGE)},	/* explosion top right    */
307 	{'|', "",		C(CLR_ORANGE)},	/* explosion middle left  */
308 	{' ', "",		C(CLR_ORANGE)},	/* explosion middle center*/
309 	{'|', "",		C(CLR_ORANGE)},	/* explosion middle right */
310 /*90*/	{'\\', "",		C(CLR_ORANGE)},	/* explosion bottom left  */
311 	{'-', "",		C(CLR_ORANGE)},	/* explosion bottom center*/
312 	{'/', "",		C(CLR_ORANGE)},	/* explosion bottom right */
313 
314 /*
315  *  Note: Additions to this array should be reflected in the
316  *	  {ibm,dec,mac}_graphics[] arrays below.
317  */
318 };
319 
320 #undef C
321 
322 #ifdef ASCIIGRAPH
323 
324 #ifdef PC9800
325 void NDECL((*ibmgraphics_mode_callback)) = 0;	/* set in tty_start_screen() */
326 #endif /* PC9800 */
327 
328 static uchar ibm_graphics[MAXPCHARS] = {
329 /* 0*/	g_FILLER(S_stone),
330 	0xb3,	/* S_vwall:	meta-3, vertical rule */
331 	0xc4,	/* S_hwall:	meta-D, horizontal rule */
332 	0xda,	/* S_tlcorn:	meta-Z, top left corner */
333 	0xbf,	/* S_trcorn:	meta-?, top right corner */
334 	0xc0,	/* S_blcorn:	meta-@, bottom left */
335 	0xd9,	/* S_brcorn:	meta-Y, bottom right */
336 	0xc5,	/* S_crwall:	meta-E, cross */
337 	0xc1,	/* S_tuwall:	meta-A, T up */
338 	0xc2,	/* S_tdwall:	meta-B, T down */
339 /*10*/	0xb4,	/* S_tlwall:	meta-4, T left */
340 	0xc3,	/* S_trwall:	meta-C, T right */
341 	0xfa,	/* S_ndoor:	meta-z, centered dot */
342 	0xfe,	/* S_vodoor:	meta-~, small centered square */
343 	0xfe,	/* S_hodoor:	meta-~, small centered square */
344 	g_FILLER(S_vcdoor),
345 	g_FILLER(S_hcdoor),
346 	240,	/* S_bars:	equivalency, courtesy Sascha */
347 	241,	/* S_tree:	plus or minus symbol */
348 	0xfa,	/* S_room:	meta-z, centered dot */
349 /*20*/	0xb0,	/* S_corr:	meta-0, light shading */
350 	0xb1,	/* S_litcorr:	meta-1, medium shading */
351 	g_FILLER(S_upstair),
352 	g_FILLER(S_dnstair),
353 	g_FILLER(S_upladder),
354 	g_FILLER(S_dnladder),
355 	g_FILLER(S_altar),
356 	g_FILLER(S_grave),
357 	g_FILLER(S_throne),
358 	g_FILLER(S_sink),
359 /*30*/	g_FILLER(S_toilet),
360 	0xf4,	/* S_fountain:	meta-t, integral top half */
361 	0xf7,	/* S_pool:	meta-w, approx. equals */
362 	0xfa,	/* S_ice:	meta-z, centered dot */
363 	0xf7,	/* S_lava:	meta-w, approx. equals */
364 	0xfa,	/* S_vodbridge:	meta-z, centered dot */
365 	0xfa,	/* S_hodbridge:	meta-z, centered dot */
366 	g_FILLER(S_vcdbridge),
367 	g_FILLER(S_hcdbridge),
368 	g_FILLER(S_air),
369 /*40*/	g_FILLER(S_cloud),
370 	0xf7,	/* S_water:	meta-w, approx. equals */
371 	g_FILLER(S_arrow_trap),
372 	g_FILLER(S_dart_trap),
373 	g_FILLER(S_falling_rock_trap),
374 	g_FILLER(S_squeaky_board),
375 	g_FILLER(S_bear_trap),
376 	g_FILLER(S_land_mine),
377 	g_FILLER(S_rolling_boulder_trap),
378 	g_FILLER(S_sleeping_gas_trap),
379 /*50*/	g_FILLER(S_rust_trap),
380 	g_FILLER(S_fire_trap),
381 	g_FILLER(S_pit),
382 	g_FILLER(S_spiked_pit),
383 	g_FILLER(S_hole),
384 	g_FILLER(S_trap_door),
385 	g_FILLER(S_teleportation_trap),
386 	g_FILLER(S_level_teleporter),
387 	g_FILLER(S_magic_portal),
388 	g_FILLER(S_web),
389 /*60*/	g_FILLER(S_statue_trap),
390 	g_FILLER(S_magic_trap),
391 	g_FILLER(S_anti_magic_trap),
392 	g_FILLER(S_polymorph_trap),
393 	0xb3,	/* S_vbeam:	meta-3, vertical rule */
394 	0xc4,	/* S_hbeam:	meta-D, horizontal rule */
395 	g_FILLER(S_lslant),
396 	g_FILLER(S_rslant),
397 	g_FILLER(S_digbeam),
398 	g_FILLER(S_flashbeam),
399 /*70*/	g_FILLER(S_boomleft),
400 	g_FILLER(S_boomright),
401 	g_FILLER(S_ss1),
402 	g_FILLER(S_ss2),
403 	g_FILLER(S_ss3),
404 	g_FILLER(S_ss4),
405 	g_FILLER(S_sw_tl),
406 	g_FILLER(S_sw_tc),
407 	g_FILLER(S_sw_tr),
408 	0xb3,	/* S_sw_ml:	meta-3, vertical rule */
409 /*80*/	0xb3,	/* S_sw_mr:	meta-3, vertical rule */
410 	g_FILLER(S_sw_bl),
411 	g_FILLER(S_sw_bc),
412 	g_FILLER(S_sw_br),
413 	g_FILLER(S_explode1),
414 	g_FILLER(S_explode2),
415 	g_FILLER(S_explode3),
416 	0xb3,	/* S_explode4:	meta-3, vertical rule */
417 	g_FILLER(S_explode5),
418 	0xb3,	/* S_explode6:	meta-3, vertical rule */
419 /*90*/	g_FILLER(S_explode7),
420 	g_FILLER(S_explode8),
421 	g_FILLER(S_explode9),
422 };
423 #endif  /* ASCIIGRAPH */
424 
425 #ifdef TERMLIB
426 void NDECL((*decgraphics_mode_callback)) = 0;  /* set in tty_start_screen() */
427 
428 static uchar dec_graphics[MAXPCHARS] = {
429 /* 0*/	g_FILLER(S_stone),
430 	0xf8,	/* S_vwall:	meta-x, vertical rule */
431 	0xf1,	/* S_hwall:	meta-q, horizontal rule */
432 	0xec,	/* S_tlcorn:	meta-l, top left corner */
433 	0xeb,	/* S_trcorn:	meta-k, top right corner */
434 	0xed,	/* S_blcorn:	meta-m, bottom left */
435 	0xea,	/* S_brcorn:	meta-j, bottom right */
436 	0xee,	/* S_crwall:	meta-n, cross */
437 	0xf6,	/* S_tuwall:	meta-v, T up */
438 	0xf7,	/* S_tdwall:	meta-w, T down */
439 /*10*/	0xf5,	/* S_tlwall:	meta-u, T left */
440 	0xf4,	/* S_trwall:	meta-t, T right */
441 	0xfe,	/* S_ndoor:	meta-~, centered dot */
442 	0xe1,	/* S_vodoor:	meta-a, solid block */
443 	0xe1,	/* S_hodoor:	meta-a, solid block */
444 	g_FILLER(S_vcdoor),
445 	g_FILLER(S_hcdoor),
446 	0xfb,	/* S_bars:	meta-{, small pi, courtesy Pat Rankin */
447 	0xe7,	/* S_tree:	meta-g, plus-or-minus, courtesy Pat Rankin */
448 	0xfe,	/* S_room:	meta-~, centered dot */
449 /*20*/	g_FILLER(S_corr),
450 	g_FILLER(S_litcorr),
451 	g_FILLER(S_upstair),
452 	g_FILLER(S_dnstair),
453 	0xf9,	/* S_upladder:	meta-y, greater-than-or-equals */
454 	0xfa,	/* S_dnladder:	meta-z, less-than-or-equals */
455 	g_FILLER(S_altar),	/* 0xc3, \E)3: meta-C, dagger */
456 	g_FILLER(S_grave),
457 	g_FILLER(S_throne),
458 	g_FILLER(S_sink),
459 /*30*/	g_FILLER(S_toilet),
460 	g_FILLER(S_fountain),	/* 0xdb, \E)3: meta-[, integral top half */
461 	0xe0,	/* S_pool:	meta-\, diamond */
462 	0xfe,	/* S_ice:	meta-~, centered dot */
463 	0xe0,	/* S_lava:	meta-\, diamond */
464 	0xfe,	/* S_vodbridge:	meta-~, centered dot */
465 	0xfe,	/* S_hodbridge:	meta-~, centered dot */
466 	g_FILLER(S_vcdbridge),
467 	g_FILLER(S_hcdbridge),
468 	g_FILLER(S_air),
469 /*40*/	g_FILLER(S_cloud),
470 	0xe0,	/* S_water:	meta-\, diamond */
471 	g_FILLER(S_arrow_trap),
472 	g_FILLER(S_dart_trap),
473 	g_FILLER(S_falling_rock_trap),
474 	g_FILLER(S_squeaky_board),
475 	g_FILLER(S_bear_trap),
476 	g_FILLER(S_land_mine),
477 	g_FILLER(S_rolling_boulder_trap),
478 	g_FILLER(S_sleeping_gas_trap),
479 /*50*/	g_FILLER(S_rust_trap),
480 	g_FILLER(S_fire_trap),
481 	g_FILLER(S_pit),
482 	g_FILLER(S_spiked_pit),
483 	g_FILLER(S_hole),
484 	g_FILLER(S_trap_door),
485 	g_FILLER(S_teleportation_trap),
486 	g_FILLER(S_level_teleporter),
487 	g_FILLER(S_magic_portal),
488 	g_FILLER(S_web),	/* 0xbd, \E)3: meta-=, int'l currency */
489 /*60*/	g_FILLER(S_statue_trap),
490 	g_FILLER(S_magic_trap),
491 	g_FILLER(S_anti_magic_trap),
492 	g_FILLER(S_polymorph_trap),
493 	0xf8,	/* S_vbeam:	meta-x, vertical rule */
494 	0xf1,	/* S_hbeam:	meta-q, horizontal rule */
495 	g_FILLER(S_lslant),
496 	g_FILLER(S_rslant),
497 	g_FILLER(S_digbeam),
498 	g_FILLER(S_flashbeam),
499 /*70*/	g_FILLER(S_boomleft),
500 	g_FILLER(S_boomright),
501 	g_FILLER(S_ss1),
502 	g_FILLER(S_ss2),
503 	g_FILLER(S_ss3),
504 	g_FILLER(S_ss4),
505 	g_FILLER(S_sw_tl),
506 	0xef,	/* S_sw_tc:	meta-o, high horizontal line */
507 	g_FILLER(S_sw_tr),
508 	0xf8,	/* S_sw_ml:	meta-x, vertical rule */
509 /*80*/	0xf8,	/* S_sw_mr:	meta-x, vertical rule */
510 	g_FILLER(S_sw_bl),
511 	0xf3,	/* S_sw_bc:	meta-s, low horizontal line */
512 	g_FILLER(S_sw_br),
513 	g_FILLER(S_explode1),
514 	0xef,	/* S_explode2:	meta-o, high horizontal line */
515 	g_FILLER(S_explode3),
516 	0xf8,	/* S_explode4:	meta-x, vertical rule */
517 	g_FILLER(S_explode5),
518 	0xf8,	/* S_explode6:	meta-x, vertical rule */
519 /*90*/	g_FILLER(S_explode7),
520 	0xf3,	/* S_explode8:	meta-s, low horizontal line */
521 	g_FILLER(S_explode9),
522 };
523 #endif  /* TERMLIB */
524 
525 #ifdef MAC_GRAPHICS_ENV
526 static uchar mac_graphics[MAXPCHARS] = {
527 /* 0*/	g_FILLER(S_stone),
528 	0xba,	/* S_vwall */
529 	0xcd,	/* S_hwall */
530 	0xc9,	/* S_tlcorn */
531 	0xbb,	/* S_trcorn */
532 	0xc8,	/* S_blcorn */
533 	0xbc,	/* S_brcorn */
534 	0xce,	/* S_crwall */
535 	0xca,	/* S_tuwall */
536 	0xcb,	/* S_tdwall */
537 /*10*/	0xb9,	/* S_tlwall */
538 	0xcc,	/* S_trwall */
539 	0xb0,	/* S_ndoor */
540 	0xee,	/* S_vodoor */
541 	0xee,	/* S_hodoor */
542 	0xef,	/* S_vcdoor */
543 	0xef,	/* S_hcdoor */
544 	0xf0,	/* S_bars:	equivalency symbol */
545 	0xf1,	/* S_tree:	plus-or-minus */
546 	g_FILLER(S_Room),
547 /*20*/	0xB0,	/* S_corr */
548 	g_FILLER(S_litcorr),
549 	g_FILLER(S_upstair),
550 	g_FILLER(S_dnstair),
551 	g_FILLER(S_upladder),
552 	g_FILLER(S_dnladder),
553 	g_FILLER(S_altar),
554 	0xef,	/* S_grave:	same as open door */
555 	g_FILLER(S_throne),
556 	g_FILLER(S_sink),
557 /*30*/	g_FILLER(S_toilet),
558 	g_FILLER(S_fountain),
559 	0xe0,	/* S_pool */
560 	g_FILLER(S_ice),
561 	g_FILLER(S_lava),
562 	g_FILLER(S_vodbridge),
563 	g_FILLER(S_hodbridge),
564 	g_FILLER(S_vcdbridge),
565 	g_FILLER(S_hcdbridge),
566 	g_FILLER(S_air),
567 /*40*/	g_FILLER(S_cloud),
568 	g_FILLER(S_water),
569 	g_FILLER(S_arrow_trap),
570 	g_FILLER(S_dart_trap),
571 	g_FILLER(S_falling_rock_trap),
572 	g_FILLER(S_squeaky_board),
573 	g_FILLER(S_bear_trap),
574 	g_FILLER(S_land_mine),
575 	g_FILLER(S_rolling_boulder_trap),
576 	g_FILLER(S_sleeping_gas_trap),
577 /*50*/	g_FILLER(S_rust_trap),
578 	g_FILLER(S_fire_trap),
579 	g_FILLER(S_pit),
580 	g_FILLER(S_spiked_pit),
581 	g_FILLER(S_hole),
582 	g_FILLER(S_trap_door),
583 	g_FILLER(S_teleportation_trap),
584 	g_FILLER(S_level_teleporter),
585 	g_FILLER(S_magic_portal),
586 	g_FILLER(S_web),
587 /*60*/	g_FILLER(S_statue_trap),
588 	g_FILLER(S_magic_trap),
589 	g_FILLER(S_anti_magic_trap),
590 	g_FILLER(S_polymorph_trap),
591 	g_FILLER(S_vbeam),
592 	g_FILLER(S_hbeam),
593 	g_FILLER(S_lslant),
594 	g_FILLER(S_rslant),
595 	g_FILLER(S_digbeam),
596 	g_FILLER(S_flashbeam),
597 /*70*/	g_FILLER(S_boomleft),
598 	g_FILLER(S_boomright),
599 	g_FILLER(S_ss1),
600 	g_FILLER(S_ss2),
601 	g_FILLER(S_ss3),
602 	g_FILLER(S_ss4),
603 	g_FILLER(S_sw_tl),
604 	g_FILLER(S_sw_tc),
605 	g_FILLER(S_sw_tr),
606 	g_FILLER(S_sw_ml),
607 /*80*/	g_FILLER(S_sw_mr),
608 	g_FILLER(S_sw_bl),
609 	g_FILLER(S_sw_bc),
610 	g_FILLER(S_sw_br),
611 	g_FILLER(S_explode1),
612 	g_FILLER(S_explode2),
613 	g_FILLER(S_explode3),
614 	g_FILLER(S_explode4),
615 	g_FILLER(S_explode5),
616 	g_FILLER(S_explode6),
617 /*90*/	g_FILLER(S_explode7),
618 	g_FILLER(S_explode8),
619 	g_FILLER(S_explode9),
620 };
621 #endif	/* MAC_GRAPHICS_ENV */
622 
623 #ifdef PC9800
624 void NDECL((*ascgraphics_mode_callback)) = 0;	/* set in tty_start_screen() */
625 #endif
626 
627 /*
628  * Convert the given character to an object class.  If the character is not
629  * recognized, then MAXOCLASSES is returned.  Used in detect.c invent.c,
630  * options.c, pickup.c, sp_lev.c, and lev_main.c.
631  */
632 int
def_char_to_objclass(ch)633 def_char_to_objclass(ch)
634     char ch;
635 {
636     int i;
637     for (i = 1; i < MAXOCLASSES; i++)
638 	if (ch == def_oc_syms[i]) break;
639     return i;
640 }
641 
642 /*
643  * Convert a character into a monster class.  This returns the _first_
644  * match made.  If there are are no matches, return MAXMCLASSES.
645  */
646 int
def_char_to_monclass(ch)647 def_char_to_monclass(ch)
648     char ch;
649 {
650     int i;
651     for (i = 1; i < MAXMCLASSES; i++)
652 	if (def_monsyms[i] == ch) break;
653     return i;
654 }
655 
656 void
assign_graphics(graph_chars,glth,maxlen,offset)657 assign_graphics(graph_chars, glth, maxlen, offset)
658 register uchar *graph_chars;
659 int glth, maxlen, offset;
660 {
661     register int i;
662 
663     for (i = 0; i < maxlen; i++)
664 	showsyms[i+offset] = (((i < glth) && graph_chars[i]) ?
665 		       graph_chars[i] : defsyms[i+offset].sym);
666 }
667 
668 void
switch_graphics(gr_set_flag)669 switch_graphics(gr_set_flag)
670 int gr_set_flag;
671 {
672     switch (gr_set_flag) {
673 	default:
674 	case ASCII_GRAPHICS:
675 	    assign_graphics((uchar *)0, 0, MAXPCHARS, 0);
676 #ifdef PC9800
677 	    if (ascgraphics_mode_callback) (*ascgraphics_mode_callback)();
678 #endif
679 	    break;
680 #ifdef ASCIIGRAPH
681 	case IBM_GRAPHICS:
682 /*
683  * Use the nice IBM Extended ASCII line-drawing characters (codepage 437).
684  *
685  * OS/2 defaults to a multilingual character set (codepage 850, corresponding
686  * to the ISO 8859 character set.  We should probably do a VioSetCp() call to
687  * set the codepage to 437.
688  */
689 	    iflags.IBMgraphics = TRUE;
690 	    iflags.DECgraphics = FALSE;
691 	    assign_graphics(ibm_graphics, SIZE(ibm_graphics), MAXPCHARS, 0);
692 #ifdef PC9800
693 	    if (ibmgraphics_mode_callback) (*ibmgraphics_mode_callback)();
694 #endif
695 	    break;
696 #endif /* ASCIIGRAPH */
697 #ifdef TERMLIB
698 	case DEC_GRAPHICS:
699 /*
700  * Use the VT100 line drawing character set.
701  */
702 	    iflags.DECgraphics = TRUE;
703 	    iflags.IBMgraphics = FALSE;
704 	    assign_graphics(dec_graphics, SIZE(dec_graphics), MAXPCHARS, 0);
705 	    if (decgraphics_mode_callback) (*decgraphics_mode_callback)();
706 	    break;
707 #endif /* TERMLIB */
708 #ifdef MAC_GRAPHICS_ENV
709 	case MAC_GRAPHICS:
710 	    assign_graphics(mac_graphics, SIZE(mac_graphics), MAXPCHARS, 0);
711 	    break;
712 #endif
713 	}
714     return;
715 }
716 
717 
718 #ifdef REINCARNATION
719 
720 /*
721  * saved display symbols for objects & features.
722  */
723 static uchar save_oc_syms[MAXOCLASSES] = DUMMY;
724 static uchar save_showsyms[MAXPCHARS]  = DUMMY;
725 static uchar save_monsyms[MAXPCHARS]   = DUMMY;
726 
727 static const uchar r_oc_syms[MAXOCLASSES] = {
728 /* 0*/	'\0',
729 	ILLOBJ_SYM,
730 	WEAPON_SYM,
731 	']',			/* armor */
732 	RING_SYM,
733 /* 5*/	',',			/* amulet */
734 	TOOL_SYM,
735 	':',			/* food */
736 	POTION_SYM,
737 	SCROLL_SYM,
738 /*10*/	SPBOOK_SYM,
739 	WAND_SYM,
740 	GEM_SYM,		/* gold -- yes it's the same as gems */
741 	GEM_SYM,
742 	ROCK_SYM,
743 /*15*/	BALL_SYM,
744 	CHAIN_SYM,
745 	VENOM_SYM
746 };
747 
748 # ifdef ASCIIGRAPH
749 /* Rogue level graphics.  Under IBM graphics mode, use the symbols that were
750  * used for Rogue on the IBM PC.  Unfortunately, this can't be completely
751  * done because some of these are control characters--armor and rings under
752  * DOS, and a whole bunch of them under Linux.  Use the TTY Rogue characters
753  * for those cases.
754  */
755 static const uchar IBM_r_oc_syms[MAXOCLASSES] = {	/* a la EPYX Rogue */
756 /* 0*/	'\0',
757 	ILLOBJ_SYM,
758 #  if defined(MSDOS) || defined(OS2) || ( defined(WIN32) && !defined(MSWIN_GRAPHICS) )
759 	0x18,			/* weapon: up arrow */
760 /*	0x0a, */ ARMOR_SYM,	/* armor:  Vert rect with o */
761 /*	0x09, */ RING_SYM,	/* ring:   circle with arrow */
762 /* 5*/	0x0c,			/* amulet: "female" symbol */
763 	TOOL_SYM,
764 	0x05,			/* food:   club (as in cards) */
765 	0xad,			/* potion: upside down '!' */
766 	0x0e,			/* scroll: musical note */
767 /*10*/	SPBOOK_SYM,
768 	0xe7,			/* wand:   greek tau */
769 	0x0f,			/* gold:   yes it's the same as gems */
770 	0x0f,			/* gems:   fancy '*' */
771 #  else
772 	')',			/* weapon  */
773 	ARMOR_SYM,		/* armor */
774 	RING_SYM,		/* ring */
775 /* 5*/	',',			/* amulet  */
776 	TOOL_SYM,
777 	':',			/* food    */
778 	0xad,			/* potion: upside down '!' */
779 	SCROLL_SYM,		/* scroll  */
780 /*10*/	SPBOOK_SYM,
781 	0xe7,			/* wand:   greek tau */
782 	GEM_SYM,		/* gold:   yes it's the same as gems */
783 	GEM_SYM,		/* gems    */
784 #  endif
785 	ROCK_SYM,
786 /*15*/	BALL_SYM,
787 	CHAIN_SYM,
788 	VENOM_SYM
789 };
790 # endif /* ASCIIGRAPH */
791 
792 void
assign_rogue_graphics(is_rlevel)793 assign_rogue_graphics(is_rlevel)
794 boolean is_rlevel;
795 {
796     /* Adjust graphics display characters on Rogue levels */
797 
798     if (is_rlevel) {
799 	register int i;
800 
801 	(void) memcpy((genericptr_t)save_showsyms,
802 		      (genericptr_t)showsyms, sizeof showsyms);
803 	(void) memcpy((genericptr_t)save_oc_syms,
804 		      (genericptr_t)oc_syms, sizeof oc_syms);
805 	(void) memcpy((genericptr_t)save_monsyms,
806 		      (genericptr_t)monsyms, sizeof monsyms);
807 
808 	/* Use a loop: char != uchar on some machines. */
809 	for (i = 0; i < MAXMCLASSES; i++)
810 	    monsyms[i] = def_monsyms[i];
811 # if defined(ASCIIGRAPH) && !defined(MSWIN_GRAPHICS)
812 	if (iflags.IBMgraphics
813 #  if defined(USE_TILES) && defined(MSDOS)
814 		&& !iflags.grmode
815 #  endif
816 		)
817 	    monsyms[S_HUMAN] = 0x01; /* smiley face */
818 # endif
819 	for (i = 0; i < MAXPCHARS; i++)
820 	    showsyms[i] = defsyms[i].sym;
821 
822 /*
823  * Some day if these rogue showsyms get much more extensive than this,
824  * we may want to create r_showsyms, and IBM_r_showsyms arrays to hold
825  * all of this info and to simply initialize it via a for() loop like r_oc_syms.
826  */
827 
828 # ifdef ASCIIGRAPH
829 	if (!iflags.IBMgraphics
830 #  if defined(USE_TILES) && defined(MSDOS)
831 		|| iflags.grmode
832 #  endif
833 				) {
834 # endif
835 	    showsyms[S_vodoor]  = showsyms[S_hodoor]  = showsyms[S_ndoor] = '+';
836 	    showsyms[S_upstair] = showsyms[S_dnstair] = '%';
837 # ifdef ASCIIGRAPH
838 	} else {
839 	    /* a la EPYX Rogue */
840 	    showsyms[S_vwall]   = 0xba; /* all walls now use	*/
841 	    showsyms[S_hwall]   = 0xcd; /* double line graphics	*/
842 	    showsyms[S_tlcorn]  = 0xc9;
843 	    showsyms[S_trcorn]  = 0xbb;
844 	    showsyms[S_blcorn]  = 0xc8;
845 	    showsyms[S_brcorn]  = 0xbc;
846 	    showsyms[S_crwall]  = 0xce;
847 	    showsyms[S_tuwall]  = 0xca;
848 	    showsyms[S_tdwall]  = 0xcb;
849 	    showsyms[S_tlwall]  = 0xb9;
850 	    showsyms[S_trwall]  = 0xcc;
851 	    showsyms[S_ndoor]   = 0xce;
852 	    showsyms[S_vodoor]  = 0xce;
853 	    showsyms[S_hodoor]  = 0xce;
854 	    showsyms[S_room]    = 0xfa; /* centered dot */
855 	    showsyms[S_corr]    = 0xb1;
856 	    showsyms[S_litcorr] = 0xb2;
857 	    showsyms[S_upstair] = 0xf0; /* Greek Xi */
858 	    showsyms[S_dnstair] = 0xf0;
859 #ifndef MSWIN_GRAPHICS
860 	    showsyms[S_arrow_trap] = 0x04; /* diamond (cards) */
861 	    showsyms[S_dart_trap] = 0x04;
862 	    showsyms[S_falling_rock_trap] = 0x04;
863 	    showsyms[S_squeaky_board] = 0x04;
864 	    showsyms[S_bear_trap] = 0x04;
865 	    showsyms[S_land_mine] = 0x04;
866 	    showsyms[S_rolling_boulder_trap] = 0x04;
867 	    showsyms[S_sleeping_gas_trap] = 0x04;
868 	    showsyms[S_rust_trap] = 0x04;
869 	    showsyms[S_fire_trap] = 0x04;
870 	    showsyms[S_pit] = 0x04;
871 	    showsyms[S_spiked_pit] = 0x04;
872 	    showsyms[S_hole] = 0x04;
873 	    showsyms[S_trap_door] = 0x04;
874 	    showsyms[S_teleportation_trap] = 0x04;
875 	    showsyms[S_level_teleporter] = 0x04;
876 	    showsyms[S_magic_portal] = 0x04;
877 	    showsyms[S_web] = 0x04;
878 	    showsyms[S_statue_trap] = 0x04;
879 	    showsyms[S_magic_trap] = 0x04;
880 	    showsyms[S_anti_magic_trap] = 0x04;
881 	    showsyms[S_polymorph_trap] = 0x04;
882 #endif
883 	}
884 #endif /* ASCIIGRAPH */
885 
886 	for (i = 0; i < MAXOCLASSES; i++) {
887 #if defined(ASCIIGRAPH) && !defined(LINUX)
888 	    if (iflags.IBMgraphics
889 # if defined(USE_TILES) && defined(MSDOS)
890 		&& !iflags.grmode
891 # endif
892 		)
893 		oc_syms[i] = IBM_r_oc_syms[i];
894 	    else
895 #endif /* ASCIIGRAPH && !LINUX */
896 		oc_syms[i] = r_oc_syms[i];
897 	}
898 #if defined(MSDOS) && defined(USE_TILES)
899 	if (iflags.grmode) tileview(TRUE);
900 #endif
901     } else {
902 	(void) memcpy((genericptr_t)showsyms,
903 		      (genericptr_t)save_showsyms, sizeof showsyms);
904 	(void) memcpy((genericptr_t)oc_syms,
905 		      (genericptr_t)save_oc_syms, sizeof oc_syms);
906 	(void) memcpy((genericptr_t)monsyms,
907 		      (genericptr_t)save_monsyms, sizeof monsyms);
908 #if defined(MSDOS) && defined(USE_TILES)
909 	if (iflags.grmode) tileview(TRUE);
910 #endif
911     }
912 }
913 #endif /* REINCARNATION */
914 
915 /*drawing.c*/
916