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