]> granicus.if.org Git - nethack/commitdiff
drawing overhaul (trunk only)
authornethack.allison <nethack.allison>
Thu, 21 Sep 2006 01:46:15 +0000 (01:46 +0000)
committernethack.allison <nethack.allison>
Thu, 21 Sep 2006 01:46:15 +0000 (01:46 +0000)
This is an overhaul to the NetHack drawing mechanism.

- eliminates the need to have separate lists in drawing.c
for the things and their associated explanations by grouping
those thing together on the same inializer in a struct.

- replaces all of these options: IBMgraphics, DECgraphics, MACgraphics,
graphics, monsters, objects, boulder, traps, effects

- drawing.c contains only the set of NetHack standard symbols for
the main game and a set of NetHack standard symbols for the
roguelevel.

- introduces a symbols file that contains named sets of
symbols that can be loaded at run time making it extensible
for situations like multinational code pages like those reported
by <Someone>, without hardcoding additional sets into the game code.

- symbols file uses names for the symbols, so offsets will not break
when new things are introduced into the game, the way the older
config file uchar load routines did.

- symbols file only contains exceptions to the standard NetHack
set, not entire sets so they are much less verbose than all of
the g_FILLER() entries that were previously in drawing.c

- 'symset' and 'roguesymset' config file options for
preselecting a symbol set from the file called 'symbols'
at startup time. The name of the symbols file is not under the
users control, only the symbol set name desired from within the
symbols file is.

- 'symset' config file option loads a desired symbol set for
everything but the rogue level.

- 'roguesymset' config file option loads a desired symbol set
for the rogue level.

- 'SYMBOLS' config file option allows the user to specify replacement
symbols on a per symbol basis. You can specify as many or as few symbols
as you wish. The symbols are identified by a name:value pair, and line
continuation is supported. Multiple symbol assignments can be made on
the same line if each name:value pair is separated by a comma.
For example:
SYMBOLS = S_bars:\xf0, S_tree: \xf1, S_room:\xfa \
  S_fountain:\xf4 \
  S_boulder:0

- 'symbols' file has the following structure:
start: DECgraphics
Handling: DEC
S_vwall: \xf8 # meta-x, vertical rule
S_hwall: \xf1 # meta-q, horizontal rule
finish
start: IBMgraphics
Handling: IBM
S_vwall: \xb3 # meta-3, vertical rule
S_hwall: \xc4 # meta-D, horizontal rule
finish

- 'symbols' file added to the source tree in the dat directory

- Port Makefiles/scripts will need to be adjusted to move them into
HACKDIR destination

39 files changed:
Files
doc/Guidebook.mn
doc/Guidebook.tex
doc/window.doc
include/decl.h
include/extern.h
include/flag.h
include/global.h
include/objclass.h
include/rm.h
src/detect.c
src/drawing.c
src/files.c
src/invent.c
src/makemon.c
src/mapglyph.c
src/mkroom.c
src/options.c
src/pager.c
src/pickup.c
src/read.c
src/weapon.c
sys/msdos/Makefile.BC
sys/msdos/Makefile.GCC
sys/msdos/Makefile.MSC
sys/msdos/vidvga.c
sys/share/NetHack.cnf
sys/share/pcmain.c
sys/share/unixtty.c
sys/unix/unixmain.c
sys/vms/vmsmain.c
sys/wince/mhfont.c
sys/winnt/Makefile.bcc
sys/winnt/Makefile.gcc
sys/winnt/Makefile.msc
sys/winnt/defaults.nh
win/tty/termcap.c
win/tty/wintty.c
win/win32/mhfont.c

diff --git a/Files b/Files
index 5ab0105cb09e0719a2aef0993a28667341c8a705..804c9e0a1dbe271eff39fc7d66c14ad5755f381b 100644 (file)
--- a/Files
+++ b/Files
@@ -16,8 +16,8 @@ Tourist.des     Valkyrie.des    Wizard.des      bigroom.des     castle.des
 cmdhelp         data.base       dungeon.def     endgame.des     gehennom.des
 help            hh              history         knox.des        license
 medusa.des      mines.des       opthelp         oracle.des      oracles.txt
-quest.txt       rumors.fal      rumors.tru      sokoban.des     tower.des
-wizhelp         yendor.des
+quest.txt       roguesym        rumors.fal      rumors.tru      sokoban.des
+symbols         tower.des       wizhelp         yendor.des
 
 doc:
 (files for all versions)
index f1045bc24c1911618449eb2bab0bc5e65b52b69a..9d41e29bd0c3a05f81d33ed10faf3a1736d13c3d 100644 (file)
@@ -5,7 +5,7 @@
 .ds vr "NetHack 3.4
 .ds f0 "\*(vr
 .ds f1
-.ds f2 "January 15, 2005
+.ds f2 "September 20, 2006
 .mt
 A Guide to the Mazes of Menace
 (Guidebook for NetHack)
@@ -1662,22 +1662,11 @@ Using a configuration file
 Any line in the configuration file starting with `#' is treated as a comment.
 Any line in the configuration file starting with ``OPTIONS='' may be
 filled out with options in the same syntax as in NETHACKOPTIONS.
-Any line starting with ``DUNGEON='', ``EFFECTS='', ``MONSTERS='',
-``OBJECTS='', ``TRAPS='', or ``BOULDER=''
-is taken as defining the corresponding
-.op dungeon,
-.op effects,
-.op monsters,
-.op objects
-.op traps
-or
-.op boulder
-option in a different syntax,
-a sequence of decimal numbers giving the character position
-in the current font to be used in displaying each entry.
-A zero in any entry in such a sequence leaves the display of that
-entry unchanged; this feature is not available using the option syntax.
-Such a sequence can be continued to multiple lines by putting a `\e'
+Any line starting with ``SYMBOLS=''
+is taken as defining the corresponding symbol
+in a different syntax, a sequence of decimal numbers giving 
+the character position in the current font to be used in displaying 
+each entry. Such a sequence can be continued to multiple lines by putting a `\e'
 at the end of each line to be continued.
 .pg
 If your copy of the game included the compile time AUTOPICKUP_EXCEPTIONS
@@ -1749,13 +1738,6 @@ new players if it detects some anticipated mistakes (default on).
 .lp "confirm "
 Have user confirm attacks on pets, shopkeepers, and other
 peaceable creatures (default on).
-.lp DECgraphics
-Use a predefined selection of characters from the DEC VT-xxx/DEC
-Rainbow/ANSI line-drawing character set to display the dungeon/effects/traps
-instead of having to define a full graphics set yourself (default off).
-This option also sets up proper handling of graphics
-characters for such terminals, so you should specify it when appropriate
-even if you override the selections with your own graphics strings.
 .lp disclose
 Controls options for disclosing various information when the game ends (defaults
 to all possibilities being disclosed).
@@ -1795,66 +1777,6 @@ Note that the vanquished monsters list includes all monsters killed by
 traps and each other as well as by you.
 .lp dogname
 Name your starting dog (ex. ``dogname:Fang'').
-Cannot be set with the `O' command.
-.lp dungeon
-Set the graphics symbols for displaying the dungeon
-(default \&``\ |--------||.-|++##.##<><>_|\e\e#{}.}..##\ #}'').
-The
-.op dungeon
-option should be followed by a string of 1-41
-characters to be used instead of the default map-drawing characters.
-The dungeon map will use the characters you specify instead of the
-default symbols, and default symbols for any you do not specify.
-Remember that you may need to escape some of these characters
-on a command line if they are special to your shell.
-
-Note that NetHack escape-processes this option string in conventional C
-fashion.  This means that `\e' is a prefix to take the following
-character literally.  Thus `\e' needs to be represented as `\e\e'.
-The special escape
-form `\em' switches on the meta bit in the following character, and the `^'
-prefix causes the following character to be treated as a control
-character.
-
-The order of the symbols is:  solid rock, vertical wall, horizontal
-wall, upper left corner, upper right corner, lower left corner, lower
-right corner, cross wall, upward T wall, downward T wall, leftward T
-wall, rightward T wall, no door, vertical open door, horizontal open
-door, vertical closed door, horizontal closed door, iron bars, tree,
-floor of a room, dark corridor, lit corridor, stairs up, stairs down,
-ladder up, ladder down, altar, grave, throne, kitchen sink, fountain, pool or moat,
-ice, lava, vertical lowered drawbridge, horizontal lowered drawbridge,
-vertical raised drawbridge, horizontal raised drawbridge, air, cloud,
-under water.
-
-You might want to use `+' for the corners and T walls for a more
-aesthetic, boxier display.  Note that in the next release, new symbols
-may be added, or the present ones rearranged.
-
-Cannot be set with the `O' command.
-.lp effects
-Set the graphics symbols for displaying special effects
-(default \&``|-\e\e/*!)(0#@*/-\e\e||\e\e-//-\e\e|\ |\e\e-/'').
-The
-.op effects
-option should be followed by a string of 1-29
-characters to be used instead of the default special-effects characters.
-This string is subjected to the same processing as the
-.op dungeon
-option.
-
-The order of the symbols is:  vertical beam, horizontal beam, left slant,
-right slant, digging beam, camera flash beam, left boomerang, right boomerang,
-four glyphs giving the sequence for magic resistance displays,
-the eight surrounding glyphs for swallowed display,
-nine glyphs for explosions.
-An explosion consists of three rows (top, middle, and bottom) of three
-characters.  The explosion is centered in the center of this 3 by 3
-array.
-
-Note that in the next release, new symbols may be added,
-or the present ones rearranged.
-
 Cannot be set with the `O' command.
 .lp extmenu
 Changes the extended commands interface to pop-up a menu of available commands.  
@@ -1891,13 +1813,6 @@ interesting and/or important information.
 .lp horsename
 Name your starting horse (ex. ``horsename:Trigger'').
 Cannot be set with the `O' command.
-.lp IBMgraphics
-Use a predefined selection of IBM extended ASCII characters to display the
-dungeon/effects/traps instead of having to define a full graphics set
-yourself (default off).
-This option also sets up proper handling of graphics
-characters for such terminals, so you should specify it when appropriate
-even if you override the selections with your own graphics strings.
 .lp ignintr
 Ignore interrupt signals, including breaks (default off).
 .lp legacy
@@ -1974,35 +1889,6 @@ Default '.'.
 Menu character accelerator to select all items on this page of a menu.
 Implemented by the Amiga, Gem and tty ports.
 Default ','.
-.lp monsters
-Set the characters used to display monster classes (default
-``abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@\ \'&;:~]'').
-This string is subjected to the same processing as the
-.op dungeon
-option.
-The order of the symbols is
-ant or other insect, blob, cockatrice,
-dog or other canine, eye or sphere, feline,
-gremlin, humanoid, imp or minor demon,
-jelly, kobold, leprechaun,
-mimic, nymph, orc,
-piercer, quadruped, rodent,
-arachnid or centipede, trapper or lurker above, horse or unicorn,
-vortex, worm, xan or other mythical/fantastic insect,
-light, zruty,
-angelic being, bat or bird, centaur,
-dragon, elemental, fungus or mold,
-gnome, giant humanoid, invisible monster,
-jabberwock, Keystone Kop, lich,
-mummy, naga, ogre,
-pudding or ooze, quantum mechanic, rust monster,
-snake, troll, umber hulk,
-vampire, wraith, xorn,
-apelike creature, zombie,
-human, ghost, golem,
-demon, sea monster, lizard,
-long worm tail, and mimic.
-Cannot be set with the `O' command.
 .lp msghistory
 The number of top line messages to save (and recall with ^P) (default 20).
 Cannot be set with the `O' command.
@@ -2060,17 +1946,6 @@ location of the `y' and `z' keys swapped.)
 When moving by numbers, to enter a count prefix for those commands
 which accept one (such as ``12s'' to search twelve times), precede it
 with the letter `n' (``n12s'').
-.lp objects
-Set the characters used to display object classes
-(default ``])[="(%!?+/$*`0_.'').
-This string is subjected to the same processing as the
-.op dungeon
-option.
-The order of the symbols is
-illegal-object (should never be seen), weapon, armor, ring, amulet, tool,
-food, potion, scroll, spellbook, wand, gold, gem or rock, boulder or statue,
-iron ball, chain, and venom.
-Cannot be set with the `O' command.
 .lp packorder
 Specify the order to list object types in (default ``")[%?+!=/(*`0_'').
 The value of this option should be a string containing the
@@ -2129,6 +2004,9 @@ of specifying your role.  Normally only the first letter of the
 value is examined; `r' is an exception with ``Rogue'', ``Ranger'',
 and ``random'' values. If you prefix a `!' or ``no'' to the value, you can 
 exclude that role from being picked randomly.
+.lp roguesymset
+This option may be used to select one of the named symbol sets found within
+``symbols'' to alter the symbols displayed on the screen on the rogue level.
 .lp rlecomp
 When writing out a save file, perform run length compression of the map. 
 Not all ports support run length compression. It has no
@@ -2177,6 +2055,9 @@ Boldface monsters and ``\fB--More--\fP'' (default off).
 This option may be set to a NetHack version level to suppress
 alert notification messages about feature changes for that 
 and prior versions (ex. ``suppress_alert:3.3.1'').
+.lp symset
+This option may be used to select one of the named symbol sets found within
+``symbols'' to alter the symbols displayed on the screen.
 .lp "time    "
 Show the elapsed game time in turns on bottom line (default off).
 .lp timed_delay
@@ -2192,24 +2073,6 @@ Put the ending display in a NetHack window instead of on stdout (default off).
 Setting this option makes the score list visible when a windowing version
 of NetHack is started without a parent window, but it no longer leaves
 the score list around after game end on a terminal or emulating window.
-.lp traps
-Set the graphics symbols for displaying traps
-(default \&``^^^^^^^^^^^^^^^^^"^^^^'').
-The
-.op traps
-option should be followed by a string of 1-22
-characters to be used instead of the default traps characters.
-This string is subjected to the same processing as the
-.op dungeon
-option.
-
-The order of the symbols is: 
-arrow trap, dart trap, falling rock trap, squeaky board, bear trap,
-land mine, rolling boulder trap, sleeping gas trap, rust trap, fire trap,
-pit, spiked pit, hole, trap door, teleportation trap, level teleporter,
-magic portal, web, statue trap, magic trap, anti-magic field, polymorph trap.
-
-Cannot be set with the `O' command.
 .lp travel
 Allow the travel command (default on).  Turning this option off will
 prevent the game from attempting unintended moves if you make inadvertent
@@ -2496,6 +2359,208 @@ in it will trigger the playing of "gong.wav".  You can have multiple
 SOUND entries in your config file.
 .pg
 .hn 2
+Modifying NetHack Symbols 
+.pg
+NetHack can load entire symbol sets from the symbol file.
+.pg
+The options that are used to select a particular symbol set from the
+symbol file are:
+.lp symset
+Set the name of the symbol set that you want to load.
+.lp roguesymset
+Set the name of the symbol set that you want to load for display
+on the rogue level.
+.pg
+You can also override one or more symbols using the SYMBOLS config
+file option. Symbols are specified as name:value pairs. Note that
+NetHack escape-processes the value string in conventional C fashion.
+This means that \ is a prefix to take the following character literally. Thus
+\ needs to be represented as \\.
+The special escape form
+\m switches on the meta bit in the symbol value, and the \^ prefix causes the
+following character to be treated as a control
+character.
+.pg
+.sd
+.TS S
+center;
+c c c.
+.\"TABLE_START
+Default        Symbol Name     Description
+       S_air   (air)
+_      S_altar (altar)
+"      S_amulet        (amulet)
+A      S_angel (angelic being)
+a      S_ant   (ant or other insect)
+^      S_anti_magic_trap       (anti-magic field)
+[      S_armor (suit or piece of armor)
+[      S_armour        (suit or piece of armor)
+^      S_arrow_trap    (arrow trap)
+0      S_ball  (iron ball)
+#      S_bars  (iron bars)
+B      S_bat   (bat or bird)
+^      S_bear_trap     (bear trap)
+-      S_blcorn        (bottom left corner)
+b      S_blob  (blob)
++      S_book  (spellbook)
+)      S_boomleft      (boomerang open left)
+(      S_boomright     (boomerang open right)
+`      S_boulder       (boulder)
+-      S_brcorn        (bottom right corner)
+C      S_centaur       (centaur)
+_      S_chain (iron chain)
+#      S_cloud (cloud)
+c      S_cockatrice    (cockatrice)
+$      S_coin  (pile of coins)
+#      S_corr  (corridor)
+-      S_crwall        (wall)
+^      S_dart_trap     (dart trap)
+&      S_demon (major demon)
+*      S_digbeam       (dig beam)
+>      S_dnladder      (ladder down)
+>      S_dnstair       (staircase down)
+d      S_dog   (dog or other canine)
+D      S_dragon        (dragon)
+;      S_eel   (sea monster)
+E      S_elemental     (elemental)
+/      S_explode1      (explosion top left)
+-      S_explode2      (explosion top center)
+`\e'   S_explode3      (explosion top right)
+|      S_explode4      (explosion middle left)
+       S_explode5      (explosion middle center)
+|      S_explode6      (explosion middle right)
+`\e'   S_explode7      (explosion bottom left)
+-      S_explode8      (explosion bottom center)
+/      S_explode9      (explosion bottom right)
+e      S_eye   (eye or sphere)
+^      S_falling_rock_trap     (falling rock trap)
+f      S_feline        (cat or other feline)
+^      S_fire_trap     (fire trap)
+!      S_flashbeam     (flash beam)
+%      S_food  (piece of food)
+{      S_fountain      (fountain)
+F      S_fungus        (fungus or mold)
+*      S_gem   (gem or rock)
+       S_ghost (ghost)
+H      S_giant (giant humanoid)
+G      S_gnome (gnome)
+'      S_golem (golem)
+|      S_grave (grave)
+g      S_gremlin       (gremlin)
+-      S_hbeam (wall)
+#      S_hcdbridge     (horizontal raised drawbridge)
++      S_hcdoor        (closed door)
+.      S_hodbridge     (horizontal lowered drawbridge)
+|      S_hodoor        (open door)
+^      S_hole  (hole)
+@      S_human (human or elf)
+h      S_humanoid      (humanoid)
+-      S_hwall (horizontal wall)
+.      S_ice   (ice)
+i      S_imp   (imp or minor demon)
+J      S_jabberwock    (jabberwock)
+j      S_jelly (jelly)
+k      S_kobold        (kobold)
+K      S_kop   (Keystone Kop)
+^      S_land_mine     (land mine)
+}      S_lava  (molten lava)
+l      S_leprechaun    (leprechaun)
+^      S_level_teleporter      (level teleporter)
+L      S_lich  (lich)
+y      S_light (light)
+#      S_litcorr       (lit corridor)
+:      S_lizard        (lizard)
+`\e'   S_lslant        (wall)
+^      S_magic_portal  (magic portal)
+^      S_magic_trap    (magic trap)
+m      S_mimic (mimic)
+]      S_mimic_def     (mimic)
+M      S_mummy (mummy)
+N      S_naga  (naga)
+.      S_ndoor (doorway)
+n      S_nymph (nymph)
+O      S_ogre  (ogre)
+o      S_orc   (orc)
+p      S_piercer       (piercer)
+^      S_pit   (pit)
+^      S_polymorph_trap        (polymorph trap)
+}      S_pool  (water)
+!      S_potion        (potion)
+P      S_pudding       (pudding or ooze)
+q      S_quadruped     (quadruped)
+Q      S_quantmech     (quantum mechanic)
+=      S_ring  (ring)
+`      S_rock  (boulder or statue)
+r      S_rodent        (rodent)
+^      S_rolling_boulder_trap  (rolling boulder trap)
+.      S_room  (floor of a room)
+/      S_rslant        (wall)
+^      S_rust_trap     (rust trap)
+R      S_rustmonst     (rust monster or disenchanter)
+?      S_scroll        (scroll)
+#      S_sink  (sink)
+^      S_sleeping_gas_trap     (sleeping gas trap)
+S      S_snake (snake)
+s      S_spider        (arachnid or centipede)
+^      S_spiked_pit    (spiked pit)
+^      S_squeaky_board (squeaky board)
+0      S_ss1   (magic shield 1 of 4)
+#      S_ss2   (magic shield 2 of 4)
+@      S_ss3   (magic shield 3 of 4)
+*      S_ss4   (magic shield 4 of 4)
+^      S_statue_trap   (statue trap)
+       S_stone (dark part of a room)
+-      S_sw_bc (swallow bottom center)
+`\e'   S_sw_bl (swallow bottom left)
+/      S_sw_br (swallow bottom right   )
+|      S_sw_ml (swallow middle left)
+|      S_sw_mr (swallow middle right)
+-      S_sw_tc (swallow top center)
+/      S_sw_tl (swallow top left)
+`\e'   S_sw_tr (swallow top right)
+-      S_tdwall        (wall)
+^      S_teleportation_trap    (teleportation trap)
+\      S_throne        (opulent throne)
+-      S_tlcorn        (top left corner)
+|      S_tlwall        (wall)
+(      S_tool  (useful item (pick-axe\, key\, lamp...))
+^      S_trap_door     (trap door)
+t      S_trapper       (trapper or lurker above)
+-      S_trcorn        (top right corner)
+#      S_tree  (tree)
+T      S_troll (troll)
+|      S_trwall        (wall)
+-      S_tuwall        (wall)
+U      S_umber (umber hulk)
+u      S_unicorn       (unicorn or horse)
+<      S_upladder      (ladder up)
+<      S_upstair       (staircase up)
+V      S_vampire       (vampire)
+|      S_vbeam (wall)
+#      S_vcdbridge     (vertical raised drawbridge)
++      S_vcdoor        (closed door)
+.      S_venom (splash of venom)
+.      S_vodbridge     (vertical lowered drawbridge)
+-      S_vodoor        (open door)
+v      S_vortex        (vortex)
+|      S_vwall (vertical wall)
+/      S_wand  (wand)
+}      S_water (water)
+)      S_weapon        (weapon)
+"      S_web   (web)
+w      S_worm  (worm)
+~      S_worm_tail     (long worm tail)
+W      S_wraith        (wraith)
+x      S_xan   (xan or other mythical/fantastic insect)
+X      S_xorn  (xorn)
+Y      S_yeti  (apelike creature)
+Z      S_zombie        (zombie)
+z      S_zruty (zruty)
+.\"TABLE_END  Do not delete this line.
+.TE
+.ed
+.pg
+.hn 2
 Configuring NetHack for Play by the Blind
 .pg
 NetHack can be set up to use only standard ASCII characters for making
@@ -2516,28 +2581,25 @@ overall location of items on the screen.
 .pg
 While it is not difficult for experienced users to edit the \fBdefaults.nh\fP
 file to accomplish this, novices may find this task somewhat daunting.
-Included in all official distributions of NetHack is a file called
-\fBNHAccess.nh\fP.  Replacing \fBdefaults.nh\fP with this file will cause
-the game to run in a manner accessible to the blind. After you have gained
-some experience with the game and with editing files, you may want to alter
-settings to better suit your preferences. Instructions on how to do this
-are included in the \fBNHAccess.nh\fP file itself. The most crucial settings to
-make the game accessible are:
-.pg
-.lp IBMgraphics
-Disable IBMgraphics by commenting out this option.
+Included within the ``symbols'' file of all official distributions of NetHack 
+is a symset called \fBNHAccess\fP.  Selecting that symset in your
+configuration file will cause the game to run in a manner accessible 
+to the blind. After you have gained some experience with the game 
+and with editing files, you may want to alter settings via \fBSYMBOLS=\fP 
+in your configuration file to better suit your preferences. 
+The most crucial settings to make the game accessible are:
+.pg
+.lp symset:NHAccess
+Load a symbol set appropriate for use by blind players.
+.lp roguesymset:NHAccess
+Load a symbol set for the rogue level that is appropriate for 
+use by blind players.
 .lp menustyle:traditional
 This will assist in the interface to speech synthesizers.
 .lp number_pad
 A lot of speech access programs use the number-pad to review the screen.
 If this is the case, disable the number_pad option and use the traditional
 Rogue-like commands.
-.lp "Character graphics"
-Comment out all character graphics sets found near the bottom of the
-\fBdefaults.nh\fP file.  Most of these replace \fBNetHack\fP's
-default representation of the dungeon using standard ASCII characters
-with fancier characters from extended character sets, and these fancier
-characters can annoy screen-readers.
 .hn 1
 Scoring
 .pg
index 754afde17a7f3bb655455c2dbaa6ecc52bd62599..24de88b100af0837fda62afae53064ef441a5807 100644 (file)
@@ -1,4 +1,8 @@
-\documentstyle[titlepage]{article}
+\documentclass{article}
+% \documentstyle[titlepage]{article}
+
+\usepackage{hyperref}
+\usepackage{longtable}
 
 \textheight 220mm
 \textwidth 160mm
@@ -27,7 +31,7 @@
 \begin{document}
 %
 % input file: guidebook.mn
-% $Revision: 1.100 $ $Date: 2006/05/18 04:18:23 $
+% $Revision: 1.101 $ $Date: 2006/07/15 03:25:04 $
 %
 %.ds h0 "
 %.ds h1 %.ds h2 \%
@@ -40,7 +44,7 @@
 %.au
 \author{Eric S. Raymond\\
 (Extensively edited and expanded for 3.5)}
-\date{November 19, 2005}
+\date{September 20, 2006}
 
 \maketitle
 
@@ -2092,17 +2096,11 @@ and the {\it fruit\/} is set to ``papaya'', you would enter the command
 Any line in the configuration file starting with `{\tt \#}' is treated as a comment.
 Any line in the configuration file starting with ``{\tt OPTIONS=}'' may be
 filled out with options in the same syntax as in NETHACKOPTIONS.
-Any line starting with ``{\tt DUNGEON=}'', ``{\tt EFFECTS=}'',
-``{\tt MONSTERS=}'', ``{\tt OBJECTS=}'', ``{\tt TRAPS=}'', 
-or ``{\tt BOULDER=}''
-is taken as defining the corresponding {\it dungeon},
-{\it effects}, {\it monsters}, {\it objects}, {\it traps\/} or
-{\it boulder\/} option in a different syntax,
-a sequence of decimal numbers giving the character position
-in the current font to be used in displaying each entry.
-A zero in any entry in such a sequence leaves the display of that
-entry unchanged; this feature is not available using the option syntax.
-Such a sequence can be continued to multiple lines by putting a
+Any line starting with ``{\tt SYMBOLS=}''
+is taken as defining the corresponding {\it symbol}
+in a different syntax, a sequence of decimal numbers giving 
+the character position in the current font to be used in displaying 
+each entry. Such a sequence can be continued to multiple lines by putting a
 `{\tt \verb+\+}' at the end of each line to be continued.
 
 %.pg
@@ -2190,14 +2188,6 @@ players if it detects some anticipated mistakes (default on).
 Have user confirm attacks on pets, shopkeepers, and other
 peaceable creatures (default on).
 %.lp
-\item[\ib{DECgraphics}]
-Use a predefined selection of characters from the DEC VT-xxx/DEC
-Rainbow/ANSI line-drawing character set to display the dungeon/effects/traps
-instead of having to define a full graphics set yourself (default off).
-This option also sets up proper handling of graphics
-characters for such terminals, so you should specify it when appropriate
-even if you override the selections with your own graphics strings.
-%.lp
 \item[\ib{disclose}]
 Controls options for disclosing various information when the game ends (defaults
 to all possibilities being disclosed).
@@ -2236,64 +2226,6 @@ traps and each other as well as by you.
 %.lp
 \item[\ib{dogname}]
 Name your starting dog (ex.\ ``{\tt dogname:Fang}'').
-Cannot be set with the `{\tt O}' command.
-%.lp
-\item[\ib{dungeon}]
-Set the graphics symbols for displaying the dungeon (default
-``\verb& |--------||.-|++##& \verb&.##<><>_|\\#{}.}..## #}&'').
-The {\it dungeon\/} option should be
-followed by a string of 1--41
-characters to be used instead of the default map-drawing characters.
-The dungeon map will use the characters you specify instead of the
-default symbols, and default symbols for any you do not specify.
-Remember that you may need to escape some of these characters
-on a command line if they are special to your shell.
-
-Note that {\it NetHack\/} escape-processes this option string in conventional C
-fashion.  This means that `\verb+\+' is a prefix to take the following
-character literally.  Thus `\verb+\+' needs to be represented as `\verb+\\+'.
-The special escape form
-`\verb+\m+' switches on the meta bit in the following character, and the
-`{\tt \^{}}' prefix causes the following character to be treated as a control
-character.
-
-The order of the symbols is:  solid rock, vertical wall, horizontal
-wall, upper left corner, upper right corner, lower left corner, lower
-right corner, cross wall, upward T wall, downward T wall, leftward T
-wall, rightward T wall, no door, vertical open door, horizontal open
-door, vertical closed door, horizontal closed door, iron bars, tree,
-floor of a room, dark corridor, lit corridor, stairs up, stairs down,
-ladder up, ladder down, altar, grave, throne, kitchen sink, fountain, pool or moat,
-ice, lava, vertical lowered drawbridge, horizontal lowered drawbridge,
-vertical raised drawbridge, horizontal raised drawbridge, air, cloud,
-under water.
-
-You might want to use `{\tt +}' for the corners and T walls for a more
-aesthetic, boxier display.  Note that in the next release, new symbols
-may be added, or the present ones rearranged.
-
-Cannot be set with the `{\tt O}' command.
-%.lp
-\item[\ib{effects}]
-Set the graphics symbols for displaying special effects (default
-``\verb&|-\\/*!)(0#@*/-\\& \verb&||\\-//-\\| |\\-/&'').
-The {\it effects\/} option should be
-followed by a string of 1--29
-characters to be used instead of the default special-effects characters.
-This string is subjected to the same processing as the {\it dungeon\/} option.
-
-The order of the symbols is:  vertical beam, horizontal beam, left slant,
-right slant, digging beam, camera flash beam, left boomerang, right boomerang,
-four glyphs giving the sequence for magic resistance displays,
-the eight surrounding glyphs for swallowed display,
-nine glyphs for explosions.
-An explosion consists of three rows (top, middle, and bottom) of three
-characters.  The explosion is centered in the center of this $3 \times 3$
-array.
-
-Note that in the next release, new symbols may be added,
-or the present ones rearranged.
-
 Cannot be set with the `{\tt O}' command.
 %.lp
 \item[\ib{extmenu}]
@@ -2338,14 +2270,6 @@ might miss some interesting and/or important information.
 Name your starting horse (ex.\ ``{\tt horsename:Trigger}'').
 Cannot be set with the `{\tt O}' command.
 %.lp
-\item[\ib{IBMgraphics}]
-Use a predefined selection of IBM extended ASCII characters to display the
-dungeon/effects/traps instead of having to define a full graphics set
-yourself (default off).
-This option also sets up proper handling of graphics
-characters for such terminals, so you should specify it when appropriate
-even if you override the selections with your own graphics strings.
-%.lp
 \item[\ib{ignintr}]
 Ignore interrupt signals, including breaks (default off).
 %.lp
@@ -2429,35 +2353,6 @@ Menu character accelerator to select all items on this page of a menu.
 Implemented by the Amiga, Gem and tty ports.
 Default `,'.
 %.lp
-\item[\ib{monsters}]
-Set the characters used to display monster classes (default
-``\verb+abcdefghijklmnopqrstuv+
-\verb+wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@ '&;:~]+'').
-This string is subjected to the same processing as the {\it dungeon\/} option.
-The order of the symbols is
-ant or other insect, blob, cockatrice,
-dog or other canine, eye or sphere, feline,
-gremlin, humanoid, imp or minor demon,
-jelly, kobold, leprechaun,
-mimic, nymph, orc,
-piercer, quadruped, rodent,
-arachnid or centipede, trapper or lurker above, horse or unicorn,
-vortex, worm, xan or other mythical/fantastic insect,
-light, zruty,
-angelic being, bat or bird, centaur,
-dragon, elemental, fungus or mold,
-gnome, giant humanoid, invisible monster,
-jabberwock, Keystone Kop, lich,
-mummy, naga, ogre,
-pudding or ooze, quantum mechanic, rust monster,
-snake, troll, umber hulk,
-vampire, wraith, xorn,
-apelike creature, zombie,
-human, ghost, golem,
-demon, sea monster, lizard,
-long worm tail, and mimic.
-Cannot be set with the `{\tt O}' command.
-%.lp
 \item[\ib{msghistory}]
 The number of top line messages to save (and recall with `{\tt \^{}P}')
 (default 20). Cannot be set with the `{\tt O}' command.
@@ -2524,16 +2419,6 @@ When moving by numbers, to enter a count prefix for those commands
 which accept one (such as ``{\tt 12s}'' to search twelve times), precede it
 with the letter `{\tt n}' (``{\tt n12s}'').
 %.lp
-\item[\ib{objects}]
-Set the characters used to display object classes (default
-``\verb&])[="(%!?+/$*`0_.&'').
-This string is subjected to the same processing as the {\it dungeon\/} option.
-The order of the symbols is
-illegal-object (should never be seen), weapon, armor, ring, amulet, tool,
-food, potion, scroll, spellbook, wand, gold, gem or rock, boulder or statue,
-iron ball, chain, and venom.
-Cannot be set with the `{\tt O}' command.
-%.lp
 \item[\ib{packorder}]
 Specify the order to list object types in (default
 ``\verb&")[%?+!=/(*`0_&''). The value of this option should be a string
@@ -2598,6 +2483,11 @@ value is examined; `r' is an exception with ``{\tt Rogue}'', {\tt Ranger}'',
 and ``{\tt random}'' values. If you prefix `{\tt !}' or ``{\tt no}'' to the 
 value, you can exclude that role from being picked randomly.
 %.lp
+\item[\ib{roguesymset}]
+This option may be used to select one of the named symbol sets found within
+{\tt symbols} to alter the symbols displayed on the screen on the
+rogue level.
+%.lp
 \item[\ib{rlecomp}]
 When writing out a save file, perform run length compression of the map.
 Not all ports support run length compression. It has no
@@ -2661,6 +2551,10 @@ This option may be set to a NetHack version level to suppress
 alert notification messages about feature changes for that 
 and prior versions (ex.\ ``{\tt suppress\_alert:3.3.1}'')
 %.lp
+\item[\ib{symset}]
+This option may be used to select one of the named symbol sets found within
+{\tt symbols} to alter the symbols displayed on the screen.
+%.lp
 \item[\ib{time}]
 Show the elapsed game time in turns on bottom line (default off).
 %.lp
@@ -2680,21 +2574,6 @@ Setting this option makes the score list visible when a windowing version
 of NetHack is started without a parent window, but it no longer leaves
 the score list around after game end on a terminal or emulating window.
 %.lp
-\item[\ib{traps}]
-Set the graphics symbols for displaying traps (default
-``\verb&^^^^^^^^^^^^^^^^^"^^^^&'').
-The {\it traps\/} option should be followed by a string of 1--22
-characters to be used instead of the default traps characters.
-This string is subjected to the same processing as the {\it dungeon\/} option.
-
-The order of the symbols is:
-arrow trap, dart trap, falling rock trap, squeaky board, bear trap,
-land mine, rolling boulder trap, sleeping gas trap, rust trap, fire trap,
-pit, spiked pit, hole, trap door, teleportation trap, level teleporter,
-magic portal, web, statue trap, magic trap, anti-magic field, polymorph trap.
-
-Cannot be set with the `{\tt O}' command.
-%.lp
 \item[\ib{travel}]
 Allow the travel command (default on).  Turning this option off will
 prevent the game from attempting unintended moves if you make inadvertent
@@ -3054,6 +2933,218 @@ specifies that any message with "chime of a cash register" contained
 in it will trigger the playing of "gong.wav".  You can have multiple
 SOUND entries in your config file.
 
+%.lp
+%.hn 2
+\subsection*{Modifying NetHack Symbols}
+
+%.pg
+NetHack can load entire symbol sets from the symbol file.
+
+%.pg
+The options that are used to select a particular symbol set from the 
+symbol file are:
+
+\blist{}
+%.lp
+\item[\ib{symset}]
+Set the name of the symbol set that you want to load.
+{\it symbols\/}.
+
+%.lp
+\item[\ib{roguesymset}]
+Set the name of the symbol set that you want to load for display 
+on the rogue level.
+\elist
+
+You can also override one or more symbols using the {\it SYMBOLS\/} config 
+file option. Symbols are specified as {\it name:value\/} pairs. Note that 
+{\it NetHack\/} escape-processes the {\it value\/} string in conventional C
+fashion.  This means that `\verb+\+' is a prefix to take the following
+character literally.  Thus `\verb+\+' needs to be represented as `\verb+\\+'.
+The special escape form
+`\verb+\m+' switches on the meta bit in the symbol value, and the
+`{\tt \^{}}' prefix causes the following character to be treated as a control
+character.
+
+{
+\small
+\begin{longtable}{lll}
+\caption[]{NetHack Symbols}\\
+Default  & Symbol Name                & Description\\
+\hline \hline
+\endhead
+\verb@ @ & S\_air                     &        (air)\\
+\verb@_@ & S\_altar                   &        (altar)\\
+\verb@"@ & S\_amulet                  &        (amulet)\\
+\verb@A@ & S\_angel                   &        (angelic being)\\
+\verb@a@ & S\_ant                     &        (ant or other insect)\\
+\verb@^@ & S\_anti\_magic\_trap       &        (anti-magic field)\\
+\verb@[@ & S\_armor                   &        (suit or piece of armor)\\
+\verb@[@ & S\_armour                  &        (suit or piece of armor)\\
+\verb@^@ & S\_arrow\_trap             &        (arrow trap)\\
+\verb@0@ & S\_ball                    &        (iron ball)\\
+\verb@#@ & S\_bars                    &        (iron bars)\\
+\verb@B@ & S\_bat                     &        (bat or bird)\\
+\verb@^@ & S\_bear\_trap              &        (bear trap)\\
+\verb@-@ & S\_blcorn                  &        (bottom left corner)\\
+\verb@b@ & S\_blob                    &        (blob)\\
+\verb@+@ & S\_book                    &        (spellbook)\\
+\verb@)@ & S\_boomleft                &        (boomerang open left)\\
+\verb@(@ & S\_boomright               &        (boomerang open right)\\
+\verb@`@ & S\_boulder                 &        (boulder)\\
+\verb@-@ & S\_brcorn                  &        (bottom right corner)\\
+\verb@C@ & S\_centaur                 &        (centaur)\\
+\verb@_@ & S\_chain                   &        (iron chain)\\
+\verb@#@ & S\_cloud                   &        (cloud)\\
+\verb@c@ & S\_cockatrice              &        (cockatrice)\\
+\verb@$@ & S\_coin                    &        (pile of coins)\\
+\verb@#@ & S\_corr                    &        (corridor)\\
+\verb@-@ & S\_crwall                  &        (wall)\\
+\verb@^@ & S\_dart\_trap              &        (dart trap)\\
+\verb@&@ & S\_demon                   &        (major demon)\\
+\verb@*@ & S\_digbeam                 &        (dig beam)\\
+\verb@>@ & S\_dnladder                &        (ladder down)\\
+\verb@>@ & S\_dnstair                 &        (staircase down)\\
+\verb@d@ & S\_dog                     &        (dog or other canine)\\
+\verb@D@ & S\_dragon                  &        (dragon)\\
+\verb@;@ & S\_eel                     &        (sea monster)\\
+\verb@E@ & S\_elemental               &        (elemental)\\
+\verb@/@ & S\_explode1                &        (explosion top left)\\
+\verb@-@ & S\_explode2                &        (explosion top center)\\
+\verb@\@ & S\_explode3                &        (explosion top right)\\
+\verb@|@ & S\_explode4                &        (explosion middle left)\\
+\verb@ @ & S\_explode5                &        (explosion middle center)\\
+\verb@|@ & S\_explode6                &        (explosion middle right)\\
+\verb@\@ & S\_explode7                &        (explosion bottom left)\\
+\verb@-@ & S\_explode8                &        (explosion bottom center)\\
+\verb@/@ & S\_explode9                &        (explosion bottom right)\\
+\verb@e@ & S\_eye                     &        (eye or sphere)\\
+\verb@^@ & S\_falling\_rock\_trap     &        (falling rock trap)\\
+\verb@f@ & S\_feline                  &        (cat or other feline)\\
+\verb@^@ & S\_fire\_trap              &        (fire trap)\\
+\verb@!@ & S\_flashbeam               &        (flash beam)\\
+\verb@%@ & S\_food                    &        (piece of food)\\
+\verb@{@ & S\_fountain                &        (fountain)\\
+\verb@F@ & S\_fungus                  &        (fungus or mold)\\
+\verb@*@ & S\_gem                     &        (gem or rock)\\
+\verb@ @ & S\_ghost                   &        (ghost)\\
+\verb@H@ & S\_giant                   &        (giant humanoid)\\
+\verb@G@ & S\_gnome                   &        (gnome)\\
+\verb@'@ & S\_golem                   &        (golem)\\
+\verb@|@ & S\_grave                   &        (grave)\\
+\verb@g@ & S\_gremlin                 &        (gremlin)\\
+\verb@-@ & S\_hbeam                   &        (wall)\\
+\verb@#@ & S\_hcdbridge               &        (horizontal raised drawbridge)\\
+\verb@+@ & S\_hcdoor                  &        (closed door)\\
+\verb@.@ & S\_hodbridge               &        (horizontal lowered drawbridge)\\
+\verb@|@ & S\_hodoor                  &        (open door)\\
+\verb@^@ & S\_hole                    &        (hole)\\
+\verb~@~ & S\_human                   &        (human or elf)\\
+\verb@h@ & S\_humanoid                &        (humanoid)\\
+\verb@-@ & S\_hwall                   &        (horizontal wall)\\
+\verb@.@ & S\_ice                     &        (ice)\\
+\verb@i@ & S\_imp                     &        (imp or minor demon)\\
+\verb@J@ & S\_jabberwock              &        (jabberwock)\\
+\verb@j@ & S\_jelly                   &        (jelly)\\
+\verb@k@ & S\_kobold                  &        (kobold)\\
+\verb@K@ & S\_kop                     &        (Keystone Kop)\\
+\verb@^@ & S\_land\_mine              &        (land mine)\\
+\verb@}@ & S\_lava                    &        (molten lava)\\
+\verb@l@ & S\_leprechaun              &        (leprechaun)\\
+\verb@^@ & S\_level\_teleporter       &        (level teleporter)\\
+\verb@L@ & S\_lich                    &        (lich)\\
+\verb@y@ & S\_light                   &        (light)\\
+\verb@#@ & S\_litcorr                 &        (lit corridor)\\
+\verb@:@ & S\_lizard                  &        (lizard)\\
+\verb@\@ & S\_lslant                  &        (wall)\\
+\verb@^@ & S\_magic\_portal           &        (magic portal)\\
+\verb@^@ & S\_magic\_trap             &        (magic trap)\\
+\verb@m@ & S\_mimic                   &        (mimic)\\
+\verb@]@ & S\_mimic\_def              &        (mimic)\\
+\verb@M@ & S\_mummy                   &        (mummy)\\
+\verb@N@ & S\_naga                    &        (naga)\\
+\verb@.@ & S\_ndoor                   &        (doorway)\\
+\verb@n@ & S\_nymph                   &        (nymph)\\
+\verb@O@ & S\_ogre                    &        (ogre)\\
+\verb@o@ & S\_orc                     &        (orc)\\
+\verb@p@ & S\_piercer                 &        (piercer)\\
+\verb@^@ & S\_pit                     &        (pit)\\
+\verb@^@ & S\_polymorph\_trap         &        (polymorph trap)\\
+\verb@}@ & S\_pool                    &        (water)\\
+\verb@!@ & S\_potion                  &        (potion)\\
+\verb@P@ & S\_pudding                 &        (pudding or ooze)\\
+\verb@q@ & S\_quadruped               &        (quadruped)\\
+\verb@Q@ & S\_quantmech               &        (quantum mechanic)\\
+\verb@=@ & S\_ring                    &        (ring)\\
+\verb@`@ & S\_rock                    &        (boulder or statue)\\
+\verb@r@ & S\_rodent                  &        (rodent)\\
+\verb@^@ & S\_rolling\_boulder\_trap  &        (rolling boulder trap)\\
+\verb@.@ & S\_room                    &        (floor of a room)\\
+\verb@/@ & S\_rslant                  &        (wall)\\
+\verb@^@ & S\_rust\_trap              &        (rust trap)\\
+\verb@R@ & S\_rustmonst               &        (rust monster or disenchanter)\\
+\verb@?@ & S\_scroll                  &        (scroll)\\
+\verb@#@ & S\_sink                    &        (sink)\\
+\verb@^@ & S\_sleeping\_gas\_trap     &        (sleeping gas trap)\\
+\verb@S@ & S\_snake                   &        (snake)\\
+\verb@s@ & S\_spider                  &        (arachnid or centipede)\\
+\verb@^@ & S\_spiked\_pit             &        (spiked pit)\\
+\verb@^@ & S\_squeaky\_board          &        (squeaky board)\\
+\verb@0@ & S\_ss1                     &        (magic shield 1 of 4)\\
+\verb@#@ & S\_ss2                     &        (magic shield 2 of 4)\\
+\verb@@@ & S\_ss3                     &        (magic shield 3 of 4)\\
+\verb@*@ & S\_ss4                     &        (magic shield 4 of 4)\\
+\verb@^@ & S\_statue\_trap            &        (statue trap)\\
+\verb@ @ & S\_stone                   &        (dark part of a room)\\
+\verb@-@ & S\_sw\_bc                  &        (swallow bottom center)\\
+\verb@\@ & S\_sw\_bl                  &        (swallow bottom left)\\
+\verb@/@ & S\_sw\_br                  &        (swallow bottom right   )\\
+\verb@|@ & S\_sw\_ml                  &        (swallow middle left)\\
+\verb@|@ & S\_sw\_mr                  &        (swallow middle right)\\
+\verb@-@ & S\_sw\_tc                  &        (swallow top center)\\
+\verb@/@ & S\_sw\_tl                  &        (swallow top left)\\
+\verb@\@ & S\_sw\_tr                  &        (swallow top right)\\
+\verb@-@ & S\_tdwall                  &        (wall)\\
+\verb@^@ & S\_teleportation\_trap     &        (teleportation trap)\\
+\verb@\@ & S\_throne                  &        (opulent throne)\\
+\verb@-@ & S\_tlcorn                  &        (top left corner)\\
+\verb@|@ & S\_tlwall                  &        (wall)\\
+\verb@(@ & S\_tool                    &        (useful item (pick-axe\, key\, lamp...))\\
+\verb@^@ & S\_trap\_door              &        (trap door)\\
+\verb@t@ & S\_trapper                 &        (trapper or lurker above)\\
+\verb@-@ & S\_trcorn                  &        (top right corner)\\
+\verb@#@ & S\_tree                    &        (tree)\\
+\verb@T@ & S\_troll                   &        (troll)\\
+\verb@|@ & S\_trwall                  &        (wall)\\
+\verb@-@ & S\_tuwall                  &        (wall)\\
+\verb@U@ & S\_umber                   &        (umber hulk)\\
+\verb@u@ & S\_unicorn                 &        (unicorn or horse)\\
+\verb@<@ & S\_upladder                &        (ladder up)\\
+\verb@<@ & S\_upstair                 &        (staircase up)\\
+\verb@V@ & S\_vampire                 &        (vampire)\\
+\verb@|@ & S\_vbeam                   &        (wall)\\
+\verb@#@ & S\_vcdbridge               &        (vertical raised drawbridge)\\
+\verb@+@ & S\_vcdoor                  &        (closed door)\\
+\verb@.@ & S\_venom                   &        (splash of venom)\\
+\verb@.@ & S\_vodbridge               &        (vertical lowered drawbridge)\\
+\verb@-@ & S\_vodoor                  &        (open door)\\
+\verb@v@ & S\_vortex                  &        (vortex)\\
+\verb@|@ & S\_vwall                   &        (vertical wall)\\
+\verb@/@ & S\_wand                    &        (wand)\\
+\verb@}@ & S\_water                   &        (water)\\
+\verb@)@ & S\_weapon                  &        (weapon)\\
+\verb@"@ & S\_web                     &        (web)\\
+\verb@w@ & S\_worm                    &        (worm)\\
+\verb@~@ & S\_worm\_tail              &        (long worm tail)\\
+\verb@W@ & S\_wraith                  &        (wraith)\\
+\verb@x@ & S\_xan                     &        (xan or other mythical/fantastic insect)\\
+\verb@X@ & S\_xorn                    &        (xorn)\\
+\verb@Y@ & S\_yeti                    &        (apelike creature)\\
+\verb@Z@ & S\_zombie                  &        (zombie)\\
+\verb@z@ & S\_zruty                   &        (zruty)
+\end{longtable}%
+}
+
 %.lp
 %.hn 2
 \subsection*{Configuring NetHack for Play by the Blind}
@@ -3077,18 +3168,22 @@ overall location of items on the screen.
 %.pg
 While it is not difficult for experienced users to edit the {\it defaults.nh\/}
 file to accomplish this, novices may find this task somewhat daunting.
-Included in all official distributions of NetHack is a file called
-{\it NHAccess.nh\/}.  Replacing {\it defaults.nh\/} with this file will cause
-the game to run in a manner accessible to the blind. After you have gained
-some experience with the game and with editing files, you may want to alter
-settings to better suit your preferences. Instructions on how to do this
-are included in the {\it NHAccess.nh\/} file itself. The most crucial
-settings to make the game accessible are:
+Included within the symbol file of all official distributions of NetHack 
+is a symset called {\it NHAccess\/}.  Selecting that symset in your
+configuration file will cause the game to run in a manner accessible 
+to the blind. After you have gained some experience with the game 
+and with editing files, you may want to alter settings via {\it SYMBOLS=\/} 
+in your configuration file to better suit your preferences. 
+The most crucial settings to make the game accessible are:
 %.pg
 \blist{}
 %.lp
-\item[\ib{IBMgraphics}]
-Disable IBMgraphics by commenting out this option.
+\item[\ib{symset:NHAccess}]
+Load a symbol set appropriate for use by blind players.
+%.lp
+\item[\ib{roguesymset:NHAccess}]
+Load a symbol set for the rogue level that is appropriate for 
+use by blind players.
 %.lp
 \item[\ib{menustyle:traditional}]
 This will assist in the interface to speech synthesizers.
@@ -3097,13 +3192,6 @@ This will assist in the interface to speech synthesizers.
 A lot of speech access programs use the number-pad to review the screen.
 If this is the case, disable the number\_pad option and use the traditional
 Rogue-like commands.
-%.lp
-\item[\ib{Character graphics}]
-Comment out all character graphics sets found near the bottom of the
-{\it defaults.nh\/} file.  Most of these replace {\it NetHack\/}'s
-default representation of the dungeon using standard ASCII characters
-with fancier characters from extended character sets, and these fancier
-characters can annoy screen-readers.
 \elist
 
 %.hn 1
@@ -3402,9 +3490,14 @@ resurrected it for 3.3.1.
 %.pg
 \medskip
 \nd There is a NetHack web site maintained by {\it Ken Lorber} at 
+{\catcode`\#=11
+\special{html:<a href="http://www.nethack.org/">}}
 http:{\tt /}{\tt /}www.nethack.org{\tt /}.
+{\catcode`\#=11
+\special{html:</a>}}
 
-%.pg
+%.hn 3
+\subsection*{Dungeoneers}
 \bigskip
 \nd From time to time, some depraved individual out there in netland sends a
 particularly intriguing modification to help out with the game.  The Gods of
index 94c176f249e541f5f22eb9c545da105cb97541aa..8f444269ea862315564e33938db9fb6335383ca3 100644 (file)
@@ -515,8 +515,8 @@ winid WIN_MESSAGE, WIN_MAP, WIN_INVEN
                        There is also a window called WIN_STATUS that is used
                        only for backward compatibility in the genl_status_*
                        set of generic status display functions.
-char *AE, *AS;         Checked in options.c to see if we should switch
-                       to DEC_GRAPHICS.  It is #ifdefed VMS and UNIX.
+char *AE, *AS;         Checked in options.c to see if we should load and 
+                       switch to DECGraphics symset.  It is #ifdefed VMS and UNIX.
 int LI, CO;            Set in sys/unix/ioctl.c.
 
 The following appears to be Unix specific.  Other ports using the tty
index 511e67c2baf5ba3642ecfbbf8a070d2d4286bbdc..ede0875790a2f2760577906d3bdec2154729b37b 100644 (file)
@@ -231,9 +231,9 @@ E NEARDATA struct spell spl_book[]; /* sized in decl.c */
 E const int zapcolors[];
 #endif
 
-E const char def_oc_syms[MAXOCLASSES]; /* default class symbols */
+E const struct class_sym def_oc_syms[MAXOCLASSES];     /* default class symbols */
 E uchar oc_syms[MAXOCLASSES];          /* current class symbols */
-E const char def_monsyms[MAXMCLASSES]; /* default class symbols */
+E const struct class_sym def_monsyms[MAXMCLASSES];     /* default class symbols */
 E uchar monsyms[MAXMCLASSES];          /* current class symbols */
 
 #include "obj.h"
@@ -269,6 +269,8 @@ E NEARDATA struct mvitals {
        uchar   mvflags;
 } mvitals[NUMMONS];
 
+E struct symparse loadsyms[];
+
 E NEARDATA struct c_color_names {
     const char *const c_black, *const c_amber, *const c_golden,
                *const c_light_blue,*const c_red, *const c_green,
@@ -347,7 +349,7 @@ E struct tc_gbl_data {      /* also declared in tcap.h */
 #endif
 
 /* xxxexplain[] is in drawing.c */
-E const char * const monexplain[], invisexplain[], * const objexplain[], * const oclass_names[];
+E const char * const monexplain[], invisexplain[], * const oclass_names[];
 
 /* Some systems want to use full pathnames for some subsets of file names,
  * rather than assuming that they're all in the current directory.  This
index 9ada0440087c0f31d6e4ca714fd783b49aad67c6..cb20ca78d66acb6bbbb21e35e1a53de821d19100 100644 (file)
@@ -491,10 +491,18 @@ E boolean FDECL(hurtle_step, (genericptr_t, int, int));
 E int FDECL(def_char_to_objclass, (CHAR_P));
 E int FDECL(def_char_to_monclass, (CHAR_P));
 #if !defined(MAKEDEFS_C) && !defined(LEV_LEX_C)
-E void FDECL(assign_graphics, (uchar *,int,int,int));
 E void FDECL(switch_graphics, (int));
 #ifdef REINCARNATION
 E void FDECL(assign_rogue_graphics, (BOOLEAN_P));
+E void NDECL(init_r_symbols);
+#endif
+E void NDECL(init_symbols);
+E void NDECL(init_disp_symbols);
+E void NDECL(init_l_symbols);
+#ifdef ASCIIGRAPH
+E void FDECL(update_l_symset, (struct symparse *,int));
+E void FDECL(update_r_symset, (struct symparse *,int));
+E void FDECL(switch_graphics, (int));
 #endif
 #ifdef BARGETHROUGH
 E boolean FDECL(cursed_object_at, (int, int));
@@ -710,6 +718,10 @@ E void FDECL(check_recordfile, (const char *));
 #if defined(WIZARD)
 E void NDECL(read_wizkit);
 #endif
+#ifdef ASCIIGRAPH
+E int FDECL(read_sym_file, (BOOLEAN_P));
+E int FDECL(parse_sym_line, (char *,BOOLEAN_P));
+#endif
 E void FDECL(paniclog, (const char *, const char *));
 E int FDECL(validate_prefix_locations, (char *));
 E char** NDECL(get_saved_games);
@@ -1524,6 +1536,12 @@ E void FDECL(set_option_mod_status, (const char *,int));
 E int FDECL(add_autopickup_exception, (const char *));
 E void NDECL(free_autopickup_exceptions);
 #endif /* AUTOPICKUP_EXCEPTIONS */
+#ifdef ASCIIGRAPH
+E int FDECL(load_symset, (const char *,BOOLEAN_P));
+E void FDECL(parsesymbols, (char *));
+E struct symparse *FDECL(match_sym, (char *));
+E int FDECL(sym_val, (char *));
+#endif
 
 /* ### pager.c ### */
 
index 78071eae3073c0bebf75b95eb5519cbed9a0e0b9..a9fe3869c39c55ff0a26e9149cfeb04a135857f6 100644 (file)
@@ -181,9 +181,15 @@ struct instance_flags {
        boolean  zerocomp;      /* write zero-compressed save files */
        boolean  rlecomp;       /* run-length comp of levels when writing savefile */
        uchar    num_pad_mode;
-       boolean  DECgraphics;   /* use DEC VT-xxx extended character set */
        boolean  echo;          /* 1 to echo characters */
+#if 0
+       boolean  DECgraphics;   /* use DEC VT-xxx extended character set */
        boolean  IBMgraphics;   /* use IBM extended character set */
+#ifdef MAC_GRAPHICS_ENV
+       boolean  MACgraphics;   /* use Macintosh extended character set, as
+                                  as defined in the special font HackFont */
+#endif
+#endif
        uchar   bouldersym;     /* symbol for boulder display */
 #ifdef TTY_GRAPHICS
        char prevmsg_window;    /* type of old message window to use */
index 5a0d755a52c10977fdb29e960339b07b3c993c74..e761b5d60e32d6fd826fea436f3072341dbfc70f 100644 (file)
@@ -26,7 +26,7 @@
 #define LICENSE       "license" /* file with license information */
 #define OPTIONFILE    "opthelp" /* file explaining runtime options */
 #define OPTIONS_USED  "options" /* compile-time options, for #version */
-
+#define SYMBOLS       "symbols" /* replacement symbol sets */
 #define LEV_EXT ".lev"         /* extension for special level files */
 
 
index 1511d85770fcd0ce2e7d4b372f2066d381bcd549..91171e429be714dbaa7a37ea18aa63e8f779504f 100644 (file)
@@ -109,6 +109,12 @@ struct objclass {
        unsigned short  oc_nutrition;   /* food value */
 };
 
+struct class_sym {
+       char sym;
+       char *name;
+       char *explain;
+};
+
 struct objdescr {
        const char *oc_name;            /* actual name */
        const char *oc_descr;           /* description when name unknown */
@@ -149,7 +155,7 @@ extern NEARDATA struct objdescr obj_descr[];
 #define MON_EXPLODE    (MAXOCLASSES+2) /* Exploding monster (e.g. gas spore) */
 
 #if 0  /* moved to decl.h so that makedefs.c won't see them */
-extern const char def_oc_syms[MAXOCLASSES];    /* default class symbols */
+extern const struct class_sym def_oc_syms[MAXOCLASSES];        /* default class symbols */
 extern uchar oc_syms[MAXOCLASSES];             /* current class symbols */
 #endif
 
index 3851d25f086222c3752ac66eef14e32b43131f93..40f0658fd701ea6e635c18428f2a4026ad0ffbf7 100644 (file)
@@ -223,17 +223,49 @@ struct symdef {
 #endif
 };
 
+struct symparse {
+       unsigned range;
+#define SYM_CONTROL    1       /* start/finish markers */
+#define SYM_PCHAR      2       /* index into showsyms  */
+#define SYM_MON                3       /* index into monsyms   */
+#define SYM_OC         4       /* index into oc_syms   */
+#define SYM_OBJ                5       /* index into objects   */
+       int idx;
+       const char *name;
+};
+
+/* general linked list of text pointers */
+struct textlist {
+       char *text;             /* the text       */
+       int idx;                /* an index value */
+       struct textlist *next;  /* next in list   */
+};
+
+#ifdef REINCARNATION
+#define ROGUEHANDLING(H) ((Is_rogue_level(&u.uz) && roguehandling && \
+                          !strcmpi(roguehandling,H)))
+#define SYMHANDLING(H) (ROGUEHANDLING(H) || \
+                        (!Is_rogue_level(&u.uz) && symhandling && \
+                         !strcmpi(symhandling,H)))
+#else
+#define SYMHANDLING(H) (symhandling && !strcmpi(symhandling,H))
+#endif
+
 extern const struct symdef defsyms[MAXPCHARS]; /* defaults */
 extern uchar showsyms[MAXPCHARS];
 extern const struct symdef def_warnsyms[WARNCOUNT];
+extern char *symset, *symhandling;             /* from drawing.c */
+extern char *roguesymset, *roguehandling;      /* from drawing.c */
 
 /*
  * Graphics sets for display symbols
  */
-#define ASCII_GRAPHICS 0       /* regular characters: '-', '+', &c */
+#define DEFAULT_GRAPHICS 0     /* regular characters: '-', '+', &c */
+#if 0
 #define IBM_GRAPHICS   1       /* PC graphic characters */
 #define DEC_GRAPHICS   2       /* VT100 line drawing characters */
 #define MAC_GRAPHICS   3       /* Macintosh drawing characters */
+#endif
 
 /*
  * The 5 possible states of doors
index efda3fe48caf81f50fb62d0a8c0a3934f665d8f8..5320610a6dccb9dfd0f290d36b377d99fc601adb 100644 (file)
@@ -425,14 +425,14 @@ int               class;          /* an object class, 0 for all */
      * detect. Rather than trump anything, show both possibilities.
      * We can exclude checking the buried obj chain for boulders below.
      */
-    sym = class ? def_oc_syms[class] : 0;
+    sym = class ? def_oc_syms[class].sym : 0;
     if (sym && iflags.bouldersym && sym == iflags.bouldersym)
        boulder = ROCK_CLASS;
 
     if (Hallucination || (Confusion && class == SCROLL_CLASS))
        Strcpy(stuff, something);
     else
-       Strcpy(stuff, class ? oclass_names[class] : "objects");
+       Strcpy(stuff, class ? def_oc_syms[class].name : "objects");
     if (boulder && class != ROCK_CLASS) Strcat(stuff, " and/or large stones");
 
     if (do_dknown) for(obj = invent; obj; obj = obj->nobj) do_dknown_of(obj);
@@ -616,7 +616,7 @@ int mclass;                 /* monster class, 0 for all */
            if (!mclass || mtmp->data->mlet == mclass ||
                (mtmp->data == &mons[PM_LONG_WORM] && mclass == S_WORM_TAIL))
                    if (mtmp->mx > 0) {
-                       if (mclass && def_monsyms[mclass] == ' ')
+                       if (mclass && def_monsyms[mclass].sym == ' ')
                                show_glyph(mtmp->mx,mtmp->my,
                                        detected_mon_to_glyph(mtmp));
                        else
@@ -917,7 +917,7 @@ struct obj *obj;
     if (flags.verbose) You("may look for an object or monster symbol.");
     ch = yn_function("What do you look for?", (char *)0, '\0');
     /* Don't filter out ' ' here; it has a use */
-    if ((ch != def_monsyms[S_GHOST]) && index(quitchars,ch)) { 
+    if ((ch != def_monsyms[S_GHOST].sym) && index(quitchars,ch)) { 
        if (flags.verbose) pline(Never_mind);
        return;
     }
index 65c4e53e9376fac27ad1aaeb5ddb0cc9429760f6..78725ae0235509381c846a60c0c6757541c1efaa 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)drawing.c  3.5     2005/09/23      */
+/*     SCCS Id: @(#)drawing.c  3.5     2006/09/16      */
 /* Copyright (c) NetHack Development Team 1992.                          */
 /* NetHack may be freely redistributed.  See license for details. */
 
 #define C(n)
 #endif
 
-#define g_FILLER(symbol) 0
+char *symset = 0, *symhandling = 0;            /* from drawing.c */
+char *roguesymset = 0, *roguehandling = 0;     /* from drawing.c */
 
 uchar oc_syms[MAXOCLASSES] = DUMMY; /* the current object  display symbols */
 uchar showsyms[MAXPCHARS]  = DUMMY; /* the current feature display symbols */
 uchar monsyms[MAXMCLASSES] = DUMMY; /* the current monster display symbols */
-uchar warnsyms[WARNCOUNT]  = DUMMY;  /* the current warning display symbols */
 
-/* Default object class symbols.  See objclass.h. */
-const char def_oc_syms[MAXOCLASSES] = {
-/* 0*/ '\0',           /* placeholder for the "random class" */
-       ILLOBJ_SYM,
-       WEAPON_SYM,
-       ARMOR_SYM,
-       RING_SYM,
-/* 5*/ AMULET_SYM,
-       TOOL_SYM,
-       FOOD_SYM,
-       POTION_SYM,
-       SCROLL_SYM,
-/*10*/ SPBOOK_SYM,
-       WAND_SYM,
-       GOLD_SYM,
-       GEM_SYM,
-       ROCK_SYM,
-/*15*/ BALL_SYM,
-       CHAIN_SYM,
-       VENOM_SYM
-};
+/* loaded primary syms */
+uchar l_oc_syms[MAXOCLASSES] = DUMMY;
+uchar l_showsyms[MAXPCHARS]  = DUMMY;
+uchar l_monsyms[MAXMCLASSES] = DUMMY;
 
-const char invisexplain[] = "remembered, unseen, creature";
+#ifdef REINCARNATION
+/* rogue syms */
+uchar r_oc_syms[MAXOCLASSES] = DUMMY;
+uchar r_showsyms[MAXPCHARS]  = DUMMY;
+uchar r_monsyms[MAXMCLASSES] = DUMMY;
+#endif
 
-/* Object descriptions.  Used in do_look(). */
-const char * const objexplain[] = {    /* these match def_oc_syms, above */
-/* 0*/ 0,
-       "strange object",
-       "weapon",
-       "suit or piece of armor",
-       "ring",
-/* 5*/ "amulet",
-       "useful item (pick-axe, key, lamp...)",
-       "piece of food",
-       "potion",
-       "scroll",
-/*10*/ "spellbook",
-       "wand",
-       "pile of coins",
-       "gem or rock",
-       "boulder or statue",
-/*15*/ "iron ball",
-       "iron chain",
-       "splash of venom"
-};
+uchar warnsyms[WARNCOUNT]  = DUMMY;  /* the current warning display symbols */
+const char invisexplain[] = "remembered, unseen, creature";
 
-/* Object class names.  Used in object_detect(). */
-const char * const oclass_names[] = {
-/* 0*/ 0,
-       "illegal objects",
-       "weapons",
-       "armor",
-       "rings",
-/* 5*/ "amulets",
-       "tools",
-       "food",
-       "potions",
-       "scrolls",
-/*10*/ "spellbooks",
-       "wands",
-       "coins",
-       "rocks",
-       "large stones",
-/*15*/ "iron balls",
-       "chains",
-       "venoms"
+/* Default object class symbols.  See objclass.h.
+ * {symbol, name explain}
+ *     name:    used in object_detect().
+ *     explain: used in do_look().
+ */
+const struct class_sym def_oc_syms[MAXOCLASSES] = {
+{ '\0',       "", ""}, /* placeholder for the "random class" */
+{ ILLOBJ_SYM, "illegal objects", "strange object"},
+{ WEAPON_SYM, "weapons", "weapon"},
+{ ARMOR_SYM,  "armor", "suit or piece of armor"},
+{ RING_SYM,   "rings", "ring"},
+{ AMULET_SYM, "amulets", "amulet"},
+{ TOOL_SYM,   "tools", "useful item (pick-axe, key, lamp...)"},
+{ FOOD_SYM,   "food", "piece of food"},
+{ POTION_SYM, "potions", "potion"},
+{ SCROLL_SYM, "scrolls", "scroll"},
+{ SPBOOK_SYM, "spellbooks", "spellbook"},
+{ WAND_SYM,   "wands", "wand"},
+{ GOLD_SYM,   "coins", "pile of coins"},
+{ GEM_SYM,    "rocks", "gem or rock"},
+{ ROCK_SYM,   "large stones", "boulder or statue"},
+{ BALL_SYM,   "iron balls", "iron ball"},
+{ CHAIN_SYM,  "chains", "iron chain"},
+{ VENOM_SYM,  "venoms", "splash of venom"}
 };
 
 /* Default monster class symbols.  See monsym.h. */
-const char def_monsyms[MAXMCLASSES] = {
-       '\0',           /* holder */
-       DEF_ANT,
-       DEF_BLOB,
-       DEF_COCKATRICE,
-       DEF_DOG,
-       DEF_EYE,
-       DEF_FELINE,
-       DEF_GREMLIN,
-       DEF_HUMANOID,
-       DEF_IMP,
-       DEF_JELLY,              /* 10 */
-       DEF_KOBOLD,
-       DEF_LEPRECHAUN,
-       DEF_MIMIC,
-       DEF_NYMPH,
-       DEF_ORC,
-       DEF_PIERCER,
-       DEF_QUADRUPED,
-       DEF_RODENT,
-       DEF_SPIDER,
-       DEF_TRAPPER,            /* 20 */
-       DEF_UNICORN,
-       DEF_VORTEX,
-       DEF_WORM,
-       DEF_XAN,
-       DEF_LIGHT,
-       DEF_ZRUTY,
-       DEF_ANGEL,
-       DEF_BAT,
-       DEF_CENTAUR,
-       DEF_DRAGON,             /* 30 */
-       DEF_ELEMENTAL,
-       DEF_FUNGUS,
-       DEF_GNOME,
-       DEF_GIANT,
-       '\0',
-       DEF_JABBERWOCK,
-       DEF_KOP,
-       DEF_LICH,
-       DEF_MUMMY,
-       DEF_NAGA,               /* 40 */
-       DEF_OGRE,
-       DEF_PUDDING,
-       DEF_QUANTMECH,
-       DEF_RUSTMONST,
-       DEF_SNAKE,
-       DEF_TROLL,
-       DEF_UMBER,
-       DEF_VAMPIRE,
-       DEF_WRAITH,
-       DEF_XORN,               /* 50 */
-       DEF_YETI,
-       DEF_ZOMBIE,
-       DEF_HUMAN,
-       DEF_GHOST,
-       DEF_GOLEM,
-       DEF_DEMON,
-       DEF_EEL,
-       DEF_LIZARD,
-       DEF_WORM_TAIL,
-       DEF_MIMIC_DEF,          /* 60 */
-};
-
-/* The explanations below are also used when the user gives a string
- * for blessed genocide, so no text should wholly contain any later
- * text.  They should also always contain obvious names (eg. cat/feline).
- */
-const char * const monexplain[MAXMCLASSES] = {
-    0,
-    "ant or other insect",     "blob",                 "cockatrice",
-    "dog or other canine",     "eye or sphere",        "cat or other feline",
-    "gremlin",                 "humanoid",             "imp or minor demon",
-    "jelly",                   "kobold",               "leprechaun",
-    "mimic",                   "nymph",                "orc",
-    "piercer",                 "quadruped",            "rodent",
-    "arachnid or centipede",   "trapper or lurker above", "unicorn or horse",
-    "vortex",          "worm", "xan or other mythical/fantastic insect",
-    "light",                   "zruty",
-
-    "angelic being",           "bat or bird",          "centaur",
-    "dragon",                  "elemental",            "fungus or mold",
-    "gnome",                   "giant humanoid",       0,
-    "jabberwock",              "Keystone Kop",         "lich",
-    "mummy",                   "naga",                 "ogre",
-    "pudding or ooze",         "quantum mechanic",     "rust monster or disenchanter",
-    "snake",                   "troll",                "umber hulk",
-    "vampire",                 "wraith",               "xorn",
-    "apelike creature",                "zombie",
-
-    "human or elf",            "ghost",                "golem",
-    "major demon",             "sea monster",          "lizard",
-    "long worm tail",          "mimic"
+const struct class_sym def_monsyms[MAXMCLASSES] = {
+ { '\0',            "", ""},
+ { DEF_ANT,         "", "ant or other insect"},
+ { DEF_BLOB,        "", "blob"},
+ { DEF_COCKATRICE,  "", "cockatrice"},
+ { DEF_DOG,         "", "dog or other canine"},
+ { DEF_EYE,         "", "eye or sphere"},
+ { DEF_FELINE,      "", "cat or other feline"},
+ { DEF_GREMLIN,     "", "gremlin"},
+ { DEF_HUMANOID,    "", "humanoid"},
+ { DEF_IMP,         "", "imp or minor demon"},
+ { DEF_JELLY,       "", "jelly"},
+ { DEF_KOBOLD,      "", "kobold"},
+ { DEF_LEPRECHAUN,  "", "leprechaun"},
+ { DEF_MIMIC,       "", "mimic"},
+ { DEF_NYMPH,       "", "nymph"},
+ { DEF_ORC,         "", "orc"},
+ { DEF_PIERCER,     "", "piercer"},
+ { DEF_QUADRUPED,   "", "quadruped"},
+ { DEF_RODENT,      "", "rodent"},
+ { DEF_SPIDER,      "", "arachnid or centipede"},
+ { DEF_TRAPPER,     "", "trapper or lurker above"},
+ { DEF_UNICORN,     "", "unicorn or horse"},
+ { DEF_VORTEX,      "", "vortex"},
+ { DEF_WORM,        "", "worm"},
+ { DEF_XAN,         "", "xan or other mythical/fantastic insect"},
+ { DEF_LIGHT,       "", "light"},
+ { DEF_ZRUTY,       "", "zruty"},
+ { DEF_ANGEL,       "", "angelic being"},
+ { DEF_BAT,         "", "bat or bird"},
+ { DEF_CENTAUR,     "", "centaur"},
+ { DEF_DRAGON,      "", "dragon"},
+ { DEF_ELEMENTAL,   "", "elemental"},
+ { DEF_FUNGUS,      "", "fungus or mold"},
+ { DEF_GNOME,       "", "gnome"},
+ { DEF_GIANT,       "", "giant humanoid"},
+ { '\0',            "", ""},
+ { DEF_JABBERWOCK,  "", "jabberwock"},
+ { DEF_KOP,         "", "Keystone Kop"},
+ { DEF_LICH,        "", "lich"},
+ { DEF_MUMMY,       "", "mummy"},
+ { DEF_NAGA,        "", "naga"},
+ { DEF_OGRE,        "", "ogre"},
+ { DEF_PUDDING,     "", "pudding or ooze"},
+ { DEF_QUANTMECH,   "", "quantum mechanic"},
+ { DEF_RUSTMONST,   "", "rust monster or disenchanter"},
+ { DEF_SNAKE,       "", "snake"},
+ { DEF_TROLL,       "", "troll"},
+ { DEF_UMBER,       "", "umber hulk"},
+ { DEF_VAMPIRE,     "", "vampire"},
+ { DEF_WRAITH,      "", "wraith"},
+ { DEF_XORN,        "", "xorn"},
+ { DEF_YETI,        "", "apelike creature"},
+ { DEF_ZOMBIE,      "", "zombie"},
+ { DEF_HUMAN,       "", "human or elf"},
+ { DEF_GHOST,       "", "ghost"},
+ { DEF_GOLEM,       "", "golem"},
+ { DEF_DEMON,       "", "major demon"},
+ { DEF_EEL,         "", "sea monster"},
+ { DEF_LIZARD,      "", "lizard"},
+ { DEF_WORM_TAIL,   "", "long worm tail"},
+ { DEF_MIMIC_DEF,   "", "mimic"},
 };
 
 const struct symdef def_warnsyms[WARNCOUNT] = {
@@ -201,7 +143,6 @@ const struct symdef def_warnsyms[WARNCOUNT] = {
 
 /*
  *  Default screen symbols with explanations and colors.
- *  Note:  {ibm|dec|mac}_graphics[] arrays also depend on this symbol order.
  */
 const struct symdef defsyms[MAXPCHARS] = {
 /* 0*/ {' ', "dark part of a room",C(NO_COLOR)},       /* stone */
@@ -231,7 +172,7 @@ const struct symdef defsyms[MAXPCHARS] = {
        {'<', "ladder up",      C(CLR_BROWN)},  /* upladder */
        {'>', "ladder down",    C(CLR_BROWN)},  /* dnladder */
        {'_', "altar",          C(CLR_GRAY)},   /* altar */
-       {'|', "grave",      C(CLR_GRAY)},   /* grave */
+       {'|', "grave",      C(CLR_GRAY)},       /* grave */
        {'\\', "opulent throne",C(HI_GOLD)},    /* throne */
 #ifdef SINKS
        {'#', "sink",           C(CLR_GRAY)},   /* sink */
@@ -244,8 +185,8 @@ const struct symdef defsyms[MAXPCHARS] = {
        {'}', "molten lava",    C(CLR_RED)},    /* lava */
        {'.', "lowered drawbridge",C(CLR_BROWN)},       /* vodbridge */
        {'.', "lowered drawbridge",C(CLR_BROWN)},       /* hodbridge */
-       {'#', "raised drawbridge",C(CLR_BROWN)},/* vcdbridge */
-       {'#', "raised drawbridge",C(CLR_BROWN)},/* hcdbridge */
+       {'#', "raised drawbridge",C(CLR_BROWN)},        /* vcdbridge */
+       {'#', "raised drawbridge",C(CLR_BROWN)},        /* hcdbridge */
        {' ', "air",            C(CLR_CYAN)},   /* open air */
        {'#', "cloud",          C(CLR_GRAY)},   /* [part of] a cloud */
 /*40*/ {'}', "water",          C(CLR_BLUE)},   /* under water */
@@ -261,7 +202,7 @@ const struct symdef defsyms[MAXPCHARS] = {
 /*50*/ {'^', "fire trap",      C(CLR_ORANGE)}, /* trap */
        {'^', "pit",            C(CLR_BLACK)},  /* trap */
        {'^', "spiked pit",     C(CLR_BLACK)},  /* trap */
-       {'^', "hole",   C(CLR_BROWN)},  /* trap */
+       {'^', "hole",           C(CLR_BROWN)},  /* trap */
        {'^', "trap door",      C(CLR_BROWN)},  /* trap */
        {'^', "teleportation trap", C(CLR_MAGENTA)},    /* trap */
        {'^', "level teleporter", C(CLR_MAGENTA)},      /* trap */
@@ -300,313 +241,40 @@ const struct symdef defsyms[MAXPCHARS] = {
        {'\\', "",              C(CLR_ORANGE)}, /* explosion bottom left  */
 /*90*/ {'-', "",               C(CLR_ORANGE)}, /* explosion bottom center*/
        {'/', "",               C(CLR_ORANGE)}, /* explosion bottom right */
-/*
- *  Note: Additions to this array should be reflected in the
- *       {ibm,dec,mac}_graphics[] arrays below.
- */
 };
 
-#undef C
-
-#ifdef ASCIIGRAPH
-
-#ifdef PC9800
-void NDECL((*ibmgraphics_mode_callback)) = 0;  /* set in tty_start_screen() */
-#endif /* PC9800 */
-
-static uchar ibm_graphics[MAXPCHARS] = {
-/* 0*/ g_FILLER(S_stone),
-       0xb3,   /* S_vwall:     meta-3, vertical rule */
-       0xc4,   /* S_hwall:     meta-D, horizontal rule */
-       0xda,   /* S_tlcorn:    meta-Z, top left corner */
-       0xbf,   /* S_trcorn:    meta-?, top right corner */
-       0xc0,   /* S_blcorn:    meta-@, bottom left */
-       0xd9,   /* S_brcorn:    meta-Y, bottom right */
-       0xc5,   /* S_crwall:    meta-E, cross */
-       0xc1,   /* S_tuwall:    meta-A, T up */
-       0xc2,   /* S_tdwall:    meta-B, T down */
-/*10*/ 0xb4,   /* S_tlwall:    meta-4, T left */
-       0xc3,   /* S_trwall:    meta-C, T right */
-       0xfa,   /* S_ndoor:     meta-z, centered dot */
-       0xfe,   /* S_vodoor:    meta-~, small centered square */
-       0xfe,   /* S_hodoor:    meta-~, small centered square */
-       g_FILLER(S_vcdoor),
-       g_FILLER(S_hcdoor),
-       240,    /* S_bars:      equivalence symbol */
-       241,    /* S_tree:      plus or minus symbol */
-       0xfa,   /* S_room:      meta-z, centered dot */
-/*20*/ 0xb0,   /* S_corr:      meta-0, light shading */
-       0xb1,   /* S_litcorr:   meta-1, medium shading */
-       g_FILLER(S_upstair),
-       g_FILLER(S_dnstair),
-       g_FILLER(S_upladder),
-       g_FILLER(S_dnladder),
-       g_FILLER(S_altar),
-       g_FILLER(S_grave),
-       g_FILLER(S_throne),
-       g_FILLER(S_sink),
-/*30*/ 0xf4,   /* S_fountain:  meta-t, integral top half */
-       0xf7,   /* S_pool:      meta-w, approx. equals */
-       0xfa,   /* S_ice:       meta-z, centered dot */
-       0xf7,   /* S_lava:      meta-w, approx. equals */
-       0xfa,   /* S_vodbridge: meta-z, centered dot */
-       0xfa,   /* S_hodbridge: meta-z, centered dot */
-       g_FILLER(S_vcdbridge),
-       g_FILLER(S_hcdbridge),
-       g_FILLER(S_air),
-       g_FILLER(S_cloud),
-/*40*/ 0xf7,   /* S_water:     meta-w, approx. equals */
-       g_FILLER(S_arrow_trap),
-       g_FILLER(S_dart_trap),
-       g_FILLER(S_falling_rock_trap),
-       g_FILLER(S_squeaky_board),
-       g_FILLER(S_bear_trap),
-       g_FILLER(S_land_mine),
-       g_FILLER(S_rolling_boulder_trap),
-       g_FILLER(S_sleeping_gas_trap),
-       g_FILLER(S_rust_trap),
-/*50*/ g_FILLER(S_fire_trap),
-       g_FILLER(S_pit),
-       g_FILLER(S_spiked_pit),
-       g_FILLER(S_hole),
-       g_FILLER(S_trap_door),
-       g_FILLER(S_teleportation_trap),
-       g_FILLER(S_level_teleporter),
-       g_FILLER(S_magic_portal),
-       g_FILLER(S_web),
-       g_FILLER(S_statue_trap),
-/*60*/ g_FILLER(S_magic_trap),
-       g_FILLER(S_anti_magic_trap),
-       g_FILLER(S_polymorph_trap),
-       0xb3,   /* S_vbeam:     meta-3, vertical rule */
-       0xc4,   /* S_hbeam:     meta-D, horizontal rule */
-       g_FILLER(S_lslant),
-       g_FILLER(S_rslant),
-       g_FILLER(S_digbeam),
-       g_FILLER(S_flashbeam),
-       g_FILLER(S_boomleft),
-/*70*/ g_FILLER(S_boomright),
-       g_FILLER(S_ss1),
-       g_FILLER(S_ss2),
-       g_FILLER(S_ss3),
-       g_FILLER(S_ss4),
-       g_FILLER(S_sw_tl),
-       g_FILLER(S_sw_tc),
-       g_FILLER(S_sw_tr),
-       0xb3,   /* S_sw_ml:     meta-3, vertical rule */
-       0xb3,   /* S_sw_mr:     meta-3, vertical rule */
-/*80*/ g_FILLER(S_sw_bl),
-       g_FILLER(S_sw_bc),
-       g_FILLER(S_sw_br),
-       g_FILLER(S_explode1),
-       g_FILLER(S_explode2),
-       g_FILLER(S_explode3),
-       0xb3,   /* S_explode4:  meta-3, vertical rule */
-       g_FILLER(S_explode5),
-       0xb3,   /* S_explode6:  meta-3, vertical rule */
-       g_FILLER(S_explode7),
-/*90*/ g_FILLER(S_explode8),
-       g_FILLER(S_explode9)
+#ifdef REINCARNATION
+/* default rogue level symbols */
+static const uchar def_r_oc_syms[MAXOCLASSES] = {
+/* 0*/ '\0',
+       ILLOBJ_SYM,
+       WEAPON_SYM,
+       ']',                    /* armor */
+       RING_SYM,
+/* 5*/ ',',                    /* amulet */
+       TOOL_SYM,
+       ':',                    /* food */
+       POTION_SYM,
+       SCROLL_SYM,
+/*10*/ SPBOOK_SYM,
+       WAND_SYM,
+       GEM_SYM,                /* gold -- yes it's the same as gems */
+       GEM_SYM,
+       ROCK_SYM,
+/*15*/ BALL_SYM,
+       CHAIN_SYM,
+       VENOM_SYM
 };
-#endif  /* ASCIIGRAPH */
+#endif
+
+#undef C
 
 #ifdef TERMLIB
 void NDECL((*decgraphics_mode_callback)) = 0;  /* set in tty_start_screen() */
-
-static uchar dec_graphics[MAXPCHARS] = {
-/* 0*/ g_FILLER(S_stone),
-       0xf8,   /* S_vwall:     meta-x, vertical rule */
-       0xf1,   /* S_hwall:     meta-q, horizontal rule */
-       0xec,   /* S_tlcorn:    meta-l, top left corner */
-       0xeb,   /* S_trcorn:    meta-k, top right corner */
-       0xed,   /* S_blcorn:    meta-m, bottom left */
-       0xea,   /* S_brcorn:    meta-j, bottom right */
-       0xee,   /* S_crwall:    meta-n, cross */
-       0xf6,   /* S_tuwall:    meta-v, T up */
-       0xf7,   /* S_tdwall:    meta-w, T down */
-/*10*/ 0xf5,   /* S_tlwall:    meta-u, T left */
-       0xf4,   /* S_trwall:    meta-t, T right */
-       0xfe,   /* S_ndoor:     meta-~, centered dot */
-       0xe1,   /* S_vodoor:    meta-a, solid block */
-       0xe1,   /* S_hodoor:    meta-a, solid block */
-       g_FILLER(S_vcdoor),
-       g_FILLER(S_hcdoor),
-       0xfb,   /* S_bars:      meta-{, small pi */
-       0xe7,   /* S_tree:      meta-g, plus-or-minus */
-       0xfe,   /* S_room:      meta-~, centered dot */
-/*20*/ g_FILLER(S_corr),
-       g_FILLER(S_litcorr),
-       g_FILLER(S_upstair),
-       g_FILLER(S_dnstair),
-       0xf9,   /* S_upladder:  meta-y, greater-than-or-equals */
-       0xfa,   /* S_dnladder:  meta-z, less-than-or-equals */
-       g_FILLER(S_altar),      /* 0xc3, \E)3: meta-C, dagger */
-       g_FILLER(S_grave),
-       g_FILLER(S_throne),
-       g_FILLER(S_sink),
-/*30*/ g_FILLER(S_fountain),   /* 0xdb, \E)3: meta-[, integral top half */
-       0xe0,   /* S_pool:      meta-\, diamond */
-       0xfe,   /* S_ice:       meta-~, centered dot */
-       0xe0,   /* S_lava:      meta-\, diamond */
-       0xfe,   /* S_vodbridge: meta-~, centered dot */
-       0xfe,   /* S_hodbridge: meta-~, centered dot */
-       g_FILLER(S_vcdbridge),
-       g_FILLER(S_hcdbridge),
-       g_FILLER(S_air),
-       g_FILLER(S_cloud),
-/*40*/ 0xe0,   /* S_water:     meta-\, diamond */
-       g_FILLER(S_arrow_trap),
-       g_FILLER(S_dart_trap),
-       g_FILLER(S_falling_rock_trap),
-       g_FILLER(S_squeaky_board),
-       g_FILLER(S_bear_trap),
-       g_FILLER(S_land_mine),
-       g_FILLER(S_rolling_boulder_trap),
-       g_FILLER(S_sleeping_gas_trap),
-       g_FILLER(S_rust_trap),
-/*50*/ g_FILLER(S_fire_trap),
-       g_FILLER(S_pit),
-       g_FILLER(S_spiked_pit),
-       g_FILLER(S_hole),
-       g_FILLER(S_trap_door),
-       g_FILLER(S_teleportation_trap),
-       g_FILLER(S_level_teleporter),
-       g_FILLER(S_magic_portal),
-       g_FILLER(S_web),        /* 0xbd, \E)3: meta-=, int'l currency */
-       g_FILLER(S_statue_trap),
-/*60*/ g_FILLER(S_magic_trap),
-       g_FILLER(S_anti_magic_trap),
-       g_FILLER(S_polymorph_trap),
-       0xf8,   /* S_vbeam:     meta-x, vertical rule */
-       0xf1,   /* S_hbeam:     meta-q, horizontal rule */
-       g_FILLER(S_lslant),
-       g_FILLER(S_rslant),
-       g_FILLER(S_digbeam),
-       g_FILLER(S_flashbeam),
-       g_FILLER(S_boomleft),
-/*70*/ g_FILLER(S_boomright),
-       g_FILLER(S_ss1),
-       g_FILLER(S_ss2),
-       g_FILLER(S_ss3),
-       g_FILLER(S_ss4),
-       g_FILLER(S_sw_tl),
-       0xef,   /* S_sw_tc:     meta-o, high horizontal line */
-       g_FILLER(S_sw_tr),
-       0xf8,   /* S_sw_ml:     meta-x, vertical rule */
-       0xf8,   /* S_sw_mr:     meta-x, vertical rule */
-/*80*/ g_FILLER(S_sw_bl),
-       0xf3,   /* S_sw_bc:     meta-s, low horizontal line */
-       g_FILLER(S_sw_br),
-       g_FILLER(S_explode1),
-       0xef,   /* S_explode2:  meta-o, high horizontal line */
-       g_FILLER(S_explode3),
-       0xf8,   /* S_explode4:  meta-x, vertical rule */
-       g_FILLER(S_explode5),
-       0xf8,   /* S_explode6:  meta-x, vertical rule */
-       g_FILLER(S_explode7),
-/*90*/ 0xf3,   /* S_explode8:  meta-s, low horizontal line */
-       g_FILLER(S_explode9)
-};
 #endif  /* TERMLIB */
 
-#ifdef MAC_GRAPHICS_ENV
-static uchar mac_graphics[MAXPCHARS] = {
-/* 0*/ g_FILLER(S_stone),
-       0xba,   /* S_vwall */
-       0xcd,   /* S_hwall */
-       0xc9,   /* S_tlcorn */
-       0xbb,   /* S_trcorn */
-       0xc8,   /* S_blcorn */
-       0xbc,   /* S_brcorn */
-       0xce,   /* S_crwall */
-       0xca,   /* S_tuwall */
-       0xcb,   /* S_tdwall */
-/*10*/ 0xb9,   /* S_tlwall */
-       0xcc,   /* S_trwall */
-       0xb0,   /* S_ndoor */
-       0xee,   /* S_vodoor */
-       0xee,   /* S_hodoor */
-       0xef,   /* S_vcdoor */
-       0xef,   /* S_hcdoor */
-       0xf0,   /* S_bars:      equivalency symbol */
-       0xf1,   /* S_tree:      plus-or-minus */
-       g_FILLER(S_Room),
-/*20*/ 0xB0,   /* S_corr */
-       g_FILLER(S_litcorr),
-       g_FILLER(S_upstair),
-       g_FILLER(S_dnstair),
-       g_FILLER(S_upladder),
-       g_FILLER(S_dnladder),
-       g_FILLER(S_altar),
-       0xef,   /* S_grave:     same as open door */
-       g_FILLER(S_throne),
-       g_FILLER(S_sink),
-/*30*/ g_FILLER(S_fountain),
-       0xe0,   /* S_pool */
-       g_FILLER(S_ice),
-       g_FILLER(S_lava),
-       g_FILLER(S_vodbridge),
-       g_FILLER(S_hodbridge),
-       g_FILLER(S_vcdbridge),
-       g_FILLER(S_hcdbridge),
-       g_FILLER(S_air),
-       g_FILLER(S_cloud),
-/*40*/ g_FILLER(S_water),
-       g_FILLER(S_arrow_trap),
-       g_FILLER(S_dart_trap),
-       g_FILLER(S_falling_rock_trap),
-       g_FILLER(S_squeaky_board),
-       g_FILLER(S_bear_trap),
-       g_FILLER(S_land_mine),
-       g_FILLER(S_rolling_boulder_trap),
-       g_FILLER(S_sleeping_gas_trap),
-       g_FILLER(S_rust_trap),
-/*50*/ g_FILLER(S_fire_trap),
-       g_FILLER(S_pit),
-       g_FILLER(S_spiked_pit),
-       g_FILLER(S_hole),
-       g_FILLER(S_trap_door),
-       g_FILLER(S_teleportation_trap),
-       g_FILLER(S_level_teleporter),
-       g_FILLER(S_magic_portal),
-       g_FILLER(S_web),
-       g_FILLER(S_statue_trap),
-/*60*/ g_FILLER(S_magic_trap),
-       g_FILLER(S_anti_magic_trap),
-       g_FILLER(S_polymorph_trap),
-       g_FILLER(S_vbeam),
-       g_FILLER(S_hbeam),
-       g_FILLER(S_lslant),
-       g_FILLER(S_rslant),
-       g_FILLER(S_digbeam),
-       g_FILLER(S_flashbeam),
-       g_FILLER(S_boomleft),
-/*70*/ g_FILLER(S_boomright),
-       g_FILLER(S_ss1),
-       g_FILLER(S_ss2),
-       g_FILLER(S_ss3),
-       g_FILLER(S_ss4),
-       g_FILLER(S_sw_tl),
-       g_FILLER(S_sw_tc),
-       g_FILLER(S_sw_tr),
-       g_FILLER(S_sw_ml),
-       g_FILLER(S_sw_mr),
-/*80*/ g_FILLER(S_sw_bl),
-       g_FILLER(S_sw_bc),
-       g_FILLER(S_sw_br),
-       g_FILLER(S_explode1),
-       g_FILLER(S_explode2),
-       g_FILLER(S_explode3),
-       g_FILLER(S_explode4),
-       g_FILLER(S_explode5),
-       g_FILLER(S_explode6),
-       g_FILLER(S_explode7),
-/*90*/ g_FILLER(S_explode8),
-       g_FILLER(S_explode9)
-};
-#endif /* MAC_GRAPHICS_ENV */
-
 #ifdef PC9800
+void NDECL((*ibmgraphics_mode_callback)) = 0;  /* set in tty_start_screen() */
 void NDECL((*ascgraphics_mode_callback)) = 0;  /* set in tty_start_screen() */
 #endif
 
@@ -621,7 +289,7 @@ def_char_to_objclass(ch)
 {
     int i;
     for (i = 1; i < MAXOCLASSES; i++)
-       if (ch == def_oc_syms[i]) break;
+       if (ch == def_oc_syms[i].sym) break;
     return i;
 }
 
@@ -635,276 +303,434 @@ def_char_to_monclass(ch)
 {
     int i;
     for (i = 1; i < MAXMCLASSES; i++)
-       if (def_monsyms[i] == ch) break;
+       if (def_monsyms[i].sym == ch) break;
     return i;
 }
 
+/*
+ * Explanations of the functions found below:
+ *
+ * switch_graphics(arg)
+ *                     Called to swap the current display symbols
+ *                     (monsyms, showsyms, oc_syms).
+ *
+ *                     If !arg then the display symbols are
+ *                     taken from def_monsyms, defsyms, def_oc_syms 
+ *                     default NetHack symbols.
+ *
+ *                     If arg then the display symbols are
+ *                     taken from the adjustable display symbols
+ *                     found in l_monsyms, l_showsyms, l_oc_syms.
+ *                     Those symbols may have been loaded from an
+ *                     external symfile by config file options or
+ *                     interactively in the options menu.
+ *
+ * init_symbols()
+ *                     Sets the current display symbols, the
+ *                     loadable symbols to the default NetHack
+ *                     symbols, including the r_* rogue level
+ *                     symbols if REINCARNATION is defined.
+ *                     This would typically be done immediately
+ *                     after execution begins. Any previously
+ *                     loaded external symbol sets are discarded.
+ *
+ * assign_rogue_graphics(arg)
+ *
+ *                     This is used in the game core to toggle in and
+ *                     out of rogue level display mode.
+ *
+ *                     If arg is TRUE, this places the rogue level
+ *                     symbols from r_monsyms, r_showsyms, and r_oc_syms
+ *                     into the current display symbols: monsyms, showsyms,
+ *                     and oc_syms. 
+ *
+ *                     If arg is FALSE, this places the symbols from
+ *                     l_monsyms, l_showsyms, l_oc_syms into the current
+ *                     display symbols: monsyms, showsyms, oc_syms.
+ *
+ * update_l_symset()
+ *                     Update a member of the loadable (l_*) symbol set.  
+ *
+ * update_r_symset()
+ *                     Update a member of the rogue (r_*) symbol set.  
+ *
+ */
+
 void
-assign_graphics(graph_chars, glth, maxlen, offset)
-register uchar *graph_chars;
-int glth, maxlen, offset;
+switch_graphics(nondefault)
+int nondefault;
 {
-    register int i;
+#ifdef ASCIIGRAPH
+       register int i;
 
-    for (i = 0; i < maxlen; i++)
-       showsyms[i+offset] = (((i < glth) && graph_chars[i]) ?
-                      graph_chars[i] : defsyms[i+offset].sym);
-}
+       if (nondefault) {
+               for (i = 0; i < MAXMCLASSES; i++)
+                   monsyms[i] = l_monsyms[i];
 
-void
-switch_graphics(gr_set_flag)
-int gr_set_flag;
-{
-    /* We're either toggling back to ASCII, in which case it is
-       appropriate to negate all the other alternatives, or we're in
-       the process of toggling one of those other ones on, in which
-       case it will be set accurately below. */
-    iflags.IBMgraphics = FALSE;
-    iflags.DECgraphics = FALSE;
-#ifdef MAC_GRAPHICS_ENV
-    iflags.MACgraphics = FALSE;
-#endif
+               for (i = 0; i < MAXPCHARS; i++)
+                   showsyms[i] = l_showsyms[i];
 
-    switch (gr_set_flag) {
-       default:
-       case ASCII_GRAPHICS:
-           assign_graphics((uchar *)0, 0, MAXPCHARS, 0);
+               for (i = 0; i < MAXOCLASSES; i++)
+                   oc_syms[i] = l_oc_syms[i];
 #ifdef PC9800
-           if (ascgraphics_mode_callback) (*ascgraphics_mode_callback)();
+               if (symset && !strncmpi(symset,"IBM",3)
+                   && ibmgraphics_mode_callback)
+                       (*ibmgraphics_mode_callback)();
+               else if (!symset && ascgraphics_mode_callback)
+                       (*ascgraphics_mode_callback)();
 #endif
-           break;
-#ifdef ASCIIGRAPH
-       case IBM_GRAPHICS:
-/*
- * Use the nice IBM Extended ASCII line-drawing characters (codepage 437).
- *
- * OS/2 defaults to a multilingual character set (codepage 850, corresponding
- * to the ISO 8859 character set.  We should probably do a VioSetCp() call to
- * set the codepage to 437.
- */
-           iflags.IBMgraphics = TRUE;
-           assign_graphics(ibm_graphics, SIZE(ibm_graphics), MAXPCHARS, 0);
-#ifdef PC9800
-           if (ibmgraphics_mode_callback) (*ibmgraphics_mode_callback)();
-#endif
-           break;
-#endif /* ASCIIGRAPH */
 #ifdef TERMLIB
-       case DEC_GRAPHICS:
-/*
- * Use the VT100 line drawing character set.
- */
-           iflags.DECgraphics = TRUE;
-           assign_graphics(dec_graphics, SIZE(dec_graphics), MAXPCHARS, 0);
-           if (decgraphics_mode_callback) (*decgraphics_mode_callback)();
-           break;
-#endif /* TERMLIB */
-#ifdef MAC_GRAPHICS_ENV
-       case MAC_GRAPHICS:
-           iflags.MACgraphics = TRUE;
-           assign_graphics(mac_graphics, SIZE(mac_graphics), MAXPCHARS, 0);
-           break;
+               if (symset && !strncmpi(symset,"DEC",3)
+                   && decgraphics_mode_callback)
+                       (*decgraphics_mode_callback)();
 #endif
-       }
-    return;
+       } else
+#endif
+       init_symbols();
 }
 
+void
+init_symbols()
+{
+       init_l_symbols();
+       init_disp_symbols();
+#ifdef REINCARNATION
+       init_r_symbols();
+#endif
+}
+
+void
+init_disp_symbols()
+{
+       register int i;
+       for (i = 0; i < MAXMCLASSES; i++)
+           monsyms[i] = def_monsyms[i].sym;
+
+       for (i = 0; i < MAXPCHARS; i++)
+           showsyms[i] = defsyms[i].sym;
+
+       for (i = 0; i < MAXOCLASSES; i++)
+           oc_syms[i] = def_oc_syms[i].sym;    
+}
+
+/* initialize defaults for the loadable symset */
+void
+init_l_symbols()
+{
+       register int i;
+       for (i = 0; i < MAXMCLASSES; i++)
+           l_monsyms[i] = def_monsyms[i].sym;
+
+       for (i = 0; i < MAXPCHARS; i++)
+           l_showsyms[i] = defsyms[i].sym;
+
+       for (i = 0; i < MAXOCLASSES; i++)
+           l_oc_syms[i] = def_oc_syms[i].sym;
+}
 
 #ifdef REINCARNATION
+void
+init_r_symbols()
+{
+       register int i;
+       /* These are defaults that can get overwritten
+          later by the roguesymbols option */
 
-/*
- * saved display symbols for objects & features.
- */
-static uchar save_oc_syms[MAXOCLASSES] = DUMMY;
-static uchar save_showsyms[MAXPCHARS]  = DUMMY;
-static uchar save_monsyms[MAXPCHARS]   = DUMMY;
+       for (i = 0; i < MAXMCLASSES; i++)
+           r_monsyms[i] = def_monsyms[i].sym;
 
-static const uchar r_oc_syms[MAXOCLASSES] = {
-/* 0*/ '\0',
-       ILLOBJ_SYM,
-       WEAPON_SYM,
-       ']',                    /* armor */
-       RING_SYM,
-/* 5*/ ',',                    /* amulet */
-       TOOL_SYM,
-       ':',                    /* food */
-       POTION_SYM,
-       SCROLL_SYM,
-/*10*/ SPBOOK_SYM,
-       WAND_SYM,
-       GEM_SYM,                /* gold -- yes it's the same as gems */
-       GEM_SYM,
-       ROCK_SYM,
-/*15*/ BALL_SYM,
-       CHAIN_SYM,
-       VENOM_SYM
-};
+       for (i = 0; i < MAXPCHARS; i++)
+           r_showsyms[i] = defsyms[i].sym;
+       r_showsyms[S_vodoor]  = r_showsyms[S_hodoor]  = r_showsyms[S_ndoor] = '+';
+       r_showsyms[S_upstair] = r_showsyms[S_dnstair] = '%';
 
-# ifdef ASCIIGRAPH
-/* Rogue level graphics.  Under IBM graphics mode, use the symbols that were
- * used for Rogue on the IBM PC.  Unfortunately, this can't be completely
- * done because some of these are control characters--armor and rings under
- * DOS, and a whole bunch of them under Linux.  Use the TTY Rogue characters
- * for those cases.
- */
-static const uchar IBM_r_oc_syms[MAXOCLASSES] = {      /* a la EPYX Rogue */
-/* 0*/ '\0',
-       ILLOBJ_SYM,
-#  if defined(MSDOS) || defined(OS2) || ( defined(WIN32) && !defined(MSWIN_GRAPHICS) )
-       0x18,                   /* weapon: up arrow */
-/*     0x0a, */ ARMOR_SYM,     /* armor:  Vert rect with o */
-/*     0x09, */ RING_SYM,      /* ring:   circle with arrow */
-/* 5*/ 0x0c,                   /* amulet: "female" symbol */
-       TOOL_SYM,
-       0x05,                   /* food:   club (as in cards) */
-       0xad,                   /* potion: upside down '!' */
-       0x0e,                   /* scroll: musical note */
-/*10*/ SPBOOK_SYM,
-       0xe7,                   /* wand:   greek tau */
-       0x0f,                   /* gold:   yes it's the same as gems */
-       0x0f,                   /* gems:   fancy '*' */
-#  else
-       ')',                    /* weapon  */
-       ARMOR_SYM,              /* armor */
-       RING_SYM,               /* ring */
-/* 5*/ ',',                    /* amulet  */
-       TOOL_SYM,
-       ':',                    /* food    */
-       0xad,                   /* potion: upside down '!' */
-       SCROLL_SYM,             /* scroll  */
-/*10*/ SPBOOK_SYM,
-       0xe7,                   /* wand:   greek tau */
-       GEM_SYM,                /* gold:   yes it's the same as gems */
-       GEM_SYM,                /* gems    */
-#  endif
-       ROCK_SYM,
-/*15*/ BALL_SYM,
-       CHAIN_SYM,
-       VENOM_SYM
-};
-# endif /* ASCIIGRAPH */
+       for (i = 0; i < MAXOCLASSES; i++)
+           r_oc_syms[i] = def_r_oc_syms[i];
+}
 
 void
 assign_rogue_graphics(is_rlevel)
 boolean is_rlevel;
 {
     /* Adjust graphics display characters on Rogue levels */
+    register int i;
 
     if (is_rlevel) {
        register int i;
 
-       (void) memcpy((genericptr_t)save_showsyms,
-                     (genericptr_t)showsyms, sizeof showsyms);
-       (void) memcpy((genericptr_t)save_oc_syms,
-                     (genericptr_t)oc_syms, sizeof oc_syms);
-       (void) memcpy((genericptr_t)save_monsyms,
-                     (genericptr_t)monsyms, sizeof monsyms);
-
-       /* Use a loop: char != uchar on some machines. */
        for (i = 0; i < MAXMCLASSES; i++)
-           monsyms[i] = def_monsyms[i];
-# if defined(ASCIIGRAPH) && !defined(MSWIN_GRAPHICS)
-       if (iflags.IBMgraphics
-#  if defined(USE_TILES) && defined(MSDOS)
-               && !iflags.grmode
-#  endif
-               )
-           monsyms[S_HUMAN] = 0x01; /* smiley face */
-# endif
-       for (i = 0; i < MAXPCHARS; i++)
-           showsyms[i] = defsyms[i].sym;
+           monsyms[i] = r_monsyms[i];
 
-/*
- * Some day if these rogue showsyms get much more extensive than this,
- * we may want to create r_showsyms, and IBM_r_showsyms arrays to hold
- * all of this info and to simply initialize it via a for() loop like r_oc_syms.
- */
+       for (i = 0; i < MAXPCHARS; i++)
+           showsyms[i] = r_showsyms[i];
 
-# ifdef ASCIIGRAPH
-       if (!iflags.IBMgraphics
-#  if defined(USE_TILES) && defined(MSDOS)
-               || iflags.grmode
-#  endif
-                               ) {
-# endif
-           showsyms[S_vodoor]  = showsyms[S_hodoor]  = showsyms[S_ndoor] = '+';
-           showsyms[S_upstair] = showsyms[S_dnstair] = '%';
-# ifdef ASCIIGRAPH
-       } else {
-           /* a la EPYX Rogue */
-           showsyms[S_vwall]   = 0xba; /* all walls now use    */
-           showsyms[S_hwall]   = 0xcd; /* double line graphics */
-           showsyms[S_tlcorn]  = 0xc9;
-           showsyms[S_trcorn]  = 0xbb;
-           showsyms[S_blcorn]  = 0xc8;
-           showsyms[S_brcorn]  = 0xbc;
-           showsyms[S_crwall]  = 0xce;
-           showsyms[S_tuwall]  = 0xca;
-           showsyms[S_tdwall]  = 0xcb;
-           showsyms[S_tlwall]  = 0xb9;
-           showsyms[S_trwall]  = 0xcc;
-           showsyms[S_ndoor]   = 0xce;
-           showsyms[S_vodoor]  = 0xce;
-           showsyms[S_hodoor]  = 0xce;
-           showsyms[S_room]    = 0xfa; /* centered dot */
-           showsyms[S_corr]    = 0xb1;
-           showsyms[S_litcorr] = 0xb2;
-           showsyms[S_upstair] = 0xf0; /* Greek Xi */
-           showsyms[S_dnstair] = 0xf0;
-#ifndef MSWIN_GRAPHICS
-           showsyms[S_arrow_trap] = 0x04; /* diamond (cards) */
-           showsyms[S_dart_trap] = 0x04;
-           showsyms[S_falling_rock_trap] = 0x04;
-           showsyms[S_squeaky_board] = 0x04;
-           showsyms[S_bear_trap] = 0x04;
-           showsyms[S_land_mine] = 0x04;
-           showsyms[S_rolling_boulder_trap] = 0x04;
-           showsyms[S_sleeping_gas_trap] = 0x04;
-           showsyms[S_rust_trap] = 0x04;
-           showsyms[S_fire_trap] = 0x04;
-           showsyms[S_pit] = 0x04;
-           showsyms[S_spiked_pit] = 0x04;
-           showsyms[S_hole] = 0x04;
-           showsyms[S_trap_door] = 0x04;
-           showsyms[S_teleportation_trap] = 0x04;
-           showsyms[S_level_teleporter] = 0x04;
-           showsyms[S_magic_portal] = 0x04;
-           showsyms[S_web] = 0x04;
-           showsyms[S_statue_trap] = 0x04;
-           showsyms[S_magic_trap] = 0x04;
-           showsyms[S_anti_magic_trap] = 0x04;
-           showsyms[S_polymorph_trap] = 0x04;
-#endif
-       }
-#endif /* ASCIIGRAPH */
+       for (i = 0; i < MAXOCLASSES; i++)
+           oc_syms[i] = r_oc_syms[i];
 
-       for (i = 0; i < MAXOCLASSES; i++) {
-#ifdef ASCIIGRAPH
-           if (iflags.IBMgraphics
-# if defined(USE_TILES) && defined(MSDOS)
-               && !iflags.grmode
-# endif
-               )
-               oc_syms[i] = IBM_r_oc_syms[i];
-           else
-#endif /* ASCIIGRAPH */
-               oc_syms[i] = r_oc_syms[i];
-       }
-#if defined(MSDOS) && defined(USE_TILES)
+# if defined(MSDOS) && defined(USE_TILES)
        if (iflags.grmode) tileview(FALSE);
-#endif
+# endif
     } else {
-       (void) memcpy((genericptr_t)showsyms,
-                     (genericptr_t)save_showsyms, sizeof showsyms);
-       (void) memcpy((genericptr_t)oc_syms,
-                     (genericptr_t)save_oc_syms, sizeof oc_syms);
-       (void) memcpy((genericptr_t)monsyms,
-                     (genericptr_t)save_monsyms, sizeof monsyms);
-#if defined(MSDOS) && defined(USE_TILES)
+       for (i = 0; i < MAXMCLASSES; i++)
+           monsyms[i] = l_monsyms[i];
+
+       for (i = 0; i < MAXPCHARS; i++)
+           showsyms[i] = l_showsyms[i];
+
+       for (i = 0; i < MAXOCLASSES; i++)
+           oc_syms[i] = l_oc_syms[i];
+# if defined(MSDOS) && defined(USE_TILES)
        if (iflags.grmode) tileview(TRUE);
-#endif
+# endif
     }
 }
+
+void
+update_r_symset(symp, val)
+struct symparse *symp;
+int val;
+{
+       switch (symp->range) {
+           case SYM_PCHAR:                     /* index into r_showsyms */
+                       r_showsyms[symp->idx] = val;
+                       break;
+           case SYM_MON:                       /* index into r_monsyms  */
+                       r_monsyms[symp->idx] = val;
+                       break;
+           case SYM_OC:                        /* index into r_oc_syms  */
+                       r_oc_syms[symp->idx] = val;
+                       break;
+           case SYM_OBJ:                       /* index into objects  */
+                       if (symp->idx == BOULDER)
+                               iflags.bouldersym = val;
+                       break;
+        }
+}
 #endif /* REINCARNATION */
 
+#ifdef ASCIIGRAPH
+void
+update_l_symset(symp, val)
+struct symparse *symp;
+int val;
+{
+       switch (symp->range) {
+           case SYM_PCHAR:                     /* index into l_showsyms */
+                       l_showsyms[symp->idx] = val;
+                       break;
+           case SYM_MON:                       /* index into l_monsyms  */
+                       l_monsyms[symp->idx] = val;
+                       break;
+           case SYM_OC:                        /* index into l_oc_syms  */
+                       l_oc_syms[symp->idx] = val;
+                       break;
+           case SYM_OBJ:                       /* index into objects  */
+                       if (symp->idx == BOULDER)
+                               iflags.bouldersym = val;
+                       break;
+        }
+}
+
+struct symparse loadsyms[] = {
+       {SYM_CONTROL, 0, "start"},
+       {SYM_CONTROL, 0, "begin"},
+       {SYM_CONTROL, 1, "finish"},
+       {SYM_CONTROL, 2, "handling"},
+       {SYM_PCHAR, S_stone, "S_stone"},
+       {SYM_PCHAR, S_vwall, "S_vwall"},
+       {SYM_PCHAR, S_hwall, "S_hwall"},
+       {SYM_PCHAR, S_tlcorn, "S_tlcorn"},
+       {SYM_PCHAR, S_trcorn, "S_trcorn"},
+       {SYM_PCHAR, S_blcorn, "S_blcorn"},
+       {SYM_PCHAR, S_brcorn, "S_brcorn"},
+       {SYM_PCHAR, S_crwall, "S_crwall"},
+       {SYM_PCHAR, S_tuwall, "S_tuwall"},
+       {SYM_PCHAR, S_tdwall, "S_tdwall"},
+       {SYM_PCHAR, S_tlwall, "S_tlwall"},
+       {SYM_PCHAR, S_trwall, "S_trwall"},
+       {SYM_PCHAR, S_ndoor, "S_ndoor"},
+       {SYM_PCHAR, S_vodoor, "S_vodoor"},
+       {SYM_PCHAR, S_hodoor, "S_hodoor"},
+       {SYM_PCHAR, S_vcdoor, "S_vcdoor"},
+       {SYM_PCHAR, S_hcdoor, "S_hcdoor"},
+       {SYM_PCHAR, S_bars, "S_bars"},
+       {SYM_PCHAR, S_tree, "S_tree"},
+       {SYM_PCHAR, S_room, "S_room"},
+       {SYM_PCHAR, S_corr, "S_corr"},
+       {SYM_PCHAR, S_litcorr, "S_litcorr"},
+       {SYM_PCHAR, S_upstair, "S_upstair"},
+       {SYM_PCHAR, S_dnstair, "S_dnstair"},
+       {SYM_PCHAR, S_upladder, "S_upladder"},
+       {SYM_PCHAR, S_dnladder, "S_dnladder"},
+       {SYM_PCHAR, S_altar, "S_altar"},
+       {SYM_PCHAR, S_grave, "S_grave"},
+       {SYM_PCHAR, S_throne, "S_throne"},
+       {SYM_PCHAR, S_sink, "S_sink"},
+       {SYM_PCHAR, S_fountain, "S_fountain"},
+       {SYM_PCHAR, S_pool, "S_pool"},
+       {SYM_PCHAR, S_ice, "S_ice"},
+       {SYM_PCHAR, S_lava, "S_lava"},
+       {SYM_PCHAR, S_vodbridge, "S_vodbridge"},
+       {SYM_PCHAR, S_hodbridge, "S_hodbridge"},
+       {SYM_PCHAR, S_vcdbridge, "S_vcdbridge"},
+       {SYM_PCHAR, S_hcdbridge, "S_hcdbridge"},
+       {SYM_PCHAR, S_air, "S_air"},
+       {SYM_PCHAR, S_cloud, "S_cloud"},
+       {SYM_PCHAR, S_water, "S_water"},
+       {SYM_PCHAR, S_arrow_trap, "S_arrow_trap"},
+       {SYM_PCHAR, S_dart_trap, "S_dart_trap"},
+       {SYM_PCHAR, S_falling_rock_trap, "S_falling_rock_trap"},
+       {SYM_PCHAR, S_squeaky_board, "S_squeaky_board"},
+       {SYM_PCHAR, S_bear_trap, "S_bear_trap"},
+       {SYM_PCHAR, S_land_mine, "S_land_mine"},
+       {SYM_PCHAR, S_rolling_boulder_trap, "S_rolling_boulder_trap"},
+       {SYM_PCHAR, S_sleeping_gas_trap, "S_sleeping_gas_trap"},
+       {SYM_PCHAR, S_rust_trap, "S_rust_trap"},
+       {SYM_PCHAR, S_fire_trap, "S_fire_trap"},
+       {SYM_PCHAR, S_pit, "S_pit"},
+       {SYM_PCHAR, S_spiked_pit, "S_spiked_pit"},
+       {SYM_PCHAR, S_hole, "S_hole"},
+       {SYM_PCHAR, S_trap_door, "S_trap_door"},
+       {SYM_PCHAR, S_teleportation_trap, "S_teleportation_trap"},
+       {SYM_PCHAR, S_level_teleporter, "S_level_teleporter"},
+       {SYM_PCHAR, S_magic_portal, "S_magic_portal"},
+       {SYM_PCHAR, S_web, "S_web"},
+       {SYM_PCHAR, S_statue_trap, "S_statue_trap"},
+       {SYM_PCHAR, S_magic_trap, "S_magic_trap"},
+       {SYM_PCHAR, S_anti_magic_trap, "S_anti_magic_trap"},
+       {SYM_PCHAR, S_polymorph_trap, "S_polymorph_trap"},
+       {SYM_PCHAR, S_vbeam, "S_vbeam"},
+       {SYM_PCHAR, S_hbeam, "S_hbeam"},
+       {SYM_PCHAR, S_lslant, "S_lslant"},
+       {SYM_PCHAR, S_rslant, "S_rslant"},
+       {SYM_PCHAR, S_digbeam, "S_digbeam"},
+       {SYM_PCHAR, S_flashbeam, "S_flashbeam"},
+       {SYM_PCHAR, S_boomleft, "S_boomleft"},
+       {SYM_PCHAR, S_boomright, "S_boomright"},
+       {SYM_PCHAR, S_ss1, "S_ss1"},
+       {SYM_PCHAR, S_ss2, "S_ss2"},
+       {SYM_PCHAR, S_ss3, "S_ss3"},
+       {SYM_PCHAR, S_ss4, "S_ss4"},
+       {SYM_PCHAR, S_sw_tl, "S_sw_tl"},
+       {SYM_PCHAR, S_sw_tc, "S_sw_tc"},
+       {SYM_PCHAR, S_sw_tr, "S_sw_tr"},
+       {SYM_PCHAR, S_sw_ml, "S_sw_ml"},
+       {SYM_PCHAR, S_sw_mr, "S_sw_mr"},
+       {SYM_PCHAR, S_sw_bl, "S_sw_bl"},
+       {SYM_PCHAR, S_sw_bc, "S_sw_bc"},
+       {SYM_PCHAR, S_sw_br, "S_sw_br"},
+       {SYM_PCHAR, S_explode1, "S_explode1"},
+       {SYM_PCHAR, S_explode2, "S_explode2"},
+       {SYM_PCHAR, S_explode3, "S_explode3"},
+       {SYM_PCHAR, S_explode4, "S_explode4"},
+       {SYM_PCHAR, S_explode5, "S_explode5"},
+       {SYM_PCHAR, S_explode6, "S_explode6"},
+       {SYM_PCHAR, S_explode7, "S_explode7"},
+       {SYM_PCHAR, S_explode8, "S_explode8"},
+       {SYM_PCHAR, S_explode9, "S_explode9"},
+       {SYM_MON, S_ANT, "S_ant"},
+       {SYM_MON, S_BLOB, "S_blob"},
+       {SYM_MON, S_COCKATRICE, "S_cockatrice"},
+       {SYM_MON, S_DOG, "S_dog"},
+       {SYM_MON, S_EYE, "S_eye"},
+       {SYM_MON, S_FELINE, "S_feline"},
+       {SYM_MON, S_GREMLIN, "S_gremlin"},
+       {SYM_MON, S_HUMANOID, "S_humanoid"},
+       {SYM_MON, S_IMP, "S_imp"},
+       {SYM_MON, S_JELLY, "S_jelly"},
+       {SYM_MON, S_KOBOLD, "S_kobold"},
+       {SYM_MON, S_LEPRECHAUN, "S_leprechaun"},
+       {SYM_MON, S_MIMIC, "S_mimic"},
+       {SYM_MON, S_NYMPH, "S_nymph"},
+       {SYM_MON, S_ORC, "S_orc"},
+       {SYM_MON, S_PIERCER, "S_piercer"},
+       {SYM_MON, S_QUADRUPED, "S_quadruped"},
+       {SYM_MON, S_RODENT, "S_rodent"},
+       {SYM_MON, S_SPIDER, "S_spider"},
+       {SYM_MON, S_TRAPPER, "S_trapper"},
+       {SYM_MON, S_UNICORN, "S_unicorn"},
+       {SYM_MON, S_VORTEX, "S_vortex"},
+       {SYM_MON, S_WORM, "S_worm"},
+       {SYM_MON, S_XAN, "S_xan"},
+       {SYM_MON, S_LIGHT, "S_light"},
+       {SYM_MON, S_ZRUTY, "S_zruty"},
+       {SYM_MON, S_ANGEL, "S_angel"},
+       {SYM_MON, S_BAT, "S_bat"},
+       {SYM_MON, S_CENTAUR, "S_centaur"},
+       {SYM_MON, S_DRAGON, "S_dragon"},
+       {SYM_MON, S_ELEMENTAL, "S_elemental"},
+       {SYM_MON, S_FUNGUS, "S_fungus"},
+       {SYM_MON, S_GNOME, "S_gnome"},
+       {SYM_MON, S_GIANT, "S_giant"},
+       {SYM_MON, S_JABBERWOCK, "S_jabberwock"},
+       {SYM_MON, S_KOP, "S_kop"},
+       {SYM_MON, S_LICH, "S_lich"},
+       {SYM_MON, S_MUMMY, "S_mummy"},
+       {SYM_MON, S_NAGA, "S_naga"},
+       {SYM_MON, S_OGRE, "S_ogre"},
+       {SYM_MON, S_PUDDING, "S_pudding"},
+       {SYM_MON, S_QUANTMECH, "S_quantmech"},
+       {SYM_MON, S_RUSTMONST, "S_rustmonst"},
+       {SYM_MON, S_SNAKE, "S_snake"},
+       {SYM_MON, S_TROLL, "S_troll"},
+       {SYM_MON, S_UMBER, "S_umber"},
+       {SYM_MON, S_VAMPIRE, "S_vampire"},
+       {SYM_MON, S_WRAITH, "S_wraith"},
+       {SYM_MON, S_XORN, "S_xorn"},
+       {SYM_MON, S_YETI, "S_yeti"},
+       {SYM_MON, S_ZOMBIE, "S_zombie"},
+       {SYM_MON, S_HUMAN, "S_human"},
+       {SYM_MON, S_GHOST, "S_ghost"},
+       {SYM_MON, S_GOLEM, "S_golem"},
+       {SYM_MON, S_DEMON, "S_demon"},
+       {SYM_MON, S_EEL, "S_eel"},
+       {SYM_MON, S_LIZARD, "S_lizard"},
+       {SYM_MON, S_WORM_TAIL, "S_worm_tail"},
+       {SYM_MON, S_MIMIC_DEF, "S_mimic_def"},
+       {SYM_OC, WEAPON_CLASS, "S_weapon"},
+       {SYM_OC, ARMOR_CLASS, "S_armor"},
+       {SYM_OC, ARMOR_CLASS, "S_armour"},
+       {SYM_OC, RING_CLASS, "S_ring"},
+       {SYM_OC, AMULET_CLASS, "S_amulet"},
+       {SYM_OC, TOOL_CLASS, "S_tool"},
+       {SYM_OC, FOOD_CLASS, "S_food"},
+       {SYM_OC, POTION_CLASS, "S_potion"},
+       {SYM_OC, SCROLL_CLASS, "S_scroll"},
+       {SYM_OC, SPBOOK_CLASS, "S_book"},
+       {SYM_OC, WAND_CLASS, "S_wand"},
+       {SYM_OC, COIN_CLASS, "S_coin"},
+       {SYM_OC, GEM_CLASS, "S_gem"},
+       {SYM_OC, ROCK_CLASS,"S_rock"},
+       {SYM_OC, BALL_CLASS, "S_ball"},
+       {SYM_OC, CHAIN_CLASS, "S_chain"},
+       {SYM_OC, VENOM_CLASS, "S_venom"},
+       {SYM_OBJ, BOULDER, "S_boulder"},
+       {0,0,(const char *)0}   /* fence post */
+};
+#endif /*ASCIIGRAPH*/
+
+/* OBSOLETE */
+#if 0
+STATIC_OVL void
+graphics_opts(opts, optype, maxlen, offset)
+register char *opts;
+const char *optype;
+int maxlen, offset;
+{
+       uchar translate[MAXPCHARS+1];
+       int length, i;
+
+       if (!(opts = string_for_env_opt(optype, opts, FALSE)))
+               return;
+       escapes(opts, opts);
+
+       length = strlen(opts);
+       if (length > maxlen) length = maxlen;
+       /* match the form obtained from PC configuration files */
+       for (i = 0; i < length; i++)
+               translate[i] = (uchar) opts[i];
+       assign_graphics(translate, length, maxlen, offset);
+}
+#endif
 /*drawing.c*/
+
index 279e3e888c712c03f9968cf99ad13d484daa9b73..16ed838259f47c73108e5dc14f34d03533a662c2 100644 (file)
@@ -185,6 +185,11 @@ STATIC_DCL char *FDECL(make_lockname, (const char *,char *));
 STATIC_DCL FILE *FDECL(fopen_config_file, (const char *));
 STATIC_DCL int FDECL(get_uchars, (FILE *,char *,char *,uchar *,BOOLEAN_P,int,const char *));
 int FDECL(parse_config_line, (FILE *,char *,char *,char *));
+#ifdef ASCIIGRAPH
+STATIC_DCL FILE *NDECL(fopen_sym_file);
+STATIC_DCL void FDECL(free_symhandling, (BOOLEAN_P));
+STATIC_DCL void FDECL(set_symhandling, (char *,BOOLEAN_P));
+#endif
 #ifdef NOCWD_ASSUMPTIONS
 STATIC_DCL void FDECL(adjust_prefix, (char *, int));
 #endif
@@ -2047,35 +2052,46 @@ char            *tmp_levels;
        } else if (match_varname(buf, "BOULDER", 3)) {
            (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
                              1, "BOULDER");
-       } else if (match_varname(buf, "GRAPHICS", 4)) {
-           len = get_uchars(fp, buf, bufp, translate, FALSE,
-                            MAXPCHARS, "GRAPHICS");
-           assign_graphics(translate, len, MAXPCHARS, 0);
-       } else if (match_varname(buf, "DUNGEON", 4)) {
-           len = get_uchars(fp, buf, bufp, translate, FALSE,
-                            MAXDCHARS, "DUNGEON");
-           assign_graphics(translate, len, MAXDCHARS, 0);
-       } else if (match_varname(buf, "TRAPS", 4)) {
-           len = get_uchars(fp, buf, bufp, translate, FALSE,
-                            MAXTCHARS, "TRAPS");
-           assign_graphics(translate, len, MAXTCHARS, MAXDCHARS);
-       } else if (match_varname(buf, "EFFECTS", 4)) {
-           len = get_uchars(fp, buf, bufp, translate, FALSE,
-                            MAXECHARS, "EFFECTS");
-           assign_graphics(translate, len, MAXECHARS, MAXDCHARS+MAXTCHARS);
-
-       } else if (match_varname(buf, "OBJECTS", 3)) {
-           /* oc_syms[0] is the RANDOM object, unused */
-           (void) get_uchars(fp, buf, bufp, &(oc_syms[1]), TRUE,
-                                       MAXOCLASSES-1, "OBJECTS");
-       } else if (match_varname(buf, "MONSTERS", 3)) {
-           /* monsyms[0] is unused */
-           (void) get_uchars(fp, buf, bufp, &(monsyms[1]), TRUE,
-                                       MAXMCLASSES-1, "MONSTERS");
        } else if (match_varname(buf, "WARNINGS", 5)) {
            (void) get_uchars(fp, buf, bufp, translate, FALSE,
                                        WARNCOUNT, "WARNINGS");
            assign_warnings(translate);
+       } else if (match_varname(buf, "SYMBOLS", 4)) {
+#ifdef ASCIIGRAPH
+               char *op, symbuf[BUFSZ];
+               boolean morelines;
+               do {
+                       morelines = FALSE;
+
+                       /* strip leading and trailing white space */
+                       while (isspace(*bufp)) bufp++;
+                       op = eos(bufp);
+                       while (--op >= bufp && isspace(*op)) *op = '\0';
+
+                       /* check for line continuation (trailing '\') */
+                       op = eos(bufp);
+                       if (--op >= bufp && *op == '\\') {
+                           *op = '\0';
+                           morelines = TRUE;
+                           /* strip trailing space now that '\' is gone */
+                           while (--op >= bufp && isspace(*op)) *op = '\0';
+                       }
+
+                       /* parse here */
+                       parsesymbols(bufp);
+       
+                       if (morelines)
+                         do  {
+                           *symbuf = '\0';
+                           if (!fgets(symbuf, BUFSZ, fp)) {
+                                       morelines = FALSE;
+                                       break;
+                           }
+                           bufp = symbuf;
+                       } while (*bufp == '#');
+               } while (morelines);
+               switch_graphics(TRUE);
+#endif /*ASCIIGRAPH*/
 #ifdef WIZARD
        } else if (match_varname(buf, "WIZKIT", 6)) {
            (void) strncpy(wizkit, bufp, WIZKIT_MAX-1);
@@ -2405,6 +2421,218 @@ read_wizkit()
 
 #endif /*WIZARD*/
 
+#ifdef ASCIIGRAPH
+extern struct symparse loadsyms[];     /* drawing.c */
+extern struct textlist *symset_list;   /* options.c */
+static int symset_count = 0;           /* for pick-list building only */
+static boolean chosen_symset_start = FALSE, chosen_symset_end = FALSE;
+
+STATIC_OVL
+FILE *
+fopen_sym_file()
+{
+       FILE *fp;
+
+       fp = fopen_datafile(SYMBOLS, "r", HACKPREFIX);
+       return fp;
+}
+
+/*
+ * Returns 1 if the chose symset was found and loaded.
+ *         0 if it wasn't found in the sym file or other problem.
+ */
+int
+read_sym_file(rogueflag)
+boolean rogueflag;
+{
+       char buf[4*BUFSZ];
+       FILE *fp;
+
+       if (!(fp = fopen_sym_file())) return 0;
+
+       symset_count = 0;
+       chosen_symset_start = chosen_symset_end = FALSE;
+       while (fgets(buf, 4*BUFSZ, fp)) {
+               if (!parse_sym_line(buf, rogueflag)) {
+                       raw_printf("Bad symbol line:  \"%.50s\"", buf);
+                       wait_synch();
+               }
+       }
+       (void) fclose(fp);
+       if (!chosen_symset_end && !chosen_symset_start) return 0;
+       if (!chosen_symset_end) {
+               raw_printf("Missing finish for symset \"%s\"",
+#ifdef REINCARNATION
+                               rogueflag ? roguesymset :
+#endif
+                               symset);
+               wait_synch();
+       }
+       return 1;
+}
+
+/* returns 0 on error */
+int
+parse_sym_line(buf, rogueflag)
+char *buf;
+boolean rogueflag;
+{
+       int val;
+       struct symparse *symp = (struct symparse *)0;
+       char *bufp, *commentp, *altp;
+       char *symsetname =
+#ifdef REINCARNATION
+                           rogueflag ? roguesymset :
+#endif
+                           symset;
+
+       if (*buf == '#')
+               return 1;
+
+       /* remove trailing comment(s) */
+       commentp = eos(buf);
+       while (--commentp > buf) {
+               if (*commentp != '#') continue;
+               *commentp = '\0';
+       }
+
+       /* remove trailing whitespace */
+       bufp = eos(buf);
+       while (--bufp > buf && isspace(*bufp))
+               continue;
+
+       if (bufp <= buf)
+               return 1;               /* skip all-blank lines */
+       else
+               *(bufp + 1) = '\0';     /* terminate line */
+
+       /* skip leading whitespace on option name */
+       while (isspace(*buf)) ++buf;
+       
+       /* find the '=' or ':' */
+       bufp = index(buf, '=');
+       altp = index(buf, ':');
+       if (!bufp || (altp && altp < bufp)) bufp = altp;
+       if (!bufp) {
+           if (strncmpi(buf, "finish", 6) == 0) {
+               /* end current graphics set */
+               chosen_symset_start = FALSE;
+               chosen_symset_end = TRUE;
+               return 1;
+           }
+           return 0;
+       }
+
+       /* skip  whitespace between '=' and value */
+       do { ++bufp; } while (isspace(*bufp));
+
+       symp = match_sym(buf);
+       if (!symp)
+               return 0;
+
+       if (!symsetname) {
+           /* A null symsetname indicates that we're just
+              building a pick-list of possible symset
+              values from the file, so only do that */
+           if (symp->range == SYM_CONTROL && symp->idx == 0) {
+               struct textlist *tmpsp;
+               tmpsp = (struct textlist *)alloc(sizeof(struct textlist));
+               tmpsp->next = (struct textlist *)0;
+               if (!symset_list) {
+                       symset_list = tmpsp;
+                       symset_count = 0;
+               } else {
+                       symset_count++;
+                       tmpsp->next = symset_list;
+                       symset_list = tmpsp;
+               }
+               tmpsp->idx = symset_count;
+               tmpsp->text = (char *)alloc(strlen(bufp)+1);
+               Strcpy(tmpsp->text, bufp);
+           }
+           return 1;
+       }
+       if (symp->range) {
+           if (symp->range == SYM_CONTROL) {
+               switch(symp->idx) {
+                   case 0:
+                           /* start of symset */
+                           if (!strcmpi(bufp, symsetname)) { /* desired one? */
+                               chosen_symset_start = TRUE;
+#ifdef REINCARNATION
+                               if (rogueflag)
+                                   init_r_symbols();
+                               else
+#endif
+                                   init_l_symbols();
+                               free_symhandling(rogueflag);
+                           }
+                           break;
+                   case 1:
+                           /* finish symset */
+                           chosen_symset_start = FALSE;
+                           chosen_symset_end = TRUE;
+                           break;
+                   case 2:
+                           /* handler type identified */
+                           if (chosen_symset_start)
+                               set_symhandling(bufp, rogueflag);
+                           break;
+               }
+           } else {            /* !SYM_CONTROL */
+               val = sym_val(bufp);
+               if (chosen_symset_start) {
+#ifdef REINCARNATION
+                       if (rogueflag)
+                           update_r_symset(symp, val);
+                       else
+#endif
+                           update_l_symset(symp, val);
+               }
+           }
+       }
+       return 1;
+}
+
+STATIC_OVL void
+free_symhandling(rogueflag)
+boolean rogueflag;
+{
+       if (rogueflag) {
+#ifdef REINCARNATION
+               if (roguehandling) {
+                       free((genericptr_t)roguehandling);
+                       roguehandling = (char *)0;
+               }
+#endif
+       } else {
+               if (symhandling) {
+                       free((genericptr_t)symhandling);
+                       symhandling = (char *)0;
+               }
+       }
+}
+
+STATIC_OVL void
+set_symhandling(handling, rogueflag)
+char *handling;
+boolean rogueflag;
+{
+       char *new_handling;
+
+       free_symhandling(rogueflag);
+       if (!handling) return;
+       new_handling = (char *)alloc(strlen(handling)+1);
+       Strcpy(new_handling, handling);
+#ifdef REINCARNATION
+       if (rogueflag)
+               roguehandling = new_handling;
+#endif
+       if (!rogueflag)
+               symhandling = new_handling;
+}
+#endif /*ASCIIGRAPH*/
+
 /* ----------  END CONFIG FILE HANDLING ----------- */
 
 /* ----------  BEGIN SCOREBOARD CREATION ----------- */
index 9bc7b6edc3f749ffc1758be3aeee7b1da1695509..f7aed474d04f845f5f3e0b251cd85bf64010325c 100644 (file)
@@ -806,7 +806,7 @@ register const char *let,*word;
 
        if(allownone) *bp++ = '-';
 #ifndef GOLDOBJ
-       if(allowgold) *bp++ = def_oc_syms[COIN_CLASS];
+       if(allowgold) *bp++ = def_oc_syms[COIN_CLASS].sym;
 #endif
        if(bp > buf && bp[-1] == '-') *bp++ = ' ';
        ap = altlets;
@@ -981,7 +981,7 @@ register const char *let,*word;
                if(ilet == '-') {
                        return(allownone ? &zeroobj : (struct obj *) 0);
                }
-               if(ilet == def_oc_syms[COIN_CLASS]) {
+               if(ilet == def_oc_syms[COIN_CLASS].sym) {
                        if (!usegold) {
                            You("cannot %s gold.", word);
                            return(struct obj *)0;
@@ -1035,7 +1035,7 @@ register const char *let,*word;
                     * counts for other things since the throw code will
                     * split off a single item anyway */
 #ifdef GOLDOBJ
-                   if (ilet != def_oc_syms[COIN_CLASS])
+                   if (ilet != def_oc_syms[COIN_CLASS].sym)
 #endif
                        allowcnt = 1;
                    if(cnt == 0 && prezero) return((struct obj *)0);
@@ -2101,8 +2101,8 @@ dotypeinv()
            if (!billx) *extra_types++ = 'x';
            *extra_types = '\0';        /* for index() */
            for (i = 0; i < MAXOCLASSES; i++)
-               if (!index(types, def_oc_syms[i])) {
-                   *extra_types++ = def_oc_syms[i];
+               if (!index(types, def_oc_syms[i].sym)) {
+                   *extra_types++ = def_oc_syms[i].sym;
                    *extra_types = '\0';
                }
 
index fa901d4609d9a29adb52d405d8f4693dd364e0aa..0c64c7f0b7323fdd9250362fe99c0c65871dcaa3 100644 (file)
@@ -1295,7 +1295,7 @@ rndmonst()
                if (tooweak(mndx, minmlev) || toostrong(mndx, maxmlev))
                    continue;
 #ifdef REINCARNATION
-               if (upper && !isupper(def_monsyms[(int)(ptr->mlet)])) continue;
+               if (upper && !isupper(def_monsyms[(int)(ptr->mlet)].sym)) continue;
 #endif
                if (elemlevel && wrong_elem_type(ptr)) continue;
                if (uncommon(mndx)) continue;
index 528e97e298b454f28e0bd698a47d13c51e9980d2..cb24ca5db8bce169dcd989b238d160ee924791c2 100644 (file)
@@ -50,10 +50,9 @@ int explcolors[] = {
 
 #ifdef ROGUE_COLOR
 # if defined(USE_TILES) && defined(MSDOS)
-#define HAS_ROGUE_IBM_GRAPHICS (iflags.IBMgraphics && !iflags.grmode && \
-       Is_rogue_level(&u.uz))
+#define HAS_ROGUE_IBM_GRAPHICS (ROGUEHANDLING("IBM") && !iflags.grmode)
 # else
-#define HAS_ROGUE_IBM_GRAPHICS (iflags.IBMgraphics && Is_rogue_level(&u.uz))
+#define HAS_ROGUE_IBM_GRAPHICS (ROGUEHANDLING("IBM"))
 # endif
 #endif
 
@@ -221,11 +220,7 @@ unsigned *ospecial;
 #ifdef TEXTCOLOR
     /* Turn off color if no color defined, or rogue level w/o PC graphics. */
 # ifdef REINCARNATION
-#  ifdef ASCIIGRAPH
     if (!has_color(color) || (Is_rogue_level(&u.uz) && !has_rogue_ibm_graphics))
-#  else
-    if (!has_color(color) || Is_rogue_level(&u.uz))
-#  endif
 # else
     if (!has_color(color))
 # endif
index 8cbbe4f84e53a543ec61abcfaf92adf80d7a2e56..8aee070a959a7451c4c1b625b4498b76254efd99 100644 (file)
@@ -114,7 +114,7 @@ mkshop()
                                return;
                        }
                        for(i=0; shtypes[i].name; i++)
-                               if(*ep == def_oc_syms[(int)shtypes[i].symb])
+                               if(*ep == def_oc_syms[(int)shtypes[i].symb].sym)
                                    goto gottype;
                        if(*ep == 'g' || *ep == 'G')
                                i = 0;
index 21ac556890d7171110255d244bfe87d2bd1b2fba..7ad4753e7e56ff3ffc00bb25612212e83cf3fd3f 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)options.c  3.5     2006/07/08      */
+/*     SCCS Id: @(#)options.c  3.5     2006/09/17      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -18,6 +18,7 @@ NEARDATA struct instance_flags iflags;        /* provide linkage */
 #include <ctype.h>
 #endif
 
+#define BACKWARD_COMPAT
 #define WINTYPELEN 16
 
 #ifdef DEFAULT_WC_TILED_MAP
@@ -86,11 +87,6 @@ static struct Bool_Opt
        {"color",         &iflags.wc_color, FALSE, SET_IN_GAME},        /*WC*/
 # endif
        {"confirm",&flags.confirm, TRUE, SET_IN_GAME},
-#if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV)
-       {"DECgraphics", &iflags.DECgraphics, FALSE, SET_IN_GAME},
-#else
-       {"DECgraphics", (boolean *)0, FALSE, SET_IN_FILE},
-#endif
        {"eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME},      /*WC*/
 #ifdef TTY_GRAPHICS
        {"extmenu", &iflags.extmenu, FALSE, SET_IN_GAME},
@@ -112,11 +108,6 @@ static struct Bool_Opt
        {"fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE},
        {"help", &flags.help, TRUE, SET_IN_GAME},
        {"hilite_pet",    &iflags.wc_hilite_pet, FALSE, SET_IN_GAME},   /*WC*/
-#ifdef ASCIIGRAPH
-       {"IBMgraphics", &iflags.IBMgraphics, FALSE, SET_IN_GAME},
-#else
-       {"IBMgraphics", (boolean *)0, FALSE, SET_IN_FILE},
-#endif
 #ifndef MAC
        {"ignintr", &flags.ignintr, FALSE, SET_IN_GAME},
 #else
@@ -126,11 +117,6 @@ static struct Bool_Opt
        {"legacy", &flags.legacy, TRUE, DISP_IN_GAME},
        {"lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME},
        {"lootabc", &flags.lootabc, FALSE, SET_IN_GAME},
-#ifdef MAC_GRAPHICS_ENV
-       {"Macgraphics", &iflags.MACgraphics, TRUE, SET_IN_GAME},
-#else
-       {"Macgraphics", (boolean *)0, FALSE, SET_IN_FILE},
-#endif
 #ifdef MAIL
        {"mail", &flags.biff, TRUE, SET_IN_GAME},
 #else
@@ -245,8 +231,10 @@ static struct Comp_Opt
        { "align_message", "message window alignment", 20, DISP_IN_GAME }, /*WC*/
        { "align_status", "status window alignment", 20, DISP_IN_GAME },   /*WC*/
        { "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
-       { "boulder",  "the symbol to use for displaying boulders",
-                                               1, SET_IN_GAME },
+#ifdef BACKWARD_COMPAT
+       { "boulder",  "deprecated (use S_boulder in sym file instead)",
+                                               1, SET_IN_FILE },
+#endif
        { "catname",  "the name of your (first) cat (e.g., catname:Tabby)",
                                                PL_PSIZ, DISP_IN_GAME },
        { "disclose", "the kinds of information to disclose at end of game",
@@ -344,6 +332,13 @@ static struct Comp_Opt
        { "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME }, /*WC*/
 #ifdef MSDOS
        { "soundcard", "type of sound card to use", 20, SET_IN_FILE },
+#endif
+       { "symset", "load a set of display symbols from the symbols file", 70, SET_IN_GAME },
+       { "roguesymset", "load a set of rogue display symbols from the roguesym file", 70,
+#ifdef REINCARNATION
+                                SET_IN_GAME },
+#else
+                                SET_IN_FILE },
 #endif
        { "suppress_alert", "suppress alerts about version-specific features",
                                                8, SET_IN_GAME },
@@ -368,6 +363,13 @@ static struct Comp_Opt
        { "windowcolors",  "the foreground/background colors of windows",       /*WC*/
                                                80, DISP_IN_GAME },
        { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
+#ifdef BACKWARD_COMPAT
+       {"DECgraphics", "deprecated", 70, SET_IN_FILE},
+       {"IBMgraphics", "deprecated", 70, SET_IN_FILE},
+# ifdef MAC_GRAPHICS_ENV
+       {"Macgraphics", "deprecated", 70, SET_IN_FILE},
+# endif
+#endif
        { (char *)0, (char *)0, 0, 0 }
 };
 
@@ -580,15 +582,12 @@ initoptions()
        flags.initgend = -1;
        flags.initalign = -1;
 
-       /* Set the default monster and object class symbols.  Don't use */
-       /* memcpy() --- sizeof char != sizeof uchar on some machines.   */
-       for (i = 0; i < MAXOCLASSES; i++)
-               oc_syms[i] = (uchar) def_oc_syms[i];
-       for (i = 0; i < MAXMCLASSES; i++)
-               monsyms[i] = (uchar) def_monsyms[i];
+       /* Set the default monster and object class symbols. */
+       init_symbols();
        for (i = 0; i < WARNCOUNT; i++)
                warnsyms[i] = def_warnsyms[i].sym;
        iflags.bouldersym = 0;
+
        iflags.travelcc.x = iflags.travelcc.y = -1;
 
      /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
@@ -599,7 +598,7 @@ initoptions()
 
        for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
                flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
-       switch_graphics(ASCII_GRAPHICS);        /* set default characters */
+       switch_graphics(DEFAULT_GRAPHICS);      /* set default characters */
 #if defined(UNIX) && defined(TTY_GRAPHICS)
        /*
         * Set defaults for some options depending on what we can
@@ -610,7 +609,13 @@ initoptions()
         */
        /* this detects the IBM-compatible console on most 386 boxes */
        if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
-               switch_graphics(IBM_GRAPHICS);
+#ifdef ASCIIGRAPH
+               if (!symset) load_symset("IBMGraphics", FALSE);
+
+               if (!roguesymset) load_symset("IBMGraphics", TRUE);
+
+               switch_graphics(TRUE);
+#endif
 # ifdef TEXTCOLOR
                iflags.use_color = TRUE;
 # endif
@@ -622,13 +627,20 @@ initoptions()
        if ((opts = nh_getenv("TERM")) &&
            !strncmpi(opts, "vt", 2) && AS && AE &&
            index(AS, '\016') && index(AE, '\017')) {
-               switch_graphics(DEC_GRAPHICS);
+#  ifdef ASCIIGRAPH
+               if (!symset) load_symset("DECGraphics", FALSE);
+
+
+
+               switch_graphics(TRUE);
+#  endif /*ASCIIGRAPH*/
        }
 # endif
 #endif /* UNIX || VMS */
 
 #ifdef MAC_GRAPHICS_ENV
-       switch_graphics(MAC_GRAPHICS);
+       if (!symset) load_symset("MACGraphics", FALSE);
+       switch_graphics(TRUE);
 #endif /* MAC_GRAPHICS_ENV */
        flags.menu_style = MENU_FULL;
 
@@ -866,27 +878,6 @@ char *op;
     return 1;
 }
 
-STATIC_OVL void
-graphics_opts(opts, optype, maxlen, offset)
-register char *opts;
-const char *optype;
-int maxlen, offset;
-{
-       uchar translate[MAXPCHARS+1];
-       int length, i;
-
-       if (!(opts = string_for_env_opt(optype, opts, FALSE)))
-               return;
-       escapes(opts, opts);
-
-       length = strlen(opts);
-       if (length > maxlen) length = maxlen;
-       /* match the form obtained from PC configuration files */
-       for (i = 0; i < length; i++)
-               translate[i] = (uchar) opts[i];
-       assign_graphics(translate, length, maxlen, offset);
-}
-
 STATIC_OVL void
 warning_opts(opts, optype)
 register char *opts;
@@ -1305,6 +1296,49 @@ boolean tinitial, tfrom_file;
                return;
        }
 
+       fullname = "roguesymset";
+       if (match_optname(opts, fullname, 7, TRUE)) {
+#if defined(REINCARNATION) && defined(ASCIIGRAPH)
+               if (duplicate) complain_about_duplicate(opts,1);
+               if (negated) bad_negation(fullname, FALSE);
+               else if ((op = string_for_opt(opts, FALSE)) != 0) {
+                   roguesymset = (char *)alloc(strlen(op) + 1);
+                   Strcpy(roguesymset, op);
+                   if (!read_sym_file(TRUE)) {
+                       badoption(opts);
+                       free((char *)roguesymset);
+                       roguesymset = (char *)0;
+                   } else {
+                       if (!initial && Is_rogue_level(&u.uz))
+                               assign_rogue_graphics(TRUE);
+                               need_redraw = TRUE;
+                   }
+               }
+#endif
+               return;
+       }
+
+       fullname = "symset";
+       if (match_optname(opts, fullname, 6, TRUE)) {
+#ifdef ASCIIGRAPH
+               if (duplicate) complain_about_duplicate(opts,1);
+               if (negated) bad_negation(fullname, FALSE);
+               else if ((op = string_for_opt(opts, FALSE)) != 0) {
+                   symset = (char *)alloc(strlen(op) + 1);
+                   Strcpy(symset, op);
+                   if (!read_sym_file(FALSE)) {
+                       badoption(opts);
+                       free((char *)symset);
+                       symset = (char *)0;
+                   } else {
+                       switch_graphics(TRUE);
+                       need_redraw = TRUE;
+                   }
+               }
+#endif
+               return;
+       }
+
        fullname = "runmode";
        if (match_optname(opts, fullname, 4, TRUE)) {
                if (duplicate) complain_about_duplicate(opts,1);
@@ -1566,93 +1600,6 @@ goodfruit:
                 */
                return;
        }
-
-       /* graphics:string */
-       fullname = "graphics";
-       if (match_optname(opts, fullname, 2, TRUE)) {
-               if (duplicate) complain_about_duplicate(opts,1);
-               if (negated) bad_negation(fullname, FALSE);
-               else graphics_opts(opts, fullname, MAXPCHARS, 0);
-               return;
-       }
-       fullname = "dungeon";
-       if (match_optname(opts, fullname, 2, TRUE)) {
-               if (duplicate) complain_about_duplicate(opts,1);
-               if (negated) bad_negation(fullname, FALSE);
-               else graphics_opts(opts, fullname, MAXDCHARS, 0);
-               return;
-       }
-       fullname = "traps";
-       if (match_optname(opts, fullname, 2, TRUE)) {
-               if (duplicate) complain_about_duplicate(opts,1);
-               if (negated) bad_negation(fullname, FALSE);
-               else graphics_opts(opts, fullname, MAXTCHARS, MAXDCHARS);
-               return;
-       }
-       fullname = "effects";
-       if (match_optname(opts, fullname, 2, TRUE)) {
-               if (duplicate) complain_about_duplicate(opts,1);
-               if (negated) bad_negation(fullname, FALSE);
-               else
-                graphics_opts(opts, fullname, MAXECHARS, MAXDCHARS+MAXTCHARS);
-               return;
-       }
-
-       /* objects:string */
-       fullname = "objects";
-       if (match_optname(opts, fullname, 7, TRUE)) {
-               int length;
-
-               if (duplicate) complain_about_duplicate(opts,1);
-               if (negated) {
-                   bad_negation(fullname, FALSE);
-                   return;
-               }
-               if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
-                       return;
-               escapes(opts, opts);
-
-               /*
-                * Override the default object class symbols.  The first
-                * object in the object class is the "random object".  I
-                * don't want to use 0 as an object class, so the "random
-                * object" is basically a place holder.
-                *
-                * The object class symbols have already been initialized in
-                * initoptions().
-                */
-               length = strlen(opts);
-               if (length >= MAXOCLASSES)
-                   length = MAXOCLASSES-1;     /* don't count RANDOM_OBJECT */
-
-               for (i = 0; i < length; i++)
-                   oc_syms[i+1] = (uchar) opts[i];
-               return;
-       }
-
-       /* monsters:string */
-       fullname = "monsters";
-       if (match_optname(opts, fullname, 8, TRUE)) {
-               int length;
-
-               if (duplicate) complain_about_duplicate(opts,1);
-               if (negated) {
-                   bad_negation(fullname, FALSE);
-                   return;
-               }
-               if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
-                       return;
-               escapes(opts, opts);
-
-               /* Override default mon class symbols set in initoptions(). */
-               length = strlen(opts);
-               if (length >= MAXMCLASSES)
-                   length = MAXMCLASSES-1;     /* mon class 0 unused */
-
-               for (i = 0; i < length; i++)
-                   monsyms[i+1] = (uchar) opts[i];
-               return;
-       }
        fullname = "warnings";
        if (match_optname(opts, fullname, 5, TRUE)) {
                if (duplicate) complain_about_duplicate(opts,1);
@@ -1660,6 +1607,7 @@ goodfruit:
                else warning_opts(opts, fullname);
                return;
        }
+#ifdef BACKWARD_COMPAT
        /* boulder:symbol */
        fullname = "boulder";
        if (match_optname(opts, fullname, 7, TRUE)) {
@@ -1692,6 +1640,7 @@ goodfruit:
                if (!initial) need_redraw = TRUE;
                return;
        }
+#endif
 
        /* name:string */
        fullname = "name";
@@ -2301,7 +2250,7 @@ goodfruit:
                        isbad = TRUE;
                    else        /* reject default object class symbols */
                        for (j = 1; j < MAXOCLASSES; j++)
-                           if (c == def_oc_syms[i]) {
+                           if (c == def_oc_syms[i].sym) {
                                isbad = TRUE;
                                break;
                            }
@@ -2331,20 +2280,102 @@ goodfruit:
                        badoption(opts);
                return;
        }
+#endif
+
+#ifdef ASCIIGRAPH
+# if defined(BACKWARD_COMPAT)
+       fullname = "DECgraphics";
+       if (match_optname(opts, fullname, 10, TRUE)) {
+               boolean badflag = FALSE;
+               if (duplicate) complain_about_duplicate(opts,1);
+               if (!negated) {
+                   if (symset) badflag = TRUE;
+                   else {
+                       symset = (char *)alloc(strlen(fullname) + 1);
+                       Strcpy(symset, fullname);
+                       if (!read_sym_file(FALSE)) {
+                               badflag = TRUE;
+                               free((char *)symset);
+                               symset = (char *)0;
+                       } else switch_graphics(TRUE);
+                   }
+                   if (badflag) {
+                       pline("Failure to load symbol set %s.",
+                               fullname);
+                       wait_synch();
+                   }
+               }
+               return;
+       }
+       fullname = "IBMgraphics";
+       if (match_optname(opts, fullname, 10, TRUE)) {
+               boolean badflag = FALSE;
+               if (duplicate) complain_about_duplicate(opts,1);
+               if (!negated) {
+                   if (symset) badflag = TRUE;
+                   else {
+                       symset = (char *)alloc(strlen(fullname) + 1);
+                       Strcpy(symset, fullname);
+                       if (!read_sym_file(FALSE)) {
+                               badflag = TRUE;
+                               free((char *)symset);
+                               symset = (char *)0;
+                       } else switch_graphics(TRUE);
+                   }
+#ifdef REINCARNATION
+                   if (roguesymset) badflag = TRUE;
+                   else {
+                       roguesymset = (char *)alloc(strlen(fullname) + 1);
+                       Strcpy(roguesymset, fullname);
+                       if (!read_sym_file(TRUE)) {
+                               badflag = TRUE;
+                               free((char *)roguesymset);
+                               roguesymset = (char *)0;
+                       }
+                       if (!initial && Is_rogue_level(&u.uz))
+                               assign_rogue_graphics(TRUE);
+                   }
+#endif
+                   if (badflag) {
+                       pline("Failure to load symbol set %s.",
+                               fullname);
+                       wait_synch();
+                   }
+               }
+               return;
+       }
+#  ifdef MAC_GRAPHICS_ENV
+       fullname = "MACgraphics";
+       if (match_optname(opts, fullname, 11, TRUE)) {
+               boolean badflag = FALSE;
+               if (duplicate) complain_about_duplicate(opts,1);
+               if (!negated) {
+                   if (symset) badflag = TRUE;
+                   else {
+                       symset = (char *)alloc(strlen(fullname) + 1);
+                       Strcpy(symset, fullname);
+                       if (!read_sym_file(FALSE)) {
+                               badflag = TRUE;
+                               free((char *)symset);
+                               symset = (char *)0;
+                       } else switch_graphics(TRUE);
+                   }
+                   if (badflag) {
+                       pline("Failure to load symbol set %s.",
+                               fullname);
+                       wait_synch();
+                   }
+               }
+               return;
+       }
+#  endif
+# endif
 #endif
        /* OK, if we still haven't recognized the option, check the boolean
         * options list
         */
        for (i = 0; boolopt[i].name; i++) {
                if (match_optname(opts, boolopt[i].name, 3, FALSE)) {
-#if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV)
-                       /* need to remember previous XXXgraphics setting
-                          in order to prevent explicit "noXXXgraphics" from
-                          overriding a preceding "YYYgraphics" request;
-                          noXXXgraphics will reset to ordinary ASCII only
-                          if/when XXXgraphics is currently in effect */
-                       boolean old_gfx = boolopt[i].addr && *boolopt[i].addr;
-#endif
 
                        /* options that don't exist */
                        if (!boolopt[i].addr) {
@@ -2365,50 +2396,6 @@ goodfruit:
                        if (duplicate_opt_detection(boolopt[i].name, 0))
                            complain_about_duplicate(boolopt[i].name,0);
 
-#if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV)
-                       if (FALSE
-# ifdef TERMLIB
-                                || (boolopt[i].addr) == &iflags.DECgraphics
-# endif
-# ifdef ASCIIGRAPH
-                                || (boolopt[i].addr) == &iflags.IBMgraphics
-# endif
-# ifdef MAC_GRAPHICS_ENV
-                                || (boolopt[i].addr) == &iflags.MACgraphics
-# endif
-                               ) {
-# ifdef REINCARNATION
-                           if (!initial && Is_rogue_level(&u.uz))
-                               assign_rogue_graphics(FALSE);
-# endif
-                           need_redraw = TRUE;
-# ifdef TERMLIB
-                           if ((boolopt[i].addr) == &iflags.DECgraphics) {
-                               if (iflags.DECgraphics != old_gfx)
-                                   switch_graphics(iflags.DECgraphics ?
-                                               DEC_GRAPHICS : ASCII_GRAPHICS);
-                           }
-# endif
-# ifdef ASCIIGRAPH
-                           if ((boolopt[i].addr) == &iflags.IBMgraphics) {
-                               if (iflags.IBMgraphics != old_gfx)
-                                   switch_graphics(!negated ?
-                                               IBM_GRAPHICS : ASCII_GRAPHICS);
-                           }
-# endif
-# ifdef MAC_GRAPHICS_ENV
-                           if ((boolopt[i].addr) == &iflags.MACgraphics) {
-                               if (iflags.MACgraphics != old_gfx)
-                                   switch_graphics(iflags.MACgraphics ?
-                                               MAC_GRAPHICS : ASCII_GRAPHICS);
-                           }
-# endif
-# ifdef REINCARNATION
-                           if (!initial && Is_rogue_level(&u.uz))
-                               assign_rogue_graphics(TRUE);
-# endif
-                       }
-#endif /* TERMLIB || ASCIIGRAPH || MAC_GRAPHICS_ENV */
 #ifdef RLECOMP
                        if ((boolopt[i].addr) == &iflags.rlecomp) {
                                if (*boolopt[i].addr)
@@ -2517,7 +2504,7 @@ oc_to_str(src,dest)
        if (i < 0 || i >= MAXOCLASSES)
            impossible("oc_to_str:  illegal object class %d", i);
        else
-           *dest++ = def_oc_syms[i];
+           *dest++ = def_oc_syms[i].sym;
     }
     *dest = '\0';
 }
@@ -2791,6 +2778,8 @@ doset()
        return 0;
 }
 
+struct textlist *symset_list;  /* files.c will populate this wil list of available sets */
+
 STATIC_OVL boolean
 special_handling(optname, setinitial, setfromfile)
 const char *optname;
@@ -3148,6 +3137,102 @@ boolean setinitial,setfromfile;
                if (pick_cnt >= 0) goto ape_again;
        }
 #endif /* AUTOPICKUP_EXCEPTIONS */
+#ifdef ASCIIGRAPH
+    } else if (!strcmp("symset", optname) ||
+              !strcmp("roguesymset", optname)) {
+       menu_item *symset_pick = (menu_item *)0;
+       boolean rogueflag = (*optname == 'r');
+       char *symset_name;
+       int chosen = -2;
+
+       /* clear symset/roguesymset as a flag to read_sym_file() to build list */
+       if (!rogueflag) {
+               symset_name = symset;
+               symset = (char *)0;
+       }
+#ifdef REINCARNATION
+       if (rogueflag) {
+               symset_name = roguesymset;
+               roguesymset = (char *)0;
+       }
+#endif
+
+       if (read_sym_file(rogueflag) && symset_list) {
+               int let = 'a';
+               struct textlist *sl;
+               tmpwin = create_nhwindow(NHW_MENU);
+               start_menu(tmpwin);
+               any.a_int = 1;
+               add_menu(tmpwin, NO_GLYPH, &any, let++, 0,
+                        ATR_NONE, "NetHack default", MENU_UNSELECTED);
+               sl = symset_list;
+               while (sl) {
+                   if (sl->text) {
+                       any.a_int = sl->idx + 2;
+                       add_menu(tmpwin, NO_GLYPH, &any, let, 0,
+                        ATR_NONE, sl->text, MENU_UNSELECTED);
+                       sl = sl->next;
+                       if (let == 'z') let = 'A';
+                       else let++;
+                   }
+               }
+               end_menu(tmpwin, "Select symbol set:");
+               if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
+                       chosen = symset_pick->item.a_int - 2;
+                       free((genericptr_t)symset_pick);
+               }
+               destroy_nhwindow(tmpwin);
+               if (chosen > -1) {
+                       sl = symset_list;
+                       while (sl) {
+                           if (sl->idx == chosen) {
+                               if (symset_name)
+                                       free((genericptr_t)symset_name);
+                               symset_name = (char *)alloc(strlen(sl->text)+1);
+                               Strcpy(symset_name, sl->text);
+                           }
+                           sl = sl->next;
+                       }
+               }
+               /* clean up */
+               while (symset_list) {
+                       sl = symset_list;
+                       if (sl->text) free((genericptr_t)sl->text);
+                       symset_list = sl->next;
+                       free((genericptr_t)sl);
+               }
+               symset_list = (struct textlist *)0;
+       }
+       if(!rogueflag) {
+           init_l_symbols();
+           if (chosen >= 0) {
+               symset = symset_name;
+               if (!read_sym_file(FALSE)) {
+                       free((genericptr_t)symset);
+                       symset = (char *)0;
+               }
+           }
+       }
+# ifdef REINCARNATION
+       if (rogueflag) {
+           init_r_symbols();
+           if (chosen >= 0) {
+               roguesymset = symset_name;
+               if (!read_sym_file(TRUE)) {
+                       free((genericptr_t)roguesymset);
+                       roguesymset = (char *)0;
+               }
+           }
+       }
+       if (Is_rogue_level(&u.uz))
+               assign_rogue_graphics(TRUE);
+       else
+               assign_rogue_graphics(FALSE);
+#else
+       switch_graphics(TRUE);
+# endif
+       need_redraw = TRUE;
+#endif /*ASCIIGRAPH*/
     } else {
        /* didn't match any of the special options */
        return FALSE;
@@ -3192,9 +3277,11 @@ char *buf;
                Sprintf(buf, "%s", iflags.altkeyhandler[0] ?
                        iflags.altkeyhandler : "default");
 #endif
+#ifdef BACKWARD_COMPAT
        else if (!strcmp(optname, "boulder"))
                Sprintf(buf, "%c", iflags.bouldersym ?
                        iflags.bouldersym : oc_syms[(int)objects[BOULDER].oc_class]);
+#endif
        else if (!strcmp(optname, "catname"))
                Sprintf(buf, "%s", catname[0] ? catname : none );
        else if (!strcmp(optname, "disclose")) {
@@ -3343,6 +3430,10 @@ char *buf;
             }
        else if (!strcmp(optname, "race"))
                Sprintf(buf, "%s", rolestring(flags.initrace, races, noun));
+#ifdef REINCARNATION
+       else if (!strcmp(optname, "roguesymset"))
+               Sprintf(buf, "%s", roguesymset ? roguesymset : "default");
+#endif
        else if (!strcmp(optname, "role"))
                Sprintf(buf, "%s", rolestring(flags.initrole, roles, name.m));
        else if (!strcmp(optname, "runmode"))
@@ -3374,6 +3465,8 @@ char *buf;
                        FEATURE_NOTICE_VER_MIN,
                        FEATURE_NOTICE_VER_PATCH);
        }
+       else if (!strcmp(optname, "symset"))
+               Sprintf(buf, "%s", symset ? symset : "default");
        else if (!strcmp(optname, "tile_file"))
                Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
        else if (!strcmp(optname, "tile_height")) {
@@ -3548,6 +3641,110 @@ free_autopickup_exceptions()
        }
 }
 #endif /* AUTOPICKUP_EXCEPTIONS */
+#ifdef ASCIIGRAPH
+/* bundle some common usage into one easy-to-use routine */
+int
+load_symset(s, rogueflag)
+const char *s;
+boolean rogueflag;
+{
+#ifdef REINCARNATION
+       if (rogueflag) {
+               if (roguesymset) free((genericptr_t)roguesymset);
+               roguesymset = (char *)alloc(strlen(s)+1);
+               Strcpy(roguesymset,s);
+               if (read_sym_file(TRUE))
+                       switch_graphics(TRUE);
+               else {
+                       free((genericptr_t)roguesymset);
+                       roguesymset = (char *)0;
+                       return 0;
+               }
+       }
+#endif
+       if (!rogueflag) {
+               if (symset) free((genericptr_t)symset);
+               symset = (char *)alloc(strlen(s)+1);
+               Strcpy(symset,s);
+               if (read_sym_file(FALSE))
+                       switch_graphics(TRUE);
+               else {
+                       free((genericptr_t)symset);
+                       symset = (char *)0;
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+/* Parse the value of a SYMBOLS line from a config file */
+void
+parsesymbols(opts)
+register char *opts;
+{
+       int val;
+       char *op, *symname, *strval, *p;
+       struct symparse *symp;
+
+       if ((op = index(opts, ',')) != 0) {
+               *op++ = 0;
+               parsesymbols(op);
+       }
+
+       /* S_sample:string */
+       symname = opts;
+       strval = index(opts, ':');
+       if (!symname || !strval) return;
+       *strval++ = 0;
+
+       /* strip leading and trailing white space from symname */
+       while (isspace(*symname)) symname++;
+       p = eos(symname);
+       while (--p >= symname && isspace(*p)) *p = '\0';
+
+       /* strip leading and trailing white space from strval */
+       while (isspace(*strval)) strval++;
+       p = eos(strval);
+       while (--p >= strval && isspace(*p)) *p = '\0';
+
+       symp = match_sym(symname);
+       if (!symp) return;
+
+       if (symp->range && symp->range != SYM_CONTROL) {
+               val = sym_val(strval);
+               update_l_symset(symp, val);
+       }
+}
+
+struct symparse *
+match_sym(buf)
+char *buf;
+{
+       size_t len = strlen(buf);
+       const char *p = index(buf, ':'),
+                  *q = index(buf, '=');
+       struct symparse *sp = loadsyms;
+
+       if (!p || (q && q < p)) p = q;
+       while(p && p > buf && isspace(*(p-1))) p--;
+       if (p) len = (int)(p - buf);
+       while(sp->range) {
+           if ((len >= strlen(sp->name)) && !strncmpi(buf, sp->name, len))
+               return sp;
+           sp++;
+       }
+       return (struct symparse *)0;
+}
+
+int sym_val(strval)
+char *strval;
+{
+       char buf[QBUFSZ];
+       buf[0] = '\0';
+       escapes(strval, buf);
+       return (int)*buf;
+}
+#endif
 
 /* data for option_help() */
 static const char *opt_intro[] = {
@@ -3792,12 +3989,12 @@ char *class_select;
        selected = FALSE;
        switch (category) {
                case 0:
-                       text = monexplain[def_char_to_monclass(*class_list)];
+                       text = def_monsyms[def_char_to_monclass(*class_list)].explain;
                        accelerator = *class_list;
                        Sprintf(buf, "%s", text);
                        break;
                case 1:
-                       text = objexplain[def_char_to_objclass(*class_list)];
+                       text = def_oc_syms[def_char_to_objclass(*class_list)].explain;
                        accelerator = next_accelerator;
                        Sprintf(buf, "%c  %s", *class_list, text);
                        break;
index 0053370addcfbd13821885d003b7cfb155f85aeb..be3f359de04138a3ae7023ae607d1b9b7a432d29 100644 (file)
@@ -573,15 +573,15 @@ do_look(mode, click_cc)
 
        /* Check for monsters */
        for (i = 0; i < MAXMCLASSES; i++) {
-           if (sym == ((from_screen || clicklook) ? monsyms[i] : def_monsyms[i]) &&
-               monexplain[i]) {
+           if (sym == ((from_screen || clicklook) ? monsyms[i] : def_monsyms[i].sym) &&
+               def_monsyms[i].explain) {
                need_to_look = TRUE;
                if (!found) {
-                   Sprintf(out_str, "%c       %s", sym, an(monexplain[i]));
-                   firstmatch = monexplain[i];
+                   Sprintf(out_str, "%c       %s", sym, an(def_monsyms[i].explain));
+                   firstmatch = def_monsyms[i].explain;
                    found++;
                } else {
-                   found += append_str(out_str, an(monexplain[i]));
+                   found += append_str(out_str, an(def_monsyms[i].explain));
                }
            }
        }
@@ -590,7 +590,7 @@ do_look(mode, click_cc)
           symbol; firstmatch is assumed to already be set for '@' */
        if (((from_screen || clicklook) ?
                (sym == monsyms[S_HUMAN] && cc.x == u.ux && cc.y == u.uy) :
-               (sym == def_monsyms[S_HUMAN] && !flags.showrace)) &&
+               (sym == def_monsyms[S_HUMAN].sym && !flags.showrace)) &&
            !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd)
            found += append_str(out_str, "you");        /* tack on "or you" */
 
@@ -611,18 +611,18 @@ do_look(mode, click_cc)
 
        /* Now check for objects */
        for (i = 1; i < MAXOCLASSES; i++) {
-           if (sym == ((from_screen || clicklook) ? oc_syms[i] : def_oc_syms[i])) {
+           if (sym == ((from_screen || clicklook) ? oc_syms[i] : def_oc_syms[i].sym)) {
                need_to_look = TRUE;
                if ((from_screen || clicklook) && i == VENOM_CLASS) {
                    skipped_venom++;
                    continue;
                }
                if (!found) {
-                   Sprintf(out_str, "%c       %s", sym, an(objexplain[i]));
-                   firstmatch = objexplain[i];
+                   Sprintf(out_str, "%c       %s", sym, an(def_oc_syms[i].explain));
+                   firstmatch = def_oc_syms[i].explain;
                    found++;
                } else {
-                   found += append_str(out_str, an(objexplain[i]));
+                   found += append_str(out_str, an(def_oc_syms[i].explain));
                }
            }
        }
@@ -697,7 +697,7 @@ do_look(mode, click_cc)
     
        /* if we ignored venom and list turned out to be short, put it back */
        if (skipped_venom && found < 2) {
-           x_str = objexplain[VENOM_CLASS];
+           x_str = def_oc_syms[VENOM_CLASS].explain;
            if (!found) {
                Sprintf(out_str, "%c       %s", sym, an(x_str));
                firstmatch = x_str;
index d321930a379f96a91078090509fd63d824d33a53..678c5ffb27a7391bcc559de8b1c43ddd7e992bfa 100644 (file)
@@ -119,11 +119,11 @@ int *itemcount;
        *itemcount = 0;
 #ifndef GOLDOBJ
        if (incl_gold)
-           ilets[iletct++] = def_oc_syms[COIN_CLASS];
+           ilets[iletct++] = def_oc_syms[COIN_CLASS].sym;
 #endif
        ilets[iletct] = '\0'; /* terminate ilets so that index() will work */
        while (otmp) {
-           c = def_oc_syms[(int)otmp->oclass];
+           c = def_oc_syms[(int)otmp->oclass].sym;
            if (!index(ilets, c) && (!filter || (*filter)(otmp)))
                ilets[iletct++] = c,  ilets[iletct] = '\0';
            *itemcount += 1;
@@ -785,7 +785,7 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */
                    any.a_obj = curr;
                    add_menu(win, obj_to_glyph(curr), &any,
                            qflags & USE_INVLET ? curr->invlet : 0,
-                           def_oc_syms[(int)objects[curr->otyp].oc_class],
+                           def_oc_syms[(int)objects[curr->otyp].oc_class].sym,
                            ATR_NONE, doname(curr), MENU_UNSELECTED);
                }
            }
@@ -901,7 +901,7 @@ int how;                    /* type of query */
                        any = zeroany;
                        any.a_int = curr->oclass;
                        add_menu(win, NO_GLYPH, &any, invlet++,
-                               def_oc_syms[(int)objects[curr->otyp].oc_class],
+                               def_oc_syms[(int)objects[curr->otyp].oc_class].sym,
                                ATR_NONE, let_to_name(*pack, FALSE),
                                MENU_UNSELECTED);
                        collected_type_name = TRUE;
index f4356cf66c4b63f9fa4cc11117166913c9982283..8d848572cb46459da8009337a1abeecbe7f4f192 100644 (file)
@@ -1612,7 +1612,7 @@ do_class_genocide()
 
                if (strlen(buf) == 1) {
                    if (buf[0] == ILLOBJ_SYM)
-                       buf[0] = def_monsyms[S_MIMIC];
+                       buf[0] = def_monsyms[S_MIMIC].sym;
                    class = def_char_to_monclass(buf[0]);
                } else {
                    char buf2[BUFSZ];
@@ -1624,7 +1624,7 @@ do_class_genocide()
                immunecnt = gonecnt = goodcnt = 0;
                for (i = LOW_PM; i < NUMMONS; i++) {
                    if (class == 0 &&
-                           strstri(monexplain[(int)mons[i].mlet], buf) != 0)
+                           strstri(def_monsyms[(int)mons[i].mlet].explain, buf) != 0)
                        class = mons[i].mlet;
                    if (mons[i].mlet == class) {
                        if (!(mons[i].geno & G_GENO)) immunecnt++;
index e20898bf9582eace72d830c19d306a797b1b7b81..e2345b1195e0407b443bd66acac851c3ddfb1f9c 100644 (file)
@@ -113,7 +113,7 @@ struct obj *obj;
     case P_NONE:
        /* not a weapon: use item class name; override "food" for corpses */
        descr = (obj->otyp == CORPSE) ? "corpse" :
-               oclass_names[(int)obj->oclass];
+               def_oc_syms[(int)obj->oclass].name;
        break;
     case P_SLING:
        if (is_ammo(obj))
@@ -121,7 +121,7 @@ struct obj *obj;
                    /* avoid "rock"; what about known glass? */
                    (obj->oclass == GEM_CLASS) ? "gem" :
                    /* in case somebody adds odd sling ammo */
-                   oclass_names[(int)obj->oclass];
+                   def_oc_syms[(int)obj->oclass].name;
        break;
     case P_BOW:
        if (is_ammo(obj)) descr = "arrow";
index b95d014dda1399ce02ddbfb91aabcea2fc6cacf7..0fc586bf6aecd82f50be07b613cdfdfb419d477e 100644 (file)
@@ -949,6 +949,7 @@ install.tag:        $(DAT)\data     $(DAT)\rumors   $(DAT)\dungeon \
        if exist $(GAMEDIR)\makefile del $(GAMEDIR)\makefile
 ! ENDIF
        copy $(SYS)\termcap       $(GAMEDIR)
+       if exist $(DAT)\symbols copy $(DAT)\symbols $(GAMEDIR)
        if exist $(DOC)\guideb*.txt copy $(DOC)\guideb*.txt  $(GAMEDIR)
        if exist $(DOC)\nethack.txt copy $(DOC)\nethack.txt  $(GAMEDIR)\NetHack.txt
        if exist $(DOC)\recover.txt copy $(DOC)\recover.txt  $(GAMEDIR)
index d434f8d291a9bc5a2e6a1e0104f752263530af22..5fe1268ddd5a2d8fa13fce6878d13c02eb061ff9 100644 (file)
@@ -448,6 +448,7 @@ ifdef TERMLIB
        @$(subst /,\,copy $(SSHR)/termcap $(GAMEDIR))
 endif
        @$(subst /,\,if exist $(DAT)/*.tib copy $(DAT)/*.tib $(GAMEDIR))
+       @$(subst /,\,if exist $(DAT)/symbols copy $(DAT)/symbols $(GAMEDIR))
        @$(subst /,\,copy $(SSHR)/NetHack.cnf  $(GAMEDIR)/defaults.nh)
        @$(subst /,\,copy $(MSYS)/NHAccess.nh  $(GAMEDIR))
        @$(subst /,\,copy $(DOC)/guidebo*.txt  $(GAMEDIR))
index 8b33985cc11da40fde4c77b1d527c3529ebd0e78..8235a84e3e8479f815f6b9384a4596b29f7a3a8f 100644 (file)
@@ -396,6 +396,7 @@ $(O)install.tag:    $(DAT)\data     $(DAT)\rumors    $(DAT)\dungeon \
        copy $(DAT)\*.lev         $(GAMEDIR)
        if exist $(GAMEDIR)\makefile del $(GAMEDIR)\makefile
 ! ENDIF
+       if exist $(DAT)\symbols copy $(DAT)\symbols $(GAMEDIR)
        copy $(SSHR)\termcap      $(GAMEDIR)
        copy *.tib                $(GAMEDIR)
        copy $(SSHR)\NetHack.cnf  $(GAMEDIR)\defaults.nh
index 136bf5d12034dd5bbbaa8a1bed072910443c61b2..f96f782382661ab66a5bafb9385de89d58ced442 100644 (file)
@@ -547,7 +547,7 @@ boolean on;
 {
 /*     vga_HideCursor(); */
        if (on) {
-/*             switch_graphics(ASCII_GRAPHICS); */
+/*             switch_graphics(DEFAULT_GRAPHICS); */
                iflags.traditional_view = TRUE;
                clipx = 0;
                clipxmax = CO - 1;
index 23b5f0f46614a284ed21f6b076d4e35db6872540..648dff003a6c6ed87600a74f802588a89fe2019c 100644 (file)
@@ -19,7 +19,7 @@
 # The three options on this line should be used for most setups.  
 # If your machine isn't very IBM-compatible, and NetHack doesn't work, 
 # try commenting out this line.
-OPTIONS=rawio,BIOS,IBMgraphics
+OPTIONS=rawio,BIOS,symset:IBMGraphics_2,roguesymset:RogueEpyx
 
 # To use VGA graphical tiles on an MS-DOS PC with VGA or better,uncomment 
 # this:
index c5715f1c3441e127d26c2d2b7aa682db304efa2f..100ccd904b9e2687f81afe8f81b752dedc88f621 100644 (file)
@@ -299,7 +299,25 @@ char *argv[];
 #endif
 
 #ifdef MSDOS
+       /* We do this early for MSDOS because there are several
+        * display/tile related options that affect init_nhwindows()
+        */
        process_options(argc, argv);
+#endif
+
+#if defined(MSDOS) || defined(WIN32)
+       /* Player didn't specify any symbol set so use IBM defaults */
+       if (!symset) {
+               load_symset("IBMGraphics_2", FALSE);
+       }
+# ifdef REINCARNATION
+       if (!roguesymset) {
+               load_symset("IBMepyx", TRUE);
+       }
+# endif
+#endif
+
+#ifdef MSDOS
        init_nhwindows(&argc,argv);
 #else
        init_nhwindows(&argc,argv);
@@ -529,13 +547,22 @@ char *argv[];
 #ifndef AMIGA
                case 'I':
                case 'i':
-                       if (!strncmpi(argv[0]+1, "IBM", 3))
-                               switch_graphics(IBM_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "IBM", 3)) {
+# ifdef ASCIIGRAPH
+                               load_symset("IBMGraphics", FALSE);
+                               load_symset("IBMGraphics", TRUE);
+                               switch_graphics(TRUE);
+# endif
+                       }
                        break;
            /*  case 'D': */
                case 'd':
-                       if (!strncmpi(argv[0]+1, "DEC", 3))
-                               switch_graphics(DEC_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "DEC", 3)) {
+# ifdef ASCIIGRAPH
+                               load_symset("DECGraphics", FALSE);
+                               switch_graphics(TRUE);
+# endif
+                       }
                        break;
 #endif
                case 'g':
index efdb319333defe0f5faa9d5567127de2602e5bc4..27092eaf6a67e5f7be0b12b2d0f6982ff3a0b1b1 100644 (file)
@@ -365,7 +365,11 @@ init_sco_cons()
        if (!strcmp(windowprocs.name, "tty") && sco_flag_console) {
                atexit(sco_mapon);
                sco_mapoff();
-               switch_graphics(IBM_GRAPHICS);
+#  ifdef ASCIIGRAPH
+               load_symset("IBMGraphics", FALSE);
+               load_symset("IBMGraphics", TRUE);
+               switch_graphics(TRUE);
+#  endif
 #  ifdef TEXTCOLOR
                if (has_colors())
                        iflags.use_color = TRUE;
index b949e095bfdd091362d977286ab48d53a715ae92..214eaa9389e6befb62c229b1e666a404053c32ff 100644 (file)
@@ -369,13 +369,22 @@ char *argv[];
                        break;
                case 'I':
                case 'i':
-                       if (!strncmpi(argv[0]+1, "IBM", 3))
-                               switch_graphics(IBM_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "IBM", 3)) {
+#ifdef ASCIIGRAPH
+                               load_symset("IBMGraphics", FALSE);
+                               load_symset("IBMGraphics", TRUE);
+                               switch_graphics(TRUE);
+#endif
+                       }
                        break;
            /*  case 'D': */
                case 'd':
-                       if (!strncmpi(argv[0]+1, "DEC", 3))
-                               switch_graphics(DEC_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "DEC", 3)) {
+#ifdef ASCIIGRAPH
+                               load_symset("DECGraphics", FALSE);
+                               switch_graphics(TRUE);
+#endif
+                       }
                        break;
                case 'p': /* profession (role) */
                        if (argv[0][2]) {
index b8fd1850eb459b4ce50f4b51f49442a37a6bbdcb..a3fec4d8f6e7b197c758fadf4f50fde9e8d6ab9a 100644 (file)
@@ -268,13 +268,22 @@ char *argv[];
                        break;
                case 'I':
                case 'i':
-                       if (!strncmpi(argv[0]+1, "IBM", 3))
-                               switch_graphics(IBM_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "IBM", 3)) {
+#ifdef ASCIIGRAPH
+                               load_symset("IBMGraphics", FALSE);
+                               load_symset("IBMGraphics", TRUE);
+                               switch_graphics(TRUE);
+#endif
+                       }
                        break;
            /*  case 'D': */
                case 'd':
-                       if (!strncmpi(argv[0]+1, "DEC", 3))
-                               switch_graphics(DEC_GRAPHICS);
+                       if (!strncmpi(argv[0]+1, "DEC", 3)) {
+#ifdef ASCIIGRAPH
+                               load_symset("DECGraphics", FALSE);
+                               switch_graphics(TRUE);
+#endif
+                       }
                        break;
                case 'p': /* profession (role) */
                        if (argv[0][2]) {
index 01ea1ac7fa70953d845e541ccc7d8458932a60a6..1f40aea1d2f128dfa2c6f542c09b8c8bddf396e1 100644 (file)
@@ -155,7 +155,7 @@ HGDIOBJ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace)
 UINT mswin_charset()
 {
        CHARSETINFO cis;
-       if( iflags.IBMgraphics )
+       if( SYMHANDLING("IBM") )
                if( TranslateCharsetInfo((DWORD*)GetOEMCP(), &cis, TCI_SRCCODEPAGE) ) 
                        return cis.ciCharset;
                else
index ada559c2135425c353829c6545f7b71ca4c2cf3d..68b539374897904286ac49164476e265a236a0a2 100644 (file)
@@ -541,6 +541,7 @@ $(O)install.tag:    $(DAT)\data     $(DAT)\rumors    $(DAT)\dungeon \
        copy $(DAT)\*.lev         $(GAMEDIR)
        if exist $(GAMEDIR)\makefile del $(GAMEDIR)\makefile
 ! ENDIF
+       if exist $(DAT)\symbols copy $(DAT)\symbols $(GAMEDIR)
        if exist $(DOC)\guidebook.txt copy $(DOC)\guidebook.txt $(GAMEDIR)\Guidebook.txt
        if exist $(DOC)\nethack.txt copy $(DOC)\nethack.txt $(GAMEDIR)\NetHack.txt
        @if exist $(SRC)\$(GAME).PDB copy $(SRC)\$(GAME).pdb $(GAMEDIR)\$(GAME).pdb
index 8d66ea18d087cf27ab6f6bdf9a14d6c7c3809478..5a020951d2e43f0e4922022534fcabe3339bf15f 100644 (file)
@@ -505,6 +505,7 @@ else
        $(subst /,\,copy $(DAT)/*.lev         $(GAMEDIR))
        $(subst /,\,if exist $(GAMEDIR)/makefile del $(GAMEDIR)/makefile)
 endif
+       $(subst /,\,if exist $(DAT)/symbols copy $(DAT)/symbols $(GAMEDIR))
        $(subst /,\,if exist $(DOC)/guidebook.txt copy $(DOC)/guidebook.txt $(GAMEDIR)/Guidebook.txt)
        $(subst /,\,if exist $(DOC)/nethack.txt copy $(DOC)/nethack.txt $(GAMEDIR)/NetHack.txt)
        $(subst /,\,copy $(NTSYS)/defaults.nh   $(GAMEDIR)/defaults.nh)
index f23787304244832508839299d3a3e8a24e06428b..2623805d81e4110e5256451a29e86c2f990e47ae 100644 (file)
@@ -510,6 +510,7 @@ $(O)install.tag:    $(DAT)\data     $(DAT)\rumors    $(DAT)\dungeon \
        copy $(DAT)\*.lev         $(GAMEDIR)
        if exist $(GAMEDIR)\makefile del $(GAMEDIR)\makefile
 ! ENDIF
+       if exist $(DAT)\symbols copy $(DAT)\symbols $(GAMEDIR)
        if exist $(DOC)\guidebook.txt copy $(DOC)\guidebook.txt $(GAMEDIR)\Guidebook.txt
        if exist $(DOC)\nethack.txt copy $(DOC)\nethack.txt $(GAMEDIR)\NetHack.txt
        @if exist $(O)$(GAME).PDB copy $(O)$(GAME).pdb $(GAMEDIR)\$(GAME).pdb
index be1d53ef78332476cbe7be3c548a88a70187cf83..c5a1fdf381cede91f71fc1950dd3f3f553c4eb91 100644 (file)
@@ -11,7 +11,7 @@
 #
 # Use the IBM character set rather than just plain ascii characters
 # for tty window-port.
-OPTIONS=IBMGraphics
+OPTIONS=symset:IBMGraphics_2,roguesymset:RogueEpyx
 
 # Keyboard handling
 # Different keyboard handlers can be loaded.
index b9a8bcf1aadbe04f7f082286a4652cba51c9942c..f6312f2d6351a413d9360f9a25a9c27162142f61 100644 (file)
@@ -386,7 +386,7 @@ tty_decgraphics_termcap_fixup()
         * Do not select NA ASCII as the primary font since people may
         * reasonably be using the UK character set.
         */
-       if (iflags.DECgraphics) xputs("\033)0");
+       if (SYMHANDLING("DEC")) xputs("\033)0");
 #ifdef PC9800
        init_hilite();
 #endif
@@ -449,19 +449,19 @@ tty_start_screen()
        xputs(TI);
        xputs(VS);
 #ifdef PC9800
-    if (!iflags.IBMgraphics && !iflags.DECgraphics)
+    if (!SYMHANDLING("IBM"))
            tty_ascgraphics_hilite_fixup();
     /* set up callback in case option is not set yet but toggled later */
     ascgraphics_mode_callback = tty_ascgraphics_hilite_fixup;
 # ifdef ASCIIGRAPH
-    if (iflags.IBMgraphics) init_hilite();
+    if (SYMHANDLING("IBM")) init_hilite();
     /* set up callback in case option is not set yet but toggled later */
     ibmgraphics_mode_callback = init_hilite;
 # endif
 #endif /* PC9800 */
 
 #ifdef TERMLIB
-       if (iflags.DECgraphics) tty_decgraphics_termcap_fixup();
+       if (SYMHANDLING("DEC")) tty_decgraphics_termcap_fixup();
        /* set up callback in case option is not set yet but toggled later */
        decgraphics_mode_callback = tty_decgraphics_termcap_fixup;
 #endif
index 3a6a09e4065cc8d983a8850ccaa0c8f1c6b973e9..6907cad478966db211a5992790f3747f901f42ed 100644 (file)
@@ -2402,7 +2402,7 @@ int in_ch;
     register char ch = (char)in_ch;
 
 # if defined(ASCIIGRAPH) && !defined(NO_TERMS)
-    if (iflags.IBMgraphics || iflags.eight_bit_tty) {
+    if (SYMHANDLING("IBM") || iflags.eight_bit_tty) {
        /* IBM-compatible displays don't need other stuff */
        (void) putchar(ch);
     } else if (ch & 0x80) {
index 39f3c0ef8f0a3578e55874e72e77c474479c53b5..2e3554f49739811d3711ea1625e6abd40aa78978 100644 (file)
@@ -183,7 +183,7 @@ HGDIOBJ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace)
 UINT mswin_charset()
 {
        CHARSETINFO cis;
-       if( iflags.IBMgraphics )
+       if( SYMHANDLING("IBM") )
                if( TranslateCharsetInfo((DWORD*)GetOEMCP(), &cis, TCI_SRCCODEPAGE) ) 
                        return cis.ciCharset;
                else