OSDN Git Service

update year to 2020
[jnethack/source.git] / src / options.c
index a3e6123..75dcf6f 100644 (file)
@@ -1,11 +1,11 @@
-/* NetHack 3.6 options.c       $NHDT-Date: 1510963525 2017/11/18 00:05:25 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.319 $ */
+/* NetHack 3.6 options.c       $NHDT-Date: 1578996303 2020/01/14 10:05:03 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.396 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2008. */
 /* NetHack may be freely redistributed.  See license for details. */
 
 /* JNetHack Copyright */
 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018            */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #ifdef OPTION_LISTS_ONLY /* (AMIGA) external program for opt lists */
@@ -25,7 +25,6 @@ NEARDATA struct instance_flags iflags; /* provide linkage */
 #endif
 
 #define BACKWARD_COMPAT
-#define WINTYPELEN 16
 
 #ifdef DEFAULT_WC_TILED_MAP
 #define PREFER_TILED TRUE
@@ -33,6 +32,11 @@ NEARDATA struct instance_flags iflags; /* provide linkage */
 #define PREFER_TILED FALSE
 #endif
 
+#ifdef CURSES_GRAPHICS
+extern int curses_read_attrs(const char *attrs);
+extern char *curses_fmt_attrs(char *);
+#endif
+
 enum window_option_types {
     MESSAGE_OPTION = 1,
     STATUS_OPTION,
@@ -43,6 +47,8 @@ enum window_option_types {
 
 #define PILE_LIMIT_DFLT 5
 
+static char empty_optstr[] = { '\0' };
+
 /*
  *  NOTE:  If you add (or delete) an option, please update the short
  *  options help (option_help()), the long options help (dat/opthelp),
@@ -83,7 +89,7 @@ static struct Bool_Opt {
 #else
     { "asksavedisk", (boolean *) 0, FALSE, SET_IN_FILE },
 #endif
-    { "autodescribe", &iflags.autodescribe, FALSE, SET_IN_GAME },
+    { "autodescribe", &iflags.autodescribe, TRUE, SET_IN_GAME },
     { "autodig", &flags.autodig, FALSE, SET_IN_GAME },
     { "autoopen", &flags.autoopen, TRUE, SET_IN_GAME },
     { "autopickup", &flags.pickup, TRUE, SET_IN_GAME },
@@ -107,15 +113,15 @@ static struct Bool_Opt {
 #endif
     { "clicklook", &iflags.clicklook, FALSE, SET_IN_GAME },
     { "cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME },
-#if defined(MICRO) || defined(WIN32)
-    { "color", &iflags.wc_color, TRUE, SET_IN_GAME }, /*WC*/
+#if defined(MICRO) || defined(WIN32) || defined(CURSES_GRAPHICS)
+    { "color", &iflags.wc_color, TRUE, SET_IN_GAME }, /* on/off: use WC or not */
 #else /* systems that support multiple terminals, many monochrome */
-    { "color", &iflags.wc_color, FALSE, SET_IN_GAME }, /*WC*/
+    { "color", &iflags.wc_color, FALSE, SET_IN_GAME },
 #endif
     { "confirm", &flags.confirm, TRUE, SET_IN_GAME },
     { "dark_room", &flags.dark_room, TRUE, SET_IN_GAME },
     { "eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME }, /*WC*/
-#ifdef TTY_GRAPHICS
+#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) || defined(X11_GRAPHICS)
     { "extmenu", &iflags.extmenu, FALSE, SET_IN_GAME },
 #else
     { "extmenu", (boolean *) 0, FALSE, SET_IN_FILE },
@@ -133,8 +139,9 @@ static struct Bool_Opt {
     { "flush", (boolean *) 0, FALSE, SET_IN_FILE },
 #endif
     { "force_invmenu", &iflags.force_invmenu, FALSE, SET_IN_GAME },
-    { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE },
+    { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE }, /*WC2*/
     { "goldX", &iflags.goldX, FALSE, SET_IN_GAME },
+    { "guicolor", &iflags.wc2_guicolor, TRUE, SET_IN_GAME}, /*WC2*/
     { "help", &flags.help, TRUE, SET_IN_GAME },
     { "herecmd_menu", &iflags.herecmd_menu, FALSE, SET_IN_GAME },
     { "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/
@@ -165,7 +172,7 @@ static struct Bool_Opt {
 #else
     { "menu_overlay", (boolean *) 0, FALSE, SET_IN_FILE },
 #endif
-    { "mouse_support", &iflags.wc_mouse_support, TRUE, DISP_IN_GAME }, /*WC*/
+    { "monpolycontrol", &iflags.mon_polycontrol, FALSE, SET_IN_WIZGAME },
 #ifdef NEWS
     { "news", &iflags.news, TRUE, DISP_IN_GAME },
 #else
@@ -178,7 +185,8 @@ static struct Bool_Opt {
 #else
     { "page_wait", (boolean *) 0, FALSE, SET_IN_FILE },
 #endif
-    { "perm_invent", &flags.perm_invent, FALSE, SET_IN_GAME },
+    /* moved perm_invent from flags to iflags and out of save file in 3.6.2 */
+    { "perm_invent", &iflags.perm_invent, FALSE, SET_IN_GAME },
     { "pickup_thrown", &flags.pickup_thrown, TRUE, SET_IN_GAME },
     { "popup_dialog", &iflags.wc_popup_dialog, FALSE, SET_IN_GAME },   /*WC*/
     { "preload_tiles", &iflags.wc_preload_tiles, TRUE, DISP_IN_GAME }, /*WC*/
@@ -209,7 +217,7 @@ static struct Bool_Opt {
     { "showscore", (boolean *) 0, FALSE, SET_IN_FILE },
 #endif
     { "silent", &flags.silent, TRUE, SET_IN_GAME },
-    { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE },
+    { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE }, /*WC2*/
     { "sortpack", &flags.sortpack, TRUE, SET_IN_GAME },
     { "sparkle", &flags.sparkle, TRUE, SET_IN_GAME },
     { "splash_screen", &iflags.wc_splash_screen, TRUE, DISP_IN_GAME }, /*WC*/
@@ -225,7 +233,10 @@ static struct Bool_Opt {
     { "tombstone", &flags.tombstone, TRUE, SET_IN_GAME },
     { "toptenwin", &iflags.toptenwin, FALSE, SET_IN_GAME },
     { "travel", &flags.travelcmd, TRUE, SET_IN_GAME },
-    { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE },
+#ifdef DEBUG
+    { "travel_debug", &iflags.trav_debug, FALSE, SET_IN_WIZGAME }, /*hack.c*/
+#endif
+    { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE }, /*WC2*/
 #ifdef WIN32
     { "use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME }, /*WC*/
 #else
@@ -240,7 +251,7 @@ static struct Bool_Opt {
     { "whatis_menu", &iflags.getloc_usemenu, FALSE, SET_IN_GAME },
     { "whatis_moveskip", &iflags.getloc_moveskip, FALSE, SET_IN_GAME },
     { "wizweight", &iflags.wizweight, FALSE, SET_IN_WIZGAME },
-    { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME },
+    { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, /*WC2*/
 #ifdef ZEROCOMP
     { "zerocomp", &iflags.zerocomp,
 #if defined(COMPRESS) || defined(ZLIB_COMP)
@@ -269,20 +280,20 @@ static struct Comp_Opt {
 */
     { "align",    "\83Q\81[\83\80\83X\83^\81[\83g\8e\9e\82Ì\91®\90« (lawful, neutral, or chaotic\82Ì\82¢\82¸\82ê\82©)", 8,
       DISP_IN_GAME },
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "align_message", "message window alignment", 20, DISP_IN_GAME }, /*WC*/
 #else
     { "align_message", "\83\81\83b\83Z\81[\83W\83E\83B\83\93\83h\83E\82Ì\91µ\82¦", 20, DISP_IN_GAME }, /*WC*/
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "align_status", "status window alignment", 20, DISP_IN_GAME },   /*WC*/
 #else
     { "align_status", "\8fó\8bµ\83E\83B\83\93\83h\83E\82Ì\91µ\82¦", 20, DISP_IN_GAME }, /*WC*/
 #endif
 /*JP
-    { "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
+    { "altkeyhandler", "alternate key handler", 20, SET_IN_GAME },
 */
-    { "altkeyhandler", "ALT\83L\81[\83n\83\93\83h\83\89", 20, DISP_IN_GAME },
+    { "altkeyhandler", "ALT\83L\81[\83n\83\93\83h\83\89", 20, SET_IN_GAME },
 #ifdef BACKWARD_COMPAT
 /*JP
     { "boulder", "deprecated (use S_boulder in sym file instead)", 1,
@@ -299,7 +310,7 @@ static struct Comp_Opt {
     { "disclose", "the kinds of information to disclose at end of game",
 */
     { "disclose", "\83Q\81[\83\80\8fI\97¹\8e\9e\82É\8c©\82é\8fî\95ñ\82Ì\8eí\97Þ",
-      sizeof(flags.end_disclose) * 2, SET_IN_GAME },
+      sizeof flags.end_disclose * 2, SET_IN_GAME },
 /*JP
     { "dogname", "the name of your (first) dog (e.g., dogname:Fang)", PL_PSIZ,
 */
@@ -320,7 +331,7 @@ static struct Comp_Opt {
 */
     { "font_map", "\83}\83b\83v\83E\83B\83\93\83h\83E\82É\8eg\97p\82·\82é\83t\83H\83\93\83g", 40,
       DISP_IN_GAME },                                              /*WC*/
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "font_menu", "the font to use in menus", 40, DISP_IN_GAME }, /*WC*/
 #else
     { "font_menu", "\83\81\83j\83\85\81[\82É\8eg\97p\82·\82é\83t\83H\83\93\83g", 40, DISP_IN_GAME }, /*WC*/
@@ -330,7 +341,7 @@ static struct Comp_Opt {
 */
     { "font_message", "\83\81\83b\83Z\81[\83W\83E\83B\83\93\83h\83E\82É\8eg\97p\82·\82é\83t\83H\83\93\83g", 40,
       DISP_IN_GAME },                                                  /*WC*/
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "font_size_map", "the size of the map font", 20, DISP_IN_GAME }, /*WC*/
 #else
     { "font_size_map", "\83}\83b\83v\83t\83H\83\93\83g\82Ì\83T\83C\83Y", 20, DISP_IN_GAME }, /*WC*/
@@ -378,7 +389,7 @@ static struct Comp_Opt {
 */
     { "horsename", "\96`\8c¯\82ð\8b\9f\82É\82·\82é(\8dÅ\8f\89\82Ì)\94n\82Ì\96¼\91O (\97á ghoulname:\83V\83\8b\83o\81[)",
       PL_PSIZ, DISP_IN_GAME },
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "map_mode", "map display mode under Windows", 20, DISP_IN_GAME }, /*WC*/
 #else
     { "map_mode", "\83E\83B\83\93\83h\83E\95\\8e¦\8e\9e\82Ì\83}\83b\83v\82Ì\95\\8e¦\83\82\81[\83h", 20, DISP_IN_GAME }, /*WC*/
@@ -448,22 +459,23 @@ static struct Comp_Opt {
     { "msghistory", "number of top line messages to save", 5, DISP_IN_GAME },
 */
     { "msghistory", "\90æ\93ª\8ds\82É\95\\8e¦\82³\82ê\82½\83\81\83b\83Z\81[\83W\97\9a\97ð\82Ì\95Û\91\90\94", 5, DISP_IN_GAME },
-#ifdef TTY_GRAPHICS
+#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
 /*JP
     { "msg_window", "the type of message window required", 1, SET_IN_GAME },
 */
-    {"msg_window", "\83\81\83b\83Z\81[\83W\83E\83B\83\93\83h\83E\82Ì\83^\83C\83v\82ð\90Ý\92è",1, SET_IN_GAME },
+    { "msg_window", "\83\81\83b\83Z\81[\83W\83E\83B\83\93\83h\83E\82Ì\83^\83C\83v\82ð\90Ý\92è",1, SET_IN_GAME },
 #else
 /*JP
     { "msg_window", "the type of message window required", 1, SET_IN_FILE },
 */
-    {"msg_window", "\83\81\83b\83Z\81[\83W\83E\83B\83\93\83h\83E\82Ì\83^\83C\83v\82ð\90Ý\92è", 1, SET_IN_FILE },
+    { "msg_window", "\83\81\83b\83Z\81[\83W\83E\83B\83\93\83h\83E\82Ì\83^\83C\83v\82ð\90Ý\92è", 1, SET_IN_FILE },
 #endif
 /*JP
     { "name", "your character's name (e.g., name:Merlin-W)", PL_NSIZ,
 */
     { "name", "\82 \82È\82½\82Ì\96¼\91O (\97á name:\83}\81[\83\8a\83\93-W)", PL_NSIZ,
       DISP_IN_GAME },
+    { "mouse_support", "game receives click info from mouse", 0, SET_IN_GAME },
 /*JP
     { "number_pad", "use the number pad for movement", 1, SET_IN_GAME },
 */
@@ -481,17 +493,16 @@ static struct Comp_Opt {
     { "palette",
 #ifndef WIN32
 /*JP
-      "palette (00c/880/-fff is blue/yellow/reverse white)", 15,
+      "palette (00c/880/-fff is blue/yellow/reverse white)", 15, SET_IN_GAME
 */
-      "\83p\83\8c\83b\83g (00c/880/-fff\82Í\82»\82ê\82¼\82ê\90Â/\89©/\94½\93]\94\92\82ð\8e¦\82·)", 15,
-      SET_IN_GAME },
+      "\83p\83\8c\83b\83g (00c/880/-fff\82Í\82»\82ê\82¼\82ê\90Â/\89©/\94½\93]\94\92\82ð\8e¦\82·)", 15, SET_IN_GAME
 #else
 /*JP
-      "palette (adjust an RGB color in palette (color-R-G-B)", 15,
+      "palette (adjust an RGB color in palette (color-R-G-B)", 15, SET_IN_FILE
 */
-      "\83p\83\8c\83b\83g (\83p\83\8c\83b\83g\82ÌRGB\90F\82ð\92²\90®\82·\82é (\90F-R-G-B)", 15,
-      SET_IN_FILE },
+      "\83p\83\8c\83b\83g (\83p\83\8c\83b\83g\82ÌRGB\90F\82ð\92²\90®\82·\82é (\90F-R-G-B)", 15, SET_IN_FILE
 #endif
+    },
 #if defined(MAC)
 /*JP
     { "hicolor", "same as palette, only order is reversed", 15, SET_IN_FILE },
@@ -499,13 +510,14 @@ static struct Comp_Opt {
     { "hicolor",  "\83p\83\8c\83b\83g\82ª\93¯\82\82Æ\82«\81A\8ew\8e¦\82µ\82½\82à\82Ì\82¾\82¯\94½\93]\82³\82¹\82é", 15, SET_IN_FILE },
 #endif
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "paranoid_confirmation", "extra prompting in certain situations", 28,
       SET_IN_GAME },
 #else
     { "paranoid_confirmation", "\88ê\95\94\82Ì\8fó\8bµ\82Å\92Ç\89Á\82Ì\8am\94F\82ð\82·\82é", 28,
       SET_IN_GAME },
 #endif
+    { "petattr",  "attributes for highlighting pets", 88, SET_IN_GAME },
 /*JP
     { "pettype", "your preferred initial pet type", 4, DISP_IN_GAME },
 */
@@ -520,14 +532,14 @@ static struct Comp_Opt {
 */
     { "pickup_types", "\8e©\93®\82Å\8fE\82¢\82 \82°\82é\95¨\82Ì\83V\83\93\83{\83\8b",
       MAXOCLASSES, SET_IN_GAME },
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "pile_limit", "threshold for \"there are many objects here\"", 24,
       SET_IN_GAME },
 #else
     { "pile_limit", "\81u\82±\82±\82É\82Í\82½\82­\82³\82ñ\82Ì\82à\82Ì\82ª\82 \82é\81v\82Ì\82µ\82«\82¢\92l", 24,
       SET_IN_GAME },
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "playmode", "normal play, non-scoring explore mode, or debug mode", 8,
       DISP_IN_GAME },
 #else
@@ -580,29 +592,38 @@ static struct Comp_Opt {
 */
     { "soundcard", "\8eg\97p\82µ\82Ä\82¢\82é\83T\83E\83\93\83h\83J\81[\83h\82Ì\8eí\97Þ", 20, SET_IN_FILE },
 #endif
-#ifdef STATUS_HILITES
-#if 0 /*JP*/
     { "statushilites",
+#ifdef STATUS_HILITES
+#if 0 /*JP:T*/
       "0=no status highlighting, N=show highlights for N turns",
 #else
-    { "statushilites",
       "0=\83X\83e\81[\83^\83X\83n\83C\83\89\83C\83g\82È\82µ\81CN\83^\81[\83\93\96\88\82É\83n\83C\83\89\83C\83g\95\\8e¦",
 #endif
-      20, SET_IN_GAME },
+      20, SET_IN_GAME
 #else
 /*JP
-    { "statushilites", "highlight control", 20, SET_IN_FILE },
+    "highlight control", 20, SET_IN_FILE
 */
-    { "statushilites", "\83n\83C\83\89\83C\83g\82Ì\90§\8cä", 20, SET_IN_FILE },
+    "\83n\83C\83\89\83C\83g\82Ì\90§\8cä", 20, SET_IN_FILE
 #endif
-#if 0 /*JP*/
+    },
+    { "statuslines",
+#ifdef CURSES_GRAPHICS
+      "2 or 3 lines for horizontal (bottom or top) status display",
+      20, SET_IN_GAME
+#else
+      "2 or 3 lines for status display",
+      20, SET_IN_FILE
+#endif
+    }, /*WC2*/
+#if 0 /*JP:T*/
     { "symset", "load a set of display symbols from the symbols file", 70,
       SET_IN_GAME },
 #else
     { "symset", "symbols\83t\83@\83C\83\8b\82©\82ç\95\\8e¦\83V\83\93\83{\83\8b\82Ì\90Ý\92è\82ð\93Ç\82Ý\8d\9e\82Þ", 70,
       SET_IN_GAME },
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "roguesymset",
       "load a set of rogue display symbols from the symbols file", 70,
       SET_IN_GAME },
@@ -615,24 +636,27 @@ static struct Comp_Opt {
 /*JP
     { "subkeyvalue", "override keystroke value", 7, SET_IN_FILE },
 */
-    {"subkeyvalue", "\83L\81[\83}\83b\83s\83\93\83O\82ð\95Ï\8dX\82·\82é", 7, SET_IN_FILE },
+    { "subkeyvalue", "\83L\81[\83}\83b\83s\83\93\83O\82ð\95Ï\8dX\82·\82é", 7, SET_IN_FILE },
 #endif
 /*JP
     { "suppress_alert", "suppress alerts about version-specific features", 8,
 */
     { "suppress_alert", "\83o\81[\83W\83\87\83\93\8aÔ\82Ì\88á\82¢\82É\8aÖ\82·\82é\8cx\8d\90\83\81\83b\83Z\81[\83W\82Ì\96³\8cø\89»", 8,
       SET_IN_GAME },
-#if 0 /*JP*/
+    /* term_cols,term_rows -> WC2_TERM_SIZE (6: room to format 1..32767) */
+    { "term_cols", "number of columns", 6, SET_IN_FILE }, /*WC2*/
+    { "term_rows", "number of rows", 6, SET_IN_FILE }, /*WC2*/
+#if 0 /*JP:T*/
     { "tile_width", "width of tiles", 20, DISP_IN_GAME },   /*WC*/
 #else
     { "tile_width", "\83^\83C\83\8b\82Ì\95\9d", 20, DISP_IN_GAME },   /*WC*/
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "tile_height", "height of tiles", 20, DISP_IN_GAME }, /*WC*/
 #else
     { "tile_height", "\83^\83C\83\8b\82Ì\8d\82\82³", 20, DISP_IN_GAME }, /*WC*/
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "tile_file", "name of tile file", 70, DISP_IN_GAME }, /*WC*/
 #else
     { "tile_file", "\83^\83C\83\8b\83t\83@\83C\83\8b\82Ì\96¼\91O", 70, DISP_IN_GAME }, /*WC*/
@@ -665,14 +689,14 @@ static struct Comp_Opt {
     { "videoshades", "\95\\8e¦\82É\83O\83\8c\83C\83X\83P\81[\83\8b\82ð\97p\82¢\82é", 32,
       DISP_IN_GAME },
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "whatis_coord", "show coordinates when auto-describing cursor position",
       1, SET_IN_GAME },
 #else
     { "whatis_coord", "\83J\81[\83\\83\8b\88Ê\92u\82ð\8e©\93®\90à\96¾\82·\82é\82Æ\82«\82É\8dÀ\95W\82ð\95\\8e¦\82·\82é",
       1, SET_IN_GAME },
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     { "whatis_filter",
       "filter coordinate locations when targeting next or previous",
       1, SET_IN_GAME },
@@ -681,7 +705,8 @@ static struct Comp_Opt {
       "\8e\9f\82â\8eè\91O\82ð\83^\81[\83Q\83b\83g\82·\82é\82Æ\82«\82É\8dÀ\95W\88Ê\92u\82ð\83t\83B\83\8b\83^\82·\82é",
       1, SET_IN_GAME },
 #endif
-#if 0 /*JP*/
+    { "windowborders", "0 (off), 1 (on), 2 (auto)", 9, SET_IN_GAME }, /*WC2*/
+#if 0 /*JP:T*/
     { "windowcolors", "the foreground/background colors of windows", /*WC*/
       80, DISP_IN_GAME },
 #else
@@ -707,6 +732,9 @@ static struct Comp_Opt {
     { "IBMgraphics", "load IBMGraphics display symbols", 70, SET_IN_FILE },
 */
     { "IBMgraphics", "IBMGraphics\95\\8e¦\83V\83\93\83{\83\8b\82ð\93Ç\82Ý\8d\9e\82Þ", 70, SET_IN_FILE },
+#ifdef CURSES_GRAPHICS
+    { "cursesgraphics", "load curses display symbols", 70, SET_IN_FILE },
+#endif
 #ifdef MAC_GRAPHICS_ENV
 /*JP
     { "Macgraphics", "load MACGraphics display symbols", 70, SET_IN_FILE },
@@ -828,7 +856,6 @@ STATIC_DCL int NDECL(count_menucolors);
 STATIC_DCL boolean FDECL(parse_role_opts, (BOOLEAN_P, const char *,
                                            char *, char **));
 
-STATIC_DCL void FDECL(oc_to_str, (char *, char *));
 STATIC_DCL void FDECL(doset_add_menu, (winid, const char *, int));
 STATIC_DCL void FDECL(opts_add_others, (winid, const char *, int,
                                         char *, int));
@@ -838,7 +865,6 @@ STATIC_DCL boolean FDECL(special_handling, (const char *,
 STATIC_DCL const char *FDECL(get_compopt_value, (const char *, char *));
 STATIC_DCL void FDECL(remove_autopickup_exception,
                       (struct autopickup_exception *));
-STATIC_DCL int FDECL(count_ape_maps, (int *, int *));
 
 STATIC_DCL boolean FDECL(is_wc_option, (const char *));
 STATIC_DCL boolean FDECL(wc_supported, (const char *));
@@ -939,7 +965,7 @@ initoptions()
 
     /* ... and _must_ parse correctly. */
     if (!read_config_file(SYSCF_FILE, SET_IN_SYS)) {
-        if (config_error_done())
+        if (config_error_done() && !iflags.initoptions_noterminate)
             nh_terminate(EXIT_FAILURE);
     }
     config_error_done();
@@ -955,7 +981,7 @@ initoptions()
 void
 initoptions_init()
 {
-#if defined(UNIX) || defined(VMS)
+#if (defined(UNIX) || defined(VMS)) && defined(TTY_GRAPHICS)
     char *opts;
 #endif
     int i;
@@ -963,8 +989,9 @@ initoptions_init()
     /* set up the command parsing */
     reset_commands(TRUE); /* init */
 
-    /* initialize the random number generator */
-    setrandom();
+    /* initialize the random number generator(s) */
+    init_random(rn2);
+    init_random(rn2_on_display_rng);
 
     /* for detection of configfile options specified multiple times */
     iflags.opt_booldup = iflags.opt_compdup = (int *) 0;
@@ -992,7 +1019,7 @@ initoptions_init()
 #endif
 #ifdef SYSFLAGS
     Strcpy(sysflags.sysflagsid, "sysflags");
-    sysflags.sysflagsid[9] = (char) sizeof(struct sysflag);
+    sysflags.sysflagsid[9] = (char) sizeof (struct sysflag);
 #endif
     flags.end_own = FALSE;
     flags.end_top = 3;
@@ -1001,8 +1028,13 @@ initoptions_init()
     flags.pile_limit = PILE_LIMIT_DFLT;  /* 5 */
     flags.runmode = RUN_LEAP;
     iflags.msg_history = 20;
+    /* msg_window has conflicting defaults for multi-interface binary */
 #ifdef TTY_GRAPHICS
     iflags.prevmsg_window = 's';
+#else
+#ifdef CURSES_GRAPHICS
+    iflags.prevmsg_window = 'r';
+#endif
 #endif
     iflags.menu_headings = ATR_INVERSE;
     iflags.getpos_coords = GPCOORDS_NONE;
@@ -1011,13 +1043,12 @@ initoptions_init()
     flags.initrole = flags.initrace = flags.initgend = flags.initalign
         = ROLE_NONE;
 
+    init_ov_primary_symbols();
+    init_ov_rogue_symbols();
     /* 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;
 
     /* for "special achievement" tracking (see obj.h,
        create_object(sp_lev.c), addinv_core1(invent.c) */
@@ -1035,6 +1066,7 @@ initoptions_init()
     for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
         flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
     switch_symbols(FALSE); /* set default characters */
+    init_rogue_symbols();
 #if defined(UNIX) && defined(TTY_GRAPHICS)
     /*
      * Set defaults for some options depending on what we can
@@ -1045,9 +1077,9 @@ initoptions_init()
      */
     /* this detects the IBM-compatible console on most 386 boxes */
     if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
-        if (!symset[PRIMARY].name)
+        if (!symset[PRIMARY].explicitly)
             load_symset("IBMGraphics", PRIMARY);
-        if (!symset[ROGUESET].name)
+        if (!symset[ROGUESET].explicitly)
             load_symset("RogueIBM", ROGUESET);
         switch_symbols(TRUE);
 #ifdef TEXTCOLOR
@@ -1062,20 +1094,34 @@ initoptions_init()
         /* [could also check "xterm" which emulates vtXXX by default] */
         && !strncmpi(opts, "vt", 2)
         && AS && AE && index(AS, '\016') && index(AE, '\017')) {
-        if (!symset[PRIMARY].name)
+        if (!symset[PRIMARY].explicitly)
             load_symset("DECGraphics", PRIMARY);
         switch_symbols(TRUE);
     }
 #endif
 #endif /* UNIX || VMS */
 
+#if defined(MSDOS) || defined(WIN32)
+    /* Use IBM defaults. Can be overridden via config file */
+    if (!symset[PRIMARY].explicitly)
+        load_symset("IBMGraphics_2", PRIMARY);
+    if (!symset[ROGUESET].explicitly)
+        load_symset("RogueEpyx", ROGUESET);
+#endif
 #ifdef MAC_GRAPHICS_ENV
-    if (!symset[PRIMARY].name)
+    if (!symset[PRIMARY].explicitly)
         load_symset("MACGraphics", PRIMARY);
     switch_symbols(TRUE);
 #endif /* MAC_GRAPHICS_ENV */
     flags.menu_style = MENU_FULL;
 
+    iflags.wc_align_message = ALIGN_TOP;
+    iflags.wc_align_status = ALIGN_BOTTOM;
+    /* used by tty and curses */
+    iflags.wc2_statuslines = 2;
+    /* only used by curses */
+    iflags.wc2_windowborders = 2; /* 'Auto' */
+
     /* since this is done before init_objects(), do partial init here */
     objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
     nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
@@ -1084,6 +1130,7 @@ initoptions_init()
 void
 initoptions_finish()
 {
+    nhsym sym = 0;
 #ifndef MAC
     char *opts = getenv("NETHACKOPTIONS");
 
@@ -1127,8 +1174,10 @@ initoptions_finish()
      */
     obj_descr[SLIME_MOLD].oc_name = "fruit";
 
-    if (iflags.bouldersym)
-        update_bouldersym();
+    sym = get_othersym(SYM_BOULDER,
+                Is_rogue_level(&u.uz) ? ROGUESET : PRIMARY);
+    if (sym)
+        showsyms[SYM_BOULDER + SYM_OFF_X] = sym;
     reglyph_darkroom();
 
 #ifdef STATUS_HILITES
@@ -1136,16 +1185,23 @@ initoptions_finish()
      * A multi-interface binary might only support status highlighting
      * for some of the interfaces; check whether we asked for it but are
      * using one which doesn't.
+     *
+     * Option processing can take place before a user-decided WindowPort
+     * is even initialized, so check for that too.
      */
-    if (iflags.hilite_delta && !wc2_supported("statushilites")) {
-        raw_printf("Status highlighting not supported for %s interface.",
-                   windowprocs.name);
-        iflags.hilite_delta = 0;
+    if (!WINDOWPORT("safe-startup")) {
+        if (iflags.hilite_delta && !wc2_supported("statushilites")) {
+            raw_printf("Status highlighting not supported for %s interface.",
+                       windowprocs.name);
+            iflags.hilite_delta = 0;
+        }
     }
 #endif
     return;
 }
 
+/* copy up to maxlen-1 characters; 'dest' must be able to hold maxlen;
+   treat comma as alternate end of 'src' */
 STATIC_OVL void
 nmcpy(dest, src, maxlen)
 char *dest;
@@ -1159,12 +1215,14 @@ int maxlen;
             break; /*exit on \0 terminator*/
         *dest++ = *src++;
     }
-    *dest = 0;
+    *dest = '\0';
 }
 
 /*
  * escapes(): escape expansion for showsyms.  C-style escapes understood
  * include \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal).
+ * (Note: unlike in C, leading digit 0 is not used to indicate octal;
+ * the letter o (either upper or lower case) is used for that.
  * The ^-prefix for control characters is also understood, and \[mM]
  * has the effect of 'meta'-ing the value which follows (so that the
  * alternate character set will be enabled).
@@ -1184,8 +1242,8 @@ int maxlen;
  */
 STATIC_OVL void
 escapes(cp, tp)
-const char *cp;
-char *tp;
+const char *cp; /* might be 'tp', updating in place */
+char *tp; /* result is never longer than 'cp' */
 {
     static NEARDATA const char oct[] = "01234567", dec[] = "0123456789",
                                hex[] = "00112233445566778899aAbBcCdDeEfF";
@@ -1270,7 +1328,7 @@ const char *optname;
 /*
 
 # errors:
-OPTIONS=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+OPTIONS=aaaaaaaaaa[ more than 247 (255 - 8 for 'OPTIONS=') total ]aaaaaaaaaa
 OPTIONS
 OPTIONS=
 MSGTYPE=stop"You swap places with "
@@ -1300,8 +1358,11 @@ boolean val_optional;
 
     if (!colon || !*++colon) {
         if (!val_optional)
+/*JP
             config_error_add("Missing parameter for '%s'", opts);
-        return (char *) 0;
+*/
+            config_error_add("'%s'\82Ì\88ø\90\94\82ª\82 \82è\82Ü\82¹\82ñ", opts);
+        return empty_optstr;
     }
     return colon;
 }
@@ -1314,7 +1375,7 @@ boolean val_optional;
 {
     if (!initial) {
         rejectoption(optname);
-        return (char *) 0;
+        return empty_optstr;
     }
     return string_for_opt(opts, val_optional);
 }
@@ -1324,7 +1385,7 @@ bad_negation(optname, with_parameter)
 const char *optname;
 boolean with_parameter;
 {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     pline_The("%s option may not %sbe negated.", optname,
               with_parameter ? "both have a value and " : "");
 #else
@@ -1398,7 +1459,7 @@ const char *optype;
     uchar translate[WARNCOUNT];
     int length, i;
 
-    if (!(opts = string_for_env_opt(optype, opts, FALSE)))
+    if ((opts = string_for_env_opt(optype, opts, FALSE)) == empty_optstr)
         return FALSE;
     escapes(opts, opts);
 
@@ -1451,7 +1512,7 @@ const char *optn;
     if (!initial) {
         Sprintf(buf, "%lu.%lu.%lu", FEATURE_NOTICE_VER_MAJ,
                 FEATURE_NOTICE_VER_MIN, FEATURE_NOTICE_VER_PATCH);
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline(
           "Feature change alerts disabled for NetHack %s features and prior.",
               buf);
@@ -1541,8 +1602,13 @@ int iscompound; /* 0 == boolean option, 1 == compound */
      * For now just return.
      */
 #else /* !MAC */
+#if 0 /*JP:T*/
     config_error_add("%s option specified multiple times: %s",
                      iscompound ? "compound" : "boolean", opts);
+#else
+    config_error_add("%s\83I\83v\83V\83\87\83\93\82ª\95¡\90\94\89ñ\8ew\92è\82³\82ê\82Ä\82¢\82Ü\82·\81F%s",
+                     iscompound ? "\95¡\8d\87" : "\90^\8bU\92l", opts);
+#endif
 #endif /* ?MAC */
     return;
 }
@@ -1561,27 +1627,57 @@ STATIC_VAR const struct paranoia_opts {
        and "d"ie vs "d"eath, synonyms for each other so doesn't matter;
        (also "p"ray vs "P"aranoia, "pray" takes precedence since "Paranoia"
        is just a synonym for "Confirm"); "b"ones vs "br"eak-wand, the
-       latter requires at least two letters; "wand"-break vs "Were"-change,
+       latter requires at least two letters; "e"at vs "ex"plore,
+       "cont"inue eating vs "C"onfirm; "wand"-break vs "Were"-change,
        both require at least two letters during config processing and use
        case-senstivity for 'O's interactive menu */
     { PARANOID_CONFIRM, "Confirm", 1, "Paranoia", 2,
+/*JP
       "for \"yes\" confirmations, require \"no\" to reject" },
-    { PARANOID_QUIT, "quit", 1, "explore", 1,
+*/
+      "\"yes\"\82ð\8am\94F\82·\82é\82Æ\82«\82É\81C\8b\91\94Û\82·\82é\82Æ\82«\82É\82Í\"no\"\82ª\95K\97v" },
+    { PARANOID_QUIT, "quit", 1, "explore", 2,
+/*JP
       "yes vs y to quit or to enter explore mode" },
+*/
+      "\8fI\97¹\82Ü\82½\82Í\92T\8c\9f\83\82\81[\83h\82É\93ü\82é\82Æ\82«\82Éy\82Å\82Í\82È\82­yes" },
     { PARANOID_DIE, "die", 1, "death", 2,
+/*JP
       "yes vs y to die (explore mode or debug mode)" },
+*/
+      "(\92T\8c\9f\83\82\81[\83h\82©\83f\83o\83b\83O\83\82\81[\83h\82Å)\8e\80\82Ê\82Æ\82«\82Éy\82Å\82Í\82È\82­yes" },
     { PARANOID_BONES, "bones", 1, 0, 0,
+/*JP
       "yes vs y to save bones data when dying in debug mode" },
+*/
+      "\83f\83o\83b\83O\83\82\81[\83h\82Å\8e\80\82ñ\82Å\8d\9c\83f\81[\83^\82ð\95Û\91\82·\82é\82Æ\82«\82Éy\82Å\82Í\82È\82­yes" },
     { PARANOID_HIT, "attack", 1, "hit", 1,
+/*JP
       "yes vs y to attack a peaceful monster" },
+*/
+      "\97F\8dD\93I\89ö\95¨\82ð\8dU\8c\82\82·\82é\82Æ\82«\82Éy\82Å\82Í\82È\82­yes" },
     { PARANOID_BREAKWAND, "wand-break", 2, "break-wand", 2,
+/*JP
       "yes vs y to break a wand via (a)pply" },
+*/
+      "(a)pply\82Å\8fñ\82ð\90Ü\82é\82Æ\82«\82Éy\82Å\82Í\82È\82­yes" },
+    { PARANOID_EATING, "eat", 1, "continue", 4,
+      "yes vs y to continue eating after first bite when satiated" },
     { PARANOID_WERECHANGE, "Were-change", 2, (const char *) 0, 0,
+/*JP
       "yes vs y to change form when lycanthropy is controllable" },
+*/
+      "\8fb\89»\95a\82ª\90§\8cä\89Â\94\\82È\8fê\8d\87\82É\95Ï\89»\82·\82é\82Æ\82«\82Éy\82Å\82Í\82È\82­yes" },
     { PARANOID_PRAY, "pray", 1, 0, 0,
+/*JP
       "y to pray (supersedes old \"prayconfirm\" option)" },
+*/
+      "\8bF\82é\82Æ\82«\82Éy\82ª\95K\97v(\8cÃ\82¢\"prayconfirm\"\83I\83v\83V\83\87\83\93\82ð\8fã\8f\91\82«\82·\82é)" },
     { PARANOID_REMOVE, "Remove", 1, "Takeoff", 1,
+/*JP
       "always pick from inventory for Remove and Takeoff" },
+*/
+      "Remove\82ÆTakeoff\82Å\8fí\82É\8e\9d\82¿\95¨\88ê\97\97\82©\82ç\91I\82Ô" },
     /* for config file parsing; interactive menu skips these */
     { 0, "none", 4, 0, 0, 0 }, /* require full word match */
     { ~0, "all", 3, 0, 0, 0 }, /* ditto */
@@ -1634,7 +1730,8 @@ static const struct {
     { "inverse", ATR_INVERSE },
     { NULL, ATR_NONE }, /* everything after this is an alias */
     { "normal", ATR_NONE },
-    { "uline", ATR_ULINE }
+    { "uline", ATR_ULINE },
+    { "reverse", ATR_INVERSE },
 };
 
 const char *
@@ -1657,18 +1754,20 @@ char *str;
 
     /* allow "lightblue", "light blue", and "light-blue" to match "light blue"
        (also junk like "_l i-gh_t---b l u e" but we won't worry about that);
-       also copes with trailing space; mungspaces removed any leading space */
+       also copes with trailing space; caller has removed any leading space */
     for (i = 0; i < SIZE(colornames); i++)
         if (colornames[i].name
             && fuzzymatch(str, colornames[i].name, " -_", TRUE)) {
             c = colornames[i].color;
             break;
         }
-    if (i == SIZE(colornames) && (*str >= '0' && *str <= '9'))
+    if (i == SIZE(colornames) && digit(*str))
         c = atoi(str);
 
-    if (c == CLR_MAX)
-        config_error_add("Unknown color '%s'", str);
+    if (c < 0 || c >= CLR_MAX) {
+        config_error_add("Unknown color '%.60s'", str);
+        c = CLR_MAX; /* "none of the above" */
+    }
 
     return c;
 }
@@ -1700,7 +1799,7 @@ boolean complain;
         }
 
     if (a == -1 && complain)
-        config_error_add("Unknown text attribute '%s'", str);
+        config_error_add("Unknown text attribute '%.50s'", str);
 
     return a;
 }
@@ -1722,19 +1821,31 @@ const char *prompt;
             break;
         any.a_int = i + 1;
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, colornames[i].name,
-                 MENU_UNSELECTED);
+                 (colornames[i].color == NO_COLOR) ? MENU_SELECTED
+                                                   : MENU_UNSELECTED);
     }
     end_menu(tmpwin, (prompt && *prompt) ? prompt : "Pick a color");
     pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
     destroy_nhwindow(tmpwin);
     if (pick_cnt > 0) {
-        i = colornames[picks->item.a_int - 1].color;
+        i = colornames[picks[0].item.a_int - 1].color;
+        /* pick_cnt==2: explicitly picked something other than the
+           preselected entry */
+        if (pick_cnt == 2 && i == NO_COLOR)
+            i = colornames[picks[1].item.a_int - 1].color;
         free((genericptr_t) picks);
         return i;
+    } else if (pick_cnt == 0) {
+        /* pick_cnt==0: explicitly picking preselected entry toggled it off */
+        return NO_COLOR;
     }
     return -1;
 }
 
+/* ask about highlighting attribute; for menu headers and menu
+   coloring patterns, only one attribute at a time is allowed;
+   for status highlighting, multiple attributes are allowed [overkill;
+   life would be much simpler if that were restricted to one also...] */
 int
 query_attr(prompt)
 const char *prompt;
@@ -1743,7 +1854,11 @@ const char *prompt;
     anything any;
     int i, pick_cnt;
     menu_item *picks = (menu_item *) 0;
+    boolean allow_many = (prompt && !strncmpi(prompt, "Choose", 6));
+    int default_attr = ATR_NONE;
 
+    if (prompt && strstri(prompt, "menu headings"))
+        default_attr = iflags.menu_headings;
     tmpwin = create_nhwindow(NHW_MENU);
     start_menu(tmpwin);
     any = zeroany;
@@ -1752,16 +1867,61 @@ const char *prompt;
             break;
         any.a_int = i + 1;
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, attrnames[i].attr,
-                 attrnames[i].name, MENU_UNSELECTED);
+                 attrnames[i].name,
+                 (attrnames[i].attr == default_attr) ? MENU_SELECTED
+                                                     : MENU_UNSELECTED);
     }
     end_menu(tmpwin, (prompt && *prompt) ? prompt : "Pick an attribute");
-    pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
+    pick_cnt = select_menu(tmpwin, allow_many ? PICK_ANY : PICK_ONE, &picks);
     destroy_nhwindow(tmpwin);
     if (pick_cnt > 0) {
-        i = attrnames[picks->item.a_int - 1].attr;
+        int j, k = 0;
+
+        if (allow_many) {
+            /* PICK_ANY, with one preselected entry (ATR_NONE) which
+               should be excluded if any other choices were picked */
+            for (i = 0; i < pick_cnt; ++i) {
+                j = picks[i].item.a_int - 1;
+                if (attrnames[j].attr != ATR_NONE || pick_cnt == 1) {
+                    switch (attrnames[j].attr) {
+                    case ATR_DIM:
+                        k |= HL_DIM;
+                        break;
+                    case ATR_BLINK:
+                        k |= HL_BLINK;
+                        break;
+                    case ATR_ULINE:
+                        k |= HL_ULINE;
+                        break;
+                    case ATR_INVERSE:
+                        k |= HL_INVERSE;
+                        break;
+                    case ATR_BOLD:
+                        k |= HL_BOLD;
+                        break;
+                    case ATR_NONE:
+                        k = HL_NONE;
+                        break;
+                    }
+                }
+            }
+        } else {
+            /* PICK_ONE, but might get 0 or 2 due to preselected entry */
+            j = picks[0].item.a_int - 1;
+            /* pick_cnt==2: explicitly picked something other than the
+               preselected entry */
+            if (pick_cnt == 2 && attrnames[j].attr == default_attr)
+                j = picks[1].item.a_int - 1;
+            k = attrnames[j].attr;
+        }
         free((genericptr_t) picks);
-        return i;
+        return k;
+    } else if (pick_cnt == 0 && !allow_many) {
+        /* PICK_ONE, preselected entry explicitly chosen */
+        return default_attr;
     }
+    /* either ESC to explicitly cancel (pick_cnt==-1) or
+       PICK_ANY with preselected entry toggled off and nothing chosen */
     return -1;
 }
 
@@ -1770,12 +1930,24 @@ static const struct {
     xchar msgtyp;
     const char *descr;
 } msgtype_names[] = {
+/*JP
     { "show", MSGTYP_NORMAL, "Show message normally" },
+*/
+    { "show", MSGTYP_NORMAL, "\92Ê\8fí\92Ê\82è\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é" },
+/*JP
     { "hide", MSGTYP_NOSHOW, "Hide message" },
+*/
+    { "hide", MSGTYP_NOSHOW, "\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82µ\82È\82¢" },
     { "noshow", MSGTYP_NOSHOW, NULL },
+/*JP
     { "stop", MSGTYP_STOP, "Prompt for more after the message" },
+*/
+    { "stop", MSGTYP_STOP, "more\83v\83\8d\83\93\83v\83g\82Å\91Ò\82Â" },
     { "more", MSGTYP_STOP, NULL },
+/*JP
     { "norep", MSGTYP_NOREP, "Do not repeat the message" }
+*/
+    { "norep", MSGTYP_NOREP, "\82±\82Ì\83\81\83b\83Z\81[\83W\82Í\8cJ\82è\95Ô\82³\82È\82¢" }
 };
 
 STATIC_OVL const char *
@@ -1790,7 +1962,7 @@ int typ;
     return (char *) 0;
 }
 
-int
+STATIC_OVL int
 query_msgtype()
 {
     winid tmpwin;
@@ -1807,7 +1979,10 @@ query_msgtype()
             add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
                  msgtype_names[i].descr, MENU_UNSELECTED);
         }
+/*JP
     end_menu(tmpwin, "How to show the message");
+*/
+    end_menu(tmpwin, "\83\81\83b\83Z\81[\83W\82Ì\95\\8e¦\95û\96@");
     pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
     destroy_nhwindow(tmpwin);
     if (pick_cnt > 0) {
@@ -1823,8 +1998,7 @@ msgtype_add(typ, pattern)
 int typ;
 char *pattern;
 {
-    struct plinemsg_type
-        *tmp = (struct plinemsg_type *) alloc(sizeof (struct plinemsg_type));
+    struct plinemsg_type *tmp = (struct plinemsg_type *) alloc(sizeof *tmp);
 
     tmp->msgtype = typ;
     tmp->regex = regex_init();
@@ -1985,7 +2159,7 @@ const char *errmsg;
     return retval;
 }
 
-boolean
+STATIC_OVL boolean
 add_menu_coloring_parsed(str, c, a)
 char *str;
 int c, a;
@@ -1995,7 +2169,7 @@ int c, a;
 
     if (!str)
         return FALSE;
-    tmp = (struct menucoloring *) alloc(sizeof (struct menucoloring));
+    tmp = (struct menucoloring *) alloc(sizeof *tmp);
     tmp->match = regex_init();
     if (!regex_compile(str, tmp->match)) {
         config_error_add("%s: %s", re_error, regex_error_desc(tmp->match));
@@ -2015,15 +2189,16 @@ int c, a;
 /* parse '"regex_string"=color&attr' and add it to menucoloring */
 boolean
 add_menu_coloring(tmpstr)
-char *tmpstr;
+char *tmpstr; /* never Null but could be empty */
 {
     int c = NO_COLOR, a = ATR_NONE;
     char *tmps, *cs, *amp;
     char str[BUFSZ];
 
-    Sprintf(str, "%s", tmpstr);
+    (void) strncpy(str, tmpstr, sizeof str - 1);
+    str[sizeof str - 1] = '\0';
 
-    if (!tmpstr || (cs = index(str, '=')) == 0) {
+    if ((cs = index(str, '=')) == 0) {
         config_error_add("Malformed MENUCOLOR");
         return FALSE;
     }
@@ -2056,7 +2231,6 @@ char *tmpstr;
             tmps++;
         }
     }
-
     return add_menu_coloring_parsed(tmps, c, a);
 }
 
@@ -2080,15 +2254,13 @@ int *color, *attr;
 void
 free_menu_coloring()
 {
-    struct menucoloring *tmp = menu_colorings;
-
-    while (tmp) {
-        struct menucoloring *tmp2 = tmp->next;
+    struct menucoloring *tmp, *tmp2;
 
+    for (tmp = menu_colorings; tmp; tmp = tmp2) {
+        tmp2 = tmp->next;
         regex_free(tmp->match);
         free((genericptr_t) tmp->origstr);
         free((genericptr_t) tmp);
-        tmp = tmp2;
     }
 }
 
@@ -2121,13 +2293,11 @@ int idx; /* 0 .. */
 STATIC_OVL int
 count_menucolors(VOID_ARGS)
 {
+    struct menucoloring *tmp;
     int count = 0;
-    struct menucoloring *tmp = menu_colorings;
 
-    while (tmp) {
+    for (tmp = menu_colorings; tmp; tmp = tmp->next)
         count++;
-        tmp = tmp->next;
-    }
     return count;
 }
 
@@ -2142,7 +2312,8 @@ char **opp;
 
     if (negated) {
         bad_negation(fullname, FALSE);
-    } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+    } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                        != empty_optstr) {
         boolean val_negated = FALSE;
 
         while ((*op == '!') || !strncmpi(op, "no", 2)) {
@@ -2276,7 +2447,7 @@ boolean tinitial, tfrom_file;
 
     /* align:string */
     fullname = "align";
-    if (match_optname(opts, fullname, sizeof("align") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "align" - 1, TRUE)) {
         if (parse_role_opts(negated, fullname, opts, &op)) {
             if ((flags.initalign = str2align(op)) == ROLE_NONE) {
                 config_error_add("Unknown %s '%s'", fullname, op);
@@ -2339,7 +2510,8 @@ boolean tinitial, tfrom_file;
     if (match_optname(opts, fullname, 3, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
-        if ((op = string_for_env_opt(fullname, opts, negated)) != 0) {
+        if ((op = string_for_env_opt(fullname, opts, negated))
+                                     != empty_optstr) {
             if (negated) {
                 bad_negation(fullname, TRUE);
                 return FALSE;
@@ -2384,7 +2556,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             nmcpy(catname, op, PL_PSIZ);
         } else
             return FALSE;
@@ -2399,7 +2572,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             nmcpy(dogname, op, PL_PSIZ);
         } else
             return FALSE;
@@ -2414,7 +2588,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             nmcpy(horsename, op, PL_PSIZ);
         } else
             return FALSE;
@@ -2422,6 +2597,35 @@ boolean tinitial, tfrom_file;
         return retval;
     }
 
+    fullname = "mouse_support";
+    if (match_optname(opts, fullname, 13, TRUE)) {
+        boolean compat = (strlen(opts) <= 13);
+
+        if (duplicate)
+            complain_about_duplicate(opts, 1);
+        op = string_for_opt(opts, (compat || !initial));
+        if (op == empty_optstr) {
+            if (compat || negated || initial) {
+                /* for backwards compatibility, "mouse_support" without a
+                   value is a synonym for mouse_support:1 */
+                iflags.wc_mouse_support = !negated;
+            }
+        } else if (negated) {
+            bad_negation(fullname, TRUE);
+            return FALSE;
+        } else {
+            int mode = atoi(op);
+
+            if (mode < 0 || mode > 2 || (mode == 0 && *op != '0')) {
+                config_error_add("Illegal %s parameter '%s'", fullname, op);
+                return FALSE;
+            } else { /* mode >= 0 */
+                iflags.wc_mouse_support = mode;
+            }
+        }
+        return retval;
+    }
+
     fullname = "number_pad";
     if (match_optname(opts, fullname, 10, TRUE)) {
         boolean compat = (strlen(opts) <= 10);
@@ -2429,7 +2633,7 @@ boolean tinitial, tfrom_file;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, (compat || !initial));
-        if (!op) {
+        if (op == empty_optstr) {
             if (compat || negated || initial) {
                 /* for backwards compatibility, "number_pad" without a
                    value is a synonym for number_pad:1 */
@@ -2472,12 +2676,13 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_opt(opts, FALSE)) != 0) {
+        } else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
             symset[ROGUESET].name = dupstr(op);
             if (!read_sym_file(ROGUESET)) {
                 clear_symsetentry(ROGUESET, TRUE);
-                config_error_add("Unable to load symbol set \"%s\" from \"%s\"",
-                           op, SYMBOLS);
+                config_error_add(
+                               "Unable to load symbol set \"%s\" from \"%s\"",
+                                 op, SYMBOLS);
                 return FALSE;
             } else {
                 if (!initial && Is_rogue_level(&u.uz))
@@ -2496,7 +2701,7 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_opt(opts, FALSE)) != 0) {
+        } else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
             symset[PRIMARY].name = dupstr(op);
             if (!read_sym_file(PRIMARY)) {
                 clear_symsetentry(PRIMARY, TRUE);
@@ -2519,7 +2724,7 @@ boolean tinitial, tfrom_file;
             complain_about_duplicate(opts, 1);
         if (negated) {
             flags.runmode = RUN_TPORT;
-        } else if ((op = string_for_opt(opts, FALSE)) != 0) {
+        } else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
             if (!strncmpi(op, "teleport", strlen(op)))
                 flags.runmode = RUN_TPORT;
             else if (!strncmpi(op, "run", strlen(op)))
@@ -2543,7 +2748,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             if (!add_menu_coloring(op))
                 return FALSE;
         } else
@@ -2556,7 +2762,8 @@ boolean tinitial, tfrom_file;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_env_opt(fullname, opts, negated);
-        if ((negated && !op) || (!negated && op)) {
+        if ((negated && op == empty_optstr)
+            || (!negated && op != empty_optstr)) {
             iflags.msg_history = negated ? 0 : atoi(op);
         } else if (negated) {
             bad_negation(fullname, TRUE);
@@ -2574,7 +2781,7 @@ boolean tinitial, tfrom_file;
 
         if (duplicate)
             complain_about_duplicate(opts, 1);
-        if (!(op = string_for_opt(opts, TRUE))) {
+        if ((op = string_for_opt(opts, TRUE)) == empty_optstr) {
             tmp = negated ? 's' : 'f';
         } else {
             if (negated) {
@@ -2587,19 +2794,18 @@ boolean tinitial, tfrom_file;
         case 's': /* single message history cycle (default if negated) */
             iflags.prevmsg_window = 's';
             break;
-        case 'c': /* combination: two singles, then full page reversed */
+        case 'c': /* combination: two singles, then full page */
             iflags.prevmsg_window = 'c';
             break;
-        case 'f': /* full page (default if no opts) */
+        case 'f': /* full page (default if specified without argument) */
             iflags.prevmsg_window = 'f';
             break;
         case 'r': /* full page (reversed) */
             iflags.prevmsg_window = 'r';
             break;
-        default: {
+        default:
             config_error_add("Unknown %s parameter '%s'", fullname, op);
-            return FALSE;
-        }
+            retval = FALSE;
         }
 #endif
         return retval;
@@ -2644,7 +2850,7 @@ boolean tinitial, tfrom_file;
             if (duplicate)
                 complain_about_duplicate(opts, 1);
             if (opttype > 0 && !negated
-                && (op = string_for_opt(opts, FALSE)) != 0) {
+                && (op = string_for_opt(opts, FALSE)) != empty_optstr) {
                 switch (opttype) {
                 case MAP_OPTION:
                     iflags.wc_fontsiz_map = atoi(op);
@@ -2668,7 +2874,8 @@ boolean tinitial, tfrom_file;
             config_error_add("Unknown %s parameter '%s'", fullname, opts);
             return FALSE;
         }
-        if (opttype > 0 && (op = string_for_opt(opts, FALSE)) != 0) {
+        if (opttype > 0
+            && (op = string_for_opt(opts, FALSE)) != empty_optstr) {
             wc_set_font_name(opttype, op);
 #ifdef MAC
             set_font_name(opttype, op);
@@ -2713,12 +2920,12 @@ boolean tinitial, tfrom_file;
         }
 #ifdef WIN32
         op = string_for_opt(opts, TRUE);
-        if (!alternative_palette(op)) {
+        if (op == empty_optstr || !alternative_palette(op)) {
             config_error_add("Error in palette parameter '%s'", op);
             return FALSE;
         }
 #else
-        if ((op = string_for_opt(opts, FALSE)) != (char *) 0) {
+        if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
             char *pt = op;
             int cnt, tmp, reverse;
             long rgb;
@@ -2768,21 +2975,22 @@ boolean tinitial, tfrom_file;
 
     if (match_optname(opts, "fruit", 2, TRUE)) {
         struct fruit *forig = 0;
-        char empty_str = '\0';
 
         if (duplicate)
             complain_about_duplicate(opts, 1);
-        op = string_for_opt(opts, negated);
+        op = string_for_opt(opts, negated || !initial);
         if (negated) {
-            if (op) {
+            if (op != empty_optstr) {
                 bad_negation("fruit", TRUE);
                 return FALSE;
             }
-            op = &empty_str;
+            op = empty_optstr;
             goto goodfruit;
         }
-        if (!op)
+        if (op == empty_optstr)
             return FALSE;
+        /* strip leading/trailing spaces, condense internal ones (3.6.2) */
+        mungspaces(op);
         if (!initial) {
             struct fruit *f;
             int fnum = 0;
@@ -2795,7 +3003,7 @@ boolean tinitial, tfrom_file;
                     forig = fruit_from_name(pl_fruit, FALSE, (int *) 0);
 
                 if (!forig && fnum >= 100) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                     config_error_add(
                              "Doing that so many times isn't very fruitful.");
 #else
@@ -2806,7 +3014,7 @@ boolean tinitial, tfrom_file;
                 }
             }
         }
   goodfruit:
+ goodfruit:
         nmcpy(pl_fruit, op, PL_FSIZ);
         sanitize_name(pl_fruit);
         /* OBJ_NAME(objects[SLIME_MOLD]) won't work for this after
@@ -2835,7 +3043,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             iflags.getpos_coords = GPCOORDS_NONE;
             return retval;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             static char gpcoords[] = { GPCOORDS_NONE, GPCOORDS_COMPASS,
                                        GPCOORDS_COMFULL, GPCOORDS_MAP,
                                        GPCOORDS_SCREEN, '\0' };
@@ -2859,7 +3068,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             iflags.getloc_filter = GFILTER_NONE;
             return retval;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             char c = lowc(*op);
 
             switch (c) {
@@ -2905,32 +3115,41 @@ boolean tinitial, tfrom_file;
             bad_negation(fullname, FALSE);
             return FALSE;
         }
-        /* if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
+        /* if ((opts = string_for_env_opt(fullname, opts, FALSE))
+                                          == empty_optstr)
          */
-        if (!(opts = string_for_opt(opts, FALSE)))
+        if ((opts = string_for_opt(opts, FALSE)) == empty_optstr)
             return FALSE;
         escapes(opts, opts);
+        /* note: dummy monclass #0 has symbol value '\0'; we allow that--
+           attempting to set bouldersym to '^@'/'\0' will reset to default */
         if (def_char_to_monclass(opts[0]) != MAXMCLASSES)
-            clash = 1;
-        else if (opts[0] >= '1' && opts[0] <= '5')
+            clash = opts[0] ? 1 : 0;
+        else if (opts[0] >= '1' && opts[0] < WARNCOUNT + '0')
             clash = 2;
         if (clash) {
             /* symbol chosen matches a used monster or warning
-               symbol which is not good - reject it*/
+               symbol which is not good - reject it */
             config_error_add(
-                "Badoption - boulder symbol '%c' conflicts with a %s symbol.",
-                             opts[0], (clash == 1) ? "monster" : "warning");
+            "Badoption - boulder symbol '%s' would conflict with a %s symbol",
+                             visctrl(opts[0]),
+                             (clash == 1) ? "monster" : "warning");
         } else {
             /*
              * Override the default boulder symbol.
              */
-            iflags.bouldersym = (uchar) opts[0];
-        }
-        /* for 'initial', update_bouldersym() is done in initoptions_finish(),
-           after all symset options have been processed */
-        if (!initial) {
-            update_bouldersym();
-            need_redraw = TRUE;
+            ov_primary_syms[SYM_BOULDER + SYM_OFF_X] = (nhsym) opts[0];
+            ov_rogue_syms[SYM_BOULDER + SYM_OFF_X] = (nhsym) opts[0];
+            /* for 'initial', update of BOULDER symbol is done in
+               initoptions_finish(), after all symset options
+               have been processed */
+            if (!initial) {
+                nhsym sym = get_othersym(SYM_BOULDER,
+                                Is_rogue_level(&u.uz) ? ROGUESET : PRIMARY);
+                if (sym)
+                    showsyms[SYM_BOULDER + SYM_OFF_X] = sym;
+                need_redraw = TRUE;
+            }
         }
         return retval;
 #else
@@ -2948,7 +3167,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             nmcpy(plname, op, PL_NSIZ);
         } else
             return FALSE;
@@ -2963,10 +3183,9 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_opt(opts, negated)) != 0) {
-#ifdef WIN32
-            (void) strncpy(iflags.altkeyhandler, op, MAX_ALTKEYHANDLER - 5);
-            load_keyboard_handler();
+        } else if ((op = string_for_opt(opts, negated)) != empty_optstr) {
+#if defined(WIN32) && defined(TTY_GRAPHICS)
+            set_altkeyhandler(op);
 #endif
         } else
             return FALSE;
@@ -2976,16 +3195,16 @@ boolean tinitial, tfrom_file;
     /* WINCAP
      * align_status:[left|top|right|bottom] */
     fullname = "align_status";
-    if (match_optname(opts, fullname, sizeof("align_status") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "align_status" - 1, TRUE)) {
         op = string_for_opt(opts, negated);
-        if (op && !negated) {
-            if (!strncmpi(op, "left", sizeof("left") - 1))
+        if ((op != empty_optstr) && !negated) {
+            if (!strncmpi(op, "left", sizeof "left" - 1))
                 iflags.wc_align_status = ALIGN_LEFT;
-            else if (!strncmpi(op, "top", sizeof("top") - 1))
+            else if (!strncmpi(op, "top", sizeof "top" - 1))
                 iflags.wc_align_status = ALIGN_TOP;
-            else if (!strncmpi(op, "right", sizeof("right") - 1))
+            else if (!strncmpi(op, "right", sizeof "right" - 1))
                 iflags.wc_align_status = ALIGN_RIGHT;
-            else if (!strncmpi(op, "bottom", sizeof("bottom") - 1))
+            else if (!strncmpi(op, "bottom", sizeof "bottom" - 1))
                 iflags.wc_align_status = ALIGN_BOTTOM;
             else {
                 config_error_add("Unknown %s parameter '%s'", fullname, op);
@@ -3001,18 +3220,18 @@ boolean tinitial, tfrom_file;
     /* WINCAP
      * align_message:[left|top|right|bottom] */
     fullname = "align_message";
-    if (match_optname(opts, fullname, sizeof("align_message") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "align_message" - 1, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if (op && !negated) {
-            if (!strncmpi(op, "left", sizeof("left") - 1))
+        if ((op != empty_optstr) && !negated) {
+            if (!strncmpi(op, "left", sizeof "left" - 1))
                 iflags.wc_align_message = ALIGN_LEFT;
-            else if (!strncmpi(op, "top", sizeof("top") - 1))
+            else if (!strncmpi(op, "top", sizeof "top" - 1))
                 iflags.wc_align_message = ALIGN_TOP;
-            else if (!strncmpi(op, "right", sizeof("right") - 1))
+            else if (!strncmpi(op, "right", sizeof "right" - 1))
                 iflags.wc_align_message = ALIGN_RIGHT;
-            else if (!strncmpi(op, "bottom", sizeof("bottom") - 1))
+            else if (!strncmpi(op, "bottom", sizeof "bottom" - 1))
                 iflags.wc_align_message = ALIGN_BOTTOM;
             else {
                 config_error_add("Unknown %s parameter '%s'", fullname, op);
@@ -3033,7 +3252,7 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if (!(op = string_for_opt(opts, FALSE)))
+        } else if ((op = string_for_opt(opts, FALSE)) == empty_optstr)
             return FALSE;
 
         if (!change_inv_order(op))
@@ -3052,7 +3271,7 @@ boolean tinitial, tfrom_file;
         flags.paranoia_bits = 0; /* clear all */
         if (negated) {
             flags.paranoia_bits = 0; /* [now redundant...] */
-        } else if ((op = string_for_opt(opts, TRUE)) != 0) {
+        } else if ((op = string_for_opt(opts, TRUE)) != empty_optstr) {
             char *pp, buf[BUFSZ];
 
             strncpy(buf, op, sizeof buf - 1);
@@ -3066,7 +3285,7 @@ boolean tinitial, tfrom_file;
                 pp = index(op, ' ');
                 if (pp)
                     *pp = '\0';
-                /* we aren't matching option names but match_optname
+                /* we aren't matching option names but match_optname()
                    does what we want once we've broken the space
                    delimited aggregate into separate tokens */
                 for (i = 0; i < SIZE(paranoia); ++i) {
@@ -3118,7 +3337,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             switch (lowc(*op)) {
             case 'u': /* Unencumbered */
                 flags.pickup_burden = UNENCUMBERED;
@@ -3151,8 +3371,8 @@ boolean tinitial, tfrom_file;
     /* types of objects to pick up automatically */
     fullname = "pickup_types";
     if (match_optname(opts, fullname, 8, TRUE)) {
-        char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1], qbuf[QBUFSZ],
-            abuf[BUFSZ] = DUMMY;
+        char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1],
+             qbuf[QBUFSZ], abuf[BUFSZ];
         int oc_sym;
         boolean badopt = FALSE, compat = (strlen(opts) <= 6), use_menu;
 
@@ -3161,7 +3381,7 @@ boolean tinitial, tfrom_file;
         oc_to_str(flags.pickup_types, tbuf);
         flags.pickup_types[0] = '\0'; /* all */
         op = string_for_opt(opts, (compat || !initial));
-        if (!op) {
+        if (op == empty_optstr) {
             if (compat || negated || initial) {
                 /* for backwards compatibility, "pickup" without a
                    value is a synonym for autopickup of all types
@@ -3173,6 +3393,8 @@ boolean tinitial, tfrom_file;
             use_menu = TRUE;
             if (flags.menu_style == MENU_TRADITIONAL
                 || flags.menu_style == MENU_COMBINATION) {
+                boolean wasspace;
+
                 use_menu = FALSE;
 #if 0 /*JP:T*/
                 Sprintf(qbuf, "New %s: [%s am] (%s)", fullname, ocl,
@@ -3181,16 +3403,24 @@ boolean tinitial, tfrom_file;
                 Sprintf(qbuf, "\90V\82µ\82¢%s: [%s am] (%s)", fullname, ocl,
                         *tbuf ? tbuf : "all");
 #endif
+                abuf[0] = '\0';
                 getlin(qbuf, abuf);
+                wasspace = (abuf[0] == ' '); /* before mungspaces */
                 op = mungspaces(abuf);
-                if (abuf[0] == '\0' || abuf[0] == '\033')
+                if (wasspace && !abuf[0])
+                    ; /* one or more spaces will remove old value */
+                else if (!abuf[0] || abuf[0] == '\033')
                     op = tbuf; /* restore */
                 else if (abuf[0] == 'm')
                     use_menu = TRUE;
+                /* note: abuf[0]=='a' is already handled via clearing the
+                   the old value (above) as a default action */
             }
             if (use_menu) {
-#if 0 /*JP*/
-                (void) choose_classes_menu("Auto-Pickup what?", 1, TRUE, ocl,
+                if (wizard && !index(ocl, VENOM_SYM))
+                    strkitten(ocl, VENOM_SYM);
+#if 0 /*JP:T*/
+                (void) choose_classes_menu("Autopickup what?", 1, TRUE, ocl,
                                            tbuf);
 #else
                 (void) choose_classes_menu("\82Ç\82ê\82ð\8e©\93®\8fE\82¢\82É\90Ý\92è\82·\82é\81H", 1, TRUE, ocl,
@@ -3233,12 +3463,13 @@ boolean tinitial, tfrom_file;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if ((negated && !op) || (!negated && op))
+        if ((negated && op == empty_optstr)
+            || (!negated && op != empty_optstr))
             flags.pile_limit = negated ? 0 : atoi(op);
         else if (negated) {
             bad_negation(fullname, TRUE);
             return FALSE;
-        } else /* !op */
+        } else /* op == empty_optstr */
             flags.pile_limit = PILE_LIMIT_DFLT;
         /* sanity check */
         if (flags.pile_limit < 0)
@@ -3256,7 +3487,7 @@ boolean tinitial, tfrom_file;
         if (duplicate || negated)
             return FALSE;
         op = string_for_opt(opts, FALSE);
-        if (!op)
+        if (op == empty_optstr)
             return FALSE;
         if (!strncmpi(op, "normal", 6) || !strcmpi(op, "play")) {
             wizard = discover = FALSE;
@@ -3273,18 +3504,18 @@ boolean tinitial, tfrom_file;
     }
 
     /* WINCAP
-     * player_selection: dialog | prompts */
+     * player_selection: dialog | prompt/prompts/prompting */
     fullname = "player_selection";
-    if (match_optname(opts, fullname, sizeof("player_selection") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "player_selection" - 1, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if (op && !negated) {
-            if (!strncmpi(op, "dialog", sizeof("dialog") - 1))
+        if (op != empty_optstr && !negated) {
+            if (!strncmpi(op, "dialog", sizeof "dialog" - 1)) {
                 iflags.wc_player_selection = VIA_DIALOG;
-            else if (!strncmpi(op, "prompt", sizeof("prompt") - 1))
+            } else if (!strncmpi(op, "prompt", sizeof "prompt" - 1)) {
                 iflags.wc_player_selection = VIA_PROMPTS;
-            else {
+            else {
                 config_error_add("Unknown %s parameter '%s'", fullname, op);
                 return FALSE;
             }
@@ -3306,11 +3537,13 @@ boolean tinitial, tfrom_file;
          *      end_disclose[NUM_DISCLOSURE_OPT];
          * with option settings for the each of the following:
          * iagvc [see disclosure_options in decl.c]:
-         * Legal setting values in that array are:
+         * Allowed setting values in that array are:
          *      DISCLOSE_PROMPT_DEFAULT_YES  ask with default answer yes
          *      DISCLOSE_PROMPT_DEFAULT_NO   ask with default answer no
          *      DISCLOSE_YES_WITHOUT_PROMPT  always disclose and don't ask
          *      DISCLOSE_NO_WITHOUT_PROMPT   never disclose and don't ask
+         *      DISCLOSE_PROMPT_DEFAULT_SPECIAL  for 'vanquished' only...
+         *      DISCLOSE_SPECIAL_WITHOUT_PROMPT  ...to set up sort order.
          *
          * Those setting values can be used in the option
          * string as a prefix to get the desired behaviour.
@@ -3324,14 +3557,15 @@ boolean tinitial, tfrom_file;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, TRUE);
-        if (op && negated) {
+        if (op != empty_optstr && negated) {
             bad_negation(fullname, TRUE);
             return FALSE;
         }
         /* "disclose" without a value means "all with prompting"
            and negated means "none without prompting" */
-        if (!op || !strcmpi(op, "all") || !strcmpi(op, "none")) {
-            if (op && !strcmpi(op, "none"))
+        if (op == empty_optstr
+            || !strcmpi(op, "all") || !strcmpi(op, "none")) {
+            if (op != empty_optstr && !strcmpi(op, "none"))
                 negated = TRUE;
             for (num = 0; num < NUM_DISCLOSURE_OPTIONS; num++)
                 flags.end_disclose[num] = negated
@@ -3404,7 +3638,7 @@ boolean tinitial, tfrom_file;
             bad_negation(fullname, FALSE);
             return FALSE;
         }
-        if (!(op = string_for_opt(opts, FALSE)))
+        if ((op = string_for_opt(opts, FALSE)) == empty_optstr)
             return FALSE;
 
         while (*op) {
@@ -3438,8 +3672,12 @@ boolean tinitial, tfrom_file;
                 config_error_add("Unknown %s parameter '%s'", fullname, op);
                 return FALSE;
             }
-            while (letter(*++op) || *op == ' ')
-                continue;
+            /* "3a" is sufficient but accept "3around" (or "3abracadabra") */
+            while (letter(*op))
+                op++;
+            /* t, a, and o can be separated by space(s) or slash or both */
+            while (*op == ' ')
+                op++;
             if (*op == '/')
                 op++;
         }
@@ -3449,7 +3687,7 @@ boolean tinitial, tfrom_file;
     fullname = "sortloot";
     if (match_optname(opts, fullname, 4, TRUE)) {
         op = string_for_env_opt(fullname, opts, FALSE);
-        if (op) {
+        if (op != empty_optstr) {
             char c = lowc(*op);
 
             switch (c) {
@@ -3475,7 +3713,7 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if (op)
+        } else if (op != empty_optstr)
             (void) feature_alert_opts(op, fullname);
         return retval;
     }
@@ -3490,11 +3728,14 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+        } else if ((opts = string_for_env_opt(fullname, opts, FALSE))
+                                              == empty_optstr) {
             return FALSE;
         }
-        if (!assign_videocolors(opts)) /* TODO: error msg */
+        if (!assign_videocolors(opts)) {
+            config_error_add("Unknown error handling '%s'", fullname);
             return FALSE;
+        }
         return retval;
     }
     /* videoshades:string */
@@ -3505,14 +3746,18 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+        } else if ((opts = string_for_env_opt(fullname, opts, FALSE))
+                                              == empty_optstr) {
             return FALSE;
         }
-        if (!assign_videoshades(opts)) /* TODO: error msg */
+        if (!assign_videoshades(opts)) {
+            config_error_add("Unknown error handling '%s'", fullname);
             return FALSE;
+        }
         return retval;
     }
 #endif /* VIDEOSHADES */
+
 #ifdef MSDOS
 #ifdef NO_TERMS
     /* video:string -- must be after longer tests */
@@ -3523,11 +3768,14 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+        } else if ((opts = string_for_env_opt(fullname, opts, FALSE))
+                                              == empty_optstr) {
             return FALSE;
         }
-        if (!assign_video(opts)) /* TODO: error msg */
+        if (!assign_video(opts)) {
+            config_error_add("Unknown error handling '%s'", fullname);
             return FALSE;
+        }
         return retval;
     }
 #endif /* NO_TERMS */
@@ -3539,49 +3787,59 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+        } else if ((opts = string_for_env_opt(fullname, opts, FALSE))
+                                              == empty_optstr) {
             return FALSE;
         }
-        if (!assign_soundcard(opts)) /* TODO: error msg */
+        if (!assign_soundcard(opts)) {
+            config_error_add("Unknown error handling '%s'", fullname);
             return FALSE;
+        }
         return retval;
     }
 #endif /* MSDOS */
 
     /* WINCAP
      *
-     *  map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12|
-     *            ascii8x12|ascii16x12|ascii12x16|ascii10x18|fit_to_screen]
+     *  map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12
+     *            |ascii8x12|ascii16x12|ascii12x16|ascii10x18|fit_to_screen
+     *            |ascii_fit_to_screen|tiles_fit_to_screen]
      */
     fullname = "map_mode";
-    if (match_optname(opts, fullname, sizeof("map_mode") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "map_mode" - 1, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if (op && !negated) {
-            if (!strncmpi(op, "tiles", sizeof("tiles") - 1))
+        if (op != empty_optstr && !negated) {
+            if (!strcmpi(op, "tiles"))
                 iflags.wc_map_mode = MAP_MODE_TILES;
-            else if (!strncmpi(op, "ascii4x6", sizeof("ascii4x6") - 1))
+            else if (!strncmpi(op, "ascii4x6", sizeof "ascii4x6" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII4x6;
-            else if (!strncmpi(op, "ascii6x8", sizeof("ascii6x8") - 1))
+            else if (!strncmpi(op, "ascii6x8", sizeof "ascii6x8" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII6x8;
-            else if (!strncmpi(op, "ascii8x8", sizeof("ascii8x8") - 1))
+            else if (!strncmpi(op, "ascii8x8", sizeof "ascii8x8" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII8x8;
-            else if (!strncmpi(op, "ascii16x8", sizeof("ascii16x8") - 1))
+            else if (!strncmpi(op, "ascii16x8", sizeof "ascii16x8" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII16x8;
-            else if (!strncmpi(op, "ascii7x12", sizeof("ascii7x12") - 1))
+            else if (!strncmpi(op, "ascii7x12", sizeof "ascii7x12" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII7x12;
-            else if (!strncmpi(op, "ascii8x12", sizeof("ascii8x12") - 1))
+            else if (!strncmpi(op, "ascii8x12", sizeof "ascii8x12" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII8x12;
-            else if (!strncmpi(op, "ascii16x12", sizeof("ascii16x12") - 1))
+            else if (!strncmpi(op, "ascii16x12", sizeof "ascii16x12" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII16x12;
-            else if (!strncmpi(op, "ascii12x16", sizeof("ascii12x16") - 1))
+            else if (!strncmpi(op, "ascii12x16", sizeof "ascii12x16" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII12x16;
-            else if (!strncmpi(op, "ascii10x18", sizeof("ascii10x18") - 1))
+            else if (!strncmpi(op, "ascii10x18", sizeof "ascii10x18" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII10x18;
             else if (!strncmpi(op, "fit_to_screen",
-                               sizeof("fit_to_screen") - 1))
+                               sizeof "fit_to_screen" - 1))
+                iflags.wc_map_mode = MAP_MODE_ASCII_FIT_TO_SCREEN;
+            else if (!strncmpi(op, "ascii_fit_to_screen",
+                               sizeof "ascii_fit_to_screen" - 1))
                 iflags.wc_map_mode = MAP_MODE_ASCII_FIT_TO_SCREEN;
+            else if (!strncmpi(op, "tiles_fit_to_screen",
+                               sizeof "tiles_fit_to_screen" - 1))
+                iflags.wc_map_mode = MAP_MODE_TILES_FIT_TO_SCREEN;
             else {
                 config_error_add("Unknown %s parameter '%s'", fullname, op);
                 return FALSE;
@@ -3600,7 +3858,8 @@ boolean tinitial, tfrom_file;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if ((negated && !op) || (!negated && op)) {
+        if ((negated && op == empty_optstr)
+            || (!negated && op != empty_optstr)) {
             iflags.wc_scroll_amount = negated ? 1 : atoi(op);
         } else if (negated) {
             bad_negation(fullname, TRUE);
@@ -3616,7 +3875,8 @@ boolean tinitial, tfrom_file;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if ((negated && !op) || (!negated && op)) {
+        if ((negated && op == empty_optstr)
+            || (!negated && op != empty_optstr)) {
             iflags.wc_scroll_margin = negated ? 5 : atoi(op);
         } else if (negated) {
             bad_negation(fullname, TRUE);
@@ -3631,13 +3891,15 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else {
 #if defined(WIN32)
+        } else {
             op = string_for_opt(opts, 0);
-            if (!op)
+            if (op == empty_optstr)
                 return FALSE;
+#ifdef TTY_GRAPHICS
             map_subkeyvalue(op);
 #endif
+#endif
         }
         return retval;
     }
@@ -3645,11 +3907,12 @@ boolean tinitial, tfrom_file;
     /* WINCAP
      * tile_width:nn */
     fullname = "tile_width";
-    if (match_optname(opts, fullname, sizeof("tile_width") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "tile_width" - 1, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if ((negated && !op) || (!negated && op)) {
+        if ((negated && op == empty_optstr)
+            || (!negated && op != empty_optstr)) {
             iflags.wc_tile_width = negated ? 0 : atoi(op);
         } else if (negated) {
             bad_negation(fullname, TRUE);
@@ -3660,10 +3923,10 @@ boolean tinitial, tfrom_file;
     /* WINCAP
      * tile_file:name */
     fullname = "tile_file";
-    if (match_optname(opts, fullname, sizeof("tile_file") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "tile_file" - 1, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
-        if ((op = string_for_opt(opts, FALSE)) != 0) {
+        if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
             if (iflags.wc_tile_file)
                 free(iflags.wc_tile_file);
             iflags.wc_tile_file = dupstr(op);
@@ -3674,11 +3937,12 @@ boolean tinitial, tfrom_file;
     /* WINCAP
      * tile_height:nn */
     fullname = "tile_height";
-    if (match_optname(opts, fullname, sizeof("tile_height") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "tile_height" - 1, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if ((negated && !op) || (!negated && op)) {
+        if ((negated && op == empty_optstr)
+            || (!negated && op != empty_optstr)) {
             iflags.wc_tile_height = negated ? 0 : atoi(op);
         } else if (negated) {
             bad_negation(fullname, TRUE);
@@ -3690,11 +3954,12 @@ boolean tinitial, tfrom_file;
     /* WINCAP
      * vary_msgcount:nn */
     fullname = "vary_msgcount";
-    if (match_optname(opts, fullname, sizeof("vary_msgcount") - 1, TRUE)) {
+    if (match_optname(opts, fullname, sizeof "vary_msgcount" - 1, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, negated);
-        if ((negated && !op) || (!negated && op)) {
+        if ((negated && op == empty_optstr)
+            || (!negated && op != empty_optstr)) {
             iflags.wc_vary_msgcount = negated ? 0 : atoi(op);
         } else if (negated) {
             bad_negation(fullname, TRUE);
@@ -3713,20 +3978,28 @@ boolean tinitial, tfrom_file;
      * OPTIONS=windowtype:Foo
      * as the first non-comment line of the file.
      * Making it first in NETHACKOPTIONS requires it to be at the _end_
-     * because option strings are processed from right to left.
+     * because comma-separated option strings are processed from right
+     * to left.
      */
     fullname = "windowtype";
     if (match_optname(opts, fullname, 3, TRUE)) {
+        if (iflags.windowtype_locked)
+            return retval;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
-            char buf[WINTYPELEN];
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
+            if (!iflags.windowtype_deferred) {
+                char buf[WINTYPELEN];
 
-            nmcpy(buf, op, WINTYPELEN);
-            choose_windows(buf);
+                nmcpy(buf, op, WINTYPELEN);
+                choose_windows(buf);
+            } else {
+                nmcpy(chosen_windowtype, op, WINTYPELEN);
+            }
         } else
             return FALSE;
         return retval;
@@ -3738,7 +4011,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE))
+                                            != empty_optstr) {
             char buf[WINTYPELEN];
 
             nmcpy(buf, op, WINTYPELEN);
@@ -3757,11 +4031,136 @@ boolean tinitial, tfrom_file;
     if (match_optname(opts, fullname, 7, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
-        if ((op = string_for_opt(opts, FALSE)) != 0) {
-            if (!wc_set_window_colors(op)) /* TODO: error msg*/
+        if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
+            if (!wc_set_window_colors(op)) {
+                config_error_add("Could not set %s '%s'", fullname, op);
                 return FALSE;
-        } else if (negated)
+            }
+        } else if (negated) {
+            bad_negation(fullname, TRUE);
+            return FALSE;
+        }
+        return retval;
+    }
+
+#ifdef CURSES_GRAPHICS
+    /* WINCAP2
+     * term_cols:amount or term_rows:amount */
+    fullname = "term_cols";
+    if (match_optname(opts, fullname, 8, TRUE)
+        /* alternate spelling */
+        || match_optname(opts, "term_columns", 9, TRUE)
+        /* different option but identical handlng */
+        || (fullname = "term_rows", match_optname(opts, fullname, 8, TRUE))) {
+        long ltmp;
+
+        if ((op = string_for_opt(opts, negated)) != empty_optstr) {
+            ltmp = atol(op);
+            if (negated) {
+                bad_negation(fullname, FALSE);
+                retval = FALSE;
+
+            /* just checks atol() sanity, not logical window size sanity */
+            } else if (ltmp <= 0L || ltmp >= (long) LARGEST_INT) {
+                config_error_add("Invalid %s: %ld", fullname, ltmp);
+                retval = FALSE;
+
+            } else {
+                if (!strcmp(fullname, "term_rows"))
+                    iflags.wc2_term_rows = (int) ltmp;
+                else /* !strcmp(fullname, "term_cols") */
+                    iflags.wc2_term_cols = (int) ltmp;
+            }
+        }
+        return retval;
+    }
+
+    /* WINCAP2
+     * petattr:string */
+    fullname = "petattr";
+    if (match_optname(opts, fullname, sizeof "petattr" - 1, TRUE)) {
+        op = string_for_opt(opts, negated);
+        if (op != empty_optstr && negated) {
+            bad_negation(fullname, TRUE);
+            retval = FALSE;
+        } else if (op != empty_optstr) {
+#ifdef CURSES_GRAPHICS
+            int itmp = curses_read_attrs(op);
+
+            if (itmp == -1) {
+                config_error_add("Unknown %s parameter '%s'", fullname, opts);
+                retval = FALSE;
+            } else
+                iflags.wc2_petattr = itmp;
+#else
+            /* non-curses windowports will not use this flag anyway
+             * but the above will not compile if we don't have curses.
+             * Just set it to a sensible default: */
+            iflags.wc2_petattr = ATR_INVERSE;
+#endif
+        } else if (negated) {
+            iflags.wc2_petattr = ATR_NONE;
+        }
+        if (retval) {
+            iflags.hilite_pet = (iflags.wc2_petattr != ATR_NONE);
+            if (!initial)
+                need_redraw = TRUE;
+        }
+        return retval;
+    }
+
+    /* WINCAP2
+     * windowborders:n */
+    fullname = "windowborders";
+    if (match_optname(opts, fullname, 10, TRUE)) {
+        op = string_for_opt(opts, negated);
+        if (negated && op != empty_optstr) {
             bad_negation(fullname, TRUE);
+            retval = FALSE;
+        } else {
+            int itmp;
+
+            if (negated)
+                itmp = 0; /* Off */
+            else if (op == empty_optstr)
+                itmp = 1; /* On */
+            else    /* Value supplied; expect 0 (off), 1 (on), or 2 (auto) */
+                itmp = atoi(op);
+
+            if (itmp < 0 || itmp > 2) {
+                config_error_add("Invalid %s (should be 0, 1, or 2): %s",
+                                 fullname, opts);
+                retval = FALSE;
+            } else {
+                iflags.wc2_windowborders = itmp;
+            }
+        }
+        return retval;
+    }
+#endif /* CURSES_GRAPHICS */
+
+    /* WINCAP2
+     * statuslines:n */
+    fullname = "statuslines";
+    if (match_optname(opts, fullname, 11, TRUE)) {
+        int itmp = 0;
+
+        op = string_for_opt(opts, negated);
+        if (negated) {
+            bad_negation(fullname, TRUE);
+            itmp = 2;
+            retval = FALSE;
+        } else if (op != empty_optstr) {
+            itmp = atoi(op);
+        }
+        if (itmp < 2 || itmp > 3) {
+            config_error_add("'%s' requires a value of 2 or 3", fullname);
+            retval = FALSE;
+        } else {
+            iflags.wc2_statuslines = itmp;
+            if (!initial)
+                need_redraw = TRUE;
+        }
         return retval;
     }
 
@@ -3773,7 +4172,7 @@ boolean tinitial, tfrom_file;
 
         if (duplicate)
             complain_about_duplicate(opts, 1);
-        if (!(op = string_for_opt(opts, !val_required))) {
+        if ((op = string_for_opt(opts, !val_required)) == empty_optstr) {
             if (val_required)
                 return FALSE; /* string_for_opt gave feedback */
             tmp = negated ? 'n' : 'f';
@@ -3814,7 +4213,8 @@ boolean tinitial, tfrom_file;
         if (negated) {
             bad_negation(fullname, FALSE);
             return FALSE;
-        } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
+        } else if ((opts = string_for_env_opt(fullname, opts, FALSE))
+                                              == empty_optstr) {
             return FALSE;
         }
         tmpattr = match_str2attr(opts, TRUE);
@@ -3834,16 +4234,16 @@ boolean tinitial, tfrom_file;
             if (negated) {
                 bad_negation(fullname, FALSE);
                 return FALSE;
-            } else if ((op = string_for_opt(opts, FALSE)) != 0) {
+            } else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
                 char c, op_buf[BUFSZ];
 
                 escapes(op, op_buf);
                 c = *op_buf;
 
-                if (illegal_menu_cmd_key(c)) {
+                if (illegal_menu_cmd_key(c))
                     return FALSE;
-                } else
-                    add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd);
+
+                add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd);
             }
             return retval;
         }
@@ -3856,10 +4256,10 @@ boolean tinitial, tfrom_file;
         if (duplicate)
             complain_about_duplicate(opts, 1);
         op = string_for_opt(opts, TRUE);
-        if (op && negated) {
+        if (op != empty_optstr && negated) {
             clear_status_hilites();
             return retval;
-        } else if (!op) {
+        } else if (op == empty_optstr) {
             config_error_add("Value is mandatory for hilite_status");
             return FALSE;
         }
@@ -3880,7 +4280,7 @@ boolean tinitial, tfrom_file;
             iflags.hilite_delta = 0L;
         } else {
             op = string_for_opt(opts, TRUE);
-            iflags.hilite_delta = (!op || !*op) ? 3L : atol(op);
+            iflags.hilite_delta = (op == empty_optstr || !*op) ? 3L : atol(op);
             if (iflags.hilite_delta < 0L)
                 iflags.hilite_delta = 1L;
         }
@@ -4005,8 +4405,9 @@ boolean tinitial, tfrom_file;
 #endif  /* ?(MAC_GRAPHICS_ENV && BACKWARD_COMPAT) */
     } /* "MACgraphics" */
 
-    /* OK, if we still haven't recognized the option, check the boolean
-     * options list
+    /*
+     * 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, TRUE)) {
@@ -4024,8 +4425,7 @@ boolean tinitial, tfrom_file;
             }
 
             op = string_for_opt(opts, TRUE);
-
-            if (op) {
+            if (op != empty_optstr) {
                 if (negated) {
                     config_error_add(
                            "Negated boolean '%s' should not have a parameter",
@@ -4041,6 +4441,11 @@ boolean tinitial, tfrom_file;
                     return FALSE;
                 }
             }
+            if (iflags.debug_fuzzer && !initial) {
+                /* don't randomly toggle this/these */
+                if (boolopt[i].addr == &flags.silent)
+                    return TRUE;
+            }
 
             *(boolopt[i].addr) = !negated;
 
@@ -4075,13 +4480,15 @@ boolean tinitial, tfrom_file;
                 || boolopt[i].addr == &flags.showscore
 #endif
                 || boolopt[i].addr == &flags.showexp) {
-#ifdef STATUS_HILITES
-                status_initialize(REASSESS_ONLY);
-#endif
+                if (VIA_WINDOWPORT())
+                    status_initialize(REASSESS_ONLY);
                 context.botl = TRUE;
-            } else if (boolopt[i].addr == &flags.invlet_constant) {
-                if (flags.invlet_constant)
+            } else if (boolopt[i].addr == &flags.invlet_constant
+                       || boolopt[i].addr == &flags.sortpack
+                       || boolopt[i].addr == &iflags.implicit_uncursed) {
+                if (!flags.invlet_constant)
                     reassign();
+                update_inventory();
             } else if (boolopt[i].addr == &flags.lit_corridor
                        || boolopt[i].addr == &flags.dark_room) {
                 /*
@@ -4098,15 +4505,30 @@ boolean tinitial, tfrom_file;
             } else if (boolopt[i].addr == &flags.showrace
                        || boolopt[i].addr == &iflags.use_inverse
                        || boolopt[i].addr == &iflags.hilite_pile
-                       || boolopt[i].addr == &iflags.hilite_pet
+                       || boolopt[i].addr == &iflags.perm_invent
+#ifdef CURSES_GRAPHICS
+                       || boolopt[i].addr == &iflags.cursesgraphics
+#endif
                        || boolopt[i].addr == &iflags.wc_ascii_map
                        || boolopt[i].addr == &iflags.wc_tiled_map) {
                 need_redraw = TRUE;
-#ifdef STATUS_HILITES
-            } else if (boolopt[i].addr == &iflags.wc2_hitpointbar) {
-                status_initialize(REASSESS_ONLY);
-                need_redraw = TRUE;
+            } else if (boolopt[i].addr == &iflags.hilite_pet) {
+#ifdef CURSES_GRAPHICS
+                if (WINDOWPORT("curses")) {
+                    /* if we're enabling hilite_pet and petattr isn't set,
+                       set it to Inverse; if we're disabling, leave petattr
+                       alone so that re-enabling will get current value back */
+                    if (iflags.hilite_pet && !iflags.wc2_petattr)
+                        iflags.wc2_petattr = curses_read_attrs("I");
+                }
 #endif
+                need_redraw = TRUE;
+            } else if (boolopt[i].addr == &iflags.wc2_hitpointbar) {
+                if (VIA_WINDOWPORT()) {
+                    /* [is reassessment really needed here?] */
+                    status_initialize(REASSESS_ONLY);
+                    need_redraw = TRUE;
+                }
 #ifdef TEXTCOLOR
             } else if (boolopt[i].addr == &iflags.use_color) {
                 need_redraw = TRUE;
@@ -4118,6 +4540,9 @@ boolean tinitial, tfrom_file;
                         set_colors();
                 }
 #endif
+            } else if (boolopt[i].addr == &iflags.use_menu_color
+                       || boolopt[i].addr == &iflags.wc2_guicolor) {
+                update_inventory();
 #endif /* TEXTCOLOR */
             }
             return retval;
@@ -4125,7 +4550,7 @@ boolean tinitial, tfrom_file;
     }
 
     /* Is it a symbol? */
-    if (strstr(opts, "S_") == opts && parsesymbols(opts)) {
+    if (strstr(opts, "S_") == opts && parsesymbols(opts, PRIMARY)) {
         switch_symbols(TRUE);
         check_gold_symbol();
         return retval;
@@ -4206,7 +4631,7 @@ static NEARDATA const char *sortltype[] = { "none", "loot", "full" };
  * Convert the given string of object classes to a string of default object
  * symbols.
  */
-STATIC_OVL void
+void
 oc_to_str(src, dest)
 char *src, *dest;
 {
@@ -4235,8 +4660,8 @@ char from_ch, to_ch;
         mapped_menu_cmds[n_menu_mapped] = from_ch;
         mapped_menu_op[n_menu_mapped] = to_ch;
         n_menu_mapped++;
-        mapped_menu_cmds[n_menu_mapped] = 0;
-        mapped_menu_op[n_menu_mapped] = 0;
+        mapped_menu_cmds[n_menu_mapped] = '\0';
+        mapped_menu_op[n_menu_mapped] = '\0';
     }
 }
 
@@ -4290,36 +4715,55 @@ boolean dolist;
             putstr(win, 0, buf);
         }
     } else {
+        const char
+            fmt3[] = " %-12s       %-2s        %-2s  %s",
+            fmt2[] = " %-12s       %-2s        %-2s",
+            fmt1[] = " %10s  %-2s  %s",
+            fmt0[] = " %14s  %s";
+
         putstr(win, 0, "");
-        putstr(win, 0, "          Page    All items");
-        Sprintf(buf, "  Select   %s       %s",
+        putstr(win, 0, "Selection:       On page   Full menu");
+        Sprintf(buf, fmt2, "Select all",
                 visctrl(get_menu_cmd_key(MENU_SELECT_PAGE)),
                 visctrl(get_menu_cmd_key(MENU_SELECT_ALL)));
         putstr(win, 0, buf);
-        Sprintf(buf, "Deselect   %s       %s",
+        Sprintf(buf, fmt2, "Deselect all",
                 visctrl(get_menu_cmd_key(MENU_UNSELECT_PAGE)),
                 visctrl(get_menu_cmd_key(MENU_UNSELECT_ALL)));
         putstr(win, 0, buf);
-        Sprintf(buf, "  Invert   %s       %s",
+        Sprintf(buf, fmt2, "Invert all",
                 visctrl(get_menu_cmd_key(MENU_INVERT_PAGE)),
                 visctrl(get_menu_cmd_key(MENU_INVERT_ALL)));
         putstr(win, 0, buf);
+        Sprintf(buf, fmt3, "Text match", "",
+                visctrl(get_menu_cmd_key(MENU_SEARCH)),
+                "Search and toggle matching entries");
+        putstr(win, 0, buf);
         putstr(win, 0, "");
-        Sprintf(buf, "   Go to   %s   Next page",
-                visctrl(get_menu_cmd_key(MENU_NEXT_PAGE)));
+        putstr(win, 0, "Navigation:");
+        Sprintf(buf, fmt1, "Go to     ",
+                visctrl(get_menu_cmd_key(MENU_NEXT_PAGE)),
+                "Next page");
         putstr(win, 0, buf);
-        Sprintf(buf, "           %s   Previous page",
-                visctrl(get_menu_cmd_key(MENU_PREVIOUS_PAGE)));
+        Sprintf(buf, fmt1, "",
+                visctrl(get_menu_cmd_key(MENU_PREVIOUS_PAGE)),
+                "Previous page");
         putstr(win, 0, buf);
-        Sprintf(buf, "           %s   First page",
-                visctrl(get_menu_cmd_key(MENU_FIRST_PAGE)));
+        Sprintf(buf, fmt1, "",
+                visctrl(get_menu_cmd_key(MENU_FIRST_PAGE)),
+                "First page");
         putstr(win, 0, buf);
-        Sprintf(buf, "           %s   Last page",
-                visctrl(get_menu_cmd_key(MENU_LAST_PAGE)));
+        Sprintf(buf, fmt1, "",
+                visctrl(get_menu_cmd_key(MENU_LAST_PAGE)),
+                "Last page");
         putstr(win, 0, buf);
-        putstr(win, 0, "");
-        Sprintf(buf, "           %s   Search and toggle matching entries",
-                visctrl(get_menu_cmd_key(MENU_SEARCH)));
+        Sprintf(buf, fmt0, "SPACE", "Next page, if any, otherwise RETURN");
+        putstr(win, 0, buf);
+        Sprintf(buf, fmt0, "RETURN/ENTER",
+                "Finish menu with any selection(s) made");
+        putstr(win, 0, buf);
+        Sprintf(buf, fmt0, "ESCAPE",
+                "Cancel menu without selecting anything");
         putstr(win, 0, buf);
     }
 }
@@ -4332,7 +4776,10 @@ boolean dolist;
 
 static char fmtstr_doset[] = "%s%-15s [%s]   ";
 static char fmtstr_doset_tab[] = "%s\t[%s]";
+/*JP
 static char n_currently_set[] = "(%d currently set)";
+*/
+static char n_currently_set[] = "(%d\8cÂ\90Ý\92è\92\86)";
 
 /* doset('O' command) menu entries for compound options */
 STATIC_OVL void
@@ -4402,7 +4849,15 @@ int nset;
 int
 count_apes(VOID_ARGS)
 {
-    return count_ape_maps((int *) 0, (int *) 0);
+    int numapes = 0;
+    struct autopickup_exception *ape = apelist;
+
+    while (ape) {
+      numapes++;
+      ape = ape->next;
+    }
+
+    return numapes;
 }
 
 enum opt_other_enums {
@@ -4420,7 +4875,7 @@ static struct other_opts {
     int NDECL((*othr_count_func));
 } othropt[] = {
     { "autopickup exceptions", SET_IN_GAME, OPT_OTHER_APEXC, count_apes },
-    { "menucolors", SET_IN_GAME, OPT_OTHER_MENUCOLOR, count_menucolors },
+    { "menu colors", SET_IN_GAME, OPT_OTHER_MENUCOLOR, count_menucolors },
     { "message types", SET_IN_GAME, OPT_OTHER_MSGTYPE, msgtype_count },
 #ifdef STATUS_HILITES
     { "status hilite rules", SET_IN_GAME, OPT_OTHER_STATHILITE,
@@ -4434,7 +4889,7 @@ int
 doset() /* changing options via menu by Per Liboriussen */
 {
     static boolean made_fmtstr = FALSE;
-    char buf[BUFSZ], buf2[BUFSZ] = DUMMY;
+    char buf[BUFSZ];
     const char *name;
     int i = 0, pass, boolcount, pick_cnt, pick_idx, opt_indx;
     boolean *bool_p;
@@ -4463,17 +4918,14 @@ doset() /* changing options via menu by Per Liboriussen */
            and adjust the format string accordingly */
         longest_name_len = 0;
         for (pass = 0; pass <= 2; pass++)
-            for (i = 0; (name = ((pass == 0)
-                                 ? boolopt[i].name
-                                 : (pass == 1)
-                                   ? compopt[i].name
+            for (i = 0; (name = ((pass == 0) ? boolopt[i].name
+                                 : (pass == 1) ? compopt[i].name
                                    : othropt[i].name)) != 0; i++) {
                 if (pass == 0 && !boolopt[i].addr)
                     continue;
                 optflags = (pass == 0) ? boolopt[i].optflags
-                                       : (pass == 1)
-                                         ? compopt[i].optflags
-                                         : othropt[i].optflags;
+                           : (pass == 1) ? compopt[i].optflags
+                             : othropt[i].optflags;
                 if (optflags < startpass || optflags > endpass)
                     continue;
                 if ((is_wc_option(name) && !wc_supported(name))
@@ -4523,7 +4975,7 @@ doset() /* changing options via menu by Per Liboriussen */
     indexoffset = boolcount;
     any = zeroany;
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
              "Compounds (selecting will prompt for new value):",
              MENU_UNSELECTED);
@@ -4606,7 +5058,7 @@ doset() /* changing options via menu by Per Liboriussen */
                 }
 #endif
             } else if (opt_indx == OPT_OTHER_MENUCOLOR) {
-                    (void) special_handling("menucolors", setinitial,
+                    (void) special_handling("menu_colors", setinitial,
                                             fromfile);
             } else if (opt_indx == OPT_OTHER_MSGTYPE) {
                     (void) special_handling("msgtype", setinitial, fromfile);
@@ -4614,7 +5066,7 @@ doset() /* changing options via menu by Per Liboriussen */
                 /* boolean option */
                 Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "",
                         boolopt[opt_indx].name);
-                parseoptions(buf, setinitial, fromfile);
+                (void) parseoptions(buf, setinitial, fromfile);
                 if (wc_supported(boolopt[opt_indx].name)
                     || wc2_supported(boolopt[opt_indx].name))
                     preference_update(boolopt[opt_indx].name);
@@ -4624,24 +5076,28 @@ doset() /* changing options via menu by Per Liboriussen */
 
                 if (!special_handling(compopt[opt_indx].name, setinitial,
                                       fromfile)) {
+                    char abuf[BUFSZ];
+
 /*JP
                     Sprintf(buf, "Set %s to what?", compopt[opt_indx].name);
 */
                     Sprintf(buf, "%s\82É\89½\82ð\90Ý\92è\82·\82é\81H", compopt[opt_indx].name);
-                    getlin(buf, buf2);
-                    if (buf2[0] == '\033')
+                    abuf[0] = '\0';
+                    getlin(buf, abuf);
+                    if (abuf[0] == '\033')
                         continue;
-                    Sprintf(buf, "%s:%s", compopt[opt_indx].name, buf2);
+                    Sprintf(buf, "%s:", compopt[opt_indx].name);
+                    (void) strncat(eos(buf), abuf,
+                                   (sizeof buf - 1 - strlen(buf)));
                     /* pass the buck */
-                    parseoptions(buf, setinitial, fromfile);
+                    (void) parseoptions(buf, setinitial, fromfile);
                 }
                 if (wc_supported(compopt[opt_indx].name)
                     || wc2_supported(compopt[opt_indx].name))
                     preference_update(compopt[opt_indx].name);
             }
         }
-        free((genericptr_t) pick_list);
-        pick_list = (menu_item *) 0;
+        free((genericptr_t) pick_list), pick_list = (menu_item *) 0;
     }
 
     destroy_nhwindow(tmpwin);
@@ -4653,6 +5109,7 @@ doset() /* changing options via menu by Per Liboriussen */
     return 0;
 }
 
+/* common to msg-types, menu-colors, autopickup-exceptions */
 STATIC_OVL int
 handle_add_list_remove(optname, numtotal)
 const char *optname;
@@ -4666,22 +5123,22 @@ int numtotal;
         char letr;
         const char *desc;
     } action_titles[] = {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         { 'a', "add new %s" },         /* [0] */
 #else
         { 'a', "\90V\82µ\82¢%s\82ð\92Ç\89Á" },     /* [0] */
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         { 'l', "list %s" },            /* [1] */
 #else
         { 'l', "%s\82ð\88ê\97\97\95\\8e¦" },       /* [1] */
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         { 'r', "remove existing %s" }, /* [2] */
 #else
         { 'r', "\8aù\82É\82 \82é%s\82ð\8dí\8f\9c" },   /* [2] */
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         { 'x', "exit this menu" },     /* [3] */
 #else
         { 'x', "\82±\82Ì\83\81\83j\83\85\81[\82ð\95Â\82\82é" }, /* [3] */
@@ -4720,7 +5177,7 @@ int numtotal;
 }
 
 struct symsetentry *symset_list = 0; /* files.c will populate this with
-                                              list of available sets */
+                                      * list of available sets */
 
 STATIC_OVL boolean
 special_handling(optname, setinitial, setfromfile)
@@ -4816,7 +5273,8 @@ boolean setinitial, setfromfile;
         destroy_nhwindow(tmpwin);
     } else if (!strcmp("pickup_types", optname)) {
         /* parseoptions will prompt for the list of types */
-        parseoptions(strcpy(buf, "pickup_types"), setinitial, setfromfile);
+        (void) parseoptions(strcpy(buf, "pickup_types"),
+                            setinitial, setfromfile);
     } else if (!strcmp("disclose", optname)) {
         /* order of disclose_names[] must correspond to
            disclosure_options in decl.c */
@@ -4951,24 +5409,24 @@ boolean setinitial, setfromfile;
         start_menu(tmpwin);
         any = zeroany;
         any.a_char = GPCOORDS_COMPASS;
-        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMPASS,
-                 0, ATR_NONE, "compass ('east' or '3s' or '2n,4w')",
+        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMPASS, 0, ATR_NONE,
+                 "compass ('east' or '3s' or '2n,4w')",
                  (gp == GPCOORDS_COMPASS) ? MENU_SELECTED : MENU_UNSELECTED);
         any.a_char = GPCOORDS_COMFULL;
         add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_COMFULL, 0, ATR_NONE,
                  "full compass ('east' or '3south' or '2north,4west')",
                  (gp == GPCOORDS_COMFULL) ? MENU_SELECTED : MENU_UNSELECTED);
         any.a_char = GPCOORDS_MAP;
-        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_MAP,
-                 0, ATR_NONE, "map <x,y>",
+        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_MAP, 0, ATR_NONE,
+                 "map <x,y>",
                  (gp == GPCOORDS_MAP) ? MENU_SELECTED : MENU_UNSELECTED);
         any.a_char = GPCOORDS_SCREEN;
-        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_SCREEN,
-                 0, ATR_NONE, "screen [row,column]",
+        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_SCREEN, 0, ATR_NONE,
+                 "screen [row,column]",
                  (gp == GPCOORDS_SCREEN) ? MENU_SELECTED : MENU_UNSELECTED);
         any.a_char = GPCOORDS_NONE;
-        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_NONE,
-                 0, ATR_NONE, "none (no coordinates displayed)",
+        add_menu(tmpwin, NO_GLYPH, &any, GPCOORDS_NONE, 0, ATR_NONE,
+                 "none (no coordinates displayed)",
                  (gp == GPCOORDS_NONE) ? MENU_SELECTED : MENU_UNSELECTED);
         any.a_long = 0L;
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
@@ -4976,7 +5434,7 @@ boolean setinitial, setfromfile;
                 1, 0, COLNO - 1, ROWNO - 1,
                 flags.verbose ? "; column 0 unused, off left edge" : "");
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
-        if (strcmp(windowprocs.name, "tty"))
+        if (strcmp(windowprocs.name, "tty")) /* only show for non-tty */
             add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
        "screen: row is offset to accommodate tty interface's use of top line",
                      MENU_UNSELECTED);
@@ -5033,35 +5491,41 @@ boolean setinitial, setfromfile;
         }
         destroy_nhwindow(tmpwin);
     } else if (!strcmp("msg_window", optname)) {
-#ifdef TTY_GRAPHICS
-        /* by Christian W. Cooper */
-        menu_item *window_pick = (menu_item *) 0;
+#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
+        if (WINDOWPORT("tty") || WINDOWPORT("curses")) {
+            /* by Christian W. Cooper */
+            menu_item *window_pick = (menu_item *) 0;
 
-        tmpwin = create_nhwindow(NHW_MENU);
-        start_menu(tmpwin);
-        any = zeroany;
-        any.a_char = 's';
-        add_menu(tmpwin, NO_GLYPH, &any, 's', 0, ATR_NONE, "single",
-                 MENU_UNSELECTED);
-        any.a_char = 'c';
-        add_menu(tmpwin, NO_GLYPH, &any, 'c', 0, ATR_NONE, "combination",
-                 MENU_UNSELECTED);
-        any.a_char = 'f';
-        add_menu(tmpwin, NO_GLYPH, &any, 'f', 0, ATR_NONE, "full",
-                 MENU_UNSELECTED);
-        any.a_char = 'r';
-        add_menu(tmpwin, NO_GLYPH, &any, 'r', 0, ATR_NONE, "reversed",
-                 MENU_UNSELECTED);
+            tmpwin = create_nhwindow(NHW_MENU);
+            start_menu(tmpwin);
+            any = zeroany;
+            if (!WINDOWPORT("curses")) {
+                any.a_char = 's';
+                add_menu(tmpwin, NO_GLYPH, &any, 's', 0, ATR_NONE,
+                         "single", MENU_UNSELECTED);
+                any.a_char = 'c';
+                add_menu(tmpwin, NO_GLYPH, &any, 'c', 0, ATR_NONE,
+                         "combination", MENU_UNSELECTED);
+            }
+            any.a_char = 'f';
+            add_menu(tmpwin, NO_GLYPH, &any, 'f', 0, ATR_NONE, "full",
+                     MENU_UNSELECTED);
+            any.a_char = 'r';
+            add_menu(tmpwin, NO_GLYPH, &any, 'r', 0, ATR_NONE, "reversed",
+                     MENU_UNSELECTED);
 /*JP
-        end_menu(tmpwin, "Select message history display type:");
+            end_menu(tmpwin, "Select message history display type:");
 */
-        end_menu(tmpwin, "\83\81\83b\83Z\81[\83W\97\9a\97ð\82Ì\95\\8e¦\95û\96@\82ð\91I\91ð\82µ\82Ä\82­\82¾\82³\82¢\81F");
-        if (select_menu(tmpwin, PICK_ONE, &window_pick) > 0) {
-            iflags.prevmsg_window = window_pick->item.a_char;
-            free((genericptr_t) window_pick);
-        }
-        destroy_nhwindow(tmpwin);
-#endif
+            end_menu(tmpwin, "\83\81\83b\83Z\81[\83W\97\9a\97ð\82Ì\95\\8e¦\95û\96@\82ð\91I\91ð\82µ\82Ä\82­\82¾\82³\82¢\81F");
+            if (select_menu(tmpwin, PICK_ONE, &window_pick) > 0) {
+                iflags.prevmsg_window = window_pick->item.a_char;
+                free((genericptr_t) window_pick);
+            }
+            destroy_nhwindow(tmpwin);
+        } else
+#endif /* msg_window for tty or curses */
+            pline("'%s' option is not supported for '%s'.",
+                  optname, windowprocs.name);
     } else if (!strcmp("sortloot", optname)) {
         const char *sortl_name;
         menu_item *sortl_pick = (menu_item *) 0;
@@ -5108,7 +5572,7 @@ boolean setinitial, setfromfile;
         any.a_int = ALIGN_RIGHT;
         add_menu(tmpwin, NO_GLYPH, &any, 'r', 0, ATR_NONE, "right",
                  MENU_UNSELECTED);
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         Sprintf(abuf, "Select %s window placement relative to the map:",
                 msg ? "message" : "status");
 #else
@@ -5200,22 +5664,32 @@ boolean setinitial, setfromfile;
             iflags.menu_headings = mhattr;
     } else if (!strcmp("msgtype", optname)) {
         int opt_idx, nmt, mttyp;
-        char mtbuf[BUFSZ] = DUMMY;
+        char mtbuf[BUFSZ];
 
   msgtypes_again:
+ msgtypes_again:
         nmt = msgtype_count();
+/*JP
         opt_idx = handle_add_list_remove("message type", nmt);
+*/
+        opt_idx = handle_add_list_remove("\83\81\83b\83Z\81[\83W\8c^", nmt);
         if (opt_idx == 3) { /* done */
             return TRUE;
         } else if (opt_idx == 0) { /* add new */
+            mtbuf[0] = '\0';
+/*JP
             getlin("What new message pattern?", mtbuf);
+*/
+            getlin("\90V\82µ\82¢\83\81\83b\83Z\81[\83W\83p\83^\81[\83\93\81F", mtbuf);
             if (*mtbuf == '\033')
                 return TRUE;
             if (*mtbuf
                 && test_regex_pattern(mtbuf, (const char *)0)
                 && (mttyp = query_msgtype()) != -1
                 && !msgtype_add(mttyp, mtbuf)) {
+/*JP
                 pline("Error adding the message type.");
+*/
+                pline("\83\81\83b\83Z\81[\83W\8c^\92Ç\89Á\83G\83\89\81[\81D");
                 wait_synch();
             }
             goto msgtypes_again;
@@ -5239,13 +5713,18 @@ boolean setinitial, setfromfile;
                 if (strlen(tmp->pattern) > ln)
                     Strcat(strncat(mtbuf, tmp->pattern, ln - 3), "...\"");
                 else
-                    Strcat(mtbuf, "\"");
+                    Strcat(strcat(mtbuf, tmp->pattern), "\"");
                 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, mtbuf,
                          MENU_UNSELECTED);
                 tmp = tmp->next;
             }
+#if 0 /*JP:T*/
             Sprintf(mtbuf, "%s message types",
                     (opt_idx == 1) ? "List of" : "Remove which");
+#else
+            Strcpy(mtbuf, (opt_idx == 1) ?
+                    "\83\81\83b\83Z\81[\83W\8c^\88ê\97\97" : "\8dí\8f\9c\82·\82é\83\81\83b\83Z\81[\83W\8c^");
+#endif
             end_menu(tmpwin, mtbuf);
             pick_cnt = select_menu(tmpwin,
                                    (opt_idx == 1) ? PICK_NONE : PICK_ANY,
@@ -5260,28 +5739,53 @@ boolean setinitial, setfromfile;
             if (pick_cnt >= 0)
                 goto msgtypes_again;
         }
-    } else if (!strcmp("menucolors", optname)) {
+    } else if (!strcmp("menu_colors", optname)) {
         int opt_idx, nmc, mcclr, mcattr;
-        char mcbuf[BUFSZ] = DUMMY;
+        char mcbuf[BUFSZ];
 
   menucolors_again:
+ menucolors_again:
         nmc = count_menucolors();
+/*JP
         opt_idx = handle_add_list_remove("menucolor", nmc);
+*/
+        opt_idx = handle_add_list_remove("\83\81\83j\83\85\81[\90F", nmc);
         if (opt_idx == 3) { /* done */
+ menucolors_done:
+            /* in case we've made a change which impacts current persistent
+               inventory window; we don't track whether an actual changed
+               occurred, so just assume there was one and that it matters;
+               if we're wrong, a redundant update is cheap... */
+            if (iflags.use_menu_color)
+                update_inventory();
+
+            /* menu colors aren't being used; if any are defined, remind
+               player how to use them */
+            else if (nmc > 0)
+                pline(
+    "To have menu colors become active, toggle 'menucolors' option to True.");
             return TRUE;
+
         } else if (opt_idx == 0) { /* add new */
+            mcbuf[0] = '\0';
+/*JP
             getlin("What new menucolor pattern?", mcbuf);
+*/
+            getlin("\90V\82µ\82¢\83\81\83j\83\85\81[\90F\83p\83^\81[\83\93\81F", mcbuf);
             if (*mcbuf == '\033')
-                return TRUE;
+                goto menucolors_done;
             if (*mcbuf
                 && test_regex_pattern(mcbuf, (const char *)0)
                 && (mcclr = query_color((char *) 0)) != -1
                 && (mcattr = query_attr((char *) 0)) != -1
                 && !add_menu_coloring_parsed(mcbuf, mcclr, mcattr)) {
+/*JP
                 pline("Error adding the menu color.");
+*/
+                pline("\83\81\83j\83\85\81[\90F\92Ç\89Á\83G\83\89\81[\81D");
                 wait_synch();
             }
             goto menucolors_again;
+
         } else { /* list (1) or remove (2) */
             int pick_idx, pick_cnt;
             int mc_idx;
@@ -5289,6 +5793,7 @@ boolean setinitial, setfromfile;
             const char *sattr, *sclr;
             menu_item *pick_list = (menu_item *) 0;
             struct menucoloring *tmp = menu_colorings;
+            char clrbuf[QBUFSZ];
 
             tmpwin = create_nhwindow(NHW_MENU);
             start_menu(tmpwin);
@@ -5296,11 +5801,12 @@ boolean setinitial, setfromfile;
             mc_idx = 0;
             while (tmp) {
                 sattr = attr2attrname(tmp->attr);
-                sclr = clr2colorname(tmp->color);
+                sclr = strcpy(clrbuf, clr2colorname(tmp->color));
+                (void) strNsubst(clrbuf, " ", "-", 0);
                 any.a_int = ++mc_idx;
                 /* construct suffix */
                 Sprintf(buf, "\"\"=%s%s%s", sclr,
-                        (tmp->attr != ATR_NONE) ? " & " : "",
+                        (tmp->attr != ATR_NONE) ? "&" : "",
                         (tmp->attr != ATR_NONE) ? sattr : "");
                 /* now main string */
                 ln = sizeof buf - strlen(buf) - 1; /* length available */
@@ -5315,8 +5821,13 @@ boolean setinitial, setfromfile;
                          MENU_UNSELECTED);
                 tmp = tmp->next;
             }
+#if 0 /*JP:T*/
             Sprintf(mcbuf, "%s menu colors",
                     (opt_idx == 1) ? "List of" : "Remove which");
+#else
+            Strcpy(mcbuf, (opt_idx == 1) ?
+                    "\83\81\83j\83\85\81[\90F\88ê\97\97" : "\8dí\8f\9c\82·\82é\83\81\83j\83\85\81[\90F");
+#endif
             end_menu(tmpwin, mcbuf);
             pick_cnt = select_menu(tmpwin,
                                    (opt_idx == 1) ? PICK_NONE : PICK_ANY,
@@ -5332,16 +5843,22 @@ boolean setinitial, setfromfile;
                 goto menucolors_again;
         }
     } else if (!strcmp("autopickup_exception", optname)) {
-        int opt_idx, pass, totalapes = 0, numapes[2] = { 0, 0 };
-        char apebuf[1 + BUFSZ] = DUMMY; /* so &apebuf[1] is BUFSZ long for getlin() */
+        int opt_idx, numapes = 0;
+        char apebuf[2 + BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */
         struct autopickup_exception *ape;
 
-    ape_again:
-        totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]);
-        opt_idx = handle_add_list_remove("autopickup exception", totalapes);
+ ape_again:
+        numapes = count_apes();
+/*JP
+        opt_idx = handle_add_list_remove("autopickup exception", numapes);
+*/
+        opt_idx = handle_add_list_remove("\8e©\93®\8fE\82¢\97á\8aO", numapes);
         if (opt_idx == 3) { /* done */
             return TRUE;
         } else if (opt_idx == 0) { /* add new */
+            /* EDIT_GETLIN:  assume user doesn't user want previous
+               exception used as default input string for this one... */
+            apebuf[0] = apebuf[1] = '\0';
 /*JP
             getlin("What new autopickup exception pattern?", &apebuf[1]);
 */
@@ -5354,7 +5871,7 @@ boolean setinitial, setfromfile;
                 /* guarantee room for \" prefix and \"\0 suffix;
                    -2 is good enough for apebuf[] but -3 makes
                    sure the whole thing fits within normal BUFSZ */
-                apebuf[sizeof apebuf - 3] = '\0';
+                apebuf[sizeof apebuf - 2] = '\0';
                 Strcat(apebuf, "\"");
                 add_autopickup_exception(apebuf);
             }
@@ -5365,21 +5882,24 @@ boolean setinitial, setfromfile;
 
             tmpwin = create_nhwindow(NHW_MENU);
             start_menu(tmpwin);
-            for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
-                if (numapes[pass] == 0)
-                    continue;
-                ape = iflags.autopickup_exceptions[pass];
+            if (numapes) {
+                ape = apelist;
                 any = zeroany;
+#if 0 /*JP:T*/
                 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
-/*JP
-                         (pass == 0) ? "Never pickup" : "Always pickup",
-*/
-                         (pass == 0) ? "\8fí\82É\8fE\82í\82È\82¢" : "\8fí\82É\8fE\82¤",
+                         "Always pickup '<'; never pickup '>'",
                          MENU_UNSELECTED);
-                for (i = 0; i < numapes[pass] && ape; i++) {
+#else
+                add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
+                         "\8fí\82É\8fE\82¤ '<'; \8fí\82É\8fE\82í\82È\82¢ '>'",
+                         MENU_UNSELECTED);
+#endif
+                for (i = 0; i < numapes && ape; i++) {
                     any.a_void = (opt_idx == 1) ? 0 : ape;
-                    /* length of pattern plus quotes is less than BUFSZ */
-                    Sprintf(apebuf, "\"%s\"", ape->pattern);
+                    /* length of pattern plus quotes (plus '<'/'>') is
+                       less than BUFSZ */
+                    Sprintf(apebuf, "\"%c%s\"", ape->grab ? '<' : '>',
+                            ape->pattern);
                     add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, apebuf,
                              MENU_UNSELECTED);
                     ape = ape->next;
@@ -5411,154 +5931,169 @@ boolean setinitial, setfromfile;
     } else if (!strcmp("symset", optname)
                || !strcmp("roguesymset", optname)) {
         menu_item *symset_pick = (menu_item *) 0;
-        boolean primaryflag = (*optname == 's'),
-                rogueflag = (*optname == 'r'),
+        boolean rogueflag = (*optname == 'r'),
                 ready_to_switch = FALSE,
                 nothing_to_do = FALSE;
         char *symset_name, fmtstr[20];
         struct symsetentry *sl;
-        int res, which_set, setcount = 0, chosen = -2;
+        int res, which_set, setcount = 0, chosen = -2, defindx = 0;
 
         which_set = rogueflag ? ROGUESET : PRIMARY;
-
+        symset_list = (struct symsetentry *) 0;
         /* clear symset[].name as a flag to read_sym_file() to build list */
         symset_name = symset[which_set].name;
         symset[which_set].name = (char *) 0;
-        symset_list = (struct symsetentry *) 0;
 
         res = read_sym_file(which_set);
+        /* put symset name back */
+        symset[which_set].name = symset_name;
+
         if (res && symset_list) {
-            char symsetchoice[BUFSZ];
-            int let = 'a', biggest = 0, thissize = 0;
+            int thissize,
+                biggest = (int) (sizeof "Default Symbols" - sizeof ""),
+                big_desc = 0;
 
-            sl = symset_list;
-            while (sl) {
+            for (sl = symset_list; sl; sl = sl->next) {
                 /* check restrictions */
-                if ((!rogueflag && sl->rogue)
-                    || (!primaryflag && sl->primary)) {
-                    sl = sl->next;
+                if (rogueflag ? sl->primary : sl->rogue)
                     continue;
-                }
+#ifndef MAC_GRAPHICS_ENV
+                if (sl->handling == H_MAC)
+                    continue;
+#endif
+
                 setcount++;
                 /* find biggest name */
-                if (sl->name)
-                    thissize = strlen(sl->name);
+                thissize = sl->name ? (int) strlen(sl->name) : 0;
                 if (thissize > biggest)
                     biggest = thissize;
-                sl = sl->next;
+                thissize = sl->desc ? (int) strlen(sl->desc) : 0;
+                if (thissize > big_desc)
+                    big_desc = thissize;
             }
             if (!setcount) {
-                pline("There are no appropriate %ssymbol sets available.",
-                      (rogueflag) ? "rogue level "
-                                  : (primaryflag) ? "primary " : "");
+#if 0 /*JP:T*/
+                pline("There are no appropriate %s symbol sets available.",
+                      rogueflag ? "rogue level" : "primary");
+#else
+                pline("\93K\90Ø\82È%s\83V\83\93\83{\83\8b\90Ý\92è\82ª\82 \82è\82Ü\82¹\82ñ\81D",
+                      rogueflag ? "rogue\83\8c\83x\83\8b" : "\97D\90æ");
+#endif
                 return TRUE;
             }
 
-            Sprintf(fmtstr, "%%-%ds %%s", biggest + 5);
+            Sprintf(fmtstr, "%%-%ds %%s", biggest + 2);
             tmpwin = create_nhwindow(NHW_MENU);
             start_menu(tmpwin);
             any = zeroany;
-            any.a_int = 1;
-            add_menu(tmpwin, NO_GLYPH, &any, let++, 0, ATR_NONE,
-                     "Default Symbols", MENU_UNSELECTED);
+            any.a_int = 1; /* -1 + 2 [see 'if (sl->name) {' below]*/
+            if (!symset_name)
+                defindx = any.a_int;
+            add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
+                     "Default Symbols",
+                     (any.a_int == defindx) ? MENU_SELECTED
+                                            : MENU_UNSELECTED);
 
-            sl = symset_list;
-            while (sl) {
+            for (sl = symset_list; sl; sl = sl->next) {
                 /* check restrictions */
-                if ((!rogueflag && sl->rogue)
-                    || (!primaryflag && sl->primary)) {
-                    sl = sl->next;
+                if (rogueflag ? sl->primary : sl->rogue)
                     continue;
-                }
+#ifndef MAC_GRAPHICS_ENV
+                if (sl->handling == H_MAC)
+                    continue;
+#endif
                 if (sl->name) {
+                    /* +2: sl->idx runs from 0 to N-1 for N symsets;
+                       +1 because Defaults are implicitly in slot [0];
+                       +1 again so that valid data is never 0 */
                     any.a_int = sl->idx + 2;
-                    Sprintf(symsetchoice, fmtstr, sl->name,
-                            sl->desc ? sl->desc : "");
-                    add_menu(tmpwin, NO_GLYPH, &any, let, 0, ATR_NONE,
-                             symsetchoice, MENU_UNSELECTED);
-                    if (let == 'z')
-                        let = 'A';
-                    else
-                        let++;
+                    if (symset_name && !strcmpi(sl->name, symset_name))
+                        defindx = any.a_int;
+                    Sprintf(buf, fmtstr, sl->name, sl->desc ? sl->desc : "");
+                    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
+                             (any.a_int == defindx) ? MENU_SELECTED
+                                                    : MENU_UNSELECTED);
                 }
-                sl = sl->next;
             }
+#if 0 /*JP:T*/
             Sprintf(buf, "Select %ssymbol set:",
                     rogueflag ? "rogue level " : "");
+#else
+            Sprintf(buf, "%s\83V\83\93\83{\83\8b\90Ý\92è\82ð\91I\91ð\82µ\82Ä\82­\82¾\82³\82¢\81F",
+                    rogueflag ? "rogue\83\8c\83x\83\8b" : "");
+#endif
             end_menu(tmpwin, buf);
-            if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
-                chosen = symset_pick->item.a_int - 2;
+            n = select_menu(tmpwin, PICK_ONE, &symset_pick);
+            if (n > 0) {
+                chosen = symset_pick[0].item.a_int;
+                /* if picking non-preselected entry yields 2, make sure
+                   that we're going with the non-preselected one */
+                if (n == 2 && chosen == defindx)
+                    chosen = symset_pick[1].item.a_int;
+                chosen -= 2; /* convert menu index to symset index;
+                              * "Default symbols" have index -1 */
                 free((genericptr_t) symset_pick);
+            } else if (n == 0 && defindx > 0) {
+                chosen = defindx - 2;
             }
             destroy_nhwindow(tmpwin);
 
             if (chosen > -1) {
                 /* chose an actual symset name from file */
-                sl = symset_list;
-                while (sl) {
-                    if (sl->idx == chosen) {
-                        if (symset_name) {
-                            free((genericptr_t) symset_name);
-                            symset_name = (char *) 0;
-                        }
-                        /* free the now stale attributes */
-                        clear_symsetentry(which_set, TRUE);
-
-                        /* transfer only the name of the symbol set */
-                        symset[which_set].name = dupstr(sl->name);
-                        ready_to_switch = TRUE;
+                for (sl = symset_list; sl; sl = sl->next)
+                    if (sl->idx == chosen)
                         break;
-                    }
-                    sl = sl->next;
+                if (sl) {
+                    /* free the now stale attributes */
+                    clear_symsetentry(which_set, TRUE);
+
+                    /* transfer only the name of the symbol set */
+                    symset[which_set].name = dupstr(sl->name);
+                    ready_to_switch = TRUE;
                 }
             } else if (chosen == -1) {
                 /* explicit selection of defaults */
                 /* free the now stale symset attributes */
-                if (symset_name) {
-                    free((genericptr_t) symset_name);
-                    symset_name = (char *) 0;
-                }
                 clear_symsetentry(which_set, TRUE);
             } else
                 nothing_to_do = TRUE;
         } else if (!res) {
             /* The symbols file could not be accessed */
+/*JP
             pline("Unable to access \"%s\" file.", SYMBOLS);
+*/
+            pline("\"%s\"\83t\83@\83C\83\8b\82É\83A\83N\83Z\83X\82Å\82«\82Ü\82¹\82ñ\81D", SYMBOLS);
             return TRUE;
         } else if (!symset_list) {
             /* The symbols file was empty */
+/*JP
             pline("There were no symbol sets found in \"%s\".", SYMBOLS);
+*/
+            pline("\"%s\"\82É\83V\83\93\83{\83\8b\90Ý\92è\82ª\82 \82è\82Ü\82¹\82ñ\81D", SYMBOLS);
             return TRUE;
         }
 
         /* clean up */
-        while (symset_list) {
-            sl = symset_list;
+        while ((sl = symset_list) != 0) {
+            symset_list = sl->next;
             if (sl->name)
-                free((genericptr_t) sl->name);
-            sl->name = (char *) 0;
-
+                free((genericptr_t) sl->name), sl->name = (char *) 0;
             if (sl->desc)
-                free((genericptr_t) sl->desc);
-            sl->desc = (char *) 0;
-
-            symset_list = sl->next;
+                free((genericptr_t) sl->desc), sl->desc = (char *) 0;
             free((genericptr_t) sl);
         }
 
         if (nothing_to_do)
             return TRUE;
 
-        if (!symset[which_set].name && symset_name)
-            symset[which_set].name = symset_name; /* not dupstr() here */
-
         /* Set default symbols and clear the handling value */
         if (rogueflag)
-            init_r_symbols();
+            init_rogue_symbols();
         else
-            init_l_symbols();
+            init_primary_symbols();
 
         if (symset[which_set].name) {
+            /* non-default symbols */
             if (read_sym_file(which_set)) {
                 ready_to_switch = TRUE;
             } else {
@@ -5577,7 +6112,6 @@ boolean setinitial, setfromfile;
             assign_graphics(PRIMARY);
         preference_update("symset");
         need_redraw = TRUE;
-        return TRUE;
 
     } else {
         /* didn't match any of the special options */
@@ -5596,68 +6130,44 @@ get_compopt_value(optname, buf)
 const char *optname;
 char *buf;
 {
-    char ocl[MAXOCLASSES + 1];
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     static const char none[] = "(none)", randomrole[] = "random",
-                      to_be_done[] = "(to be done)", defopt[] = "default",
-                      defbrief[] = "def";
+                      to_be_done[] = "(to be done)",
+                      defopt[] = "default", defbrief[] = "def";
 #else
     static const char none[] = "(\82È\82µ)", randomrole[] = "\83\89\83\93\83_\83\80",
-                      to_be_done[] = "(\96¢\90Ý\92è)", defopt[] = "\83f\83t\83H\83\8b\83g",
-                      defbrief[] = "def";
+                      to_be_done[] = "(\96¢\90Ý\92è)",
+                      defopt[] = "\83f\83t\83H\83\8b\83g", defbrief[] = "def";
 #endif
+    char ocl[MAXOCLASSES + 1];
     int i;
 
     buf[0] = '\0';
-    if (!strcmp(optname, "align_message"))
-#if 0 /*JP*/
+    if (!strcmp(optname, "align_message")
+        || !strcmp(optname, "align_status")) {
+        int which = !strcmp(optname, "align_status") ? iflags.wc_align_status
+                                                     : iflags.wc_align_message;
+#if 0 /*JP:T*/
         Sprintf(buf, "%s",
-                iflags.wc_align_message == ALIGN_TOP
-                    ? "top"
-                    : iflags.wc_align_message == ALIGN_LEFT
-                          ? "left"
-                          : iflags.wc_align_message == ALIGN_BOTTOM
-                                ? "bottom"
-                                : iflags.wc_align_message == ALIGN_RIGHT
-                                      ? "right"
-                                      : defopt);
+                (which == ALIGN_TOP) ? "top"
+                : (which == ALIGN_LEFT) ? "left"
+                  : (which == ALIGN_BOTTOM) ? "bottom"
+                    : (which == ALIGN_RIGHT) ? "right"
+                      : defopt);
 #else
         Sprintf(buf, "%s",
-                iflags.wc_align_message == ALIGN_TOP
-                    ? "\8fã\91¤"
-                    : iflags.wc_align_message == ALIGN_LEFT
-                          ? "\8d\91¤"
-                          : iflags.wc_align_message == ALIGN_BOTTOM
-                                ? "\89º\91¤"
-                                : iflags.wc_align_message == ALIGN_RIGHT
-                                      ? "\89E\91¤" : defopt);
-#endif
-    else if (!strcmp(optname, "align_status"))
+                (which == ALIGN_TOP) ? "\8fã\91¤"
+                : (which == ALIGN_LEFT) ? "\8d\91¤"
+                  : (which == ALIGN_BOTTOM) ? "\89º\91¤"
+                    : (which == ALIGN_RIGHT) ? "\89E\91¤"
+                      : defopt);
+#endif
+    } else if (!strcmp(optname, "align"))
 #if 0 /*JP*/
-        Sprintf(buf, "%s",
-                iflags.wc_align_status == ALIGN_TOP
-                    ? "top"
-                    : iflags.wc_align_status == ALIGN_LEFT
-                          ? "left"
-                          : iflags.wc_align_status == ALIGN_BOTTOM
-                                ? "bottom"
-                                : iflags.wc_align_status == ALIGN_RIGHT
-                                      ? "right"
-                                      : defopt);
-#else
-        Sprintf(buf, "%s",
-                iflags.wc_align_status == ALIGN_TOP
-                    ? "\8fã\91¤"
-                    : iflags.wc_align_status == ALIGN_LEFT
-                          ? "\8d\91¤"
-                          : iflags.wc_align_status == ALIGN_BOTTOM
-                                ? "\89º\91¤"
-                                : iflags.wc_align_status == ALIGN_RIGHT
-                                      ? "\89E\91¤"
-                                      : defopt);
-#endif
-    else if (!strcmp(optname, "align"))
         Sprintf(buf, "%s", rolestring(flags.initalign, aligns, adj));
+#else
+        Sprintf(buf, "%s", rolestring(flags.initalign, aligns, noun));
+#endif
 #ifdef WIN32
     else if (!strcmp(optname, "altkeyhandler"))
         Sprintf(buf, "%s",
@@ -5669,8 +6179,8 @@ char *buf;
 #ifdef BACKWARD_COMPAT
     else if (!strcmp(optname, "boulder"))
         Sprintf(buf, "%c",
-                iflags.bouldersym
-                    ? iflags.bouldersym
+                ov_primary_syms[SYM_BOULDER + SYM_OFF_X]
+                    ? ov_primary_syms[SYM_BOULDER + SYM_OFF_X]
                     : showsyms[(int) objects[BOULDER].oc_class + SYM_OFF_O]);
 #endif
     else if (!strcmp(optname, "catname"))
@@ -5788,6 +6298,25 @@ char *buf;
 #endif
     } else if (!strcmp(optname, "name")) {
         Sprintf(buf, "%s", plname);
+    } else if (!strcmp(optname, "mouse_support")) {
+#ifdef WIN32
+#define MOUSEFIX1 ", QuickEdit off"
+#define MOUSEFIX2 ", QuickEdit unchanged"
+#else
+#define MOUSEFIX1 ", O/S adjusted"
+#define MOUSEFIX2 ", O/S unchanged"
+#endif
+        static const char *mousemodes[][2] = {
+            { "0=off", "" },
+            { "1=on",  MOUSEFIX1 },
+            { "2=on",  MOUSEFIX2 },
+        };
+#undef MOUSEFIX1
+#undef MOUSEFIX2
+        int ms = iflags.wc_mouse_support;
+
+        if (ms >= 0 && ms <= 2)
+            Sprintf(buf, "%s%s", mousemodes[ms][0], mousemodes[ms][1]);
     } else if (!strcmp(optname, "number_pad")) {
         static const char *numpadmodes[] = {
 /*JP
@@ -5802,7 +6331,7 @@ char *buf;
             "4=on, phone layout, MSDOS compatible",
 */
             "4=\97L\8cø\81C\93d\98b\8e®\82Ì\94z\92u\81CMSDOS \8cÝ\8a·",
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             "-1=off, y & z swapped", /*[5]*/
 #else
             "-1=\96³\8cø\81Cy\82Æz\82ð\93ü\82ê\91Ö\82¦", /*[5]*/
@@ -5831,8 +6360,20 @@ char *buf;
             if (flags.paranoia_bits & paranoia[i].flagmask)
                 Sprintf(eos(tmpbuf), " %s", paranoia[i].argname);
         Strcpy(buf, tmpbuf[0] ? &tmpbuf[1] : "none");
+    } else if (!strcmp(optname, "petattr")) {
+#ifdef CURSES_GRAPHICS
+        if (WINDOWPORT("curses")) {
+            char tmpbuf[QBUFSZ];
+
+            Strcpy(buf, curses_fmt_attrs(tmpbuf));
+        } else
+#endif
+        if (iflags.wc2_petattr != 0)
+            Sprintf(buf, "0x%08x", iflags.wc2_petattr);
+        else
+            Strcpy(buf, defopt);
     } else if (!strcmp(optname, "pettype")) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat"
                            : (preferred_pet == 'd') ? "dog"
                              : (preferred_pet == 'h') ? "horse"
@@ -5897,7 +6438,7 @@ char *buf;
                 break;
             }
     } else if (!strcmp(optname, "player_selection")) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         Sprintf(buf, "%s", iflags.wc_player_selection ? "prompts" : "dialog");
 #else
         Sprintf(buf, "%s\93ü\97Í", iflags.wc_player_selection ? "\83v\83\8d\83\93\83v\83g" : "\83_\83C\83A\83\8d\83O");
@@ -5914,6 +6455,10 @@ char *buf;
             Sprintf(buf, "%ld (on: highlight status for %ld turns)",
                     iflags.hilite_delta, iflags.hilite_delta);
 #endif
+    } else if (!strcmp(optname,"statuslines")) {
+        if (wc2_supported(optname))
+            Strcpy(buf, (iflags.wc2_statuslines < 3) ? "2" : "3");
+        /* else default to "unknown" */
     } else if (!strcmp(optname, "suppress_alert")) {
         if (flags.suppress_alert == 0L)
             Strcpy(buf, none);
@@ -5925,6 +6470,16 @@ char *buf;
                 symset[PRIMARY].name ? symset[PRIMARY].name : "default");
         if (currentgraphics == PRIMARY && symset[PRIMARY].name)
             Strcat(buf, ", active");
+    } else if (!strcmp(optname, "term_cols")) {
+        if (iflags.wc2_term_cols)
+            Sprintf(buf, "%d", iflags.wc2_term_cols);
+        else
+            Strcpy(buf, defopt);
+    } else if (!strcmp(optname, "term_rows")) {
+        if (iflags.wc2_term_rows)
+            Sprintf(buf, "%d", iflags.wc2_term_rows);
+        else
+            Strcpy(buf, defopt);
     } else if (!strcmp(optname, "tile_file")) {
         Sprintf(buf, "%s",
                 iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
@@ -5961,6 +6516,12 @@ char *buf;
                 ttycolors[CLR_YELLOW], ttycolors[CLR_BRIGHT_BLUE],
                 ttycolors[CLR_BRIGHT_MAGENTA], ttycolors[CLR_BRIGHT_CYAN]);
 #endif /* VIDEOSHADES */
+    } else if (!strcmp(optname,"windowborders")) {
+        Sprintf(buf, "%s",
+                (iflags.wc2_windowborders == 0) ? "0=off"
+                : (iflags.wc2_windowborders == 1) ? "1=on"
+                  : (iflags.wc2_windowborders == 2) ? "2=auto"
+                    : defopt);
     } else if (!strcmp(optname, "windowtype")) {
         Sprintf(buf, "%s", windowprocs.name);
     } else if (!strcmp(optname, "windowcolors")) {
@@ -5984,13 +6545,12 @@ char *buf;
 #endif
     }
 
-    if (buf[0])
-        return buf;
-    else
+    if (!buf[0])
 /*JP
-        return "unknown";
+        Strcpy(buf, "unknown");
 */
-        return "\95s\96¾";
+        Strcpy(buf, "\95s\96¾");
+    return buf;
 }
 
 int
@@ -6001,18 +6561,16 @@ dotogglepickup()
     flags.pickup = !flags.pickup;
     if (flags.pickup) {
         oc_to_str(flags.pickup_types, ocl);
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         Sprintf(buf, "ON, for %s objects%s", ocl[0] ? ocl : "all",
-                (iflags.autopickup_exceptions[AP_LEAVE]
-                 || iflags.autopickup_exceptions[AP_GRAB])
-                    ? ((count_ape_maps((int *) 0, (int *) 0) == 1)
+                (apelist)
+                    ? ((count_apes() == 1)
                            ? ", with one exception"
                            : ", with some exceptions")
                     : "");
 #else
         Sprintf(buf, "%s\83A\83C\83e\83\80\82É\82Â\82¢\82Ä\83I\83\93%s", ocl[0] ? ocl : "\91S\82Ä\82Ì",
-                (iflags.autopickup_exceptions[AP_LEAVE]
-                 || iflags.autopickup_exceptions[AP_GRAB])
+                (apelist)
                     ? "\81C\97á\8aO\82 \82è"
                     : "");
 #endif
@@ -6037,7 +6595,7 @@ const char *mapping;
         APE_regex_error[] = "regex error in AUTOPICKUP_EXCEPTION",
         APE_syntax_error[] = "syntax error in AUTOPICKUP_EXCEPTION";
 
-    struct autopickup_exception *ape, **apehead;
+    struct autopickup_exception *ape;
     char text[256], end;
     int n;
     boolean grab = FALSE;
@@ -6069,13 +6627,11 @@ const char *mapping;
         free((genericptr_t) ape);
         return 0;
     }
-    apehead = (grab) ? &iflags.autopickup_exceptions[AP_GRAB]
-                     : &iflags.autopickup_exceptions[AP_LEAVE];
 
     ape->pattern = dupstr(text);
     ape->grab = grab;
-    ape->next = *apehead;
-    *apehead = ape;
+    ape->next = apelist;
+    apelist = ape;
     return 1;
 }
 
@@ -6083,18 +6639,16 @@ STATIC_OVL void
 remove_autopickup_exception(whichape)
 struct autopickup_exception *whichape;
 {
-    struct autopickup_exception *ape, *prev = 0;
-    int chain = whichape->grab ? AP_GRAB : AP_LEAVE;
+    struct autopickup_exception *ape, *freeape, *prev = 0;
 
-    for (ape = iflags.autopickup_exceptions[chain]; ape;) {
+    for (ape = apelist; ape;) {
         if (ape == whichape) {
-            struct autopickup_exception *freeape = ape;
-
+            freeape = ape;
             ape = ape->next;
             if (prev)
                 prev->next = ape;
             else
-                iflags.autopickup_exceptions[chain] = ape;
+                apelist = ape;
             regex_free(freeape->regex);
             free((genericptr_t) freeape->pattern);
             free((genericptr_t) freeape);
@@ -6105,42 +6659,16 @@ struct autopickup_exception *whichape;
     }
 }
 
-STATIC_OVL int
-count_ape_maps(leave, grab)
-int *leave, *grab;
-{
-    struct autopickup_exception *ape;
-    int pass, totalapes, numapes[2];
-
-    numapes[0] = numapes[1] = 0;
-    for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
-        ape = iflags.autopickup_exceptions[pass];
-        while (ape) {
-            ape = ape->next;
-            numapes[pass]++;
-        }
-    }
-    totalapes = numapes[AP_LEAVE] + numapes[AP_GRAB];
-    if (leave)
-        *leave = numapes[AP_LEAVE];
-    if (grab)
-        *grab = numapes[AP_GRAB];
-    return totalapes;
-}
-
 void
 free_autopickup_exceptions()
 {
-    struct autopickup_exception *ape;
-    int pass;
-
-    for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
-        while ((ape = iflags.autopickup_exceptions[pass]) != 0) {
-            regex_free(ape->regex);
-            free((genericptr_t) ape->pattern);
-            iflags.autopickup_exceptions[pass] = ape->next;
-            free((genericptr_t) ape);
-        }
+    struct autopickup_exception *ape = apelist;
+
+    while ((ape = apelist) != 0) {
+      regex_free(ape->regex);
+      free((genericptr_t) ape->pattern);
+      apelist = ape->next;
+      free((genericptr_t) ape);
     }
 }
 
@@ -6178,8 +6706,9 @@ free_symsets()
 
 /* Parse the value of a SYMBOLS line from a config file */
 boolean
-parsesymbols(opts)
+parsesymbols(opts, which_set)
 register char *opts;
+int which_set;
 {
     int val;
     char *op, *symname, *strval;
@@ -6187,7 +6716,7 @@ register char *opts;
 
     if ((op = index(opts, ',')) != 0) {
         *op++ = 0;
-        if (!parsesymbols(op))
+        if (!parsesymbols(op, which_set))
             return FALSE;
     }
 
@@ -6210,7 +6739,10 @@ register char *opts;
 
     if (symp->range && symp->range != SYM_CONTROL) {
         val = sym_val(strval);
-        update_l_symset(symp, val);
+        if (which_set == ROGUESET)
+            update_ov_rogue_symset(symp, val);
+        else
+            update_ov_primary_symset(symp, val);
     }
     return TRUE;
 }
@@ -6242,9 +6774,9 @@ char *buf;
 
 int
 sym_val(strval)
-const char *strval;
+const char *strval; /* up to 4*BUFSZ-1 long; only first few chars matter */
 {
-    char buf[QBUFSZ];
+    char buf[QBUFSZ], tmp[QBUFSZ]; /* to hold trucated copy of 'strval' */
 
     buf[0] = '\0';
     if (!strval[0] || !strval[1]) { /* empty, or single character */
@@ -6265,8 +6797,9 @@ const char *strval;
         /* not simple quote or basic backslash;
            strip closing quote and let escapes() deal with it */
         } else {
-            char *p, tmp[QBUFSZ];
+            char *p;
 
+            /* +1: skip opening single quote */
             (void) strncpy(tmp, strval + 1, sizeof tmp - 1);
             tmp[sizeof tmp - 1] = '\0';
             if ((p = rindex(tmp, '\'')) != 0) {
@@ -6274,18 +6807,22 @@ const char *strval;
                 escapes(tmp, buf);
             } /* else buf[0] stays '\0' */
         }
-    } else /* not lone char nor single quote */
-        escapes(strval, buf);
+    } else { /* not lone char nor single quote */
+        (void) strncpy(tmp, strval, sizeof tmp - 1);
+        tmp[sizeof tmp - 1] = '\0';
+        escapes(tmp, buf);
+    }
 
     return (int) *buf;
 }
 
 /* data for option_help() */
 static const char *opt_intro[] = {
+    "",
 /*JP
-    "", "                 NetHack Options Help:", "",
+    "                 NetHack Options Help:", "",
 */
-    "", "               NetHack\83I\83v\83V\83\87\83\93\83w\83\8b\83v\81F", "",
+    "               NetHack\83I\83v\83V\83\87\83\93\83w\83\8b\83v\81F", "",
 #define CONFIG_SLOT 3 /* fill in next value at run-time */
     (char *) 0,
 #if !defined(MICRO) && !defined(MAC)
@@ -6305,9 +6842,10 @@ static const char *opt_intro[] = {
     "-- \97á\82¦\82Î\8e\9f\82Ì\82æ\82¤\82É\82µ\82Ü\82·\81F$ DEFINE NETHACKOPTIONS \"noautopickup,fruit:kumquat\"",
 #endif
 /*JP
-    "or press \"O\" while playing and use the menu.", "",
+    "or press \"O\" while playing and use the menu.",
 */
     "\82à\82µ\82­\82Í\83Q\81[\83\80\83v\83\8c\83C\92\86\82É\"O\"\83{\83^\83\93\82ð\89\9f\82·\82±\82Æ\82Å\90Ý\92è\89Â\94\\82Å\82·\81D",
+    "",
 /*JP
  "Boolean options (which can be negated by prefixing them with '!' or \"no\"):",
 */
@@ -6322,9 +6860,10 @@ static const char *opt_epilog[] = {
 */
     "\83I\83v\83V\83\87\83\93\82É\82Í\83Q\81[\83\80\8aJ\8en\91O\82Ì\82Ý\82É\82µ\82©\90Ý\92è\82Å\82«\82È\82¢\82à\82Ì\82ª\82 \82è\82Ü\82·\81D",
 /*JP
-    "items will not be selectable in the 'O' command's menu.", (char *) 0
+    "items will not be selectable in the 'O' command's menu.",
 */
-    "\82»\82ê\82ç\82Í'O'\83R\83}\83\93\83h\82Ì\83\81\83j\83\85\81[\82Å\82Í\91I\91ð\82·\82é\82±\82Æ\82ª\82Å\82«\82Ü\82¹\82ñ\81D", (char *) 0
+    "\82»\82ê\82ç\82Í'O'\83R\83}\83\93\83h\82Ì\83\81\83j\83\85\81[\82Å\82Í\91I\91ð\82·\82é\82±\82Æ\82ª\82Å\82«\82Ü\82¹\82ñ\81D",
+    (char *) 0
 };
 
 void
@@ -6427,11 +6966,11 @@ struct fruit *replace_fruit;
 {
     register int i;
     register struct fruit *f;
-    int highest_fruit_id = 0;
+    int highest_fruit_id = 0, globpfx;
     char buf[PL_FSIZ], altname[PL_FSIZ];
     boolean user_specified = (str == pl_fruit);
     /* if not user-specified, then it's a fruit name for a fruit on
-     * a bones level...
+     * a bones level or from orctown raider's loot...
      */
 
     /* Note: every fruit has an id (kept in obj->spe) of at least 1;
@@ -6442,39 +6981,54 @@ struct fruit *replace_fruit;
 
         /* force fruit to be singular; this handling is not
            needed--or wanted--for fruits from bones because
-           they already received it in their original game */
+           they already received it in their original game;
+           str==pl_fruit but makesingular() creates a copy
+           so we need to copy that back into pl_fruit */
         nmcpy(pl_fruit, makesingular(str), PL_FSIZ);
+        /* (assertion doesn't matter; we use 'pl_fruit' from here on out) */
         /* assert( str == pl_fruit ); */
 
         /* disallow naming after other foods (since it'd be impossible
-         * to tell the difference)
+         * to tell the difference); globs might have a size prefix which
+         * needs to be skipped in order to match the object type name
          */
+        globpfx = (!strncmp(pl_fruit, "small ", 6)
+                   || !strncmp(pl_fruit, "large ", 6)) ? 6
+                  : (!strncmp(pl_fruit, "very large ", 11)) ? 11
+                    : 0;
         for (i = bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) {
-            if (!strcmp(OBJ_NAME(objects[i]), pl_fruit)) {
+            if (!strcmp(OBJ_NAME(objects[i]), pl_fruit)
+                || (globpfx > 0
+                    && !strcmp(OBJ_NAME(objects[i]), &pl_fruit[globpfx]))) {
                 found = TRUE;
                 break;
             }
         }
-        {
+        if (!found) {
             char *c;
 
             for (c = pl_fruit; *c >= '0' && *c <= '9'; c++)
                 continue;
-            if (isspace((uchar) *c) || *c == 0)
+            if (!*c || isspace((uchar) *c))
                 numeric = TRUE;
         }
         if (found || numeric
-            || !strncmp(str, "cursed ", 7)
-            || !strncmp(str, "uncursed ", 9)
-            || !strncmp(str, "blessed ", 8)
-            || !strncmp(str, "partly eaten ", 13)
-            || (!strncmp(str, "tin of ", 7)
-                && (!strcmp(str + 7, "spinach")
-                    || name_to_mon(str + 7) >= LOW_PM))
-            || !strcmp(str, "empty tin")
-            || ((str_end_is(str, " corpse")
-                 || str_end_is(str, " egg"))
-                && name_to_mon(str) >= LOW_PM)) {
+            /* these checks for applying food attributes to actual items
+               are case sensitive; "glob of foo" is caught by 'found'
+               if 'foo' is a valid glob; when not valid, allow it as-is */
+            || !strncmp(pl_fruit, "cursed ", 7)
+            || !strncmp(pl_fruit, "uncursed ", 9)
+            || !strncmp(pl_fruit, "blessed ", 8)
+            || !strncmp(pl_fruit, "partly eaten ", 13)
+            || (!strncmp(pl_fruit, "tin of ", 7)
+                && (!strcmp(pl_fruit + 7, "spinach")
+                    || name_to_mon(pl_fruit + 7) >= LOW_PM))
+            || !strcmp(pl_fruit, "empty tin")
+            || (!strcmp(pl_fruit, "glob")
+                || (globpfx > 0 && !strcmp("glob", &pl_fruit[globpfx])))
+            || ((str_end_is(pl_fruit, " corpse")
+                 || str_end_is(pl_fruit, " egg"))
+                && name_to_mon(pl_fruit) >= LOW_PM)) {
             Strcpy(buf, pl_fruit);
             Strcpy(pl_fruit, "candied ");
             nmcpy(pl_fruit + 8, buf, PL_FSIZ - 8);
@@ -6492,11 +7046,11 @@ struct fruit *replace_fruit;
             /* replace_fruit is already part of the fruit chain;
                update it in place rather than looking it up again */
             f = replace_fruit;
-            copynchars(f->fname, str, PL_FSIZ - 1);
+            copynchars(f->fname, pl_fruit, PL_FSIZ - 1);
             goto nonew;
         }
     } else {
-        /* not user_supplied, so assumed to be from bones */
+        /* not user_supplied, so assumed to be from bones (or orc gang) */
         copynchars(altname, str, PL_FSIZ - 1);
         sanitize_name(altname);
         flags.made_fruit = TRUE; /* for safety.  Any fruit name added from a
@@ -6610,10 +7164,30 @@ char *class_select;
                 break;
         }
     }
+    if (category == 1 && next_accelerator <= 'z') {
+        /* for objects, add "A - ' '  all classes", after a separator */
+        any = zeroany;
+        add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
+        any.a_int = (int) ' ';
+        Sprintf(buf, "%c  %s", (char) any.a_int, "all classes of objects");
+        /* we won't preselect this even if the incoming list is empty;
+           having it selected means that it would have to be explicitly
+           de-selected in order to select anything else */
+        add_menu(win, NO_GLYPH, &any, 'A', 0, ATR_NONE, buf, MENU_UNSELECTED);
+    }
     end_menu(win, prompt);
     n = select_menu(win, way ? PICK_ANY : PICK_ONE, &pick_list);
     destroy_nhwindow(win);
     if (n > 0) {
+        if (category == 1) {
+            /* for object classes, first check for 'all'; it means 'use
+               a blank list' rather than 'collect every possible choice' */
+            for (i = 0; i < n; ++i)
+                if (pick_list[i].item.a_int == ' ') {
+                    pick_list[0].item.a_int = ' ';
+                    n = 1; /* return 1; also an implicit 'break;' */
+                }
+        }
         for (i = 0; i < n; ++i)
             *class_select++ = (char) pick_list[i].item.a_int;
         free((genericptr_t) pick_list);
@@ -6675,6 +7249,12 @@ static struct wc_Opt wc2_options[] = {
     { "status hilite rules", WC2_HILITE_STATUS },
     /* statushilites doesn't have its own bit */
     { "statushilites", WC2_HILITE_STATUS },
+    { "term_cols", WC2_TERM_SIZE },
+    { "term_rows", WC2_TERM_SIZE },
+    { "petattr", WC2_PETATTR },
+    { "guicolor", WC2_GUICOLOR },
+    { "statuslines", WC2_STATUSLINES },
+    { "windowborders", WC2_WINDOWBORDERS },
     { (char *) 0, 0L }
 };