OSDN Git Service

patch src/
[jnethack/source.git] / src / drawing.c
1 /* NetHack 3.6  drawing.c       $NHDT-Date: 1447124657 2015/11/10 03:04:17 $  $NHDT-Branch: master $:$NHDT-Revision: 1.49 $ */
2 /* Copyright (c) NetHack Development Team 1992.                   */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11 #include "tcap.h"
12
13 /* Relevant header information in rm.h, objclass.h, and monsym.h. */
14
15 #ifdef C
16 #undef C
17 #endif
18
19 #ifdef TEXTCOLOR
20 #define C(n) n
21 #else
22 #define C(n)
23 #endif
24
25 struct symsetentry symset[NUM_GRAPHICS];
26
27 int currentgraphics = 0;
28
29 nhsym showsyms[SYM_MAX] = DUMMY; /* symbols to be displayed */
30 nhsym l_syms[SYM_MAX] = DUMMY;   /* loaded symbols          */
31 nhsym r_syms[SYM_MAX] = DUMMY;   /* rogue symbols           */
32
33 nhsym warnsyms[WARNCOUNT] = DUMMY; /* the current warning display symbols */
34 const char invisexplain[] = "remembered, unseen, creature";
35
36 /* Default object class symbols.  See objclass.h.
37  * {symbol, name, explain}
38  *     name:    used in object_detect().
39  *     explain: used in do_look().
40  */
41 const struct class_sym def_oc_syms[MAXOCLASSES] = {
42     { '\0', "", "" }, /* placeholder for the "random class" */
43     { ILLOBJ_SYM, "illegal objects", "strange object" },
44     { WEAPON_SYM, "weapons", "weapon" },
45     { ARMOR_SYM, "armor", "suit or piece of armor" },
46     { RING_SYM, "rings", "ring" },
47     { AMULET_SYM, "amulets", "amulet" },
48     { TOOL_SYM, "tools", "useful item (pick-axe, key, lamp...)" },
49     { FOOD_SYM, "food", "piece of food" },
50     { POTION_SYM, "potions", "potion" },
51     { SCROLL_SYM, "scrolls", "scroll" },
52     { SPBOOK_SYM, "spellbooks", "spellbook" },
53     { WAND_SYM, "wands", "wand" },
54     { GOLD_SYM, "coins", "pile of coins" },
55     { GEM_SYM, "rocks", "gem or rock" },
56     { ROCK_SYM, "large stones", "boulder or statue" },
57     { BALL_SYM, "iron balls", "iron ball" },
58     { CHAIN_SYM, "chains", "iron chain" },
59     { VENOM_SYM, "venoms", "splash of venom" }
60 };
61
62 /* Default monster class symbols.  See monsym.h. */
63 const struct class_sym def_monsyms[MAXMCLASSES] = {
64     { '\0', "", "" },
65     { DEF_ANT, "", "ant or other insect" },
66     { DEF_BLOB, "", "blob" },
67     { DEF_COCKATRICE, "", "cockatrice" },
68     { DEF_DOG, "", "dog or other canine" },
69     { DEF_EYE, "", "eye or sphere" },
70     { DEF_FELINE, "", "cat or other feline" },
71     { DEF_GREMLIN, "", "gremlin" },
72     { DEF_HUMANOID, "", "humanoid" },
73     { DEF_IMP, "", "imp or minor demon" },
74     { DEF_JELLY, "", "jelly" },
75     { DEF_KOBOLD, "", "kobold" },
76     { DEF_LEPRECHAUN, "", "leprechaun" },
77     { DEF_MIMIC, "", "mimic" },
78     { DEF_NYMPH, "", "nymph" },
79     { DEF_ORC, "", "orc" },
80     { DEF_PIERCER, "", "piercer" },
81     { DEF_QUADRUPED, "", "quadruped" },
82     { DEF_RODENT, "", "rodent" },
83     { DEF_SPIDER, "", "arachnid or centipede" },
84     { DEF_TRAPPER, "", "trapper or lurker above" },
85     { DEF_UNICORN, "", "unicorn or horse" },
86     { DEF_VORTEX, "", "vortex" },
87     { DEF_WORM, "", "worm" },
88     { DEF_XAN, "", "xan or other mythical/fantastic insect" },
89     { DEF_LIGHT, "", "light" },
90     { DEF_ZRUTY, "", "zruty" },
91     { DEF_ANGEL, "", "angelic being" },
92     { DEF_BAT, "", "bat or bird" },
93     { DEF_CENTAUR, "", "centaur" },
94     { DEF_DRAGON, "", "dragon" },
95     { DEF_ELEMENTAL, "", "elemental" },
96     { DEF_FUNGUS, "", "fungus or mold" },
97     { DEF_GNOME, "", "gnome" },
98     { DEF_GIANT, "", "giant humanoid" },
99     { '\0', "", "invisible monster" },
100     { DEF_JABBERWOCK, "", "jabberwock" },
101     { DEF_KOP, "", "Keystone Kop" },
102     { DEF_LICH, "", "lich" },
103     { DEF_MUMMY, "", "mummy" },
104     { DEF_NAGA, "", "naga" },
105     { DEF_OGRE, "", "ogre" },
106     { DEF_PUDDING, "", "pudding or ooze" },
107     { DEF_QUANTMECH, "", "quantum mechanic" },
108     { DEF_RUSTMONST, "", "rust monster or disenchanter" },
109     { DEF_SNAKE, "", "snake" },
110     { DEF_TROLL, "", "troll" },
111     { DEF_UMBER, "", "umber hulk" },
112     { DEF_VAMPIRE, "", "vampire" },
113     { DEF_WRAITH, "", "wraith" },
114     { DEF_XORN, "", "xorn" },
115     { DEF_YETI, "", "apelike creature" },
116     { DEF_ZOMBIE, "", "zombie" },
117     { DEF_HUMAN, "", "human or elf" },
118     { DEF_GHOST, "", "ghost" },
119     { DEF_GOLEM, "", "golem" },
120     { DEF_DEMON, "", "major demon" },
121     { DEF_EEL, "", "sea monster" },
122     { DEF_LIZARD, "", "lizard" },
123     { DEF_WORM_TAIL, "", "long worm tail" },
124     { DEF_MIMIC_DEF, "", "mimic" },
125 };
126
127 const struct symdef def_warnsyms[WARNCOUNT] = {
128     /* white warning  */
129 /*JP
130     { '0', "unknown creature causing you worry",    C(CLR_WHITE) },
131 */
132     { '0', "\82 \82È\82½\82ª\8bC\82É\82µ\82Ä\82¢\82é\93ä\82Ì\89ö\95¨", C(CLR_WHITE)},
133     /* pink warning   */
134 /*JP
135     { '1', "unknown creature causing you concern",  C(CLR_RED) },
136 */
137     { '1', "\82 \82È\82½\82ª\90S\94z\82µ\82Ä\82¢\82é\93ä\82Ì\89ö\95¨", C(CLR_RED)},
138     /* red warning    */
139 /*JP
140     { '2', "unknown creature causing you anxiety",  C(CLR_RED) },
141 */
142     { '2', "\82 \82È\82½\82ª\8c\9c\94O\82µ\82Ä\82¢\82é\93ä\82Ì\89ö\95¨", C(CLR_RED)},
143     /* ruby warning   */
144 /*JP
145     { '3', "unknown creature causing you disquiet", C(CLR_RED) },
146 */
147     { '3', "\82 \82È\82½\82ª\8bC\82ð\82à\82ñ\82Å\82¢\82é\93ä\82Ì\89ö\95¨", C(CLR_RED)},
148     /* purple warning */
149 /*JP
150     { '4', "unknown creature causing you alarm",    C(CLR_MAGENTA) },
151 */
152     { '4', "\82 \82È\82½\82ª\8b°\82ê\82Ä\82¢\82é\93ä\82Ì\89ö\95¨", C(CLR_MAGENTA)},
153     /* black warning  */
154 /*JP
155     { '5', "unknown creature causing you dread",    C(CLR_BRIGHT_MAGENTA) },
156 */
157     { '5', "\82 \82È\82½\82ª\94ñ\8fí\82É\8b°\82ê\82Ä\82¢\82é\93ä\82Ì\89ö\95¨", C(CLR_BRIGHT_MAGENTA)},
158 };
159
160 /*
161  *  Default screen symbols with explanations and colors.
162  */
163 const struct symdef defsyms[MAXPCHARS] = {
164 /* 0*/ { ' ', "dark part of a room", C(NO_COLOR) },  /* stone */
165        { '|', "wall", C(CLR_GRAY) },                 /* vwall */
166        { '-', "wall", C(CLR_GRAY) },                 /* hwall */
167        { '-', "wall", C(CLR_GRAY) },                 /* tlcorn */
168        { '-', "wall", C(CLR_GRAY) },                 /* trcorn */
169        { '-', "wall", C(CLR_GRAY) },                 /* blcorn */
170        { '-', "wall", C(CLR_GRAY) },                 /* brcorn */
171        { '-', "wall", C(CLR_GRAY) },                 /* crwall */
172        { '-', "wall", C(CLR_GRAY) },                 /* tuwall */
173        { '-', "wall", C(CLR_GRAY) },                 /* tdwall */
174 /*10*/ { '|', "wall", C(CLR_GRAY) },                 /* tlwall */
175        { '|', "wall", C(CLR_GRAY) },                 /* trwall */
176        { '.', "doorway", C(CLR_GRAY) },              /* ndoor */
177        { '-', "open door", C(CLR_BROWN) },           /* vodoor */
178        { '|', "open door", C(CLR_BROWN) },           /* hodoor */
179        { '+', "closed door", C(CLR_BROWN) },         /* vcdoor */
180        { '+', "closed door", C(CLR_BROWN) },         /* hcdoor */
181        { '#', "iron bars", C(HI_METAL) },            /* bars */
182        { '#', "tree", C(CLR_GREEN) },                /* tree */
183        { '.', "floor of a room", C(CLR_GRAY) },      /* room */
184 /*20*/ { '.', "dark part of a room", C(CLR_BLACK) }, /* dark room */
185        { '#', "corridor", C(CLR_GRAY) },             /* dark corr */
186        { '#', "lit corridor", C(CLR_GRAY) },   /* lit corr (see mapglyph.c) */
187        { '<', "staircase up", C(CLR_GRAY) },         /* upstair */
188        { '>', "staircase down", C(CLR_GRAY) },       /* dnstair */
189        { '<', "ladder up", C(CLR_BROWN) },           /* upladder */
190        { '>', "ladder down", C(CLR_BROWN) },         /* dnladder */
191        { '_', "altar", C(CLR_GRAY) },                /* altar */
192        { '|', "grave", C(CLR_GRAY) },                /* grave */
193        { '\\', "opulent throne", C(HI_GOLD) },       /* throne */
194 /*30*/ { '#', "sink", C(CLR_GRAY) },                 /* sink */
195        { '{', "fountain", C(CLR_BLUE) },             /* fountain */
196        { '}', "water", C(CLR_BLUE) },                /* pool */
197        { '.', "ice", C(CLR_CYAN) },                  /* ice */
198        { '}', "molten lava", C(CLR_RED) },           /* lava */
199        { '.', "lowered drawbridge", C(CLR_BROWN) },  /* vodbridge */
200        { '.', "lowered drawbridge", C(CLR_BROWN) },  /* hodbridge */
201        { '#', "raised drawbridge", C(CLR_BROWN) },   /* vcdbridge */
202        { '#', "raised drawbridge", C(CLR_BROWN) },   /* hcdbridge */
203        { ' ', "air", C(CLR_CYAN) },                  /* open air */
204 /*40*/ { '#', "cloud", C(CLR_GRAY) },                /* [part of] a cloud */
205        { '}', "water", C(CLR_BLUE) },                /* under water */
206        { '^', "arrow trap", C(HI_METAL) },           /* trap */
207        { '^', "dart trap", C(HI_METAL) },            /* trap */
208        { '^', "falling rock trap", C(CLR_GRAY) },    /* trap */
209        { '^', "squeaky board", C(CLR_BROWN) },       /* trap */
210        { '^', "bear trap", C(HI_METAL) },            /* trap */
211        { '^', "land mine", C(CLR_RED) },             /* trap */
212        { '^', "rolling boulder trap", C(CLR_GRAY) }, /* trap */
213        { '^', "sleeping gas trap", C(HI_ZAP) },      /* trap */
214 /*50*/ { '^', "rust trap", C(CLR_BLUE) },            /* trap */
215        { '^', "fire trap", C(CLR_ORANGE) },          /* trap */
216        { '^', "pit", C(CLR_BLACK) },                 /* trap */
217        { '^', "spiked pit", C(CLR_BLACK) },          /* trap */
218        { '^', "hole", C(CLR_BROWN) },                /* trap */
219        { '^', "trap door", C(CLR_BROWN) },           /* trap */
220        { '^', "teleportation trap", C(CLR_MAGENTA) },  /* trap */
221        { '^', "level teleporter", C(CLR_MAGENTA) },    /* trap */
222        { '^', "magic portal", C(CLR_BRIGHT_MAGENTA) }, /* trap */
223        { '"', "web", C(CLR_GRAY) },                    /* web */
224 /*60*/ { '^', "statue trap", C(CLR_GRAY) },            /* trap */
225        { '^', "magic trap", C(HI_ZAP) },               /* trap */
226        { '^', "anti-magic field", C(HI_ZAP) },         /* trap */
227        { '^', "polymorph trap", C(CLR_BRIGHT_GREEN) }, /* trap */
228        { '^', "vibrating square", C(CLR_YELLOW) },     /* trap */
229        { '|', "wall", C(CLR_GRAY) },            /* vbeam */
230        { '-', "wall", C(CLR_GRAY) },            /* hbeam */
231        { '\\', "wall", C(CLR_GRAY) },           /* lslant */
232        { '/', "wall", C(CLR_GRAY) },            /* rslant */
233        { '*', "", C(CLR_WHITE) },               /* dig beam */
234        { '!', "", C(CLR_WHITE) },               /* camera flash beam */
235        { ')', "", C(HI_WOOD) },                 /* boomerang open left */
236 /*70*/ { '(', "", C(HI_WOOD) },                 /* boomerang open right */
237        { '0', "", C(HI_ZAP) },                  /* 4 magic shield symbols */
238        { '#', "", C(HI_ZAP) },
239        { '@', "", C(HI_ZAP) },
240        { '*', "", C(HI_ZAP) },
241        { '#', "poison cloud", C(CLR_BRIGHT_GREEN) },   /* part of a cloud */
242        { '?', "valid position", C(CLR_BRIGHT_GREEN) }, /*  target position */
243        { '/', "", C(CLR_GREEN) },         /* swallow top left      */
244        { '-', "", C(CLR_GREEN) },         /* swallow top center    */
245        { '\\', "", C(CLR_GREEN) },        /* swallow top right     */
246 /*80*/ { '|', "", C(CLR_GREEN) },         /* swallow middle left   */
247        { '|', "", C(CLR_GREEN) },         /* swallow middle right  */
248        { '\\', "", C(CLR_GREEN) },        /* swallow bottom left   */
249        { '-', "", C(CLR_GREEN) },         /* swallow bottom center */
250        { '/', "", C(CLR_GREEN) },         /* swallow bottom right  */
251        { '/', "", C(CLR_ORANGE) },        /* explosion top left     */
252        { '-', "", C(CLR_ORANGE) },        /* explosion top center   */
253        { '\\', "", C(CLR_ORANGE) },       /* explosion top right    */
254        { '|', "", C(CLR_ORANGE) },        /* explosion middle left  */
255        { ' ', "", C(CLR_ORANGE) },        /* explosion middle center*/
256 /*90*/ { '|', "", C(CLR_ORANGE) },        /* explosion middle right */
257        { '\\', "", C(CLR_ORANGE) },       /* explosion bottom left  */
258        { '-', "", C(CLR_ORANGE) },        /* explosion bottom center*/
259        { '/', "", C(CLR_ORANGE) },        /* explosion bottom right */
260 };
261
262 /* default rogue level symbols */
263 static const uchar def_r_oc_syms[MAXOCLASSES] = {
264 /* 0*/ '\0', ILLOBJ_SYM, WEAPON_SYM, ']', /* armor */
265        RING_SYM,
266 /* 5*/ ',',                     /* amulet */
267        TOOL_SYM, ':',           /* food */
268        POTION_SYM, SCROLL_SYM,
269 /*10*/ SPBOOK_SYM, WAND_SYM,
270        GEM_SYM,                /* gold -- yes it's the same as gems */
271        GEM_SYM, ROCK_SYM,
272 /*15*/ BALL_SYM, CHAIN_SYM, VENOM_SYM
273 };
274
275 #undef C
276
277 #ifdef TERMLIB
278 void NDECL((*decgraphics_mode_callback)) = 0; /* set in tty_start_screen() */
279 #endif /* TERMLIB */
280
281 #ifdef PC9800
282 void NDECL((*ibmgraphics_mode_callback)) = 0; /* set in tty_start_screen() */
283 void NDECL((*ascgraphics_mode_callback)) = 0; /* set in tty_start_screen() */
284 #endif
285
286 /*
287  * Convert the given character to an object class.  If the character is not
288  * recognized, then MAXOCLASSES is returned.  Used in detect.c, invent.c,
289  * objnam.c, options.c, pickup.c, sp_lev.c, lev_main.c, and tilemap.c.
290  */
291 int
292 def_char_to_objclass(ch)
293 char ch;
294 {
295     int i;
296     for (i = 1; i < MAXOCLASSES; i++)
297         if (ch == def_oc_syms[i].sym)
298             break;
299     return i;
300 }
301
302 /*
303  * Convert a character into a monster class.  This returns the _first_
304  * match made.  If there are are no matches, return MAXMCLASSES.
305  * Used in detect.c, options.c, read.c, sp_lev.c, and lev_main.c
306  */
307 int
308 def_char_to_monclass(ch)
309 char ch;
310 {
311     int i;
312     for (i = 1; i < MAXMCLASSES; i++)
313         if (ch == def_monsyms[i].sym)
314             break;
315     return i;
316 }
317
318 /*
319  * Explanations of the functions found below:
320  *
321  * init_symbols()
322  *                     Sets the current display symbols, the
323  *                     loadable symbols to the default NetHack
324  *                     symbols, including the r_syms rogue level
325  *                     symbols. This would typically be done
326  *                     immediately after execution begins. Any
327  *                     previously loaded external symbol sets are
328  *                     discarded.
329  *
330  * switch_symbols(arg)
331  *                     Called to swap in new current display symbols
332  *                     (showsyms) from either the default symbols,
333  *                     or from the loaded symbols.
334  *
335  *                     If (arg == 0) then showsyms are taken from
336  *                     defsyms, def_oc_syms, and def_monsyms.
337  *
338  *                     If (arg != 0), which is the normal expected
339  *                     usage, then showsyms are taken from the
340  *                     adjustable display symbols found in l_syms.
341  *                     l_syms may have been loaded from an external
342  *                     symbol file by config file options or interactively
343  *                     in the Options menu.
344  *
345  * assign_graphics(arg)
346  *
347  *                     This is used in the game core to toggle in and
348  *                     out of other {rogue} level display modes.
349  *
350  *                     If arg is ROGUESET, this places the rogue level
351  *                     symbols from r_syms into showsyms.
352  *
353  *                     If arg is PRIMARY, this places the symbols
354  *                     from l_monsyms into showsyms.
355  *
356  * update_l_symset()
357  *                     Update a member of the loadable (l_*) symbol set.
358  *
359  * update_r_symset()
360  *                     Update a member of the rogue (r_*) symbol set.
361  *
362  */
363
364 void
365 init_symbols()
366 {
367     init_l_symbols();
368     init_showsyms();
369     init_r_symbols();
370 }
371
372 void
373 update_bouldersym()
374 {
375     showsyms[SYM_BOULDER + SYM_OFF_X] = iflags.bouldersym;
376     l_syms[SYM_BOULDER + SYM_OFF_X] = iflags.bouldersym;
377     r_syms[SYM_BOULDER + SYM_OFF_X] = iflags.bouldersym;
378 }
379
380 void
381 init_showsyms()
382 {
383     register int i;
384
385     for (i = 0; i < MAXPCHARS; i++)
386         showsyms[i + SYM_OFF_P] = defsyms[i].sym;
387     for (i = 0; i < MAXOCLASSES; i++)
388         showsyms[i + SYM_OFF_O] = def_oc_syms[i].sym;
389     for (i = 0; i < MAXMCLASSES; i++)
390         showsyms[i + SYM_OFF_M] = def_monsyms[i].sym;
391     for (i = 0; i < WARNCOUNT; i++)
392         showsyms[i + SYM_OFF_W] = def_warnsyms[i].sym;
393     for (i = 0; i < MAXOTHER; i++) {
394         if (i == SYM_BOULDER)
395             showsyms[i + SYM_OFF_X] = iflags.bouldersym
396                                         ? iflags.bouldersym
397                                         : def_oc_syms[ROCK_CLASS].sym;
398         else if (i == SYM_INVISIBLE)
399             showsyms[i + SYM_OFF_X] = DEF_INVISIBLE;
400     }
401 }
402
403 /* initialize defaults for the loadable symset */
404 void
405 init_l_symbols()
406 {
407     register int i;
408
409     for (i = 0; i < MAXPCHARS; i++)
410         l_syms[i + SYM_OFF_P] = defsyms[i].sym;
411     for (i = 0; i < MAXOCLASSES; i++)
412         l_syms[i + SYM_OFF_O] = def_oc_syms[i].sym;
413     for (i = 0; i < MAXMCLASSES; i++)
414         l_syms[i + SYM_OFF_M] = def_monsyms[i].sym;
415     for (i = 0; i < WARNCOUNT; i++)
416         l_syms[i + SYM_OFF_W] = def_warnsyms[i].sym;
417     for (i = 0; i < MAXOTHER; i++) {
418         if (i == SYM_BOULDER)
419             l_syms[i + SYM_OFF_X] = iflags.bouldersym
420                                       ? iflags.bouldersym
421                                       : def_oc_syms[ROCK_CLASS].sym;
422         else if (i == SYM_INVISIBLE)
423             l_syms[i + SYM_OFF_X] = DEF_INVISIBLE;
424     }
425
426     clear_symsetentry(PRIMARY, FALSE);
427 }
428
429 void
430 init_r_symbols()
431 {
432     register int i;
433
434     /* These are defaults that can get overwritten
435        later by the roguesymbols option */
436
437     for (i = 0; i < MAXPCHARS; i++)
438         r_syms[i + SYM_OFF_P] = defsyms[i].sym;
439     r_syms[S_vodoor] = r_syms[S_hodoor] = r_syms[S_ndoor] = '+';
440     r_syms[S_upstair] = r_syms[S_dnstair] = '%';
441
442     for (i = 0; i < MAXOCLASSES; i++)
443         r_syms[i + SYM_OFF_O] = def_r_oc_syms[i];
444     for (i = 0; i < MAXMCLASSES; i++)
445         r_syms[i + SYM_OFF_M] = def_monsyms[i].sym;
446     for (i = 0; i < WARNCOUNT; i++)
447         r_syms[i + SYM_OFF_W] = def_warnsyms[i].sym;
448     for (i = 0; i < MAXOTHER; i++) {
449         if (i == SYM_BOULDER)
450             r_syms[i + SYM_OFF_X] = iflags.bouldersym
451                                       ? iflags.bouldersym
452                                       : def_oc_syms[ROCK_CLASS].sym;
453         else if (i == SYM_INVISIBLE)
454             r_syms[i + SYM_OFF_X] = DEF_INVISIBLE;
455     }
456
457     clear_symsetentry(ROGUESET, FALSE);
458     /* default on Rogue level is no color
459      * but some symbol sets can override that
460      */
461     symset[ROGUESET].nocolor = 1;
462 }
463
464 void
465 assign_graphics(whichset)
466 int whichset;
467 {
468     register int i;
469
470     switch (whichset) {
471     case ROGUESET:
472         /* Adjust graphics display characters on Rogue levels */
473
474         for (i = 0; i < SYM_MAX; i++)
475             showsyms[i] = r_syms[i];
476
477 #if defined(MSDOS) && defined(USE_TILES)
478         if (iflags.grmode)
479             tileview(FALSE);
480 #endif
481         currentgraphics = ROGUESET;
482         break;
483
484     case PRIMARY:
485     default:
486         for (i = 0; i < SYM_MAX; i++)
487             showsyms[i] = l_syms[i];
488
489 #if defined(MSDOS) && defined(USE_TILES)
490         if (iflags.grmode)
491             tileview(TRUE);
492 #endif
493         currentgraphics = PRIMARY;
494         break;
495     }
496 }
497
498 void
499 switch_symbols(nondefault)
500 int nondefault;
501 {
502     register int i;
503
504     if (nondefault) {
505         for (i = 0; i < SYM_MAX; i++)
506             showsyms[i] = l_syms[i];
507 #ifdef PC9800
508         if (SYMHANDLING(H_IBM) && ibmgraphics_mode_callback)
509             (*ibmgraphics_mode_callback)();
510         else if (!symset[currentgraphics].name && ascgraphics_mode_callback)
511             (*ascgraphics_mode_callback)();
512 #endif
513 #ifdef TERMLIB
514         if (SYMHANDLING(H_DEC) && decgraphics_mode_callback)
515             (*decgraphics_mode_callback)();
516 #endif
517     } else
518         init_symbols();
519 }
520
521 void
522 update_l_symset(symp, val)
523 struct symparse *symp;
524 int val;
525 {
526     l_syms[symp->idx] = val;
527 }
528
529 void
530 update_r_symset(symp, val)
531 struct symparse *symp;
532 int val;
533 {
534     r_syms[symp->idx] = val;
535 }
536
537 void
538 clear_symsetentry(which_set, name_too)
539 int which_set;
540 boolean name_too;
541 {
542     if (symset[which_set].desc)
543         free((genericptr_t) symset[which_set].desc);
544     symset[which_set].desc = (char *) 0;
545
546     symset[which_set].handling = H_UNK;
547     symset[which_set].nocolor = 0;
548     /* initialize restriction bits */
549     symset[which_set].primary = 0;
550     symset[which_set].rogue = 0;
551
552     if (name_too) {
553         if (symset[which_set].name)
554             free((genericptr_t) symset[which_set].name);
555         symset[which_set].name = (char *) 0;
556     }
557 }
558
559 /*
560  * If you are adding code somewhere to be able to recognize
561  * particular types of symset "handling", define a
562  * H_XXX macro in include/rm.h and add the name
563  * to this array at the matching offset.
564  */
565 const char *known_handling[] = {
566     "UNKNOWN", /* H_UNK */
567     "IBM",     /* H_IBM */
568     "DEC",     /* H_DEC */
569     (const char *) 0,
570 };
571
572 /*
573  * Accepted keywords for symset restrictions.
574  * These can be virtually anything that you want to
575  * be able to test in the code someplace.
576  * Be sure to:
577  *    - add a corresponding Bitfield to the symsetentry struct in rm.h
578  *    - initialize the field to zero in parse_sym_line in the SYM_CONTROL
579  *      case 0 section of the idx switch. The location is prefaced with
580  *      with a comment stating "initialize restriction bits".
581  *    - set the value appropriately based on the index of your keyword
582  *      under the case 5 sections of the same SYM_CONTROL idx switches.
583  *    - add the field to clear_symsetentry()
584  */
585 const char *known_restrictions[] = {
586     "primary", "rogue", (const char *) 0,
587 };
588
589 struct symparse loadsyms[] = {
590     { SYM_CONTROL, 0, "start" },
591     { SYM_CONTROL, 0, "begin" },
592     { SYM_CONTROL, 1, "finish" },
593     { SYM_CONTROL, 2, "handling" },
594     { SYM_CONTROL, 3, "description" },
595     { SYM_CONTROL, 4, "color" },
596     { SYM_CONTROL, 4, "colour" },
597     { SYM_CONTROL, 5, "restrictions" },
598     { SYM_PCHAR, S_stone, "S_stone" },
599     { SYM_PCHAR, S_vwall, "S_vwall" },
600     { SYM_PCHAR, S_hwall, "S_hwall" },
601     { SYM_PCHAR, S_tlcorn, "S_tlcorn" },
602     { SYM_PCHAR, S_trcorn, "S_trcorn" },
603     { SYM_PCHAR, S_blcorn, "S_blcorn" },
604     { SYM_PCHAR, S_brcorn, "S_brcorn" },
605     { SYM_PCHAR, S_crwall, "S_crwall" },
606     { SYM_PCHAR, S_tuwall, "S_tuwall" },
607     { SYM_PCHAR, S_tdwall, "S_tdwall" },
608     { SYM_PCHAR, S_tlwall, "S_tlwall" },
609     { SYM_PCHAR, S_trwall, "S_trwall" },
610     { SYM_PCHAR, S_ndoor, "S_ndoor" },
611     { SYM_PCHAR, S_vodoor, "S_vodoor" },
612     { SYM_PCHAR, S_hodoor, "S_hodoor" },
613     { SYM_PCHAR, S_vcdoor, "S_vcdoor" },
614     { SYM_PCHAR, S_hcdoor, "S_hcdoor" },
615     { SYM_PCHAR, S_bars, "S_bars" },
616     { SYM_PCHAR, S_tree, "S_tree" },
617     { SYM_PCHAR, S_room, "S_room" },
618     { SYM_PCHAR, S_corr, "S_corr" },
619     { SYM_PCHAR, S_litcorr, "S_litcorr" },
620     { SYM_PCHAR, S_upstair, "S_upstair" },
621     { SYM_PCHAR, S_dnstair, "S_dnstair" },
622     { SYM_PCHAR, S_upladder, "S_upladder" },
623     { SYM_PCHAR, S_dnladder, "S_dnladder" },
624     { SYM_PCHAR, S_altar, "S_altar" },
625     { SYM_PCHAR, S_grave, "S_grave" },
626     { SYM_PCHAR, S_throne, "S_throne" },
627     { SYM_PCHAR, S_sink, "S_sink" },
628     { SYM_PCHAR, S_fountain, "S_fountain" },
629     { SYM_PCHAR, S_pool, "S_pool" },
630     { SYM_PCHAR, S_ice, "S_ice" },
631     { SYM_PCHAR, S_lava, "S_lava" },
632     { SYM_PCHAR, S_vodbridge, "S_vodbridge" },
633     { SYM_PCHAR, S_hodbridge, "S_hodbridge" },
634     { SYM_PCHAR, S_vcdbridge, "S_vcdbridge" },
635     { SYM_PCHAR, S_hcdbridge, "S_hcdbridge" },
636     { SYM_PCHAR, S_air, "S_air" },
637     { SYM_PCHAR, S_cloud, "S_cloud" },
638     { SYM_PCHAR, S_poisoncloud, "S_poisoncloud" },
639     { SYM_PCHAR, S_water, "S_water" },
640     { SYM_PCHAR, S_arrow_trap, "S_arrow_trap" },
641     { SYM_PCHAR, S_dart_trap, "S_dart_trap" },
642     { SYM_PCHAR, S_falling_rock_trap, "S_falling_rock_trap" },
643     { SYM_PCHAR, S_squeaky_board, "S_squeaky_board" },
644     { SYM_PCHAR, S_bear_trap, "S_bear_trap" },
645     { SYM_PCHAR, S_land_mine, "S_land_mine" },
646     { SYM_PCHAR, S_rolling_boulder_trap, "S_rolling_boulder_trap" },
647     { SYM_PCHAR, S_sleeping_gas_trap, "S_sleeping_gas_trap" },
648     { SYM_PCHAR, S_rust_trap, "S_rust_trap" },
649     { SYM_PCHAR, S_fire_trap, "S_fire_trap" },
650     { SYM_PCHAR, S_pit, "S_pit" },
651     { SYM_PCHAR, S_spiked_pit, "S_spiked_pit" },
652     { SYM_PCHAR, S_hole, "S_hole" },
653     { SYM_PCHAR, S_trap_door, "S_trap_door" },
654     { SYM_PCHAR, S_teleportation_trap, "S_teleportation_trap" },
655     { SYM_PCHAR, S_level_teleporter, "S_level_teleporter" },
656     { SYM_PCHAR, S_magic_portal, "S_magic_portal" },
657     { SYM_PCHAR, S_web, "S_web" },
658     { SYM_PCHAR, S_statue_trap, "S_statue_trap" },
659     { SYM_PCHAR, S_magic_trap, "S_magic_trap" },
660     { SYM_PCHAR, S_anti_magic_trap, "S_anti_magic_trap" },
661     { SYM_PCHAR, S_polymorph_trap, "S_polymorph_trap" },
662     { SYM_PCHAR, S_vbeam, "S_vbeam" },
663     { SYM_PCHAR, S_hbeam, "S_hbeam" },
664     { SYM_PCHAR, S_lslant, "S_lslant" },
665     { SYM_PCHAR, S_rslant, "S_rslant" },
666     { SYM_PCHAR, S_digbeam, "S_digbeam" },
667     { SYM_PCHAR, S_flashbeam, "S_flashbeam" },
668     { SYM_PCHAR, S_boomleft, "S_boomleft" },
669     { SYM_PCHAR, S_boomright, "S_boomright" },
670     { SYM_PCHAR, S_goodpos, "S_goodpos" },
671     { SYM_PCHAR, S_ss1, "S_ss1" },
672     { SYM_PCHAR, S_ss2, "S_ss2" },
673     { SYM_PCHAR, S_ss3, "S_ss3" },
674     { SYM_PCHAR, S_ss4, "S_ss4" },
675     { SYM_PCHAR, S_sw_tl, "S_sw_tl" },
676     { SYM_PCHAR, S_sw_tc, "S_sw_tc" },
677     { SYM_PCHAR, S_sw_tr, "S_sw_tr" },
678     { SYM_PCHAR, S_sw_ml, "S_sw_ml" },
679     { SYM_PCHAR, S_sw_mr, "S_sw_mr" },
680     { SYM_PCHAR, S_sw_bl, "S_sw_bl" },
681     { SYM_PCHAR, S_sw_bc, "S_sw_bc" },
682     { SYM_PCHAR, S_sw_br, "S_sw_br" },
683     { SYM_PCHAR, S_explode1, "S_explode1" },
684     { SYM_PCHAR, S_explode2, "S_explode2" },
685     { SYM_PCHAR, S_explode3, "S_explode3" },
686     { SYM_PCHAR, S_explode4, "S_explode4" },
687     { SYM_PCHAR, S_explode5, "S_explode5" },
688     { SYM_PCHAR, S_explode6, "S_explode6" },
689     { SYM_PCHAR, S_explode7, "S_explode7" },
690     { SYM_PCHAR, S_explode8, "S_explode8" },
691     { SYM_PCHAR, S_explode9, "S_explode9" },
692     { SYM_OC, WEAPON_CLASS + SYM_OFF_O, "S_weapon" },
693     { SYM_OC, ARMOR_CLASS + SYM_OFF_O, "S_armor" },
694     { SYM_OC, ARMOR_CLASS + SYM_OFF_O, "S_armour" },
695     { SYM_OC, RING_CLASS + SYM_OFF_O, "S_ring" },
696     { SYM_OC, AMULET_CLASS + SYM_OFF_O, "S_amulet" },
697     { SYM_OC, TOOL_CLASS + SYM_OFF_O, "S_tool" },
698     { SYM_OC, FOOD_CLASS + SYM_OFF_O, "S_food" },
699     { SYM_OC, POTION_CLASS + SYM_OFF_O, "S_potion" },
700     { SYM_OC, SCROLL_CLASS + SYM_OFF_O, "S_scroll" },
701     { SYM_OC, SPBOOK_CLASS + SYM_OFF_O, "S_book" },
702     { SYM_OC, WAND_CLASS + SYM_OFF_O, "S_wand" },
703     { SYM_OC, COIN_CLASS + SYM_OFF_O, "S_coin" },
704     { SYM_OC, GEM_CLASS + SYM_OFF_O, "S_gem" },
705     { SYM_OC, ROCK_CLASS + SYM_OFF_O, "S_rock" },
706     { SYM_OC, BALL_CLASS + SYM_OFF_O, "S_ball" },
707     { SYM_OC, CHAIN_CLASS + SYM_OFF_O, "S_chain" },
708     { SYM_OC, VENOM_CLASS + SYM_OFF_O, "S_venom" },
709     { SYM_MON, S_ANT + SYM_OFF_M, "S_ant" },
710     { SYM_MON, S_BLOB + SYM_OFF_M, "S_blob" },
711     { SYM_MON, S_COCKATRICE + SYM_OFF_M, "S_cockatrice" },
712     { SYM_MON, S_DOG + SYM_OFF_M, "S_dog" },
713     { SYM_MON, S_EYE + SYM_OFF_M, "S_eye" },
714     { SYM_MON, S_FELINE + SYM_OFF_M, "S_feline" },
715     { SYM_MON, S_GREMLIN + SYM_OFF_M, "S_gremlin" },
716     { SYM_MON, S_HUMANOID + SYM_OFF_M, "S_humanoid" },
717     { SYM_MON, S_IMP + SYM_OFF_M, "S_imp" },
718     { SYM_MON, S_JELLY + SYM_OFF_M, "S_jelly" },
719     { SYM_MON, S_KOBOLD + SYM_OFF_M, "S_kobold" },
720     { SYM_MON, S_LEPRECHAUN + SYM_OFF_M, "S_leprechaun" },
721     { SYM_MON, S_MIMIC + SYM_OFF_M, "S_mimic" },
722     { SYM_MON, S_NYMPH + SYM_OFF_M, "S_nymph" },
723     { SYM_MON, S_ORC + SYM_OFF_M, "S_orc" },
724     { SYM_MON, S_PIERCER + SYM_OFF_M, "S_piercer" },
725     { SYM_MON, S_QUADRUPED + SYM_OFF_M, "S_quadruped" },
726     { SYM_MON, S_RODENT + SYM_OFF_M, "S_rodent" },
727     { SYM_MON, S_SPIDER + SYM_OFF_M, "S_spider" },
728     { SYM_MON, S_TRAPPER + SYM_OFF_M, "S_trapper" },
729     { SYM_MON, S_UNICORN + SYM_OFF_M, "S_unicorn" },
730     { SYM_MON, S_VORTEX + SYM_OFF_M, "S_vortex" },
731     { SYM_MON, S_WORM + SYM_OFF_M, "S_worm" },
732     { SYM_MON, S_XAN + SYM_OFF_M, "S_xan" },
733     { SYM_MON, S_LIGHT + SYM_OFF_M, "S_light" },
734     { SYM_MON, S_ZRUTY + SYM_OFF_M, "S_zruty" },
735     { SYM_MON, S_ANGEL + SYM_OFF_M, "S_angel" },
736     { SYM_MON, S_BAT + SYM_OFF_M, "S_bat" },
737     { SYM_MON, S_CENTAUR + SYM_OFF_M, "S_centaur" },
738     { SYM_MON, S_DRAGON + SYM_OFF_M, "S_dragon" },
739     { SYM_MON, S_ELEMENTAL + SYM_OFF_M, "S_elemental" },
740     { SYM_MON, S_FUNGUS + SYM_OFF_M, "S_fungus" },
741     { SYM_MON, S_GNOME + SYM_OFF_M, "S_gnome" },
742     { SYM_MON, S_GIANT + SYM_OFF_M, "S_giant" },
743     { SYM_MON, S_JABBERWOCK + SYM_OFF_M, "S_jabberwock" },
744     { SYM_MON, S_KOP + SYM_OFF_M, "S_kop" },
745     { SYM_MON, S_LICH + SYM_OFF_M, "S_lich" },
746     { SYM_MON, S_MUMMY + SYM_OFF_M, "S_mummy" },
747     { SYM_MON, S_NAGA + SYM_OFF_M, "S_naga" },
748     { SYM_MON, S_OGRE + SYM_OFF_M, "S_ogre" },
749     { SYM_MON, S_PUDDING + SYM_OFF_M, "S_pudding" },
750     { SYM_MON, S_QUANTMECH + SYM_OFF_M, "S_quantmech" },
751     { SYM_MON, S_RUSTMONST + SYM_OFF_M, "S_rustmonst" },
752     { SYM_MON, S_SNAKE + SYM_OFF_M, "S_snake" },
753     { SYM_MON, S_TROLL + SYM_OFF_M, "S_troll" },
754     { SYM_MON, S_UMBER + SYM_OFF_M, "S_umber" },
755     { SYM_MON, S_VAMPIRE + SYM_OFF_M, "S_vampire" },
756     { SYM_MON, S_WRAITH + SYM_OFF_M, "S_wraith" },
757     { SYM_MON, S_XORN + SYM_OFF_M, "S_xorn" },
758     { SYM_MON, S_YETI + SYM_OFF_M, "S_yeti" },
759     { SYM_MON, S_ZOMBIE + SYM_OFF_M, "S_zombie" },
760     { SYM_MON, S_HUMAN + SYM_OFF_M, "S_human" },
761     { SYM_MON, S_GHOST + SYM_OFF_M, "S_ghost" },
762     { SYM_MON, S_GOLEM + SYM_OFF_M, "S_golem" },
763     { SYM_MON, S_DEMON + SYM_OFF_M, "S_demon" },
764     { SYM_MON, S_EEL + SYM_OFF_M, "S_eel" },
765     { SYM_MON, S_LIZARD + SYM_OFF_M, "S_lizard" },
766     { SYM_MON, S_WORM_TAIL + SYM_OFF_M, "S_worm_tail" },
767     { SYM_MON, S_MIMIC_DEF + SYM_OFF_M, "S_mimic_def" },
768     { SYM_OTH, SYM_BOULDER + SYM_OFF_X, "S_boulder" },
769     { SYM_OTH, SYM_INVISIBLE + SYM_OFF_X, "S_invisible" },
770     { 0, 0, (const char *) 0 } /* fence post */
771 };
772
773 /*drawing.c*/