1 /* NetHack 3.7	symbols.c	$NHDT-Date: 1596498214 2020/08/03 23:43:34 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */
2 /* Copyright (c) NetHack Development Team 2020.                   */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #include "hack.h"
6 #include "tcap.h"
7 
8 extern const uchar def_r_oc_syms[MAXOCLASSES];      /* drawing.c */
9 
10 #if defined(TERMLIB) || defined(CURSES_GRAPHICS)
11 void (*decgraphics_mode_callback)(void) = 0; /* set in tty_start_screen() */
12 #endif /* TERMLIB || CURSES */
13 
14 #ifdef PC9800
15 void (*ibmgraphics_mode_callback)(void) = 0; /* set in tty_start_screen() */
16 void (*ascgraphics_mode_callback)(void) = 0; /* set in tty_start_screen() */
17 #endif
18 
19 #ifdef CURSES_GRAPHICS
20 void (*cursesgraphics_mode_callback)(void) = 0;
21 #endif
22 /*
23  * Explanations of the functions found below:
24  *
25  * init_symbols()
26  *                     Sets the current display symbols, the
27  *                     loadable symbols to the default NetHack
28  *                     symbols. This would typically be done
29  *                     immediately after execution begins. Any
30  *                     previously loaded external symbol sets are
31  *                     discarded.
32  *
33  * switch_symbols(arg)
34  *                     Called to swap in new current display symbols
35  *                     (showsyms) from either the default symbols,
36  *                     or from the loaded symbols.
37  *
38  *                     If (arg == 0) then showsyms are taken from
39  *                     defsyms, def_oc_syms, and def_monsyms.
40  *
41  *                     If (arg != 0), which is the normal expected
42  *                     usage, then showsyms are taken from the
43  *                     adjustable display symbols found in g.primary_syms.
44  *                     g.primary_syms may have been loaded from an external
45  *                     symbol file by config file options or interactively
46  *                     in the Options menu.
47  *
48  * assign_graphics(arg)
49  *
50  *                     This is used in the game core to toggle in and
51  *                     out of other level display modes.
52  *
53  *                     If arg is PRIMARY, this places the symbols
54  *                     from g.primary_syms into g.showsyms.
55  *
56  * update_primary_symset()
57  *                     Update a member of the primary(primary_*) symbol set.
58  *
59  * update_ov_primary_symset()
60  *                     Update a member of the overrides for primary symbol set.
61  *
62  */
63 
64 void
init_symbols(void)65 init_symbols(void)
66 {
67     init_ov_primary_symbols();
68     init_primary_symbols();
69     init_showsyms();
70 }
71 
72 void
init_showsyms(void)73 init_showsyms(void)
74 {
75     register int i;
76 
77     for (i = 0; i < MAXPCHARS; i++)
78         g.showsyms[i + SYM_OFF_P] = defsyms[i].sym;
79     for (i = 0; i < MAXOCLASSES; i++)
80         g.showsyms[i + SYM_OFF_O] = def_oc_syms[i].sym;
81     for (i = 0; i < MAXMCLASSES; i++)
82         g.showsyms[i + SYM_OFF_M] = def_monsyms[i].sym;
83     for (i = 0; i < WARNCOUNT; i++)
84         g.showsyms[i + SYM_OFF_W] = def_warnsyms[i].sym;
85     for (i = 0; i < MAXOTHER; i++)
86         g.showsyms[i + SYM_OFF_X] = get_othersym(i, PRIMARY);
87 }
88 
89 /* initialize defaults for the overrides to the primary symset */
90 void
init_ov_primary_symbols(void)91 init_ov_primary_symbols(void)
92 {
93     register int i;
94 
95     for (i = 0; i < SYM_MAX; i++)
96         g.ov_primary_syms[i] = (nhsym) 0;
97 }
98 
99 nhsym
get_othersym(int idx,int which_set UNUSED)100 get_othersym(int idx, int which_set UNUSED)
101 {
102     nhsym sym = (nhsym) 0;
103     int oidx = idx + SYM_OFF_X;
104 
105     sym = g.ov_primary_syms[oidx] ? g.ov_primary_syms[oidx]
106                                   : g.primary_syms[oidx];
107     if (!sym) {
108         switch(idx) {
109             case SYM_NOTHING:
110             case SYM_UNEXPLORED:
111                 sym = DEF_NOTHING;
112                 break;
113             case SYM_BOULDER:
114                 sym = def_oc_syms[ROCK_CLASS].sym;
115                 break;
116             case SYM_INVISIBLE:
117                 sym = DEF_INVISIBLE;
118                 break;
119 #if 0
120             /* these intentionally have no defaults */
121             case SYM_PET_OVERRIDE:
122             case SYM_HERO_OVERRIDE:
123                 break;
124 #endif
125         }
126     }
127     return sym;
128 }
129 
130 /* initialize defaults for the primary symset */
131 void
init_primary_symbols(void)132 init_primary_symbols(void)
133 {
134     register int i;
135 
136     for (i = 0; i < MAXPCHARS; i++)
137         g.primary_syms[i + SYM_OFF_P] = defsyms[i].sym;
138     for (i = 0; i < MAXOCLASSES; i++)
139         g.primary_syms[i + SYM_OFF_O] = def_oc_syms[i].sym;
140     for (i = 0; i < MAXMCLASSES; i++)
141         g.primary_syms[i + SYM_OFF_M] = def_monsyms[i].sym;
142     for (i = 0; i < WARNCOUNT; i++)
143         g.primary_syms[i + SYM_OFF_W] = def_warnsyms[i].sym;
144     for (i = 0; i < MAXOTHER; i++)
145         g.primary_syms[i + SYM_OFF_X] = get_othersym(i, PRIMARY);
146 
147     clear_symsetentry(PRIMARY, FALSE);
148 }
149 
150 void
assign_graphics(int whichset)151 assign_graphics(int whichset)
152 {
153     register int i;
154 
155     switch (whichset) {
156     case PRIMARY:
157     default:
158         for (i = 0; i < SYM_MAX; i++)
159             g.showsyms[i] = g.ov_primary_syms[i] ? g.ov_primary_syms[i]
160                                              : g.primary_syms[i];
161 
162 #if defined(MSDOS) && defined(USE_TILES)
163         if (iflags.grmode)
164             tileview(TRUE);
165 #endif
166         g.currentgraphics = PRIMARY;
167         break;
168     }
169 }
170 
171 void
switch_symbols(int nondefault)172 switch_symbols(int nondefault)
173 {
174     register int i;
175 
176     if (nondefault) {
177         for (i = 0; i < SYM_MAX; i++)
178             g.showsyms[i] = g.ov_primary_syms[i] ? g.ov_primary_syms[i]
179                                              : g.primary_syms[i];
180 #ifdef PC9800
181         if (SYMHANDLING(H_IBM) && ibmgraphics_mode_callback)
182             (*ibmgraphics_mode_callback)();
183         else if (SYMHANDLING(H_UNK) && ascgraphics_mode_callback)
184             (*ascgraphics_mode_callback)();
185 #endif
186 #if defined(TERMLIB) || defined(CURSES_GRAPHICS)
187         /* curses doesn't assign any routine to dec..._callback but
188            probably does the expected initialization under the hood
189            for terminals capable of rendering DECgraphics */
190         if (SYMHANDLING(H_DEC) && decgraphics_mode_callback)
191             (*decgraphics_mode_callback)();
192 # ifdef CURSES_GRAPHICS
193         /* there aren't any symbol sets with CURS handling, and the
194            curses interface never assigns a routine to curses..._callback */
195         if (SYMHANDLING(H_CURS) && cursesgraphics_mode_callback)
196             (*cursesgraphics_mode_callback)();
197 # endif
198 #endif
199     } else {
200         init_primary_symbols();
201         init_showsyms();
202     }
203 }
204 
205 void
update_ov_primary_symset(struct symparse * symp,int val)206 update_ov_primary_symset(struct symparse* symp, int val)
207 {
208     g.ov_primary_syms[symp->idx] = val;
209 }
210 
211 void
update_primary_symset(struct symparse * symp,int val)212 update_primary_symset(struct symparse* symp, int val)
213 {
214     g.primary_syms[symp->idx] = val;
215 }
216 
217 void
clear_symsetentry(int which_set,boolean name_too)218 clear_symsetentry(int which_set, boolean name_too)
219 {
220     if (g.symset[which_set].desc)
221         free((genericptr_t) g.symset[which_set].desc);
222     g.symset[which_set].desc = (char *) 0;
223 
224     g.symset[which_set].handling = H_UNK;
225     g.symset[which_set].nocolor = 0;
226     /* initialize restriction bits */
227     g.symset[which_set].primary = 0;
228 
229     if (name_too) {
230         if (g.symset[which_set].name)
231             free((genericptr_t) g.symset[which_set].name);
232         g.symset[which_set].name = (char *) 0;
233     }
234 }
235 
236 /*
237  * If you are adding code somewhere to be able to recognize
238  * particular types of symset "handling", define a
239  * H_XXX macro in include/rm.h and add the name
240  * to this array at the matching offset.
241  */
242 const char *known_handling[] = {
243     "UNKNOWN", /* H_UNK  */
244     "IBM",     /* H_IBM  */
245     "DEC",     /* H_DEC  */
246     "CURS",    /* H_CURS */
247     "MAC",     /* H_MAC  -- pre-OSX MACgraphics */
248     (const char *) 0,
249 };
250 
251 /*
252  * Accepted keywords for symset restrictions.
253  * These can be virtually anything that you want to
254  * be able to test in the code someplace.
255  * Be sure to:
256  *    - add a corresponding Bitfield to the symsetentry struct in rm.h
257  *    - initialize the field to zero in parse_sym_line in the SYM_CONTROL
258  *      case 0 section of the idx switch. The location is prefaced with
259  *      with a comment stating "initialize restriction bits".
260  *    - set the value appropriately based on the index of your keyword
261  *      under the case 5 sections of the same SYM_CONTROL idx switches.
262  *    - add the field to clear_symsetentry()
263  */
264 const char *known_restrictions[] = {
265     "primary", (const char *) 0,
266 };
267 
268 const struct symparse loadsyms[] = {
269     { SYM_CONTROL, 0, "start" },
270     { SYM_CONTROL, 0, "begin" },
271     { SYM_CONTROL, 1, "finish" },
272     { SYM_CONTROL, 2, "handling" },
273     { SYM_CONTROL, 3, "description" },
274     { SYM_CONTROL, 4, "color" },
275     { SYM_CONTROL, 4, "colour" },
276     { SYM_CONTROL, 5, "restrictions" },
277     { SYM_PCHAR, S_stone, "S_stone" },
278     { SYM_PCHAR, S_vwall, "S_vwall" },
279     { SYM_PCHAR, S_hwall, "S_hwall" },
280     { SYM_PCHAR, S_tlcorn, "S_tlcorn" },
281     { SYM_PCHAR, S_trcorn, "S_trcorn" },
282     { SYM_PCHAR, S_blcorn, "S_blcorn" },
283     { SYM_PCHAR, S_brcorn, "S_brcorn" },
284     { SYM_PCHAR, S_crwall, "S_crwall" },
285     { SYM_PCHAR, S_tuwall, "S_tuwall" },
286     { SYM_PCHAR, S_tdwall, "S_tdwall" },
287     { SYM_PCHAR, S_tlwall, "S_tlwall" },
288     { SYM_PCHAR, S_trwall, "S_trwall" },
289     { SYM_PCHAR, S_ndoor, "S_ndoor" },
290     { SYM_PCHAR, S_vodoor, "S_vodoor" },
291     { SYM_PCHAR, S_hodoor, "S_hodoor" },
292     { SYM_PCHAR, S_vcdoor, "S_vcdoor" },
293     { SYM_PCHAR, S_hcdoor, "S_hcdoor" },
294     { SYM_PCHAR, S_bars, "S_bars" },
295     { SYM_PCHAR, S_tree, "S_tree" },
296     { SYM_PCHAR, S_room, "S_room" },
297     { SYM_PCHAR, S_darkroom, "S_darkroom" },
298     { SYM_PCHAR, S_corr, "S_corr" },
299     { SYM_PCHAR, S_litcorr, "S_litcorr" },
300     { SYM_PCHAR, S_upstair, "S_upstair" },
301     { SYM_PCHAR, S_dnstair, "S_dnstair" },
302     { SYM_PCHAR, S_upladder, "S_upladder" },
303     { SYM_PCHAR, S_dnladder, "S_dnladder" },
304     { SYM_PCHAR, S_altar, "S_altar" },
305     { SYM_PCHAR, S_grave, "S_grave" },
306     { SYM_PCHAR, S_throne, "S_throne" },
307     { SYM_PCHAR, S_sink, "S_sink" },
308     { SYM_PCHAR, S_fountain, "S_fountain" },
309     { SYM_PCHAR, S_pool, "S_pool" },
310     { SYM_PCHAR, S_ice, "S_ice" },
311     { SYM_PCHAR, S_grass, "S_grass" },
312     { SYM_PCHAR, S_lava, "S_lava" },
313     { SYM_PCHAR, S_vodbridge, "S_vodbridge" },
314     { SYM_PCHAR, S_hodbridge, "S_hodbridge" },
315     { SYM_PCHAR, S_vcdbridge, "S_vcdbridge" },
316     { SYM_PCHAR, S_hcdbridge, "S_hcdbridge" },
317     { SYM_PCHAR, S_air, "S_air" },
318     { SYM_PCHAR, S_cloud, "S_cloud" },
319     { SYM_PCHAR, S_poisoncloud, "S_poisoncloud" },
320     { SYM_PCHAR, S_water, "S_water" },
321     { SYM_PCHAR, S_engraving, "S_engraving" },
322     { SYM_PCHAR, S_arrow_trap, "S_arrow_trap" },
323     { SYM_PCHAR, S_dart_trap, "S_dart_trap" },
324     { SYM_PCHAR, S_falling_rock_trap, "S_falling_rock_trap" },
325     { SYM_PCHAR, S_squeaky_board, "S_squeaky_board" },
326     { SYM_PCHAR, S_bear_trap, "S_bear_trap" },
327     { SYM_PCHAR, S_land_mine, "S_land_mine" },
328     { SYM_PCHAR, S_rolling_boulder_trap, "S_rolling_boulder_trap" },
329     { SYM_PCHAR, S_sleeping_gas_trap, "S_sleeping_gas_trap" },
330     { SYM_PCHAR, S_rust_trap, "S_rust_trap" },
331     { SYM_PCHAR, S_fire_trap, "S_fire_trap" },
332     { SYM_PCHAR, S_pit, "S_pit" },
333     { SYM_PCHAR, S_spiked_pit, "S_spiked_pit" },
334     { SYM_PCHAR, S_hole, "S_hole" },
335     { SYM_PCHAR, S_trap_door, "S_trap_door" },
336     { SYM_PCHAR, S_teleportation_trap, "S_teleportation_trap" },
337     { SYM_PCHAR, S_level_teleporter, "S_level_teleporter" },
338     { SYM_PCHAR, S_magic_portal, "S_magic_portal" },
339     { SYM_PCHAR, S_web, "S_web" },
340     { SYM_PCHAR, S_statue_trap, "S_statue_trap" },
341     { SYM_PCHAR, S_magic_trap, "S_magic_trap" },
342     { SYM_PCHAR, S_anti_magic_trap, "S_anti_magic_trap" },
343     { SYM_PCHAR, S_polymorph_trap, "S_polymorph_trap" },
344     { SYM_PCHAR, S_vibrating_square, "S_vibrating_square" },
345     { SYM_PCHAR, S_vbeam, "S_vbeam" },
346     { SYM_PCHAR, S_hbeam, "S_hbeam" },
347     { SYM_PCHAR, S_lslant, "S_lslant" },
348     { SYM_PCHAR, S_rslant, "S_rslant" },
349     { SYM_PCHAR, S_digbeam, "S_digbeam" },
350     { SYM_PCHAR, S_flashbeam, "S_flashbeam" },
351     { SYM_PCHAR, S_boomleft, "S_boomleft" },
352     { SYM_PCHAR, S_boomright, "S_boomright" },
353     { SYM_PCHAR, S_goodpos, "S_goodpos" },
354     { SYM_PCHAR, S_ss1, "S_ss1" },
355     { SYM_PCHAR, S_ss2, "S_ss2" },
356     { SYM_PCHAR, S_ss3, "S_ss3" },
357     { SYM_PCHAR, S_ss4, "S_ss4" },
358     { SYM_PCHAR, S_sw_tl, "S_sw_tl" },
359     { SYM_PCHAR, S_sw_tc, "S_sw_tc" },
360     { SYM_PCHAR, S_sw_tr, "S_sw_tr" },
361     { SYM_PCHAR, S_sw_ml, "S_sw_ml" },
362     { SYM_PCHAR, S_sw_mr, "S_sw_mr" },
363     { SYM_PCHAR, S_sw_bl, "S_sw_bl" },
364     { SYM_PCHAR, S_sw_bc, "S_sw_bc" },
365     { SYM_PCHAR, S_sw_br, "S_sw_br" },
366     { SYM_PCHAR, S_explode1, "S_explode1" },
367     { SYM_PCHAR, S_explode2, "S_explode2" },
368     { SYM_PCHAR, S_explode3, "S_explode3" },
369     { SYM_PCHAR, S_explode4, "S_explode4" },
370     { SYM_PCHAR, S_explode5, "S_explode5" },
371     { SYM_PCHAR, S_explode6, "S_explode6" },
372     { SYM_PCHAR, S_explode7, "S_explode7" },
373     { SYM_PCHAR, S_explode8, "S_explode8" },
374     { SYM_PCHAR, S_explode9, "S_explode9" },
375     { SYM_OC, ILLOBJ_CLASS + SYM_OFF_O, "S_strange_obj" },
376     { SYM_OC, WEAPON_CLASS + SYM_OFF_O, "S_weapon" },
377     { SYM_OC, ARMOR_CLASS + SYM_OFF_O, "S_armor" },
378     { SYM_OC, ARMOR_CLASS + SYM_OFF_O, "S_armour" },
379     { SYM_OC, RING_CLASS + SYM_OFF_O, "S_ring" },
380     { SYM_OC, AMULET_CLASS + SYM_OFF_O, "S_amulet" },
381     { SYM_OC, TOOL_CLASS + SYM_OFF_O, "S_tool" },
382     { SYM_OC, FOOD_CLASS + SYM_OFF_O, "S_food" },
383     { SYM_OC, POTION_CLASS + SYM_OFF_O, "S_potion" },
384     { SYM_OC, SCROLL_CLASS + SYM_OFF_O, "S_scroll" },
385     { SYM_OC, SPBOOK_CLASS + SYM_OFF_O, "S_book" },
386     { SYM_OC, WAND_CLASS + SYM_OFF_O, "S_wand" },
387     { SYM_OC, COIN_CLASS + SYM_OFF_O, "S_coin" },
388     { SYM_OC, GEM_CLASS + SYM_OFF_O, "S_gem" },
389     { SYM_OC, ROCK_CLASS + SYM_OFF_O, "S_rock" },
390     { SYM_OC, BALL_CLASS + SYM_OFF_O, "S_ball" },
391     { SYM_OC, CHAIN_CLASS + SYM_OFF_O, "S_chain" },
392     { SYM_OC, VENOM_CLASS + SYM_OFF_O, "S_venom" },
393     { SYM_MON, S_ANT + SYM_OFF_M, "S_ant" },
394     { SYM_MON, S_BLOB + SYM_OFF_M, "S_blob" },
395     { SYM_MON, S_COCKATRICE + SYM_OFF_M, "S_cockatrice" },
396     { SYM_MON, S_DOG + SYM_OFF_M, "S_dog" },
397     { SYM_MON, S_EYE + SYM_OFF_M, "S_eye" },
398     { SYM_MON, S_FELINE + SYM_OFF_M, "S_feline" },
399     { SYM_MON, S_GREMLIN + SYM_OFF_M, "S_gremlin" },
400     { SYM_MON, S_HUMANOID + SYM_OFF_M, "S_humanoid" },
401     { SYM_MON, S_IMP + SYM_OFF_M, "S_imp" },
402     { SYM_MON, S_JELLY + SYM_OFF_M, "S_jelly" },
403     { SYM_MON, S_KOBOLD + SYM_OFF_M, "S_kobold" },
404     { SYM_MON, S_LEPRECHAUN + SYM_OFF_M, "S_leprechaun" },
405     { SYM_MON, S_MIMIC + SYM_OFF_M, "S_mimic" },
406     { SYM_MON, S_NYMPH + SYM_OFF_M, "S_nymph" },
407     { SYM_MON, S_ORC + SYM_OFF_M, "S_orc" },
408     { SYM_MON, S_PIERCER + SYM_OFF_M, "S_piercer" },
409     { SYM_MON, S_QUADRUPED + SYM_OFF_M, "S_quadruped" },
410     { SYM_MON, S_RODENT + SYM_OFF_M, "S_rodent" },
411     { SYM_MON, S_SPIDER + SYM_OFF_M, "S_spider" },
412     { SYM_MON, S_TRAPPER + SYM_OFF_M, "S_trapper" },
413     { SYM_MON, S_UNICORN + SYM_OFF_M, "S_unicorn" },
414     { SYM_MON, S_VORTEX + SYM_OFF_M, "S_vortex" },
415     { SYM_MON, S_WORM + SYM_OFF_M, "S_worm" },
416     { SYM_MON, S_XAN + SYM_OFF_M, "S_xan" },
417     { SYM_MON, S_LIGHT + SYM_OFF_M, "S_light" },
418     { SYM_MON, S_ZRUTY + SYM_OFF_M, "S_zruty" },
419     { SYM_MON, S_ANGEL + SYM_OFF_M, "S_angel" },
420     { SYM_MON, S_BAT + SYM_OFF_M, "S_bat" },
421     { SYM_MON, S_CENTAUR + SYM_OFF_M, "S_centaur" },
422     { SYM_MON, S_DRAGON + SYM_OFF_M, "S_dragon" },
423     { SYM_MON, S_ELEMENTAL + SYM_OFF_M, "S_elemental" },
424     { SYM_MON, S_FUNGUS + SYM_OFF_M, "S_fungus" },
425     { SYM_MON, S_GNOME + SYM_OFF_M, "S_gnome" },
426     { SYM_MON, S_GIANT + SYM_OFF_M, "S_giant" },
427     { SYM_MON, S_JABBERWOCK + SYM_OFF_M, "S_jabberwock" },
428     { SYM_MON, S_KOP + SYM_OFF_M, "S_kop" },
429     { SYM_MON, S_LICH + SYM_OFF_M, "S_lich" },
430     { SYM_MON, S_MUMMY + SYM_OFF_M, "S_mummy" },
431     { SYM_MON, S_NAGA + SYM_OFF_M, "S_naga" },
432     { SYM_MON, S_OGRE + SYM_OFF_M, "S_ogre" },
433     { SYM_MON, S_PUDDING + SYM_OFF_M, "S_pudding" },
434     { SYM_MON, S_ELF + SYM_OFF_M, "S_elf" },
435     { SYM_MON, S_RUSTMONST + SYM_OFF_M, "S_rustmonst" },
436     { SYM_MON, S_SNAKE + SYM_OFF_M, "S_snake" },
437     { SYM_MON, S_TROLL + SYM_OFF_M, "S_troll" },
438     { SYM_MON, S_ABERRATION + SYM_OFF_M, "S_aberration" },
439     { SYM_MON, S_VAMPIRE + SYM_OFF_M, "S_vampire" },
440     { SYM_MON, S_WRAITH + SYM_OFF_M, "S_wraith" },
441     { SYM_MON, S_XORN + SYM_OFF_M, "S_xorn" },
442     { SYM_MON, S_YETI + SYM_OFF_M, "S_yeti" },
443     { SYM_MON, S_ZOMBIE + SYM_OFF_M, "S_zombie" },
444     { SYM_MON, S_HUMAN + SYM_OFF_M, "S_human" },
445     { SYM_MON, S_GOLEM + SYM_OFF_M, "S_golem" },
446     { SYM_MON, S_DEMON + SYM_OFF_M, "S_demon" },
447     { SYM_MON, S_EEL + SYM_OFF_M, "S_eel" },
448     { SYM_MON, S_LIZARD + SYM_OFF_M, "S_lizard" },
449     { SYM_MON, S_WORM_TAIL + SYM_OFF_M, "S_worm_tail" },
450     { SYM_MON, S_MIMIC_DEF + SYM_OFF_M, "S_mimic_def" },
451     { SYM_OTH, SYM_NOTHING + SYM_OFF_X, "S_nothing" },
452     { SYM_OTH, SYM_UNEXPLORED + SYM_OFF_X, "S_unexplored" },
453     { SYM_OTH, SYM_BOULDER + SYM_OFF_X, "S_boulder" },
454     { SYM_OTH, SYM_INVISIBLE + SYM_OFF_X, "S_invisible" },
455     { SYM_OTH, SYM_PET_OVERRIDE + SYM_OFF_X, "S_pet_override" },
456     { SYM_OTH, SYM_HERO_OVERRIDE + SYM_OFF_X, "S_hero_override" },
457     { 0, 0, (const char *) 0 } /* fence post */
458 };
459 
460 /*symbols.c*/
461