1 /* NetHack 3.6 options.c $NHDT-Date: 1448241657 2015/11/23 01:20:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.243 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
10 #ifdef OPTION_LISTS_ONLY /* (AMIGA) external program for opt lists */
14 NEARDATA struct flag flags; /* provide linkage */
16 NEARDATA struct sysflag sysflags; /* provide linkage */
18 NEARDATA struct instance_flags iflags; /* provide linkage */
26 #define BACKWARD_COMPAT
29 #ifdef DEFAULT_WC_TILED_MAP
30 #define PREFER_TILED TRUE
32 #define PREFER_TILED FALSE
35 #define MESSAGE_OPTION 1
36 #define STATUS_OPTION 2
41 #define PILE_LIMIT_DFLT 5
44 * NOTE: If you add (or delete) an option, please update the short
45 * options help (option_help()), the long options help (dat/opthelp),
46 * and the current options setting display function (doset()),
47 * and also the Guidebooks.
49 * The order matters. If an option is a an initial substring of another
50 * option (e.g. time and timed_delay) the shorter one must come first.
53 static struct Bool_Opt {
55 boolean *addr, initvalue;
58 { "acoustics", &flags.acoustics, TRUE, SET_IN_GAME },
59 #if defined(SYSFLAGS) && defined(AMIGA)
60 /* Amiga altmeta causes Alt+key to be converted into Meta+key by
61 low level nethack code; on by default, can be toggled off if
62 Alt+key is needed for some ASCII chars on non-ASCII keyboard */
63 { "altmeta", &sysflags.altmeta, TRUE, DISP_IN_GAME },
66 /* non-Amiga altmeta causes nethack's top level command loop to treat
67 two character sequence "ESC c" as M-c, for terminals or emulators
68 which send "ESC c" when Alt+c is pressed; off by default, enabling
69 this can potentially make trouble if user types ESC when nethack
70 is honoring this conversion request (primarily after starting a
71 count prefix prior to a command and then deciding to cancel it) */
72 { "altmeta", &iflags.altmeta, FALSE, SET_IN_GAME },
74 { "altmeta", (boolean *) 0, TRUE, DISP_IN_GAME },
77 { "ascii_map", &iflags.wc_ascii_map, !PREFER_TILED, SET_IN_GAME }, /*WC*/
78 #if defined(SYSFLAGS) && defined(MFLOPPY)
79 { "asksavedisk", &sysflags.asksavedisk, FALSE, SET_IN_GAME },
81 { "asksavedisk", (boolean *) 0, FALSE, SET_IN_FILE },
83 { "autodig", &flags.autodig, FALSE, SET_IN_GAME },
84 { "autoopen", &flags.autoopen, TRUE, SET_IN_GAME },
85 { "autopickup", &flags.pickup, TRUE, SET_IN_GAME },
86 { "autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME },
87 #if defined(MICRO) && !defined(AMIGA)
88 { "BIOS", &iflags.BIOS, FALSE, SET_IN_FILE },
90 { "BIOS", (boolean *) 0, FALSE, SET_IN_FILE },
92 { "blind", &u.uroleplay.blind, FALSE, DISP_IN_GAME },
93 { "bones", &flags.bones, TRUE, SET_IN_FILE },
95 { "checkpoint", &flags.ins_chkpt, TRUE, SET_IN_GAME },
97 { "checkpoint", (boolean *) 0, FALSE, SET_IN_FILE },
100 { "checkspace", &iflags.checkspace, TRUE, SET_IN_GAME },
102 { "checkspace", (boolean *) 0, FALSE, SET_IN_FILE },
104 { "clicklook", &iflags.clicklook, FALSE, SET_IN_GAME },
105 { "cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME },
106 #if defined(MICRO) || defined(WIN32)
107 { "color", &iflags.wc_color, TRUE, SET_IN_GAME }, /*WC*/
108 #else /* systems that support multiple terminals, many monochrome */
109 { "color", &iflags.wc_color, FALSE, SET_IN_GAME }, /*WC*/
111 { "confirm", &flags.confirm, TRUE, SET_IN_GAME },
112 { "dark_room", &flags.dark_room, TRUE, SET_IN_GAME },
113 { "eight_bit_tty", &iflags.wc_eight_bit_input, FALSE,
114 SET_IN_GAME }, /*WC*/
116 { "extmenu", &iflags.extmenu, FALSE, SET_IN_GAME },
118 { "extmenu", (boolean *) 0, FALSE, SET_IN_FILE },
121 { "fast_map", &flags.fast_map, TRUE, SET_IN_GAME },
123 { "fast_map", (boolean *) 0, TRUE, SET_IN_FILE },
125 { "female", &flags.female, FALSE, DISP_IN_GAME },
126 { "fixinv", &flags.invlet_constant, TRUE, SET_IN_GAME },
127 #if defined(SYSFLAGS) && defined(AMIFLUSH)
128 { "flush", &sysflags.amiflush, FALSE, SET_IN_GAME },
130 { "flush", (boolean *) 0, FALSE, SET_IN_FILE },
132 { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE },
133 { "help", &flags.help, TRUE, SET_IN_GAME },
134 { "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/
135 { "hilite_pile", &iflags.hilite_pile, FALSE, SET_IN_GAME },
137 { "ignintr", &flags.ignintr, FALSE, SET_IN_GAME },
139 { "ignintr", (boolean *) 0, FALSE, SET_IN_FILE },
141 { "implicit_uncursed", &iflags.implicit_uncursed, TRUE, SET_IN_GAME },
142 { "large_font", &iflags.obsolete, FALSE, SET_IN_FILE }, /* OBSOLETE */
143 { "legacy", &flags.legacy, TRUE, DISP_IN_GAME },
144 { "lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME },
145 { "lootabc", &flags.lootabc, FALSE, SET_IN_GAME },
147 { "mail", &flags.biff, TRUE, SET_IN_GAME },
149 { "mail", (boolean *) 0, TRUE, SET_IN_FILE },
151 { "mention_walls", &iflags.mention_walls, FALSE, SET_IN_GAME },
152 { "menucolors", &iflags.use_menu_color, FALSE, SET_IN_GAME },
153 /* for menu debugging only*/
154 { "menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_GAME },
155 { "menu_objsyms", &iflags.menu_head_objsym, FALSE, SET_IN_GAME },
156 { "mouse_support", &iflags.wc_mouse_support, TRUE, DISP_IN_GAME }, /*WC*/
158 { "news", &iflags.news, TRUE, DISP_IN_GAME },
160 { "news", (boolean *) 0, FALSE, SET_IN_FILE },
162 { "nudist", &u.uroleplay.nudist, FALSE, DISP_IN_GAME },
163 { "null", &flags.null, TRUE, SET_IN_GAME },
164 #if defined(SYSFLAGS) && defined(MAC)
165 { "page_wait", &sysflags.page_wait, TRUE, SET_IN_GAME },
167 { "page_wait", (boolean *) 0, FALSE, SET_IN_FILE },
169 { "perm_invent", &flags.perm_invent, FALSE, SET_IN_GAME },
170 { "pickup_thrown", &flags.pickup_thrown, TRUE, SET_IN_GAME },
171 { "popup_dialog", &iflags.wc_popup_dialog, FALSE, SET_IN_GAME }, /*WC*/
172 { "preload_tiles", &iflags.wc_preload_tiles, TRUE, DISP_IN_GAME }, /*WC*/
173 { "pushweapon", &flags.pushweapon, FALSE, SET_IN_GAME },
174 #if defined(MICRO) && !defined(AMIGA)
175 { "rawio", &iflags.rawio, FALSE, DISP_IN_GAME },
177 { "rawio", (boolean *) 0, FALSE, SET_IN_FILE },
179 { "rest_on_space", &flags.rest_on_space, FALSE, SET_IN_GAME },
181 { "rlecomp", &iflags.rlecomp,
182 #if defined(COMPRESS) || defined(ZLIB_COMP)
189 { "safe_pet", &flags.safe_dog, TRUE, SET_IN_GAME },
190 { "sanity_check", &iflags.sanity_check, FALSE, SET_IN_GAME },
191 { "selectsaved", &iflags.wc2_selectsaved, TRUE, DISP_IN_GAME }, /*WC*/
192 { "showexp", &flags.showexp, FALSE, SET_IN_GAME },
193 { "showrace", &flags.showrace, FALSE, SET_IN_GAME },
195 { "showscore", &flags.showscore, FALSE, SET_IN_GAME },
197 { "showscore", (boolean *) 0, FALSE, SET_IN_FILE },
199 { "silent", &flags.silent, TRUE, SET_IN_GAME },
200 { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE },
201 { "sortpack", &flags.sortpack, TRUE, SET_IN_GAME },
202 { "sparkle", &flags.sparkle, TRUE, SET_IN_GAME },
203 { "splash_screen", &iflags.wc_splash_screen, TRUE, DISP_IN_GAME }, /*WC*/
204 { "standout", &flags.standout, FALSE, SET_IN_GAME },
205 #if defined(STATUS_VIA_WINDOWPORT) && defined(STATUS_HILITES)
206 { "statushilites", &iflags.use_status_hilites, TRUE, SET_IN_GAME },
208 { "statushilites", &iflags.use_status_hilites, FALSE, DISP_IN_GAME },
210 { "tiled_map", &iflags.wc_tiled_map, PREFER_TILED, DISP_IN_GAME }, /*WC*/
211 { "time", &flags.time, FALSE, SET_IN_GAME },
213 { "timed_delay", &flags.nap, TRUE, SET_IN_GAME },
215 { "timed_delay", (boolean *) 0, FALSE, SET_IN_GAME },
217 { "tombstone", &flags.tombstone, TRUE, SET_IN_GAME },
218 { "toptenwin", &iflags.toptenwin, FALSE, SET_IN_GAME },
219 { "travel", &flags.travelcmd, TRUE, SET_IN_GAME },
220 { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE },
222 { "use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME }, /*WC*/
224 { "use_inverse", &iflags.wc_inverse, FALSE, SET_IN_GAME }, /*WC*/
226 { "verbose", &flags.verbose, TRUE, SET_IN_GAME },
227 { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME },
229 { "zerocomp", &iflags.zerocomp,
230 #if defined(COMPRESS) || defined(ZLIB_COMP)
237 { (char *) 0, (boolean *) 0, FALSE, 0 }
240 /* compound options, for option_help() and external programs like Amiga
242 static struct Comp_Opt {
243 const char *name, *descr;
244 int size; /* for frontends and such allocating space --
245 * usually allowed size of data in game, but
246 * occasionally maximum reasonable size for
247 * typing when game maintains information in
248 * a different format */
252 { "align", "your starting alignment (lawful, neutral, or chaotic)", 8,
254 { "align", "
\83Q
\81[
\83\80\83X
\83^
\81[
\83g
\8e\9e\82Ì
\91®
\90« (lawful, neutral, or chaotic
\82Ì
\82¢
\82¸
\82ê
\82©)", 8,
257 { "align_message", "message window alignment", 20, DISP_IN_GAME }, /*WC*/
259 { "align_message", "
\83\81\83b
\83Z
\81[
\83W
\83E
\83B
\83\93\83h
\83E
\82Ì
\91µ
\82¦", 20, DISP_IN_GAME }, /*WC*/
262 { "align_status", "status window alignment", 20, DISP_IN_GAME }, /*WC*/
264 { "align_status", "
\8fó
\8bµ
\83E
\83B
\83\93\83h
\83E
\82Ì
\91µ
\82¦", 20, DISP_IN_GAME }, /*WC*/
267 { "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
269 { "altkeyhandler", "ALT
\83L
\81[
\83n
\83\93\83h
\83\89", 20, DISP_IN_GAME },
270 #ifdef BACKWARD_COMPAT
272 { "boulder", "deprecated (use S_boulder in sym file instead)", 1,
274 { "boulder", "
\8b\90\8aâ
\82ð
\95\
\8e¦
\82·
\82é
\83V
\83\93\83{
\83\8b\95¶
\8e\9a", 1,
278 { "catname", "the name of your (first) cat (e.g., catname:Tabby)",
280 { "catname", "
\96`
\8c¯
\82ð
\8b\9f\82É
\82·
\82é(
\8dÅ
\8f\89\82Ì)
\94L
\82Ì
\96¼
\91O (
\97á catname:
\82½
\82Ü)",
281 PL_PSIZ, DISP_IN_GAME },
283 { "disclose", "the kinds of information to disclose at end of game",
285 { "disclose", "
\83Q
\81[
\83\80\8fI
\97¹
\8e\9e\82É
\8c©
\82é
\8fî
\95ñ
\82Ì
\8eí
\97Þ",
286 sizeof(flags.end_disclose) * 2, SET_IN_GAME },
288 { "dogname", "the name of your (first) dog (e.g., dogname:Fang)", PL_PSIZ,
290 { "dogname", "
\96`
\8c¯
\82ð
\8b\9f\82É
\82·
\82é(
\8dÅ
\8f\89\82Ì)
\8c¢
\82Ì
\96¼
\91O (
\97á dogname:
\83|
\83`)", PL_PSIZ,
293 { "dungeon", "the symbols to use in drawing the dungeon map",
295 { "dungeon", "
\83_
\83\93\83W
\83\87\83\93\82ð
\95`
\89æ
\82·
\82é
\83V
\83\93\83{
\83\8b\95¶
\8e\9a",
296 MAXDCHARS + 1, SET_IN_FILE },
298 { "effects", "the symbols to use in drawing special effects",
300 { "effects", "
\93Á
\8eê
\8cø
\89Ê
\82ð
\95`
\89æ
\82·
\82é
\83V
\83\93\83{
\83\8b\95¶
\8e\9a",
301 MAXECHARS + 1, SET_IN_FILE },
303 { "font_map", "the font to use in the map window", 40,
305 { "font_map", "
\83}
\83b
\83v
\83E
\83B
\83\93\83h
\83E
\82É
\8eg
\97p
\82·
\82é
\83t
\83H
\83\93\83g", 40,
306 DISP_IN_GAME }, /*WC*/
308 { "font_menu", "the font to use in menus", 40, DISP_IN_GAME }, /*WC*/
310 { "font_menu", "
\83\81\83j
\83\85\81[
\82É
\8eg
\97p
\82·
\82é
\83t
\83H
\83\93\83g", 40, DISP_IN_GAME }, /*WC*/
313 { "font_message", "the font to use in the message window", 40,
315 { "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,
316 DISP_IN_GAME }, /*WC*/
318 { "font_size_map", "the size of the map font", 20, DISP_IN_GAME }, /*WC*/
320 { "font_size_map", "
\83}
\83b
\83v
\83t
\83H
\83\93\83g
\82Ì
\83T
\83C
\83Y", 20, DISP_IN_GAME }, /*WC*/
323 { "font_size_menu", "the size of the menu font", 20,
325 { "font_size_menu", "
\83\81\83j
\83\85\81[
\83t
\83H
\83\93\83g
\82Ì
\83T
\83C
\83Y", 20,
326 DISP_IN_GAME }, /*WC*/
328 { "font_size_message", "the size of the message font", 20,
330 { "font_size_message", "
\83\81\83b
\83Z
\81[
\83W
\83t
\83H
\83\93\83g
\82Ì
\83T
\83C
\83Y", 20,
331 DISP_IN_GAME }, /*WC*/
333 { "font_size_status", "the size of the status font", 20,
335 { "font_size_status", "
\8fó
\8bµ
\83t
\83H
\83\93\83g
\82Ì
\83T
\83C
\83Y", 20,
336 DISP_IN_GAME }, /*WC*/
338 { "font_size_text", "the size of the text font", 20,
340 { "font_size_text", "
\83e
\83L
\83X
\83g
\83t
\83H
\83\93\83g
\82Ì
\83T
\83C
\83Y", 20,
341 DISP_IN_GAME }, /*WC*/
343 { "font_status", "the font to use in status window", 40,
345 { "font_status", "
\8fó
\8bµ
\83E
\83B
\83\93\83h
\83E
\82É
\8eg
\97p
\82·
\82é
\83t
\83H
\83\93\83g", 40,
346 DISP_IN_GAME }, /*WC*/
348 { "font_text", "the font to use in text windows", 40,
350 { "font_text", "
\83e
\83L
\83X
\83g
\83E
\83B
\83\93\83h
\83E
\82É
\8eg
\97p
\82·
\82é
\83t
\83H
\83\93\83g", 40,
351 DISP_IN_GAME }, /*WC*/
353 { "fruit", "the name of a fruit you enjoy eating", PL_FSIZ, SET_IN_GAME },
355 { "fruit", "
\8dD
\95¨
\82Ì
\89Ê
\95¨
\82Ì
\96¼
\91O", PL_FSIZ, SET_IN_GAME },
357 { "gender", "your starting gender (male or female)", 8, DISP_IN_GAME },
359 { "gender", "
\83Q
\81[
\83\80\8aJ
\8en
\8e\9e\82Ì
\90«
\95Ê(male
\82Ü
\82½
\82Í female)", 8, DISP_IN_GAME },
361 { "horsename", "the name of your (first) horse (e.g., horsename:Silver)",
363 { "horsename", "
\96`
\8c¯
\82ð
\8b\9f\82É
\82·
\82é(
\8dÅ
\8f\89\82Ì)
\94n
\82Ì
\96¼
\91O (
\97á ghoulname:
\83V
\83\8b\83o
\81[)",
364 PL_PSIZ, DISP_IN_GAME },
366 { "map_mode", "map display mode under Windows", 20, DISP_IN_GAME }, /*WC*/
368 { "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*/
371 { "menustyle", "user interface for object selection", MENUTYPELEN,
373 { "menustyle", "
\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\91I
\91ð
\82·
\82é
\82Æ
\82«
\82Ì
\83\86\81[
\83U
\81[
\83C
\83\93\83^
\83t
\83F
\81[
\83X", MENUTYPELEN,
376 { "menu_deselect_all", "deselect all items in a menu", 4, SET_IN_FILE },
378 { "menu_deselect_all", "
\91S
\82Ä
\82Ì
\83A
\83C
\83e
\83\80\82ð
\94ñ
\91I
\91ð", 4, SET_IN_FILE },
380 { "menu_deselect_page", "deselect all items on this page of a menu", 4,
382 { "menu_deselect_page", "
\8c»
\8dÝ
\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\83y
\81[
\83W
\82Ì
\83A
\83C
\83e
\83\80\82ð
\94ñ
\91I
\91ð", 4,
385 { "menu_first_page", "jump to the first page in a menu", 4, SET_IN_FILE },
387 { "menu_first_page", "
\83\81\83j
\83\85\81[
\82Ì
\8dÅ
\8f\89\82Ì
\83y
\81[
\83W
\82Ö", 4, SET_IN_FILE },
389 { "menu_headings", "text attribute for menu headings", 9, SET_IN_GAME },
391 { "menu_headings", "
\8b
\92²
\81C
\94½
\93]
\82Ü
\82½
\82Í
\89º
\90ü
\82Å
\8eí
\97Þ
\82ð
\95\
\8e¦
\82·
\82é", 9, SET_IN_GAME },
393 { "menu_invert_all", "invert all items in a menu", 4, SET_IN_FILE },
395 { "menu_invert_all", "
\91S
\82Ä
\82Ì
\83A
\83C
\83e
\83\80\82ð
\94½
\93]", 4, SET_IN_FILE },
397 { "menu_invert_page", "invert all items on this page of a menu", 4,
399 { "menu_invert_page", "
\8c»
\8dÝ
\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\83y
\81[
\83W
\82Ì
\83A
\83C
\83e
\83\80\82ð
\94½
\93]",
402 { "menu_last_page", "jump to the last page in a menu", 4, SET_IN_FILE },
404 { "menu_last_page", "
\83\81\83j
\83\85\81[
\82Ì
\8dÅ
\8cã
\82Ì
\83y
\81[
\83W
\82Ö", 4, SET_IN_FILE },
406 { "menu_next_page", "goto the next menu page", 4, SET_IN_FILE },
408 { "menu_next_page", "
\8e\9f\82Ì
\83\81\83j
\83\85\81[
\82Ì
\83y
\81[
\83W
\82Ö", 4, SET_IN_FILE },
410 { "menu_previous_page", "goto the previous menu page", 4, SET_IN_FILE },
412 { "menu_previous_page", "
\91O
\82Ì
\83\81\83j
\83\85\81[
\82Ì
\83y
\81[
\83W
\82Ö", 4, SET_IN_FILE },
414 { "menu_search", "search for a menu item", 4, SET_IN_FILE },
416 { "menu_search", "
\83\81\83j
\83\85\81[
\82Ì
\8c\9f\8dõ", 4, SET_IN_FILE },
418 { "menu_select_all", "select all items in a menu", 4, SET_IN_FILE },
420 { "menu_select_all", "
\91S
\82Ä
\82Ì
\83A
\83C
\83e
\83\80\82ð
\91I
\91ð", 4, SET_IN_FILE },
422 { "menu_select_page", "select all items on this page of a menu", 4,
424 { "menu_select_page", "
\8c»
\8dÝ
\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\91S
\82Ä
\82Ì
\83A
\83C
\83e
\83\80\82ð
\91I
\91ð", 4,
427 { "monsters", "the symbols to use for monsters", MAXMCLASSES,
429 { "monsters", "
\83\82\83\93\83X
\83^
\81[
\82É
\8eg
\97p
\82³
\82ê
\82é
\83V
\83\93\83{
\83\8b\95¶
\8e\9a", MAXMCLASSES,
432 { "msghistory", "number of top line messages to save", 5, DISP_IN_GAME },
434 { "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 },
437 { "msg_window", "the type of message window required", 1, SET_IN_GAME },
439 {"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 },
442 { "msg_window", "the type of message window required", 1, SET_IN_FILE },
444 {"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 },
447 { "name", "your character's name (e.g., name:Merlin-W)", PL_NSIZ,
449 { "name", "
\82 \82È
\82½
\82Ì
\96¼
\91O (
\97á name:
\83}
\81[
\83\8a\83\93-W)", PL_NSIZ,
452 { "number_pad", "use the number pad for movement", 1, SET_IN_GAME },
454 { "number_pad", "
\83i
\83\93\83o
\81[
\83p
\83b
\83h
\82ð
\8eg
\97p
\82·
\82é", 1, SET_IN_GAME },
456 { "objects", "the symbols to use for objects", MAXOCLASSES, SET_IN_FILE },
458 { "objects", "
\83A
\83C
\83e
\83\80\82É
\8eg
\97p
\82³
\82ê
\82é
\83V
\83\93\83{
\83\8b\95¶
\8e\9a", MAXOCLASSES, SET_IN_FILE },
460 { "packorder", "the inventory order of the items in your pack",
462 { "packorder", "
\94w
\95\89\82¢
\91Ü
\93à
\82Ì
\95¨
\82Ì
\8f\87\94Ô",
463 MAXOCLASSES, SET_IN_GAME },
468 "palette (00c/880/-fff is blue/yellow/reverse white)", 15,
470 "
\83p
\83\8c\83b
\83g (00c/880/-fff
\82Í
\82»
\82ê
\82¼
\82ê
\90Â/
\89©/
\94½
\93]
\94\92\82ð
\8e¦
\82·)", 15,
474 "palette (adjust an RGB color in palette (color-R-G-B)", 15,
476 "
\83p
\83\8c\83b
\83g (
\83p
\83\8c\83b
\83g
\82ÌRGB
\90F
\82ð
\92²
\90®
\82·
\82é (
\90F-R-G-B)", 15,
481 { "hicolor", "same as palette, only order is reversed", 15, SET_IN_FILE },
483 { "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 },
487 { "paranoid_confirmation", "extra prompting in certain situations", 28,
490 { "paranoid_confirmation", "
\88ê
\95\94\82Ì
\8fó
\8bµ
\82Å
\92Ç
\89Á
\82Ì
\8am
\94F
\82ð
\82·
\82é", 28,
494 { "pettype", "your preferred initial pet type", 4, DISP_IN_GAME },
496 { "pettype", "
\82 \82È
\82½
\82Ì
\91I
\91ð
\82µ
\82½
\8f\89\8aú
\83y
\83b
\83g
\82Ì
\8eí
\97Þ", 4, DISP_IN_GAME },
498 { "pickup_burden", "maximum burden picked up before prompt", 20,
500 { "pickup_burden", "
\8fE
\82¤
\82Æ
\82«
\82É
\8dÅ
\91å
\89×
\8fd
\82É
\82È
\82é
\8eè
\91O
\82Å
\8am
\94F
\82·
\82é", 20,
503 { "pickup_types", "types of objects to pick up automatically",
505 { "pickup_types", "
\8e©
\93®
\82Å
\8fE
\82¢
\82 \82°
\82é
\95¨
\82Ì
\83V
\83\93\83{
\83\8b",
506 MAXOCLASSES, SET_IN_GAME },
508 { "pile_limit", "threshold for \"there are many objects here\"", 24,
511 { "pile_limit", "
\81u
\82±
\82±
\82É
\82Í
\82½
\82
\82³
\82ñ
\82Ì
\82à
\82Ì
\82ª
\82 \82é
\81v
\82Ì
\82µ
\82«
\82¢
\92l", 24,
515 { "playmode", "normal play, non-scoring explore mode, or debug mode", 8,
518 { "playmode", "
\92Ê
\8fí
\83\82\81[
\83h
\81C
\92T
\8c\9f\83\82\81[
\83h
\81C
\83f
\83o
\83b
\83O
\83\82\81[
\83h
\82Ì
\82¢
\82¸
\82ê
\82©", 8,
522 { "player_selection", "choose character via dialog or prompts", 12,
524 { "player_selection", "
\83L
\83\83\83\89\83N
\83^
\81[
\91I
\91ð
\82É
\83_
\83C
\83A
\83\8d\83O
\82â
\8am
\94F
\89æ
\96Ê
\82ð
\8eg
\82¤", 12,
527 { "race", "your starting race (e.g., Human, Elf)", PL_CSIZ,
529 { "race", "
\83Q
\81[
\83\80\8aJ
\8en
\8e\9e\82Ì
\8eí
\91° (
\97á Human, Elf)", PL_CSIZ,
532 { "role", "your starting role (e.g., Barbarian, Valkyrie)", PL_CSIZ,
534 { "role", "
\83Q
\81[
\83\80\8aJ
\8en
\8e\9e\82Ì
\90E
\8bÆ (
\97á Barbarian, Valkyrie)", PL_CSIZ,
537 { "runmode", "display frequency when `running' or `travelling'",
539 { "runmode", "
\83g
\83\89\83x
\83\8b\83R
\83}
\83\93\83h
\93\99\82Å
\82Ì
\98A
\91±
\88Ú
\93®
\8e\9e\82Ì
\95`
\89æ
\95p
\93x",
540 sizeof "teleport", SET_IN_GAME },
542 { "scores", "the parts of the score list you wish to see", 32,
544 { "scores", "
\83Q
\81[
\83\80\8fI
\97¹
\8e\9e\82É
\8c©
\82é
\83X
\83R
\83A
\82Ì
\8eí
\97Þ", 32,
547 { "scroll_amount", "amount to scroll map when scroll_margin is reached",
549 { "scroll_amount", "scroll_margin
\82É
\93Í
\82¢
\82½
\82Æ
\82«
\82Ì
\83}
\83b
\83v
\83X
\83N
\83\8d\81[
\83\8b\97Ê",
550 20, DISP_IN_GAME }, /*WC*/
552 { "scroll_margin", "scroll map when this far from the edge", 20,
554 { "scroll_margin", "
\83}
\83b
\83v
\92[
\82©
\82ç
\82Ì
\83}
\83b
\83v
\83X
\83N
\83\8d\81[
\83\8b\8aJ
\8en
\8b\97\97£", 20,
555 DISP_IN_GAME }, /*WC*/
557 { "sortloot", "sort object selection lists by description", 4,
559 { "sortloot", "
\95¨
\91Ì
\91I
\91ð
\83\8a\83X
\83g
\82ð
\90à
\96¾
\82Å
\83\
\81[
\83g
\82·
\82é", 4,
563 { "soundcard", "type of sound card to use", 20, SET_IN_FILE },
565 { "soundcard", "
\8eg
\97p
\82µ
\82Ä
\82¢
\82é
\83T
\83E
\83\93\83h
\83J
\81[
\83h
\82Ì
\8eí
\97Þ", 20, SET_IN_FILE },
568 { "symset", "load a set of display symbols from the symbols file", 70,
571 { "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,
576 "load a set of rogue display symbols from the symbols file", 70,
580 "symbols
\83t
\83@
\83C
\83\8b\82©
\82ç
\83\8d\81[
\83O
\83\8c\83x
\83\8b\82Ì
\95\
\8e¦
\83V
\83\93\83{
\83\8b\82Ì
\90Ý
\92è
\82ð
\93Ç
\82Ý
\8d\9e\82Þ", 70,
584 { "suppress_alert", "suppress alerts about version-specific features", 8,
586 { "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,
589 { "tile_width", "width of tiles", 20, DISP_IN_GAME }, /*WC*/
591 { "tile_width", "
\83^
\83C
\83\8b\82Ì
\95\9d", 20, DISP_IN_GAME }, /*WC*/
594 { "tile_height", "height of tiles", 20, DISP_IN_GAME }, /*WC*/
596 { "tile_height", "
\83^
\83C
\83\8b\82Ì
\8d\82\82³", 20, DISP_IN_GAME }, /*WC*/
599 { "tile_file", "name of tile file", 70, DISP_IN_GAME }, /*WC*/
601 { "tile_file", "
\83^
\83C
\83\8b\83t
\83@
\83C
\83\8b\82Ì
\96¼
\91O", 70, DISP_IN_GAME }, /*WC*/
604 { "traps", "the symbols to use in drawing traps", MAXTCHARS + 1,
606 { "traps", "ã©
\82ð
\95`
\89æ
\82·
\82é
\83V
\83\93\83{
\83\8b\95¶
\8e\9a", MAXTCHARS + 1,
609 { "vary_msgcount", "show more old messages at a time", 20,
611 { "vary_msgcount", "
\88ê
\93x
\82É
\95\
\8e¦
\82·
\82é
\83\81\83b
\83Z
\81[
\83W
\82Ì
\90\94", 20,
612 DISP_IN_GAME }, /*WC*/
615 { "video", "method of video updating", 20, SET_IN_FILE },
617 { "video", "
\8eg
\97p
\82·
\82é
\83r
\83f
\83I
\83\82\81[
\83h
\82ð
\90Ý
\92è
\82·
\82é", 20, SET_IN_FILE },
621 { "videocolors", "color mappings for internal screen routines", 40,
623 { "videocolors", "
\93à
\91 \83X
\83N
\83\8a\81[
\83\93\83\8b\81[
\83`
\83\93\97p
\82Ì
\83J
\83\89\81[
\83}
\83b
\83v
\82ð
\97p
\82¢
\82é", 40,
626 { "videoshades", "gray shades to map to black/gray/white", 32,
628 { "videoshades", "
\95\
\8e¦
\82É
\83O
\83\8c\83C
\83X
\83P
\81[
\83\8b\82ð
\97p
\82¢
\82é", 32,
633 { "subkeyvalue", "override keystroke value", 7, SET_IN_FILE },
635 {"subkeyvalue", "
\83L
\81[
\83}
\83b
\83s
\83\93\83O
\82ð
\95Ï
\8dX
\82·
\82é", 7, SET_IN_FILE },
638 { "windowcolors", "the foreground/background colors of windows", /*WC*/
640 { "windowcolors", "
\83E
\83B
\83\93\83h
\83E
\82ð
\8ew
\92è
\82µ
\82½
\91O
\8ci
\90F/
\94w
\8ci
\90F
\82Å
\95\
\8e¦
\82·
\82é", /*WC*/
644 { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
646 { "windowtype", "
\8eg
\97p
\82·
\82é
\83E
\83C
\83\93\83h
\83E
\83V
\83X
\83e
\83\80", WINTYPELEN, DISP_IN_GAME },
649 { "windowchain", "window processor to use", WINTYPELEN, SET_IN_SYS },
651 { "windowchain", "
\8eg
\97p
\82·
\82é
\83E
\83B
\83\93\83h
\83E
\83v
\83\8d\83Z
\83b
\83T", WINTYPELEN, SET_IN_SYS },
653 #ifdef BACKWARD_COMPAT
655 { "DECgraphics", "load DECGraphics display symbols", 70, SET_IN_FILE },
657 { "DECgraphics", "DECGraphics
\95\
\8e¦
\83V
\83\93\83{
\83\8b\82ð
\93Ç
\82Ý
\8d\9e\82Þ", 70, SET_IN_FILE },
659 { "IBMgraphics", "load IBMGraphics display symbols", 70, SET_IN_FILE },
661 { "IBMgraphics", "IBMGraphics
\95\
\8e¦
\83V
\83\93\83{
\83\8b\82ð
\93Ç
\82Ý
\8d\9e\82Þ", 70, SET_IN_FILE },
662 #ifdef MAC_GRAPHICS_ENV
664 { "Macgraphics", "load MACGraphics display symbols", 70, SET_IN_FILE },
666 { "Macgraphics", "MACGraphics
\95\
\8e¦
\83V
\83\93\83{
\83\8b\82ð
\93Ç
\82Ý
\8d\9e\82Þ", 70, SET_IN_FILE },
670 { "kcode", "
\92[
\96\96\82Ì
\8a¿
\8e\9a\83R
\81[
\83h,", 4, SET_IN_FILE },
672 { (char *) 0, (char *) 0, 0, 0 }
675 #ifdef OPTION_LISTS_ONLY
678 #else /* use rest of file */
680 extern struct symparse loadsyms[];
681 static boolean need_redraw; /* for doset() */
683 #if defined(TOS) && defined(TEXTCOLOR)
684 extern boolean colors_changed; /* in tos.c */
688 extern char *shade[3]; /* in sys/msdos/video.c */
689 extern char ttycolors[CLR_MAX]; /* in sys/msdos/video.c */
692 static char def_inv_order[MAXOCLASSES] = {
693 COIN_CLASS, AMULET_CLASS, WEAPON_CLASS, ARMOR_CLASS, FOOD_CLASS,
694 SCROLL_CLASS, SPBOOK_CLASS, POTION_CLASS, RING_CLASS, WAND_CLASS,
695 TOOL_CLASS, GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0,
699 * Default menu manipulation command accelerators. These may _not_ be:
701 * + a number - reserved for counts
702 * + an upper or lower case US ASCII letter - used for accelerators
703 * + ESC - reserved for escaping the menu
704 * + NULL, CR or LF - reserved for commiting the selection(s). NULL
705 * is kind of odd, but the tty's xwaitforspace() will return it if
706 * someone hits a <ret>.
707 * + a default object class symbol - used for object class accelerators
709 * Standard letters (for now) are:
722 * The command name list is duplicated in the compopt array.
729 #define NUM_MENU_CMDS 11
730 static const menu_cmd_t default_menu_cmd_info[NUM_MENU_CMDS] = {
731 /* 0*/ { "menu_first_page", MENU_FIRST_PAGE },
732 { "menu_last_page", MENU_LAST_PAGE },
733 { "menu_next_page", MENU_NEXT_PAGE },
734 { "menu_previous_page", MENU_PREVIOUS_PAGE },
735 { "menu_select_all", MENU_SELECT_ALL },
736 /* 5*/ { "menu_deselect_all", MENU_UNSELECT_ALL },
737 { "menu_invert_all", MENU_INVERT_ALL },
738 { "menu_select_page", MENU_SELECT_PAGE },
739 { "menu_deselect_page", MENU_UNSELECT_PAGE },
740 { "menu_invert_page", MENU_INVERT_PAGE },
741 /*10*/ { "menu_search", MENU_SEARCH },
745 * Allow the user to map incoming characters to various menu commands.
746 * The accelerator list must be a valid C string.
748 #define MAX_MENU_MAPPED_CMDS 32 /* some number */
749 char mapped_menu_cmds[MAX_MENU_MAPPED_CMDS + 1]; /* exported */
750 static char mapped_menu_op[MAX_MENU_MAPPED_CMDS + 1];
751 static short n_menu_mapped = 0;
753 static boolean initial, from_file;
755 STATIC_DCL void FDECL(doset_add_menu, (winid, const char *, int));
756 STATIC_DCL void FDECL(nmcpy, (char *, const char *, int));
757 STATIC_DCL void FDECL(escapes, (const char *, char *));
758 STATIC_DCL void FDECL(rejectoption, (const char *));
759 STATIC_DCL void FDECL(badoption, (const char *));
760 STATIC_DCL char *FDECL(string_for_opt, (char *, BOOLEAN_P));
761 STATIC_DCL char *FDECL(string_for_env_opt, (const char *, char *, BOOLEAN_P));
762 STATIC_DCL void FDECL(bad_negation, (const char *, BOOLEAN_P));
763 STATIC_DCL int FDECL(change_inv_order, (char *));
764 STATIC_DCL void FDECL(oc_to_str, (char *, char *));
765 STATIC_DCL int FDECL(feature_alert_opts, (char *, const char *));
766 STATIC_DCL const char *FDECL(get_compopt_value, (const char *, char *));
767 STATIC_DCL boolean FDECL(special_handling, (const char *,
768 BOOLEAN_P, BOOLEAN_P));
769 STATIC_DCL void FDECL(warning_opts, (char *, const char *));
770 STATIC_DCL boolean FDECL(duplicate_opt_detection, (const char *, int));
771 STATIC_DCL void FDECL(complain_about_duplicate, (const char *, int));
773 STATIC_OVL void FDECL(wc_set_font_name, (int, char *));
774 STATIC_OVL int FDECL(wc_set_window_colors, (char *));
775 STATIC_OVL boolean FDECL(is_wc_option, (const char *));
776 STATIC_OVL boolean FDECL(wc_supported, (const char *));
777 STATIC_OVL boolean FDECL(is_wc2_option, (const char *));
778 STATIC_OVL boolean FDECL(wc2_supported, (const char *));
779 STATIC_DCL void FDECL(remove_autopickup_exception,
780 (struct autopickup_exception *));
781 STATIC_OVL int FDECL(count_ape_maps, (int *, int *));
782 STATIC_DCL const char *FDECL(attr2attrname, (int));
783 STATIC_DCL int NDECL(query_color);
784 STATIC_DCL int NDECL(query_msgtype);
785 STATIC_DCL int FDECL(query_attr, (const char *));
786 STATIC_DCL const char * FDECL(msgtype2name, (int));
787 STATIC_DCL boolean FDECL(msgtype_add, (int, char *));
788 STATIC_DCL void FDECL(free_one_msgtype, (int));
789 STATIC_DCL int NDECL(msgtype_count);
790 STATIC_DCL boolean FDECL(add_menu_coloring_parsed, (char *, int, int));
791 STATIC_DCL void FDECL(free_one_menu_coloring, (int));
792 STATIC_DCL int NDECL(count_menucolors);
793 STATIC_DCL int FDECL(handle_add_list_remove, (const char *, int));
800 for (x = 0; x < COLNO; x++)
801 for (y = 0; y < ROWNO; y++) {
802 struct rm *lev = &levl[x][y];
804 if (!flags.dark_room || !iflags.use_color
805 || Is_rogue_level(&u.uz)) {
806 if (lev->glyph == cmap_to_glyph(S_darkroom))
807 lev->glyph = lev->waslit ? cmap_to_glyph(S_room)
808 : cmap_to_glyph(S_stone);
810 if (lev->glyph == cmap_to_glyph(S_room) && lev->seenv
811 && lev->waslit && !cansee(x, y))
812 lev->glyph = cmap_to_glyph(S_darkroom);
813 else if (lev->glyph == cmap_to_glyph(S_stone)
814 && lev->typ == ROOM && lev->seenv && !cansee(x, y))
815 lev->glyph = cmap_to_glyph(S_darkroom);
818 if (flags.dark_room && iflags.use_color)
819 showsyms[S_darkroom] = showsyms[S_room];
821 showsyms[S_darkroom] = showsyms[S_stone];
824 /* check whether a user-supplied option string is a proper leading
825 substring of a particular option name; option string might have
826 a colon or equals sign and arbitrary value appended to it */
828 match_optname(user_string, opt_name, min_length, val_allowed)
829 const char *user_string, *opt_name;
833 int len = (int) strlen(user_string);
836 const char *p = index(user_string, ':'),
837 *q = index(user_string, '=');
839 if (!p || (q && q < p))
841 while (p && p > user_string && isspace((uchar) * (p - 1)))
844 len = (int) (p - user_string);
847 return (boolean) (len >= min_length
848 && !strncmpi(opt_name, user_string, len));
851 /* most environment variables will eventually be printed in an error
852 * message if they don't work, and most error message paths go through
853 * BUFSZ buffers, which could be overflowed by a maliciously long
854 * environment variable. If a variable can legitimately be long, or
855 * if it's put in a smaller buffer, the responsible code will have to
856 * bounds-check itself.
862 char *getev = getenv(ev);
864 if (getev && strlen(getev) <= (BUFSZ / 2))
870 /* process options, possibly including SYSCF */
876 /* someday there may be other SYSCF alternatives besides text file */
878 /* If SYSCF_FILE is specified, it _must_ exist... */
880 /* ... and _must_ parse correctly. */
881 if (!read_config_file(SYSCF_FILE, SET_IN_SYS)) {
882 raw_printf("Error(s) found in SYSCF_FILE, quitting.");
883 terminate(EXIT_FAILURE);
886 * TODO [maybe]: parse the sysopt entries which are space-separated
887 * lists of usernames into arrays with one name per element.
891 initoptions_finish();
897 #if defined(UNIX) || defined(VMS)
902 /* set up the command parsing */
903 reset_commands(TRUE); /* init */
905 /* initialize the random number generator */
908 /* for detection of configfile options specified multiple times */
909 iflags.opt_booldup = iflags.opt_compdup = (int *) 0;
911 for (i = 0; boolopt[i].name; i++) {
913 *(boolopt[i].addr) = boolopt[i].initvalue;
915 #if defined(COMPRESS) || defined(ZLIB_COMP)
916 set_savepref("externalcomp");
917 set_restpref("externalcomp");
919 set_savepref("!rlecomp");
920 set_restpref("!rlecomp");
924 set_savepref("zerocomp");
925 set_restpref("zerocomp");
928 set_savepref("rlecomp");
929 set_restpref("rlecomp");
933 Strcpy(sysflags.sysflagsid, "sysflags");
934 sysflags.sysflagsid[9] = (char) sizeof(struct sysflag);
936 flags.end_own = FALSE;
938 flags.end_around = 2;
939 flags.paranoia_bits = PARANOID_PRAY; /* old prayconfirm=TRUE */
940 flags.pile_limit = PILE_LIMIT_DFLT; /* 5 */
941 flags.runmode = RUN_LEAP;
942 iflags.msg_history = 20;
944 iflags.prevmsg_window = 's';
946 iflags.menu_headings = ATR_INVERSE;
948 /* hero's role, race, &c haven't been chosen yet */
949 flags.initrole = flags.initrace = flags.initgend = flags.initalign =
952 /* Set the default monster and object class symbols. */
954 for (i = 0; i < WARNCOUNT; i++)
955 warnsyms[i] = def_warnsyms[i].sym;
956 iflags.bouldersym = 0;
958 iflags.travelcc.x = iflags.travelcc.y = -1;
960 /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
961 (void) memcpy((genericptr_t) flags.inv_order,
962 (genericptr_t) def_inv_order, sizeof flags.inv_order);
963 flags.pickup_types[0] = '\0';
964 flags.pickup_burden = MOD_ENCUMBER;
965 flags.sortloot = 'l'; /* sort only loot by default */
967 for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
968 flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
969 switch_symbols(FALSE); /* set default characters */
970 #if defined(UNIX) && defined(TTY_GRAPHICS)
972 * Set defaults for some options depending on what we can
973 * detect about the environment's capabilities.
974 * This has to be done after the global initialization above
975 * and before reading user-specific initialization via
976 * config file/environment variable below.
978 /* this detects the IBM-compatible console on most 386 boxes */
979 if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
980 if (!symset[PRIMARY].name)
981 load_symset("IBMGraphics", PRIMARY);
982 if (!symset[ROGUESET].name)
983 load_symset("RogueIBM", ROGUESET);
984 switch_symbols(TRUE);
986 iflags.use_color = TRUE;
989 #endif /* UNIX && TTY_GRAPHICS */
990 #if defined(UNIX) || defined(VMS)
992 /* detect whether a "vt" terminal can handle alternate charsets */
993 if ((opts = nh_getenv("TERM"))
994 /* [could also check "xterm" which emulates vtXXX by default] */
995 && !strncmpi(opts, "vt", 2)
996 && AS && AE && index(AS, '\016') && index(AE, '\017')) {
997 if (!symset[PRIMARY].name)
998 load_symset("DECGraphics", PRIMARY);
999 switch_symbols(TRUE);
1002 #endif /* UNIX || VMS */
1004 #ifdef MAC_GRAPHICS_ENV
1005 if (!symset[PRIMARY].name)
1006 load_symset("MACGraphics", PRIMARY);
1007 switch_symbols(TRUE);
1008 #endif /* MAC_GRAPHICS_ENV */
1009 flags.menu_style = MENU_FULL;
1011 /* since this is done before init_objects(), do partial init here */
1012 objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
1013 nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
1017 initoptions_finish()
1020 char *opts = getenv("NETHACKOPTIONS");
1023 opts = getenv("HACKOPTIONS");
1025 if (*opts == '/' || *opts == '\\' || *opts == '@') {
1027 opts++; /* @filename */
1028 /* looks like a filename */
1029 if (strlen(opts) < BUFSZ / 2)
1030 read_config_file(opts, SET_IN_FILE);
1032 read_config_file((char *) 0, SET_IN_FILE);
1033 /* let the total length of options be long;
1034 * parseoptions() will check each individually
1036 parseoptions(opts, TRUE, FALSE);
1040 read_config_file((char *) 0, SET_IN_FILE);
1042 (void) fruitadd(pl_fruit, (struct fruit *) 0);
1044 * Remove "slime mold" from list of object names. This will
1045 * prevent it from being wished unless it's actually present
1046 * as a named (or default) fruit. Wishing for "fruit" will
1047 * result in the player's preferred fruit [better than "\033"].
1049 obj_descr[SLIME_MOLD].oc_name = "fruit";
1051 if (iflags.bouldersym)
1052 update_bouldersym();
1058 nmcpy(dest, src, maxlen)
1065 for (count = 1; count < maxlen; count++) {
1066 if (*src == ',' || *src == '\0')
1067 break; /*exit on \0 terminator*/
1074 * escapes(): escape expansion for showsyms. C-style escapes understood
1075 * include \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal).
1076 * The ^-prefix for control characters is also understood, and \[mM]
1077 * has the effect of 'meta'-ing the value which follows (so that the
1078 * alternate character set will be enabled).
1080 * For 3.4.3 and earlier, input ending with "\M", backslash, or caret
1081 * prior to terminating '\0' would pull that '\0' into the output and then
1082 * keep processing past it, potentially overflowing the output buffer.
1083 * Now, trailing \ or ^ will act like \\ or \^ and add '\\' or '^' to the
1084 * output and stop there; trailing \M will fall through to \<other> and
1085 * yield 'M', then stop. Any \X or \O followed by something other than
1086 * an appropriate digit will also fall through to \<other> and yield 'X'
1087 * or 'O', plus stop if the non-digit is end-of-string.
1094 static NEARDATA const char oct[] = "01234567", dec[] = "0123456789",
1095 hex[] = "00112233445566778899aAbBcCdDeEfF";
1097 int cval, meta, dcount;
1100 /* \M has to be followed by something to do meta conversion,
1101 otherwise it will just be \M which ultimately yields 'M' */
1102 meta = (*cp == '\\' && (cp[1] == 'm' || cp[1] == 'M') && cp[2]);
1106 cval = dcount = 0; /* for decimal, octal, hexadecimal cases */
1107 if ((*cp != '\\' && *cp != '^') || !cp[1]) {
1108 /* simple character, or nothing left for \ or ^ to escape */
1110 } else if (*cp == '^') { /* expand control-character syntax */
1111 cval = (*++cp & 0x1f);
1113 /* remaining cases are all for backslash and we know cp[1] is not
1115 } else if (index(dec, cp[1])) {
1116 ++cp; /* move past backslash to first digit */
1118 cval = (cval * 10) + (*cp - '0');
1119 } while (*++cp && index(dec, *cp) && ++dcount < 3);
1120 } else if ((cp[1] == 'o' || cp[1] == 'O') && cp[2]
1121 && index(oct, cp[2])) {
1122 cp += 2; /* move past backslash and 'O' */
1124 cval = (cval * 8) + (*cp - '0');
1125 } while (*++cp && index(oct, *cp) && ++dcount < 3);
1126 } else if ((cp[1] == 'x' || cp[1] == 'X') && cp[2]
1127 && (dp = index(hex, cp[2])) != 0) {
1128 cp += 2; /* move past backslash and 'X' */
1130 cval = (cval * 16) + ((int) (dp - hex) / 2);
1131 } while (*++cp && (dp = index(hex, *cp)) != 0 && ++dcount < 2);
1132 } else { /* C-style character escapes */
1157 *tp++ = (char) cval;
1163 rejectoption(optname)
1164 const char *optname;
1167 pline("\"%s\" settable only from %s.", optname, lastconfigfile);
1169 pline("%s can be set only from NETHACKOPTIONS or %s.", optname,
1179 if (!strncmp(opts, "h", 1) || !strncmp(opts, "?", 1))
1182 pline("Bad syntax: %s. Enter \"?g\" for help.", opts);
1191 raw_printf("Bad syntax in OPTIONS in %s: %s%s.\n", lastconfigfile,
1199 raw_printf("Bad syntax in NETHACKOPTIONS: %s%s.\n",
1210 string_for_opt(opts, val_optional)
1212 boolean val_optional;
1214 char *colon, *equals;
1216 colon = index(opts, ':');
1217 equals = index(opts, '=');
1218 if (!colon || (equals && equals < colon))
1221 if (!colon || !*++colon) {
1230 string_for_env_opt(optname, opts, val_optional)
1231 const char *optname;
1233 boolean val_optional;
1236 rejectoption(optname);
1239 return string_for_opt(opts, val_optional);
1243 bad_negation(optname, with_parameter)
1244 const char *optname;
1245 boolean with_parameter;
1247 pline_The("%s option may not %sbe negated.", optname,
1248 with_parameter ? "both have a value and " : "");
1252 * Change the inventory order, using the given string as the new order.
1253 * Missing characters in the new order are filled in at the end from
1254 * the current inv_order, except for gold, which is forced to be first
1255 * if not explicitly present.
1257 * This routine returns 1 unless there is a duplicate or bad char in
1261 change_inv_order(op)
1265 char *sp, buf[BUFSZ];
1268 /* !!!! probably unnecessary with gold as normal inventory */
1270 for (sp = op; *sp; sp++) {
1271 oc_sym = def_char_to_objclass(*sp);
1272 /* reject bad or duplicate entries */
1273 if (oc_sym == MAXOCLASSES || oc_sym == RANDOM_CLASS
1274 || oc_sym == ILLOBJ_CLASS || !index(flags.inv_order, oc_sym)
1275 || index(sp + 1, *sp))
1277 /* retain good ones */
1278 buf[num++] = (char) oc_sym;
1282 /* fill in any omitted classes, using previous ordering */
1283 for (sp = flags.inv_order; *sp; sp++)
1284 if (!index(buf, *sp)) {
1286 buf[num] = '\0'; /* explicitly terminate for next index() */
1289 Strcpy(flags.inv_order, buf);
1294 warning_opts(opts, optype)
1295 register char *opts;
1298 uchar translate[WARNCOUNT];
1301 if (!(opts = string_for_env_opt(optype, opts, FALSE)))
1303 escapes(opts, opts);
1305 length = (int) strlen(opts);
1306 /* match the form obtained from PC configuration files */
1307 for (i = 0; i < WARNCOUNT; i++)
1308 translate[i] = (i >= length) ? 0
1309 : opts[i] ? (uchar) opts[i]
1310 : def_warnsyms[i].sym;
1311 assign_warnings(translate);
1315 assign_warnings(graph_chars)
1316 register uchar *graph_chars;
1320 for (i = 0; i < WARNCOUNT; i++)
1322 warnsyms[i] = graph_chars[i];
1326 feature_alert_opts(op, optn)
1331 boolean rejectver = FALSE;
1332 unsigned long fnv = get_feature_notice_ver(op); /* version.c */
1336 if (fnv > get_current_feature_ver())
1339 flags.suppress_alert = fnv;
1342 You_cant("disable new feature alerts for future versions.");
1345 "\n%s=%s Invalid reference to a future version ignored",
1352 Sprintf(buf, "%lu.%lu.%lu", FEATURE_NOTICE_VER_MAJ,
1353 FEATURE_NOTICE_VER_MIN, FEATURE_NOTICE_VER_PATCH);
1355 "Feature change alerts disabled for NetHack %s features and prior.",
1362 set_duplicate_opt_detection(on_or_off)
1367 if (on_or_off != 0) {
1369 if (iflags.opt_booldup)
1370 impossible("iflags.opt_booldup already on (memory leak)");
1371 iflags.opt_booldup = (int *) alloc(SIZE(boolopt) * sizeof(int));
1372 optptr = iflags.opt_booldup;
1373 for (k = 0; k < SIZE(boolopt); ++k)
1376 if (iflags.opt_compdup)
1377 impossible("iflags.opt_compdup already on (memory leak)");
1378 iflags.opt_compdup = (int *) alloc(SIZE(compopt) * sizeof(int));
1379 optptr = iflags.opt_compdup;
1380 for (k = 0; k < SIZE(compopt); ++k)
1384 if (iflags.opt_booldup)
1385 free((genericptr_t) iflags.opt_booldup);
1386 iflags.opt_booldup = (int *) 0;
1387 if (iflags.opt_compdup)
1388 free((genericptr_t) iflags.opt_compdup);
1389 iflags.opt_compdup = (int *) 0;
1394 duplicate_opt_detection(opts, iscompound)
1396 int iscompound; /* 0 == boolean option, 1 == compound */
1400 if (!iscompound && iflags.opt_booldup && initial && from_file) {
1401 for (i = 0; boolopt[i].name; i++) {
1402 if (match_optname(opts, boolopt[i].name, 3, FALSE)) {
1403 optptr = iflags.opt_booldup + i;
1411 } else if (iscompound && iflags.opt_compdup && initial && from_file) {
1412 for (i = 0; compopt[i].name; i++) {
1413 if (match_optname(opts, compopt[i].name, strlen(compopt[i].name),
1415 optptr = iflags.opt_compdup + i;
1428 complain_about_duplicate(opts, iscompound)
1430 int iscompound; /* 0 == boolean option, 1 == compound */
1433 /* the Mac has trouble dealing with the output of messages while
1434 * processing the config file. That should get fixed one day.
1435 * For now just return.
1438 raw_printf("\nWarning - %s option specified multiple times: %s.\n",
1439 iscompound ? "compound" : "boolean", opts);
1445 /* paranoia[] - used by parseoptions() and special_handling() */
1446 STATIC_VAR const struct paranoia_opts {
1447 int flagmask; /* which paranoid option */
1448 const char *argname; /* primary name */
1449 int argMinLen; /* minimum number of letters to match */
1450 const char *synonym; /* alternate name (optional) */
1452 const char *explain; /* for interactive menu */
1454 /* there are some initial-letter conflicts: "a"ttack vs "a"ll, "attack"
1455 takes precedence and "all" isn't present in the interactive menu,
1456 and "d"ie vs "d"eath, synonyms for each other so doesn't matter;
1457 (also "p"ray vs "P"aranoia, "pray" takes precedence since "Paranoia"
1458 is just a synonym for "Confirm") */
1459 { PARANOID_CONFIRM, "Confirm", 1, "Paranoia", 2,
1460 "for \"yes\" confirmations, require \"no\" to reject" },
1461 { PARANOID_QUIT, "quit", 1, "explore", 1,
1462 "yes vs y to quit or to enter explore mode" },
1463 { PARANOID_DIE, "die", 1, "death", 2,
1464 "yes vs y to die (explore mode or debug mode)" },
1465 { PARANOID_BONES, "bones", 1, 0, 0,
1466 "yes vs y to save bones data when dying in debug mode" },
1467 { PARANOID_HIT, "attack", 1, "hit", 1,
1468 "yes vs y to attack a peaceful monster" },
1469 { PARANOID_PRAY, "pray", 1, 0, 0,
1470 "y to pray (supersedes old \"prayconfirm\" option)" },
1471 { PARANOID_REMOVE, "Remove", 1, "Takeoff", 1,
1472 "always pick from inventory for Remove and Takeoff" },
1473 { PARANOID_BREAKWAND, "wand", 1, "breakwand", 2,
1474 "yes vs y to break a wand" },
1475 /* for config file parsing; interactive menu skips these */
1476 { 0, "none", 4, 0, 0, 0 }, /* require full word match */
1477 { ~0, "all", 3, 0, 0, 0 }, /* ditto */
1480 extern struct menucoloring *menu_colorings;
1482 static const struct {
1486 { "black", CLR_BLACK },
1488 { "green", CLR_GREEN },
1489 { "brown", CLR_BROWN },
1490 { "blue", CLR_BLUE },
1491 { "magenta", CLR_MAGENTA },
1492 { "cyan", CLR_CYAN },
1493 { "gray", CLR_GRAY },
1494 { "grey", CLR_GRAY },
1495 { "orange", CLR_ORANGE },
1496 { "light green", CLR_BRIGHT_GREEN },
1497 { "yellow", CLR_YELLOW },
1498 { "light blue", CLR_BRIGHT_BLUE },
1499 { "light magenta", CLR_BRIGHT_MAGENTA },
1500 { "light cyan", CLR_BRIGHT_CYAN },
1501 { "white", CLR_WHITE }
1504 static const struct {
1508 { "none", ATR_NONE },
1509 { "bold", ATR_BOLD },
1511 { "underline", ATR_ULINE },
1512 { "blink", ATR_BLINK },
1513 { "inverse", ATR_INVERSE }
1522 for (i = 0; i < SIZE(colornames); i++)
1523 if (colornames[i].color == clr)
1524 return colornames[i].name;
1534 for (i = 0; i < SIZE(attrnames); i++)
1535 if (attrnames[i].attr == attr)
1536 return attrnames[i].name;
1546 menu_item *picks = (menu_item *) 0;
1548 tmpwin = create_nhwindow(NHW_MENU);
1551 for (i = 0; i < SIZE(colornames); i++) {
1552 if (!strcmp(colornames[i].name, "grey"))
1555 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, colornames[i].name,
1558 end_menu(tmpwin, "Pick a color");
1559 pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
1560 destroy_nhwindow(tmpwin);
1562 i = colornames[picks->item.a_int - 1].color;
1563 free((genericptr_t) picks);
1576 menu_item *picks = (menu_item *) 0;
1578 tmpwin = create_nhwindow(NHW_MENU);
1581 for (i = 0; i < SIZE(attrnames); i++) {
1583 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, attrnames[i].attr,
1584 attrnames[i].name, MENU_UNSELECTED);
1586 end_menu(tmpwin, prompt ? prompt : "Pick an attribute");
1587 pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
1588 destroy_nhwindow(tmpwin);
1590 i = attrnames[picks->item.a_int - 1].attr;
1591 free((genericptr_t) picks);
1597 static const struct {
1601 } msgtype_names[] = {
1602 { "show", MSGTYP_NORMAL, "Show message normally" },
1603 { "hide", MSGTYP_NOSHOW, "Hide message" },
1604 { "noshow", MSGTYP_NOSHOW, NULL },
1605 { "stop", MSGTYP_STOP, "Prompt for more after the message" },
1606 { "more", MSGTYP_STOP, NULL },
1607 { "norep", MSGTYP_NOREP, "Do not repeat the message" }
1616 for (i = 0; i < SIZE(msgtype_names); i++)
1617 if (msgtype_names[i].descr && msgtype_names[i].msgtyp == typ)
1618 return msgtype_names[i].name;
1628 menu_item *picks = (menu_item *) 0;
1630 tmpwin = create_nhwindow(NHW_MENU);
1633 for (i = 0; i < SIZE(msgtype_names); i++)
1634 if (msgtype_names[i].descr) {
1635 any.a_int = msgtype_names[i].msgtyp + 1;
1636 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
1637 msgtype_names[i].descr, MENU_UNSELECTED);
1639 end_menu(tmpwin, "How to show the message");
1640 pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
1641 destroy_nhwindow(tmpwin);
1643 i = picks->item.a_int - 1;
1644 free((genericptr_t) picks);
1651 msgtype_add(typ, pattern)
1655 struct plinemsg_type *tmp
1656 = (struct plinemsg_type *) alloc(sizeof (struct plinemsg_type));
1661 tmp->regex = regex_init();
1662 if (!regex_compile(pattern, tmp->regex)) {
1663 static const char *re_error = "MSGTYPE regex error";
1665 if (!iflags.window_inited)
1666 raw_printf("\n%s: %s\n", re_error, regex_error_desc(tmp->regex));
1668 pline("%s: %s", re_error, regex_error_desc(tmp->regex));
1670 regex_free(tmp->regex);
1671 free((genericptr_t) tmp);
1674 tmp->pattern = dupstr(pattern);
1675 tmp->next = plinemsg_types;
1676 plinemsg_types = tmp;
1683 struct plinemsg_type *tmp, *tmp2 = 0;
1685 for (tmp = plinemsg_types; tmp; tmp = tmp2) {
1687 free((genericptr_t) tmp->pattern);
1688 regex_free(tmp->regex);
1689 free((genericptr_t) tmp);
1691 plinemsg_types = (struct plinemsg_type *) 0;
1695 free_one_msgtype(idx)
1698 struct plinemsg_type *tmp = plinemsg_types;
1699 struct plinemsg_type *prev = NULL;
1703 struct plinemsg_type *next = tmp->next;
1705 regex_free(tmp->regex);
1706 free((genericptr_t) tmp->pattern);
1707 free((genericptr_t) tmp);
1711 plinemsg_types = next;
1724 struct plinemsg_type *tmp = plinemsg_types;
1727 if (regex_match(msg, tmp->regex))
1728 return tmp->msgtype;
1731 return MSGTYP_NORMAL;
1738 struct plinemsg_type *tmp = plinemsg_types;
1748 msgtype_parse_add(str)
1754 if (sscanf(str, "%10s \"%255[^\"]\"", msgtype, pattern) == 2) {
1758 for (i = 0; i < SIZE(msgtype_names); i++)
1759 if (!strncmpi(msgtype_names[i].name, msgtype, strlen(msgtype))) {
1760 typ = msgtype_names[i].msgtyp;
1764 return msgtype_add(typ, pattern);
1770 add_menu_coloring_parsed(str, c, a)
1774 static const char re_error[] = "Menucolor regex error";
1775 struct menucoloring *tmp;
1779 tmp = (struct menucoloring *) alloc(sizeof (struct menucoloring));
1780 tmp->match = regex_init();
1781 if (!regex_compile(str, tmp->match)) {
1782 if (!iflags.window_inited)
1783 raw_printf("\n%s: %s\n", re_error, regex_error_desc(tmp->match));
1785 pline("%s: %s", re_error, regex_error_desc(tmp->match));
1787 regex_free(tmp->match);
1791 tmp->next = menu_colorings;
1792 tmp->origstr = dupstr(str);
1795 menu_colorings = tmp;
1800 /* parse '"regex_string"=color&attr' and add it to menucoloring */
1802 add_menu_coloring(str)
1805 int i, c = NO_COLOR, a = ATR_NONE;
1806 char *tmps, *cs, *amp;
1808 if (!str || (cs = index(str, '=')) == 0)
1811 tmps = cs + 1; /* advance past '=' */
1813 if ((amp = index(tmps, '&')) != 0)
1816 /* allow "lightblue", "light blue", and "light-blue" to match "light blue"
1817 (also junk like "_l i-gh_t---b l u e" but we won't worry about that);
1818 also copes with trailing space; mungspaces removed any leading space */
1819 for (i = 0; i < SIZE(colornames); i++)
1820 if (fuzzymatch(tmps, colornames[i].name, " -_", TRUE)) {
1821 c = colornames[i].color;
1824 if (i == SIZE(colornames) && (*tmps >= '0' && *tmps <= '9'))
1831 tmps = amp + 1; /* advance past '&' */
1832 /* unlike colors, none of he attribute names has any embedded spaces,
1833 but use of fuzzymatch() allows us ignore the presence of leading
1834 and/or trailing (and also embedded) spaces in the user's string;
1835 dash and underscore skipping could be omitted but does no harm */
1836 for (i = 0; i < SIZE(attrnames); i++)
1837 if (fuzzymatch(tmps, attrnames[i].name, " -_", TRUE)) {
1838 a = attrnames[i].attr;
1841 if (i == SIZE(attrnames) && (*tmps >= '0' && *tmps <= '9'))
1845 /* the regexp portion here has not been condensed by mungspaces() */
1848 if (*tmps == '"' || *tmps == '\'') {
1850 while (isspace((uchar) *cs))
1858 return add_menu_coloring_parsed(tmps, c, a);
1862 get_menu_coloring(str, color, attr)
1866 struct menucoloring *tmpmc;
1868 if (iflags.use_menu_color)
1869 for (tmpmc = menu_colorings; tmpmc; tmpmc = tmpmc->next)
1870 if (regex_match(str, tmpmc->match)) {
1871 *color = tmpmc->color;
1872 *attr = tmpmc->attr;
1879 free_menu_coloring()
1881 struct menucoloring *tmp = menu_colorings;
1884 struct menucoloring *tmp2 = tmp->next;
1886 regex_free(tmp->match);
1887 free((genericptr_t) tmp->origstr);
1888 free((genericptr_t) tmp);
1894 free_one_menu_coloring(idx)
1897 struct menucoloring *tmp = menu_colorings;
1898 struct menucoloring *prev = NULL;
1902 struct menucoloring *next = tmp->next;
1904 regex_free(tmp->match);
1905 free((genericptr_t) tmp->origstr);
1906 free((genericptr_t) tmp);
1910 menu_colorings = next;
1923 struct menucoloring *tmp = menu_colorings;
1933 parseoptions(opts, tinitial, tfrom_file)
1934 register char *opts;
1935 boolean tinitial, tfrom_file;
1939 boolean negated, val_negated, duplicate;
1941 const char *fullname;
1944 from_file = tfrom_file;
1945 if ((op = index(opts, ',')) != 0) {
1947 parseoptions(op, initial, from_file);
1949 if (strlen(opts) > BUFSZ / 2) {
1950 badoption("option too long");
1954 /* strip leading and trailing white space */
1955 while (isspace((uchar) *opts))
1958 while (--op >= opts && isspace((uchar) *op))
1964 while ((*opts == '!') || !strncmpi(opts, "no", 2)) {
1972 /* variant spelling */
1974 if (match_optname(opts, "colour", 5, FALSE))
1975 Strcpy(opts, "color"); /* fortunately this isn't longer */
1977 /* special boolean options */
1979 if (match_optname(opts, "female", 3, FALSE)) {
1980 if (duplicate_opt_detection(opts, 0))
1981 complain_about_duplicate(opts, 0);
1982 if (!initial && flags.female == negated)
1983 pline("That is not anatomically possible.");
1985 flags.initgend = flags.female = !negated;
1989 if (match_optname(opts, "male", 4, FALSE)) {
1990 if (duplicate_opt_detection(opts, 0))
1991 complain_about_duplicate(opts, 0);
1992 if (!initial && flags.female != negated)
1993 pline("That is not anatomically possible.");
1995 flags.initgend = flags.female = negated;
1999 #if defined(MICRO) && !defined(AMIGA)
2000 /* included for compatibility with old NetHack.cnf files */
2001 if (match_optname(opts, "IBM_", 4, FALSE)) {
2002 iflags.BIOS = !negated;
2007 /* compound options */
2009 /* This first batch can be duplicated if their values are negated */
2013 if (match_optname(opts, fullname, sizeof("align") - 1, TRUE)) {
2015 bad_negation(fullname, FALSE);
2016 } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
2017 val_negated = FALSE;
2018 while ((*op == '!') || !strncmpi(op, "no", 2)) {
2023 val_negated = !val_negated;
2026 if (!setrolefilter(op))
2029 if (duplicate_opt_detection(opts, 1))
2030 complain_about_duplicate(opts, 1);
2031 if ((flags.initalign = str2align(op)) == ROLE_NONE)
2038 /* role:string or character:string */
2040 if (match_optname(opts, fullname, 4, TRUE)
2041 || match_optname(opts, (fullname = "character"), 4, TRUE)) {
2043 bad_negation(fullname, FALSE);
2044 } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
2045 val_negated = FALSE;
2046 while ((*op == '!') || !strncmpi(op, "no", 2)) {
2051 val_negated = !val_negated;
2054 if (!setrolefilter(op))
2057 if (duplicate_opt_detection(opts, 1))
2058 complain_about_duplicate(opts, 1);
2059 if ((flags.initrole = str2role(op)) == ROLE_NONE)
2061 else /* Backwards compatibility */
2062 nmcpy(pl_character, op, PL_NSIZ);
2070 if (match_optname(opts, fullname, 4, TRUE)) {
2072 bad_negation(fullname, FALSE);
2073 } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
2074 val_negated = FALSE;
2075 while ((*op == '!') || !strncmpi(op, "no", 2)) {
2080 val_negated = !val_negated;
2083 if (!setrolefilter(op))
2086 if (duplicate_opt_detection(opts, 1))
2087 complain_about_duplicate(opts, 1);
2088 if ((flags.initrace = str2race(op)) == ROLE_NONE)
2090 else /* Backwards compatibility */
2098 fullname = "gender";
2099 if (match_optname(opts, fullname, 4, TRUE)) {
2101 bad_negation(fullname, FALSE);
2102 } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
2103 val_negated = FALSE;
2104 while ((*op == '!') || !strncmpi(op, "no", 2)) {
2109 val_negated = !val_negated;
2112 if (!setrolefilter(op))
2115 if (duplicate_opt_detection(opts, 1))
2116 complain_about_duplicate(opts, 1);
2117 if ((flags.initgend = str2gend(op)) == ROLE_NONE)
2120 flags.female = flags.initgend;
2126 /* We always check for duplicates on the remaining compound options,
2127 although individual option processing can choose to complain or not */
2130 duplicate_opt_detection(opts, 1); /* 1 means check compounds */
2132 fullname = "pettype";
2133 if (match_optname(opts, fullname, 3, TRUE)) {
2135 complain_about_duplicate(opts, 1);
2136 if ((op = string_for_env_opt(fullname, opts, negated)) != 0) {
2138 bad_negation(fullname, TRUE);
2140 switch (lowc(*op)) {
2142 preferred_pet = 'd';
2145 case 'f': /* feline */
2146 preferred_pet = 'c';
2148 case 'h': /* horse */
2149 case 'q': /* quadruped */
2150 /* avoids giving "unrecognized type of pet" but
2151 pet_type(dog.c) won't actually honor this */
2152 preferred_pet = 'h';
2154 case 'n': /* no pet */
2155 preferred_pet = 'n';
2157 case '*': /* random */
2158 preferred_pet = '\0';
2162 pline("Unrecognized pet type '%s'.", op);
2164 pline("'%s'
\82Í
\83y
\83b
\83g
\82Ì
\8eí
\97Þ
\82Æ
\82µ
\82Ä
\8eó
\82¯
\95t
\82¯
\82ç
\82ê
\82Ü
\82¹
\82ñ
\81D", op);
2169 preferred_pet = 'n';
2173 fullname = "catname";
2174 if (match_optname(opts, fullname, 3, TRUE)) {
2176 complain_about_duplicate(opts, 1);
2178 bad_negation(fullname, FALSE);
2179 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
2180 nmcpy(catname, op, PL_PSIZ);
2181 sanitize_name(catname);
2185 fullname = "dogname";
2186 if (match_optname(opts, fullname, 3, TRUE)) {
2188 complain_about_duplicate(opts, 1);
2190 bad_negation(fullname, FALSE);
2191 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
2192 nmcpy(dogname, op, PL_PSIZ);
2193 sanitize_name(dogname);
2197 fullname = "horsename";
2198 if (match_optname(opts, fullname, 5, TRUE)) {
2200 complain_about_duplicate(opts, 1);
2202 bad_negation(fullname, FALSE);
2203 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
2204 nmcpy(horsename, op, PL_PSIZ);
2205 sanitize_name(horsename);
2209 fullname = "number_pad";
2210 if (match_optname(opts, fullname, 10, TRUE)) {
2211 boolean compat = (strlen(opts) <= 10);
2214 complain_about_duplicate(opts, 1);
2215 op = string_for_opt(opts, (compat || !initial));
2217 if (compat || negated || initial) {
2218 /* for backwards compatibility, "number_pad" without a
2219 value is a synonym for number_pad:1 */
2220 iflags.num_pad = !negated;
2221 iflags.num_pad_mode = 0;
2223 } else if (negated) {
2224 bad_negation("number_pad", TRUE);
2227 int mode = atoi(op);
2229 if (mode < -1 || mode > 4 || (mode == 0 && *op != '0')) {
2232 } else if (mode <= 0) {
2233 iflags.num_pad = FALSE;
2234 /* German keyboard; y and z keys swapped */
2235 iflags.num_pad_mode = (mode < 0); /* 0 or 1 */
2236 } else { /* mode > 0 */
2237 iflags.num_pad = TRUE;
2238 iflags.num_pad_mode = 0;
2239 /* PC Hack / MSDOS compatibility */
2240 if (mode == 2 || mode == 4)
2241 iflags.num_pad_mode |= 1;
2242 /* phone keypad layout */
2243 if (mode == 3 || mode == 4)
2244 iflags.num_pad_mode |= 2;
2247 reset_commands(FALSE);
2248 number_pad(iflags.num_pad ? 1 : 0);
2252 fullname = "roguesymset";
2253 if (match_optname(opts, fullname, 7, TRUE)) {
2255 complain_about_duplicate(opts, 1);
2257 bad_negation(fullname, FALSE);
2258 } else if ((op = string_for_opt(opts, FALSE)) != 0) {
2259 symset[ROGUESET].name = dupstr(op);
2260 if (!read_sym_file(ROGUESET)) {
2261 clear_symsetentry(ROGUESET, TRUE);
2262 raw_printf("Unable to load symbol set \"%s\" from \"%s\".",
2266 if (!initial && Is_rogue_level(&u.uz))
2267 assign_graphics(ROGUESET);
2274 fullname = "symset";
2275 if (match_optname(opts, fullname, 6, TRUE)) {
2277 complain_about_duplicate(opts, 1);
2279 bad_negation(fullname, FALSE);
2280 } else if ((op = string_for_opt(opts, FALSE)) != 0) {
2281 symset[PRIMARY].name = dupstr(op);
2282 if (!read_sym_file(PRIMARY)) {
2283 clear_symsetentry(PRIMARY, TRUE);
2284 raw_printf("Unable to load symbol set \"%s\" from \"%s\".",
2288 switch_symbols(TRUE);
2295 fullname = "runmode";
2296 if (match_optname(opts, fullname, 4, TRUE)) {
2298 complain_about_duplicate(opts, 1);
2300 flags.runmode = RUN_TPORT;
2301 } else if ((op = string_for_opt(opts, FALSE)) != 0) {
2302 if (!strncmpi(op, "teleport", strlen(op)))
2303 flags.runmode = RUN_TPORT;
2304 else if (!strncmpi(op, "run", strlen(op)))
2305 flags.runmode = RUN_LEAP;
2306 else if (!strncmpi(op, "walk", strlen(op)))
2307 flags.runmode = RUN_STEP;
2308 else if (!strncmpi(op, "crawl", strlen(op)))
2309 flags.runmode = RUN_CRAWL;
2316 /* menucolor:"regex_string"=color */
2317 fullname = "menucolor";
2318 if (match_optname(opts, fullname, 9, TRUE)) {
2320 bad_negation(fullname, FALSE);
2321 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
2322 if (!add_menu_coloring(op))
2327 fullname = "msghistory";
2328 if (match_optname(opts, fullname, 3, TRUE)) {
2330 complain_about_duplicate(opts, 1);
2331 op = string_for_env_opt(fullname, opts, negated);
2332 if ((negated && !op) || (!negated && op)) {
2333 iflags.msg_history = negated ? 0 : atoi(op);
2335 bad_negation(fullname, TRUE);
2339 fullname = "msg_window";
2340 /* msg_window:single, combo, full or reversed */
2341 if (match_optname(opts, fullname, 4, TRUE)) {
2342 /* allow option to be silently ignored by non-tty ports */
2347 complain_about_duplicate(opts, 1);
2348 if (!(op = string_for_opt(opts, TRUE))) {
2349 tmp = negated ? 's' : 'f';
2352 bad_negation(fullname, TRUE);
2358 case 's': /* single message history cycle (default if negated) */
2359 iflags.prevmsg_window = 's';
2361 case 'c': /* combination: two singles, then full page reversed */
2362 iflags.prevmsg_window = 'c';
2364 case 'f': /* full page (default if no opts) */
2365 iflags.prevmsg_window = 'f';
2367 case 'r': /* full page (reversed) */
2368 iflags.prevmsg_window = 'r';
2378 * setting font options */
2380 if (!strncmpi(opts, fullname, 4)) {
2382 char *fontopts = opts + 4;
2384 if (!strncmpi(fontopts, "map", 3) || !strncmpi(fontopts, "_map", 4))
2385 opttype = MAP_OPTION;
2386 else if (!strncmpi(fontopts, "message", 7)
2387 || !strncmpi(fontopts, "_message", 8))
2388 opttype = MESSAGE_OPTION;
2389 else if (!strncmpi(fontopts, "text", 4)
2390 || !strncmpi(fontopts, "_text", 5))
2391 opttype = TEXT_OPTION;
2392 else if (!strncmpi(fontopts, "menu", 4)
2393 || !strncmpi(fontopts, "_menu", 5))
2394 opttype = MENU_OPTION;
2395 else if (!strncmpi(fontopts, "status", 6)
2396 || !strncmpi(fontopts, "_status", 7))
2397 opttype = STATUS_OPTION;
2398 else if (!strncmpi(fontopts, "_size", 5)) {
2399 if (!strncmpi(fontopts, "_size_map", 8))
2400 opttype = MAP_OPTION;
2401 else if (!strncmpi(fontopts, "_size_message", 12))
2402 opttype = MESSAGE_OPTION;
2403 else if (!strncmpi(fontopts, "_size_text", 9))
2404 opttype = TEXT_OPTION;
2405 else if (!strncmpi(fontopts, "_size_menu", 9))
2406 opttype = MENU_OPTION;
2407 else if (!strncmpi(fontopts, "_size_status", 11))
2408 opttype = STATUS_OPTION;
2414 complain_about_duplicate(opts, 1);
2415 if (opttype > 0 && !negated
2416 && (op = string_for_opt(opts, FALSE)) != 0) {
2419 iflags.wc_fontsiz_map = atoi(op);
2421 case MESSAGE_OPTION:
2422 iflags.wc_fontsiz_message = atoi(op);
2425 iflags.wc_fontsiz_text = atoi(op);
2428 iflags.wc_fontsiz_menu = atoi(op);
2431 iflags.wc_fontsiz_status = atoi(op);
2439 if (opttype > 0 && (op = string_for_opt(opts, FALSE)) != 0) {
2440 wc_set_font_name(opttype, op);
2442 set_font_name(opttype, op);
2446 bad_negation(fullname, TRUE);
2450 if (match_optname(opts, "palette", 3, TRUE)
2452 || match_optname(opts, "hicolor", 3, TRUE)
2455 int color_number, color_incr;
2459 complain_about_duplicate(opts, 1);
2462 if (match_optname(opts, "hicolor", 3, TRUE)) {
2464 bad_negation("hicolor", FALSE);
2467 color_number = CLR_MAX + 4; /* HARDCODED inverse number */
2472 bad_negation("palette", FALSE);
2481 op = string_for_opt(opts, TRUE);
2482 if (!alternative_palette(op))
2485 if ((op = string_for_opt(opts, FALSE)) != (char *) 0) {
2487 int cnt, tmp, reverse;
2490 while (*pt && color_number >= 0) {
2500 if (*pt && *pt != '/') {
2508 tmp = (tmp + 9) & 0xf; /* Assumes ASCII... */
2510 tmp &= 0xf; /* Digits in ASCII too... */
2513 /* Add an extra so we fill f -> ff and 0 -> 00 */
2522 change_color(color_number, rgb, reverse);
2523 color_number += color_incr;
2532 #endif /* CHANGE_COLOR */
2534 if (match_optname(opts, "fruit", 2, TRUE)) {
2535 struct fruit *forig = 0;
2536 char empty_str = '\0';
2539 complain_about_duplicate(opts, 1);
2540 op = string_for_opt(opts, negated);
2543 bad_negation("fruit", TRUE);
2555 for (f = ffruit; f; f = f->nextf) {
2556 if (!strcmp(op, f->fname))
2560 if (!flags.made_fruit) {
2561 for (forig = ffruit; forig; forig = forig->nextf) {
2562 if (!strcmp(pl_fruit, forig->fname)) {
2567 if (!forig && num >= 100) {
2569 pline("Doing that so many times isn't very fruitful.");
2571 pline("
\82»
\82ñ
\82È
\82É
\89½
\89ñ
\82à
\82â
\82Á
\82Ä
\82à
\82Ù
\82Æ
\82ñ
\82Ç
\88Ó
\96¡
\82Í
\82È
\82¢
\81D");
2576 nmcpy(pl_fruit, op, PL_FSIZ);
2577 sanitize_name(pl_fruit);
2578 /* OBJ_NAME(objects[SLIME_MOLD]) won't work after initialization */
2580 nmcpy(pl_fruit, "slime mold", PL_FSIZ);
2582 (void) fruitadd(pl_fruit, forig);
2583 pline("Fruit is now \"%s\".", pl_fruit);
2585 /* If initial, then initoptions is allowed to do it instead
2586 * of here (initoptions always has to do it even if there's
2587 * no fruit option at all. Also, we don't want people
2588 * setting multiple fruits in their options.)
2593 fullname = "warnings";
2594 if (match_optname(opts, fullname, 5, TRUE)) {
2596 complain_about_duplicate(opts, 1);
2598 bad_negation(fullname, FALSE);
2600 warning_opts(opts, fullname);
2604 #ifdef BACKWARD_COMPAT
2605 /* boulder:symbol */
2606 fullname = "boulder";
2607 if (match_optname(opts, fullname, 7, TRUE)) {
2610 complain_about_duplicate(opts, 1);
2612 bad_negation(fullname, FALSE);
2615 /* if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
2617 if (!(opts = string_for_opt(opts, FALSE)))
2619 escapes(opts, opts);
2620 if (def_char_to_monclass(opts[0]) != MAXMCLASSES)
2622 else if (opts[0] >= '1' && opts[0] <= '5')
2625 /* symbol chosen matches a used monster or warning
2626 symbol which is not good - reject it*/
2628 "Badoption - boulder symbol '%c' conflicts with a %s symbol.",
2629 opts[0], (clash == 1) ? "monster" : "warning");
2632 * Override the default boulder symbol.
2634 iflags.bouldersym = (uchar) opts[0];
2644 if (match_optname(opts, fullname, 4, TRUE)) {
2646 complain_about_duplicate(opts, 1);
2648 bad_negation(fullname, FALSE);
2649 else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
2650 nmcpy(plname, op, PL_NSIZ);
2654 /* altkeyhandler:string */
2655 fullname = "altkeyhandler";
2656 if (match_optname(opts, fullname, 4, TRUE)) {
2658 complain_about_duplicate(opts, 1);
2660 bad_negation(fullname, FALSE);
2661 } else if ((op = string_for_opt(opts, negated)) != 0) {
2663 (void) strncpy(iflags.altkeyhandler, op, MAX_ALTKEYHANDLER - 5);
2664 load_keyboard_handler();
2671 * align_status:[left|top|right|bottom] */
2672 fullname = "align_status";
2673 if (match_optname(opts, fullname, sizeof("align_status") - 1, TRUE)) {
2674 op = string_for_opt(opts, negated);
2675 if (op && !negated) {
2676 if (!strncmpi(op, "left", sizeof("left") - 1))
2677 iflags.wc_align_status = ALIGN_LEFT;
2678 else if (!strncmpi(op, "top", sizeof("top") - 1))
2679 iflags.wc_align_status = ALIGN_TOP;
2680 else if (!strncmpi(op, "right", sizeof("right") - 1))
2681 iflags.wc_align_status = ALIGN_RIGHT;
2682 else if (!strncmpi(op, "bottom", sizeof("bottom") - 1))
2683 iflags.wc_align_status = ALIGN_BOTTOM;
2687 bad_negation(fullname, TRUE);
2691 * align_message:[left|top|right|bottom] */
2692 fullname = "align_message";
2693 if (match_optname(opts, fullname, sizeof("align_message") - 1, TRUE)) {
2695 complain_about_duplicate(opts, 1);
2696 op = string_for_opt(opts, negated);
2697 if (op && !negated) {
2698 if (!strncmpi(op, "left", sizeof("left") - 1))
2699 iflags.wc_align_message = ALIGN_LEFT;
2700 else if (!strncmpi(op, "top", sizeof("top") - 1))
2701 iflags.wc_align_message = ALIGN_TOP;
2702 else if (!strncmpi(op, "right", sizeof("right") - 1))
2703 iflags.wc_align_message = ALIGN_RIGHT;
2704 else if (!strncmpi(op, "bottom", sizeof("bottom") - 1))
2705 iflags.wc_align_message = ALIGN_BOTTOM;
2709 bad_negation(fullname, TRUE);
2712 /* the order to list the pack */
2713 fullname = "packorder";
2714 if (match_optname(opts, fullname, 4, TRUE)) {
2716 complain_about_duplicate(opts, 1);
2718 bad_negation(fullname, FALSE);
2720 } else if (!(op = string_for_opt(opts, FALSE)))
2723 if (!change_inv_order(op))
2728 /* user can change required response for some prompts (quit, die, hit),
2729 or add an extra prompt (pray, Remove) that isn't ordinarily there */
2730 fullname = "paranoid_confirmation";
2731 if (match_optname(opts, fullname, 8, TRUE)) {
2732 /* at present we don't complain about duplicates for this
2733 option, but we do throw away the old settings whenever
2734 we process a new one [clearing old flags is essential
2735 for handling default paranoid_confirm:pray sanely] */
2736 flags.paranoia_bits = 0; /* clear all */
2738 flags.paranoia_bits = 0; /* [now redundant...] */
2739 } else if ((op = string_for_opt(opts, TRUE)) != 0) {
2740 char *pp, buf[BUFSZ];
2742 op = mungspaces(strcpy(buf, op));
2744 /* We're looking to parse
2745 "paranoid_confirm:whichone wheretwo whothree"
2746 and "paranoid_confirm:" prefix has already
2747 been stripped off by the time we get here */
2748 pp = index(op, ' ');
2751 /* we aren't matching option names but match_optname
2752 does what we want once we've broken the space
2753 delimited aggregate into separate tokens */
2754 for (i = 0; i < SIZE(paranoia); ++i) {
2755 if (match_optname(op, paranoia[i].argname,
2756 paranoia[i].argMinLen, FALSE)
2757 || (paranoia[i].synonym
2758 && match_optname(op, paranoia[i].synonym,
2759 paranoia[i].synMinLen, FALSE))) {
2760 if (paranoia[i].flagmask)
2761 flags.paranoia_bits |= paranoia[i].flagmask;
2762 else /* 0 == "none", so clear all */
2763 flags.paranoia_bits = 0;
2767 if (i == SIZE(paranoia)) {
2768 /* didn't match anything, so arg is bad;
2769 any flags already set will stay set */
2773 /* move on to next token */
2777 break; /* no next token */
2783 /* accept deprecated boolean; superseded by paranoid_confirm:pray */
2784 fullname = "prayconfirm";
2785 if (match_optname(opts, fullname, 4, FALSE)) {
2787 flags.paranoia_bits &= ~PARANOID_PRAY;
2789 flags.paranoia_bits |= PARANOID_PRAY;
2793 /* maximum burden picked up before prompt (Warren Cheung) */
2794 fullname = "pickup_burden";
2795 if (match_optname(opts, fullname, 8, TRUE)) {
2797 complain_about_duplicate(opts, 1);
2799 bad_negation(fullname, FALSE);
2801 } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
2802 switch (tolower(*op)) {
2805 flags.pickup_burden = UNENCUMBERED;
2807 /* Burdened (slight encumbrance) */
2809 flags.pickup_burden = SLT_ENCUMBER;
2811 /* streSsed (moderate encumbrance) */
2813 flags.pickup_burden = MOD_ENCUMBER;
2815 /* straiNed (heavy encumbrance) */
2817 flags.pickup_burden = HVY_ENCUMBER;
2819 /* OverTaxed (extreme encumbrance) */
2822 flags.pickup_burden = EXT_ENCUMBER;
2826 flags.pickup_burden = OVERLOADED;
2835 /* types of objects to pick up automatically */
2836 if (match_optname(opts, "pickup_types", 8, TRUE)) {
2837 char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1], qbuf[QBUFSZ],
2840 boolean badopt = FALSE, compat = (strlen(opts) <= 6), use_menu;
2843 complain_about_duplicate(opts, 1);
2844 oc_to_str(flags.pickup_types, tbuf);
2845 flags.pickup_types[0] = '\0'; /* all */
2846 op = string_for_opt(opts, (compat || !initial));
2848 if (compat || negated || initial) {
2849 /* for backwards compatibility, "pickup" without a
2850 value is a synonym for autopickup of all types
2851 (and during initialization, we can't prompt yet) */
2852 flags.pickup = !negated;
2855 oc_to_str(flags.inv_order, ocl);
2857 if (flags.menu_style == MENU_TRADITIONAL
2858 || flags.menu_style == MENU_COMBINATION) {
2861 Sprintf(qbuf, "New pickup_types: [%s am] (%s)", ocl,
2862 *tbuf ? tbuf : "all");
2864 Sprintf(qbuf, "
\90V
\82µ
\82¢pickup_type
\82ð
\93ü
\97Í
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F[%s am] (%s)", ocl,
2865 *tbuf ? tbuf : "all");
2868 op = mungspaces(abuf);
2869 if (abuf[0] == '\0' || abuf[0] == '\033')
2870 op = tbuf; /* restore */
2871 else if (abuf[0] == 'm')
2876 (void) choose_classes_menu("Auto-Pickup what?", 1, TRUE, ocl,
2879 (void) choose_classes_menu("
\82Ç
\82ê
\82ð
\8e©
\93®
\8fE
\82¢
\82É
\90Ý
\92è
\82·
\82é
\81H", 1, TRUE, ocl,
2886 bad_negation("pickup_types", TRUE);
2891 if (*op != 'a' && *op != 'A') {
2894 oc_sym = def_char_to_objclass(*op);
2895 /* make sure all are valid obj symbols occurring once */
2896 if (oc_sym != MAXOCLASSES
2897 && !index(flags.pickup_types, oc_sym)) {
2898 flags.pickup_types[num] = (char) oc_sym;
2899 flags.pickup_types[++num] = '\0';
2910 /* pile limit: when walking over objects, number which triggers
2911 "there are several/many objects here" instead of listing them */
2912 fullname = "pile_limit";
2913 if (match_optname(opts, fullname, 4, TRUE)) {
2915 complain_about_duplicate(opts, 1);
2916 op = string_for_opt(opts, negated);
2917 if ((negated && !op) || (!negated && op))
2918 flags.pile_limit = negated ? 0 : atoi(op);
2920 bad_negation(fullname, TRUE);
2922 flags.pile_limit = PILE_LIMIT_DFLT;
2924 if (flags.pile_limit < 0)
2925 flags.pile_limit = PILE_LIMIT_DFLT;
2929 /* play mode: normal, explore/discovery, or debug/wizard */
2930 fullname = "playmode";
2931 if (match_optname(opts, fullname, 4, TRUE)) {
2933 complain_about_duplicate(opts, 1);
2935 bad_negation(fullname, FALSE);
2936 if (duplicate || negated)
2938 op = string_for_opt(opts, TRUE);
2939 if (!strncmpi(op, "normal", 6) || !strcmpi(op, "play")) {
2940 wizard = discover = FALSE;
2941 } else if (!strncmpi(op, "explore", 6)
2942 || !strncmpi(op, "discovery", 6)) {
2943 wizard = FALSE, discover = TRUE;
2944 } else if (!strncmpi(op, "debug", 5) || !strncmpi(op, "wizard", 6)) {
2945 wizard = TRUE, discover = FALSE;
2947 raw_printf("Invalid value for \"%s\":%s.", fullname, op);
2953 * player_selection: dialog | prompts */
2954 fullname = "player_selection";
2955 if (match_optname(opts, fullname, sizeof("player_selection") - 1, TRUE)) {
2957 complain_about_duplicate(opts, 1);
2958 op = string_for_opt(opts, negated);
2959 if (op && !negated) {
2960 if (!strncmpi(op, "dialog", sizeof("dialog") - 1))
2961 iflags.wc_player_selection = VIA_DIALOG;
2962 else if (!strncmpi(op, "prompt", sizeof("prompt") - 1))
2963 iflags.wc_player_selection = VIA_PROMPTS;
2967 bad_negation(fullname, TRUE);
2971 /* things to disclose at end of game */
2972 if (match_optname(opts, "disclose", 7, TRUE)) {
2974 * The order that the end_disclose options are stored:
2975 * inventory, attribs, vanquished, genocided,
2976 * conduct, overview.
2977 * There is an array in flags:
2978 * end_disclose[NUM_DISCLOSURE_OPT];
2979 * with option settings for the each of the following:
2980 * iagvc [see disclosure_options in decl.c]:
2981 * Legal setting values in that array are:
2982 * DISCLOSE_PROMPT_DEFAULT_YES ask with default answer yes
2983 * DISCLOSE_PROMPT_DEFAULT_NO ask with default answer no
2984 * DISCLOSE_YES_WITHOUT_PROMPT always disclose and don't ask
2985 * DISCLOSE_NO_WITHOUT_PROMPT never disclose and don't ask
2987 * Those setting values can be used in the option
2988 * string as a prefix to get the desired behaviour.
2990 * For backward compatibility, no prefix is required,
2991 * and the presence of a i,a,g,v, or c without a prefix
2992 * sets the corresponding value to DISCLOSE_YES_WITHOUT_PROMPT.
2994 boolean badopt = FALSE;
2995 int idx, prefix_val;
2998 complain_about_duplicate(opts, 1);
2999 op = string_for_opt(opts, TRUE);
3000 if (op && negated) {
3001 bad_negation("disclose", TRUE);
3004 /* "disclose" without a value means "all with prompting"
3005 and negated means "none without prompting" */
3006 if (!op || !strcmpi(op, "all") || !strcmpi(op, "none")) {
3007 if (op && !strcmpi(op, "none"))
3009 for (num = 0; num < NUM_DISCLOSURE_OPTIONS; num++)
3010 flags.end_disclose[num] = negated
3011 ? DISCLOSE_NO_WITHOUT_PROMPT
3012 : DISCLOSE_PROMPT_DEFAULT_YES;
3018 while (*op && num < sizeof flags.end_disclose - 1) {
3019 static char valid_settings[] = {
3020 DISCLOSE_PROMPT_DEFAULT_YES, DISCLOSE_PROMPT_DEFAULT_NO,
3021 DISCLOSE_YES_WITHOUT_PROMPT, DISCLOSE_NO_WITHOUT_PROMPT, '\0'
3023 register char c, *dop;
3027 c = 'v'; /* killed -> vanquished */
3029 c = 'o'; /* dungeon -> overview */
3030 dop = index(disclosure_options, c);
3032 idx = (int) (dop - disclosure_options);
3033 if (idx < 0 || idx > NUM_DISCLOSURE_OPTIONS - 1) {
3034 impossible("bad disclosure index %d %c", idx, c);
3037 if (prefix_val != -1) {
3038 flags.end_disclose[idx] = prefix_val;
3041 flags.end_disclose[idx] = DISCLOSE_YES_WITHOUT_PROMPT;
3042 } else if (index(valid_settings, c)) {
3044 } else if (c == ' ') {
3055 if (!strncmpi(opts, "kcode", 3)){
3056 if ((op = string_for_env_opt("kcode", opts, FALSE)) != 0){
3063 /* scores:5t[op] 5a[round] o[wn] */
3064 if (match_optname(opts, "scores", 4, TRUE)) {
3066 complain_about_duplicate(opts, 1);
3068 bad_negation("scores", FALSE);
3071 if (!(op = string_for_opt(opts, FALSE)))
3081 } else if (*op == '!') {
3091 flags.end_top = inum;
3095 flags.end_around = inum;
3099 flags.end_own = !negated;
3105 while (letter(*++op) || *op == ' ')
3113 fullname = "sortloot";
3114 if (match_optname(opts, fullname, 4, TRUE)) {
3115 op = string_for_env_opt(fullname, opts, FALSE);
3117 switch (tolower(*op)) {
3121 flags.sortloot = tolower(*op);
3131 fullname = "suppress_alert";
3132 if (match_optname(opts, fullname, 4, TRUE)) {
3134 complain_about_duplicate(opts, 1);
3135 op = string_for_opt(opts, negated);
3137 bad_negation(fullname, FALSE);
3139 (void) feature_alert_opts(op, fullname);
3144 /* videocolors:string */
3145 fullname = "videocolors";
3146 if (match_optname(opts, fullname, 6, TRUE)
3147 || match_optname(opts, "videocolours", 10, TRUE)) {
3149 complain_about_duplicate(opts, 1);
3151 bad_negation(fullname, FALSE);
3153 } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
3156 if (!assign_videocolors(opts))
3160 /* videoshades:string */
3161 fullname = "videoshades";
3162 if (match_optname(opts, fullname, 6, TRUE)) {
3164 complain_about_duplicate(opts, 1);
3166 bad_negation(fullname, FALSE);
3168 } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
3171 if (!assign_videoshades(opts))
3175 #endif /* VIDEOSHADES */
3178 /* video:string -- must be after longer tests */
3180 if (match_optname(opts, fullname, 5, TRUE)) {
3182 complain_about_duplicate(opts, 1);
3184 bad_negation(fullname, FALSE);
3186 } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
3189 if (!assign_video(opts))
3193 #endif /* NO_TERMS */
3194 /* soundcard:string -- careful not to match boolean 'sound' */
3195 fullname = "soundcard";
3196 if (match_optname(opts, fullname, 6, TRUE)) {
3198 complain_about_duplicate(opts, 1);
3200 bad_negation(fullname, FALSE);
3202 } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
3205 if (!assign_soundcard(opts))
3213 * map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12|
3214 * ascii8x12|ascii16x12|ascii12x16|ascii10x18|fit_to_screen]
3216 fullname = "map_mode";
3217 if (match_optname(opts, fullname, sizeof("map_mode") - 1, TRUE)) {
3219 complain_about_duplicate(opts, 1);
3220 op = string_for_opt(opts, negated);
3221 if (op && !negated) {
3222 if (!strncmpi(op, "tiles", sizeof("tiles") - 1))
3223 iflags.wc_map_mode = MAP_MODE_TILES;
3224 else if (!strncmpi(op, "ascii4x6", sizeof("ascii4x6") - 1))
3225 iflags.wc_map_mode = MAP_MODE_ASCII4x6;
3226 else if (!strncmpi(op, "ascii6x8", sizeof("ascii6x8") - 1))
3227 iflags.wc_map_mode = MAP_MODE_ASCII6x8;
3228 else if (!strncmpi(op, "ascii8x8", sizeof("ascii8x8") - 1))
3229 iflags.wc_map_mode = MAP_MODE_ASCII8x8;
3230 else if (!strncmpi(op, "ascii16x8", sizeof("ascii16x8") - 1))
3231 iflags.wc_map_mode = MAP_MODE_ASCII16x8;
3232 else if (!strncmpi(op, "ascii7x12", sizeof("ascii7x12") - 1))
3233 iflags.wc_map_mode = MAP_MODE_ASCII7x12;
3234 else if (!strncmpi(op, "ascii8x12", sizeof("ascii8x12") - 1))
3235 iflags.wc_map_mode = MAP_MODE_ASCII8x12;
3236 else if (!strncmpi(op, "ascii16x12", sizeof("ascii16x12") - 1))
3237 iflags.wc_map_mode = MAP_MODE_ASCII16x12;
3238 else if (!strncmpi(op, "ascii12x16", sizeof("ascii12x16") - 1))
3239 iflags.wc_map_mode = MAP_MODE_ASCII12x16;
3240 else if (!strncmpi(op, "ascii10x18", sizeof("ascii10x18") - 1))
3241 iflags.wc_map_mode = MAP_MODE_ASCII10x18;
3242 else if (!strncmpi(op, "fit_to_screen",
3243 sizeof("fit_to_screen") - 1))
3244 iflags.wc_map_mode = MAP_MODE_ASCII_FIT_TO_SCREEN;
3248 bad_negation(fullname, TRUE);
3252 * scroll_amount:nn */
3253 fullname = "scroll_amount";
3254 if (match_optname(opts, fullname, sizeof("scroll_amount") - 1, TRUE)) {
3256 complain_about_duplicate(opts, 1);
3257 op = string_for_opt(opts, negated);
3258 if ((negated && !op) || (!negated && op)) {
3259 iflags.wc_scroll_amount = negated ? 1 : atoi(op);
3261 bad_negation(fullname, TRUE);
3265 * scroll_margin:nn */
3266 fullname = "scroll_margin";
3267 if (match_optname(opts, fullname, sizeof("scroll_margin") - 1, TRUE)) {
3269 complain_about_duplicate(opts, 1);
3270 op = string_for_opt(opts, negated);
3271 if ((negated && !op) || (!negated && op)) {
3272 iflags.wc_scroll_margin = negated ? 5 : atoi(op);
3274 bad_negation(fullname, TRUE);
3277 fullname = "subkeyvalue";
3278 if (match_optname(opts, fullname, 5, TRUE)) {
3279 /* no duplicate complaint here */
3281 bad_negation(fullname, FALSE);
3284 op = string_for_opt(opts, 0);
3285 map_subkeyvalue(op);
3292 fullname = "tile_width";
3293 if (match_optname(opts, fullname, sizeof("tile_width") - 1, TRUE)) {
3295 complain_about_duplicate(opts, 1);
3296 op = string_for_opt(opts, negated);
3297 if ((negated && !op) || (!negated && op)) {
3298 iflags.wc_tile_width = negated ? 0 : atoi(op);
3300 bad_negation(fullname, TRUE);
3305 fullname = "tile_file";
3306 if (match_optname(opts, fullname, sizeof("tile_file") - 1, TRUE)) {
3308 complain_about_duplicate(opts, 1);
3309 if ((op = string_for_opt(opts, FALSE)) != 0) {
3310 if (iflags.wc_tile_file)
3311 free(iflags.wc_tile_file);
3312 iflags.wc_tile_file = (char *) alloc(strlen(op) + 1);
3313 Strcpy(iflags.wc_tile_file, op);
3319 fullname = "tile_height";
3320 if (match_optname(opts, fullname, sizeof("tile_height") - 1, TRUE)) {
3322 complain_about_duplicate(opts, 1);
3323 op = string_for_opt(opts, negated);
3324 if ((negated && !op) || (!negated && op)) {
3325 iflags.wc_tile_height = negated ? 0 : atoi(op);
3327 bad_negation(fullname, TRUE);
3331 * vary_msgcount:nn */
3332 fullname = "vary_msgcount";
3333 if (match_optname(opts, fullname, sizeof("vary_msgcount") - 1, TRUE)) {
3335 complain_about_duplicate(opts, 1);
3336 op = string_for_opt(opts, negated);
3337 if ((negated && !op) || (!negated && op)) {
3338 iflags.wc_vary_msgcount = negated ? 0 : atoi(op);
3340 bad_negation(fullname, TRUE);
3343 fullname = "windowtype";
3344 if (match_optname(opts, fullname, 3, TRUE)) {
3346 complain_about_duplicate(opts, 1);
3348 bad_negation(fullname, FALSE);
3350 } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
3351 char buf[WINTYPELEN];
3352 nmcpy(buf, op, WINTYPELEN);
3353 choose_windows(buf);
3358 fullname = "windowchain";
3359 if (match_optname(opts, fullname, 3, TRUE)) {
3361 bad_negation(fullname, FALSE);
3363 } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
3364 char buf[WINTYPELEN];
3365 nmcpy(buf, op, WINTYPELEN);
3366 addto_windowchain(buf);
3373 * setting window colors
3374 * syntax: windowcolors=menu foregrnd/backgrnd text foregrnd/backgrnd
3376 fullname = "windowcolors";
3377 if (match_optname(opts, fullname, 7, TRUE)) {
3379 complain_about_duplicate(opts, 1);
3380 if ((op = string_for_opt(opts, FALSE)) != 0) {
3381 if (!wc_set_window_colors(op))
3384 bad_negation(fullname, TRUE);
3388 /* menustyle:traditional or combination or full or partial */
3389 if (match_optname(opts, "menustyle", 4, TRUE)) {
3391 boolean val_required = (strlen(opts) > 5 && !negated);
3394 complain_about_duplicate(opts, 1);
3395 if (!(op = string_for_opt(opts, !val_required))) {
3397 return; /* string_for_opt gave feedback */
3398 tmp = negated ? 'n' : 'f';
3403 case 'n': /* none */
3404 case 't': /* traditional */
3405 flags.menu_style = MENU_TRADITIONAL;
3407 case 'c': /* combo: trad.class sel+menu */
3408 flags.menu_style = MENU_COMBINATION;
3410 case 'p': /* partial: no class menu */
3411 flags.menu_style = MENU_PARTIAL;
3413 case 'f': /* full: class menu + menu */
3414 flags.menu_style = MENU_FULL;
3422 fullname = "menu_headings";
3423 if (match_optname(opts, fullname, 12, TRUE)) {
3425 complain_about_duplicate(opts, 1);
3427 bad_negation(fullname, FALSE);
3429 } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
3432 for (i = 0; i < SIZE(attrnames); i++)
3433 if (!strcmpi(opts, attrnames[i].name)) {
3434 iflags.menu_headings = attrnames[i].attr;
3441 /* check for menu command mapping */
3442 for (i = 0; i < NUM_MENU_CMDS; i++) {
3443 fullname = default_menu_cmd_info[i].name;
3445 complain_about_duplicate(opts, 1);
3446 if (match_optname(opts, fullname, (int) strlen(fullname), TRUE)) {
3448 bad_negation(fullname, FALSE);
3449 } else if ((op = string_for_opt(opts, FALSE)) != 0) {
3451 char c, op_buf[BUFSZ];
3452 boolean isbad = FALSE;
3454 escapes(op, op_buf);
3457 if (c == 0 || c == '\r' || c == '\n' || c == '\033'
3458 || c == ' ' || digit(c) || (letter(c) && c != '@'))
3460 else /* reject default object class symbols */
3461 for (j = 1; j < MAXOCLASSES; j++)
3462 if (c == def_oc_syms[i].sym) {
3470 add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd);
3475 #if defined(STATUS_VIA_WINDOWPORT) && defined(STATUS_HILITES)
3476 /* hilite fields in status prompt */
3477 if (match_optname(opts, "hilite_status", 13, TRUE)) {
3479 complain_about_duplicate(opts, 1);
3480 op = string_for_opt(opts, TRUE);
3481 if (op && negated) {
3482 clear_status_hilites(tfrom_file);
3485 /* a value is mandatory */
3489 if (!set_status_hilites(op, tfrom_file))
3495 #if defined(BACKWARD_COMPAT)
3496 fullname = "DECgraphics";
3497 if (match_optname(opts, fullname, 3, TRUE)) {
3498 boolean badflag = FALSE;
3501 complain_about_duplicate(opts, 1);
3503 /* There is no rogue level DECgraphics-specific set */
3504 if (symset[PRIMARY].name) {
3507 symset[PRIMARY].name = dupstr(fullname);
3508 if (!read_sym_file(PRIMARY)) {
3510 clear_symsetentry(PRIMARY, TRUE);
3512 switch_symbols(TRUE);
3515 pline("Failure to load symbol set %s.", fullname);
3521 fullname = "IBMgraphics";
3522 if (match_optname(opts, fullname, 3, TRUE)) {
3523 const char *sym_name = fullname;
3524 boolean badflag = FALSE;
3527 complain_about_duplicate(opts, 1);
3529 for (i = 0; i < NUM_GRAPHICS; ++i) {
3530 if (symset[i].name) {
3534 sym_name = "RogueIBM";
3535 symset[i].name = dupstr(sym_name);
3536 if (!read_sym_file(i)) {
3538 clear_symsetentry(i, TRUE);
3544 pline("Failure to load symbol set %s.", sym_name);
3547 switch_symbols(TRUE);
3548 if (!initial && Is_rogue_level(&u.uz))
3549 assign_graphics(ROGUESET);
3555 #ifdef MAC_GRAPHICS_ENV
3556 fullname = "MACgraphics";
3557 if (match_optname(opts, fullname, 3, TRUE)) {
3558 boolean badflag = FALSE;
3561 complain_about_duplicate(opts, 1);
3563 if (symset[PRIMARY].name) {
3566 symset[PRIMARY].name = dupstr(fullname);
3567 if (!read_sym_file(PRIMARY)) {
3569 clear_symsetentry(PRIMARY, TRUE);
3573 pline("Failure to load symbol set %s.", fullname);
3576 switch_symbols(TRUE);
3577 if (!initial && Is_rogue_level(&u.uz))
3578 assign_graphics(ROGUESET);
3585 /* OK, if we still haven't recognized the option, check the boolean
3588 for (i = 0; boolopt[i].name; i++) {
3589 if (match_optname(opts, boolopt[i].name, 3, FALSE)) {
3590 /* options that don't exist */
3591 if (!boolopt[i].addr) {
3592 if (!initial && !negated)
3593 pline_The("\"%s\" option is not available.",
3597 /* options that must come from config file */
3598 if (!initial && (boolopt[i].optflags == SET_IN_FILE)) {
3599 rejectoption(boolopt[i].name);
3603 *(boolopt[i].addr) = !negated;
3605 /* 0 means boolean opts */
3606 if (duplicate_opt_detection(boolopt[i].name, 0))
3607 complain_about_duplicate(boolopt[i].name, 0);
3610 if ((boolopt[i].addr) == &iflags.rlecomp) {
3611 if (*boolopt[i].addr)
3612 set_savepref("rlecomp");
3614 set_savepref("!rlecomp");
3618 if ((boolopt[i].addr) == &iflags.zerocomp) {
3619 if (*boolopt[i].addr)
3620 set_savepref("zerocomp");
3622 set_savepref("externalcomp");
3625 /* only do processing below if setting with doset() */
3629 if ((boolopt[i].addr) == &flags.time
3630 || (boolopt[i].addr) == &flags.showexp
3631 #ifdef SCORE_ON_BOTL
3632 || (boolopt[i].addr) == &flags.showscore
3635 #ifdef STATUS_VIA_WINDOWPORT
3636 status_initialize(REASSESS_ONLY);
3638 context.botl = TRUE;
3639 } else if ((boolopt[i].addr) == &flags.invlet_constant) {
3640 if (flags.invlet_constant)
3642 } else if (((boolopt[i].addr) == &flags.lit_corridor)
3643 || ((boolopt[i].addr) == &flags.dark_room)) {
3645 * All corridor squares seen via night vision or
3646 * candles & lamps change. Update them by calling
3647 * newsym() on them. Don't do this if we are
3648 * initializing the options --- the vision system
3651 vision_recalc(2); /* shut down vision */
3652 vision_full_recalc = 1; /* delayed recalc */
3653 if (iflags.use_color)
3654 need_redraw = TRUE; /* darkroom refresh */
3655 } else if ((boolopt[i].addr) == &iflags.use_inverse
3656 || (boolopt[i].addr) == &flags.showrace
3657 || (boolopt[i].addr) == &iflags.hilite_pet) {
3660 } else if ((boolopt[i].addr) == &iflags.use_color) {
3663 if ((boolopt[i].addr) == &iflags.use_color && iflags.BIOS) {
3670 #endif /* TEXTCOLOR */
3676 /* out of valid options */
3680 static NEARDATA const char *menutype[] = { "traditional", "combination",
3681 "full", "partial" };
3683 static NEARDATA const char *burdentype[] = { "unencumbered", "burdened",
3684 "stressed", "strained",
3685 "overtaxed", "overloaded" };
3687 static NEARDATA const char *runmodes[] = { "teleport", "run", "walk",
3690 static NEARDATA const char *sortltype[] = { "none", "loot", "full" };
3693 * Convert the given string of object classes to a string of default object
3697 oc_to_str(src, dest)
3702 while ((i = (int) *src++) != 0) {
3703 if (i < 0 || i >= MAXOCLASSES)
3704 impossible("oc_to_str: illegal object class %d", i);
3706 *dest++ = def_oc_syms[i].sym;
3712 * Add the given mapping to the menu command map list. Always keep the
3713 * maps valid C strings.
3716 add_menu_cmd_alias(from_ch, to_ch)
3717 char from_ch, to_ch;
3719 if (n_menu_mapped >= MAX_MENU_MAPPED_CMDS) {
3720 pline("out of menu map space.");
3722 mapped_menu_cmds[n_menu_mapped] = from_ch;
3723 mapped_menu_op[n_menu_mapped] = to_ch;
3725 mapped_menu_cmds[n_menu_mapped] = 0;
3726 mapped_menu_op[n_menu_mapped] = 0;
3731 * Map the given character to its corresponding menu command. If it
3732 * doesn't match anything, just return the original.
3738 char *found = index(mapped_menu_cmds, ch);
3740 int idx = (int) (found - mapped_menu_cmds);
3741 ch = mapped_menu_op[idx];
3746 #if defined(MICRO) || defined(MAC) || defined(WIN32)
3747 #define OPTIONS_HEADING "OPTIONS"
3749 #define OPTIONS_HEADING "NETHACKOPTIONS"
3752 static char fmtstr_doset_add_menu[] = "%s%-15s [%s] ";
3753 static char fmtstr_doset_add_menu_tab[] = "%s\t[%s]";
3756 doset_add_menu(win, option, indexoffset)
3757 winid win; /* window to add to */
3758 const char *option; /* option name */
3759 int indexoffset; /* value to add to index in compopt[], or zero
3760 if option cannot be changed */
3762 const char *value = "unknown"; /* current value */
3763 char buf[BUFSZ], buf2[BUFSZ];
3768 if (indexoffset == 0) {
3770 value = get_compopt_value(option, buf2);
3772 for (i = 0; compopt[i].name; i++)
3773 if (strcmp(option, compopt[i].name) == 0)
3776 if (compopt[i].name) {
3777 any.a_int = i + 1 + indexoffset;
3778 value = get_compopt_value(option, buf2);
3780 /* We are trying to add an option not found in compopt[].
3781 This is almost certainly bad, but we'll let it through anyway
3782 (with a zero value, so it can't be selected). */
3786 /* " " replaces "a - " -- assumes menus follow that style */
3787 if (!iflags.menu_tab_sep)
3788 Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : " ", option,
3791 Sprintf(buf, fmtstr_doset_add_menu_tab, option, value);
3792 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
3795 /* Changing options via menu by Per Liboriussen */
3799 char buf[BUFSZ], buf2[BUFSZ];
3800 int i = 0, pass, boolcount, pick_cnt, pick_idx, opt_indx;
3804 menu_item *pick_list;
3805 int indexoffset, startpass, endpass;
3806 boolean setinitial = FALSE, fromfile = FALSE;
3807 int biggest_name = 0;
3808 const char *n_currently_set = "(%d currently set)";
3810 tmpwin = create_nhwindow(NHW_MENU);
3814 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
3816 "Booleans (selecting will toggle value):", MENU_UNSELECTED);
3818 "
\90^
\8bU
\83I
\83v
\83V
\83\87\83\93 (
\91I
\91ð
\82·
\82é
\82Æ
\92l
\82ª
\90Ø
\82è
\91Ö
\82í
\82è
\82Ü
\82·)
\81F", MENU_UNSELECTED);
3820 /* first list any other non-modifiable booleans, then modifiable ones */
3821 for (pass = 0; pass <= 1; pass++)
3822 for (i = 0; boolopt[i].name; i++)
3823 if ((bool_p = boolopt[i].addr) != 0
3824 && ((boolopt[i].optflags == DISP_IN_GAME && pass == 0)
3825 || (boolopt[i].optflags == SET_IN_GAME && pass == 1))) {
3826 if (bool_p == &flags.female)
3827 continue; /* obsolete */
3828 if (bool_p == &iflags.sanity_check && !wizard)
3830 if (bool_p == &iflags.menu_tab_sep && !wizard)
3832 if (is_wc_option(boolopt[i].name)
3833 && !wc_supported(boolopt[i].name))
3835 if (is_wc2_option(boolopt[i].name)
3836 && !wc2_supported(boolopt[i].name))
3838 any.a_int = (pass == 0) ? 0 : i + 1;
3839 if (!iflags.menu_tab_sep)
3840 Sprintf(buf, "%s%-17s [%s]", pass == 0 ? " " : "",
3841 boolopt[i].name, *bool_p ? "true" : "false");
3843 Sprintf(buf, "%s\t[%s]", boolopt[i].name,
3844 *bool_p ? "true" : "false");
3845 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
3850 indexoffset = boolcount;
3852 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
3854 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
3855 "Compounds (selecting will prompt for new value):",
3858 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
3859 "
\95¶
\8e\9a\97ñ
\83I
\83v
\83V
\83\87\83\93 (
\91I
\91ð
\82·
\82é
\82Æ
\90V
\82µ
\82¢
\92l
\82Ì
\93ü
\97Í
\82ð
\8b\81\82ß
\82Ü
\82·)
\81F",
3863 #ifdef notyet /* SYSCF */
3864 /* XXX I think this is still fragile. Fixing initial/from_file and/or
3866 the SET_* etc to bitmaps will let me make this better. */
3868 startpass = SET_IN_SYS;
3871 startpass = DISP_IN_GAME;
3872 endpass = SET_IN_GAME;
3874 /* spin through the options to find the biggest name
3875 and adjust the format string accordingly if needed */
3877 for (i = 0; compopt[i].name; i++)
3878 if (compopt[i].optflags >= startpass && compopt[i].optflags <= endpass
3879 && strlen(compopt[i].name) > (unsigned) biggest_name)
3880 biggest_name = (int) strlen(compopt[i].name);
3881 if (biggest_name > 30)
3883 if (!iflags.menu_tab_sep)
3884 Sprintf(fmtstr_doset_add_menu, "%%s%%-%ds [%%s]", biggest_name);
3886 /* deliberately put `playmode', `name', `role', `race', `gender' first
3887 (also alignment if anything ever comes before it in compopt[]) */
3888 doset_add_menu(tmpwin, "playmode", 0);
3889 doset_add_menu(tmpwin, "name", 0);
3890 doset_add_menu(tmpwin, "role", 0);
3891 doset_add_menu(tmpwin, "race", 0);
3892 doset_add_menu(tmpwin, "gender", 0);
3894 for (pass = startpass; pass <= endpass; pass++)
3895 for (i = 0; compopt[i].name; i++)
3896 if (compopt[i].optflags == pass) {
3897 if (!strcmp(compopt[i].name, "playmode")
3898 || !strcmp(compopt[i].name, "name")
3899 || !strcmp(compopt[i].name, "role")
3900 || !strcmp(compopt[i].name, "race")
3901 || !strcmp(compopt[i].name, "gender"))
3903 else if (is_wc_option(compopt[i].name)
3904 && !wc_supported(compopt[i].name))
3906 else if (is_wc2_option(compopt[i].name)
3907 && !wc2_supported(compopt[i].name))
3910 doset_add_menu(tmpwin, compopt[i].name,
3911 (pass == DISP_IN_GAME) ? 0 : indexoffset);
3914 Sprintf(buf2, n_currently_set, msgtype_count());
3915 Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : " ",
3916 "message types", buf2);
3917 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
3919 Sprintf(buf2, n_currently_set, count_menucolors());
3920 Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : " ",
3921 "menucolors", buf2);
3922 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
3923 #ifdef STATUS_VIA_WINDOWPORT
3924 #ifdef STATUS_HILITES
3926 get_status_hilites(buf2, 60);
3928 Sprintf(buf2, "%s", "(none)");
3929 if (!iflags.menu_tab_sep)
3930 Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : " ",
3931 "status_hilites", buf2);
3933 Sprintf(buf, fmtstr_doset_add_menu_tab, "status_hilites", buf2);
3934 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
3938 Sprintf(buf2, n_currently_set, count_ape_maps((int *) 0, (int *) 0));
3939 Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : " ",
3940 "autopickup exceptions", buf2);
3941 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
3942 #ifdef PREFIXES_IN_USE
3944 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
3945 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
3946 "Variable playground locations:", MENU_UNSELECTED);
3947 for (i = 0; i < PREFIX_COUNT; i++)
3948 doset_add_menu(tmpwin, fqn_prefix_names[i], 0);
3951 end_menu(tmpwin, "Set what options?");
3953 end_menu(tmpwin, "
\82Ç
\82Ì
\83I
\83v
\83V
\83\87\83\93\82ð
\90Ý
\92è
\82µ
\82Ü
\82·
\82©
\81H");
3954 need_redraw = FALSE;
3955 if ((pick_cnt = select_menu(tmpwin, PICK_ANY, &pick_list)) > 0) {
3957 * Walk down the selection list and either invert the booleans
3958 * or prompt for new values. In most cases, call parseoptions()
3959 * to take care of options that require special attention, like
3962 for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) {
3963 opt_indx = pick_list[pick_idx].item.a_int - 1;
3964 if (opt_indx == -2) {
3965 /* -2 due to -1 offset for select_menu() */
3966 (void) special_handling("autopickup_exception", setinitial,
3968 #ifdef STATUS_VIA_WINDOWPORT
3969 #ifdef STATUS_HILITES
3970 } else if (opt_indx == -3) {
3971 /* -3 due to -1 offset for select_menu() */
3972 if (!status_hilite_menu()) {
3973 pline("Bad status hilite(s) specified.");
3975 if (wc2_supported("status_hilites"))
3976 preference_update("status_hilites");
3980 } else if (opt_indx == -4) {
3981 (void) special_handling("menucolors", setinitial,
3983 } else if (opt_indx == -5) {
3984 (void) special_handling("msgtype", setinitial, fromfile);
3985 } else if (opt_indx < boolcount) {
3986 /* boolean option */
3987 Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "",
3988 boolopt[opt_indx].name);
3989 parseoptions(buf, setinitial, fromfile);
3990 if (wc_supported(boolopt[opt_indx].name)
3991 || wc2_supported(boolopt[opt_indx].name))
3992 preference_update(boolopt[opt_indx].name);
3994 /* compound option */
3995 opt_indx -= boolcount;
3997 if (!special_handling(compopt[opt_indx].name, setinitial,
4000 Sprintf(buf, "Set %s to what?", compopt[opt_indx].name);
4002 Sprintf(buf, "%s
\82É
\89½
\82ð
\90Ý
\92è
\82·
\82é
\81H", compopt[opt_indx].name);
4004 if (buf2[0] == '\033')
4006 Sprintf(buf, "%s:%s", compopt[opt_indx].name, buf2);
4008 parseoptions(buf, setinitial, fromfile);
4010 if (wc_supported(compopt[opt_indx].name)
4011 || wc2_supported(compopt[opt_indx].name))
4012 preference_update(compopt[opt_indx].name);
4015 free((genericptr_t) pick_list);
4016 pick_list = (menu_item *) 0;
4019 destroy_nhwindow(tmpwin);
4028 handle_add_list_remove(optname, numtotal)
4029 const char *optname;
4034 int i, pick_cnt, pick_idx, opt_idx;
4035 menu_item *pick_list = (menu_item *) 0;
4036 static const struct action {
4039 } action_titles[] = {
4041 { 'a', "add new %s" }, /* [0] */
4043 { 'a', "
\90V
\82µ
\82¢%s
\82ð
\92Ç
\89Á" }, /* [0] */
4046 { 'l', "list %s" }, /* [1] */
4048 { 'l', "%s
\82ð
\88ê
\97\97\95\
\8e¦" }, /* [1] */
4051 { 'r', "remove existing %s" }, /* [2] */
4053 { 'r', "
\8aù
\82É
\82 \82é%s
\82ð
\8dí
\8f\9c" }, /* [2] */
4056 { 'x', "exit this menu" }, /* [3] */
4058 { 'x', "
\82±
\82Ì
\83\81\83j
\83\85\81[
\82ð
\95Â
\82¶
\82é" }, /* [3] */
4063 tmpwin = create_nhwindow(NHW_MENU);
4066 for (i = 0; i < SIZE(action_titles); i++) {
4069 /* omit list and remove if there aren't any yet */
4070 if (!numtotal && (i == 1 || i == 2))
4072 Sprintf(tmpbuf, action_titles[i].desc,
4073 (i == 1) ? makeplural(optname) : optname);
4074 add_menu(tmpwin, NO_GLYPH, &any, action_titles[i].letr, 0, ATR_NONE,
4076 #if 0 /* this ought to work but doesn't... */
4077 (action_titles[i].letr == 'x') ? MENU_SELECTED :
4082 end_menu(tmpwin, "Do what?");
4084 end_menu(tmpwin, "
\82Ç
\82¤
\82·
\82é
\81H");
4085 if ((pick_cnt = select_menu(tmpwin, PICK_ONE, &pick_list)) > 0) {
4086 for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) {
4087 opt_idx = pick_list[pick_idx].item.a_int - 1;
4089 free((genericptr_t) pick_list);
4090 pick_list = (menu_item *) 0;
4092 destroy_nhwindow(tmpwin);
4095 opt_idx = 3; /* none selected, exit menu */
4099 struct symsetentry *symset_list = 0; /* files.c will populate this with
4100 list of available sets */
4103 special_handling(optname, setinitial, setfromfile)
4104 const char *optname;
4105 boolean setinitial, setfromfile;
4112 /* Special handling of menustyle, pickup_burden, pickup_types,
4113 * disclose, runmode, msg_window, menu_headings, sortloot,
4114 * and number_pad options.
4115 * Also takes care of interactive autopickup_exception_handling changes.
4117 if (!strcmp("menustyle", optname)) {
4118 const char *style_name;
4119 menu_item *style_pick = (menu_item *) 0;
4120 tmpwin = create_nhwindow(NHW_MENU);
4123 for (i = 0; i < SIZE(menutype); i++) {
4124 style_name = menutype[i];
4125 /* note: separate `style_name' variable used
4126 to avoid an optimizer bug in VAX C V2.3 */
4128 add_menu(tmpwin, NO_GLYPH, &any, *style_name, 0, ATR_NONE,
4129 style_name, MENU_UNSELECTED);
4132 end_menu(tmpwin, "Select menustyle:");
4134 end_menu(tmpwin, "
\83\81\83j
\83\85\81[
\83X
\83^
\83C
\83\8b\82ð
\91I
\91ð
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F");
4135 if (select_menu(tmpwin, PICK_ONE, &style_pick) > 0) {
4136 flags.menu_style = style_pick->item.a_int - 1;
4137 free((genericptr_t) style_pick);
4139 destroy_nhwindow(tmpwin);
4140 } else if (!strcmp("paranoid_confirmation", optname)) {
4141 menu_item *paranoia_picks = (menu_item *) 0;
4143 tmpwin = create_nhwindow(NHW_MENU);
4146 for (i = 0; paranoia[i].flagmask != 0; ++i) {
4147 if (paranoia[i].flagmask == PARANOID_BONES && !wizard)
4149 any.a_int = paranoia[i].flagmask;
4150 add_menu(tmpwin, NO_GLYPH, &any, *paranoia[i].argname, 0,
4151 ATR_NONE, paranoia[i].explain,
4152 (flags.paranoia_bits & paranoia[i].flagmask)
4156 end_menu(tmpwin, "Actions requiring extra confirmation:");
4157 i = select_menu(tmpwin, PICK_ANY, ¶noia_picks);
4159 /* player didn't cancel; we reset all the paranoia options
4160 here even if there were no items picked, since user
4161 could have toggled off preselected ones to end up with 0 */
4162 flags.paranoia_bits = 0;
4164 /* at least 1 item set, either preselected or newly picked */
4166 flags.paranoia_bits |= paranoia_picks[i].item.a_int;
4167 free((genericptr_t) paranoia_picks);
4170 destroy_nhwindow(tmpwin);
4171 } else if (!strcmp("pickup_burden", optname)) {
4172 const char *burden_name, *burden_letters = "ubsntl";
4173 menu_item *burden_pick = (menu_item *) 0;
4175 tmpwin = create_nhwindow(NHW_MENU);
4178 for (i = 0; i < SIZE(burdentype); i++) {
4179 burden_name = burdentype[i];
4181 add_menu(tmpwin, NO_GLYPH, &any, burden_letters[i], 0, ATR_NONE,
4182 burden_name, MENU_UNSELECTED);
4185 end_menu(tmpwin, "Select encumbrance level:");
4187 end_menu(tmpwin, "
\8cx
\8d\90\82ð
\8fo
\82·
\89×
\8fd
\83\8c\83x
\83\8b\82ð
\91I
\91ð
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F");
4188 if (select_menu(tmpwin, PICK_ONE, &burden_pick) > 0) {
4189 flags.pickup_burden = burden_pick->item.a_int - 1;
4190 free((genericptr_t) burden_pick);
4192 destroy_nhwindow(tmpwin);
4193 } else if (!strcmp("pickup_types", optname)) {
4194 /* parseoptions will prompt for the list of types */
4195 parseoptions(strcpy(buf, "pickup_types"), setinitial, setfromfile);
4196 } else if (!strcmp("disclose", optname)) {
4197 /* order of disclose_names[] must correspond to
4198 disclosure_options in decl.c */
4199 static const char *disclosure_names[] = {
4200 "inventory", "attributes", "vanquished",
4201 "genocides", "conduct", "overview",
4203 int disc_cat[NUM_DISCLOSURE_OPTIONS];
4204 int pick_cnt, pick_idx, opt_idx;
4205 menu_item *disclosure_pick = (menu_item *) 0;
4207 tmpwin = create_nhwindow(NHW_MENU);
4210 for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) {
4211 Sprintf(buf, "%-12s[%c%c]", disclosure_names[i],
4212 flags.end_disclose[i], disclosure_options[i]);
4214 add_menu(tmpwin, NO_GLYPH, &any, disclosure_options[i], 0,
4215 ATR_NONE, buf, MENU_UNSELECTED);
4219 end_menu(tmpwin, "Change which disclosure options categories:");
4221 end_menu(tmpwin, "
\82Ç
\82Ì
\83J
\83e
\83S
\83\8a\82Ì
\95\
\8e¦
\8fî
\95ñ
\83I
\83v
\83V
\83\87\83\93\82ð
\95Ï
\8dX
\82µ
\82Ü
\82·
\82©
\81F");
4222 pick_cnt = select_menu(tmpwin, PICK_ANY, &disclosure_pick);
4224 for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) {
4225 opt_idx = disclosure_pick[pick_idx].item.a_int - 1;
4226 disc_cat[opt_idx] = 1;
4228 free((genericptr_t) disclosure_pick);
4229 disclosure_pick = (menu_item *) 0;
4231 destroy_nhwindow(tmpwin);
4233 for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) {
4236 Sprintf(buf, "Disclosure options for %s:",
4238 Sprintf(buf, "%s
\82Ì
\8fo
\97Í
\8c`
\8e®
\81F",
4239 disclosure_names[i]);
4240 tmpwin = create_nhwindow(NHW_MENU);
4243 /* 'y','n',and '+' work as alternate selectors; '-' doesn't */
4244 any.a_char = DISCLOSE_NO_WITHOUT_PROMPT;
4245 add_menu(tmpwin, NO_GLYPH, &any, 'a', any.a_char, ATR_NONE,
4247 "Never disclose, without prompting",
4249 "
\8am
\94F
\82¹
\82¸
\82É
\8fo
\97Í
\82à
\82µ
\82È
\82¢",
4251 any.a_char = DISCLOSE_YES_WITHOUT_PROMPT;
4252 add_menu(tmpwin, NO_GLYPH, &any, 'b', any.a_char, ATR_NONE,
4254 "Always disclose, without prompting",
4256 "
\8am
\94F
\82¹
\82¸
\82É
\8fo
\97Í
\82·
\82é",
4258 any.a_char = DISCLOSE_PROMPT_DEFAULT_NO;
4259 add_menu(tmpwin, NO_GLYPH, &any, 'c', any.a_char, ATR_NONE,
4261 "Prompt, with default answer of \"No\"",
4263 "
\8am
\94F
\82·
\82é
\81C
\83f
\83t
\83H
\83\8b\83g
\82Í
\81u
\8fo
\97Í
\82µ
\82È
\82¢
\81v",
4265 any.a_char = DISCLOSE_PROMPT_DEFAULT_YES;
4266 add_menu(tmpwin, NO_GLYPH, &any, 'd', any.a_char, ATR_NONE,
4268 "Prompt, with default answer of \"Yes\"",
4270 "
\8am
\94F
\82·
\82é
\81C
\83f
\83t
\83H
\83\8b\83g
\82Í
\81u
\8fo
\97Í
\82·
\82é
\81v",
4272 end_menu(tmpwin, buf);
4273 if (select_menu(tmpwin, PICK_ONE, &disclosure_pick) > 0) {
4274 flags.end_disclose[i] = disclosure_pick->item.a_char;
4275 free((genericptr_t) disclosure_pick);
4277 destroy_nhwindow(tmpwin);
4280 } else if (!strcmp("runmode", optname)) {
4281 const char *mode_name;
4282 menu_item *mode_pick = (menu_item *) 0;
4284 tmpwin = create_nhwindow(NHW_MENU);
4287 for (i = 0; i < SIZE(runmodes); i++) {
4288 mode_name = runmodes[i];
4290 add_menu(tmpwin, NO_GLYPH, &any, *mode_name, 0, ATR_NONE,
4291 mode_name, MENU_UNSELECTED);
4294 end_menu(tmpwin, "Select run/travel display mode:");
4296 end_menu(tmpwin, "
\91\96\8ds/
\83g
\83\89\83x
\83\8b\82Ì
\95\
\8e¦
\83\82\81[
\83h
\82ð
\91I
\91ð
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F");
4297 if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) {
4298 flags.runmode = mode_pick->item.a_int - 1;
4299 free((genericptr_t) mode_pick);
4301 destroy_nhwindow(tmpwin);
4302 } else if (!strcmp("msg_window", optname)) {
4304 /* by Christian W. Cooper */
4305 menu_item *window_pick = (menu_item *) 0;
4307 tmpwin = create_nhwindow(NHW_MENU);
4311 add_menu(tmpwin, NO_GLYPH, &any, 's', 0, ATR_NONE, "single",
4314 add_menu(tmpwin, NO_GLYPH, &any, 'c', 0, ATR_NONE, "combination",
4317 add_menu(tmpwin, NO_GLYPH, &any, 'f', 0, ATR_NONE, "full",
4320 add_menu(tmpwin, NO_GLYPH, &any, 'r', 0, ATR_NONE, "reversed",
4323 end_menu(tmpwin, "Select message history display type:");
4325 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");
4326 if (select_menu(tmpwin, PICK_ONE, &window_pick) > 0) {
4327 iflags.prevmsg_window = window_pick->item.a_char;
4328 free((genericptr_t) window_pick);
4330 destroy_nhwindow(tmpwin);
4332 } else if (!strcmp("sortloot", optname)) {
4333 const char *sortl_name;
4334 menu_item *sortl_pick = (menu_item *) 0;
4336 tmpwin = create_nhwindow(NHW_MENU);
4339 for (i = 0; i < SIZE(sortltype); i++) {
4340 sortl_name = sortltype[i];
4341 any.a_char = *sortl_name;
4342 add_menu(tmpwin, NO_GLYPH, &any, *sortl_name, 0, ATR_NONE,
4343 sortl_name, MENU_UNSELECTED);
4345 end_menu(tmpwin, "Select loot sorting type:");
4346 if (select_menu(tmpwin, PICK_ONE, &sortl_pick) > 0) {
4347 flags.sortloot = sortl_pick->item.a_char;
4348 free((genericptr_t) sortl_pick);
4350 destroy_nhwindow(tmpwin);
4351 } else if (!strcmp("align_message", optname)
4352 || !strcmp("align_status", optname)) {
4353 menu_item *window_pick = (menu_item *) 0;
4355 boolean msg = (*(optname + 6) == 'm');
4357 tmpwin = create_nhwindow(NHW_MENU);
4360 any.a_int = ALIGN_TOP;
4361 add_menu(tmpwin, NO_GLYPH, &any, 't', 0, ATR_NONE, "top",
4363 any.a_int = ALIGN_BOTTOM;
4364 add_menu(tmpwin, NO_GLYPH, &any, 'b', 0, ATR_NONE, "bottom",
4366 any.a_int = ALIGN_LEFT;
4367 add_menu(tmpwin, NO_GLYPH, &any, 'l', 0, ATR_NONE, "left",
4369 any.a_int = ALIGN_RIGHT;
4370 add_menu(tmpwin, NO_GLYPH, &any, 'r', 0, ATR_NONE, "right",
4373 Sprintf(abuf, "Select %s window placement relative to the map:",
4374 msg ? "message" : "status");
4376 Sprintf(abuf, "%s
\83E
\83B
\83\93\83h
\83E
\82Ì
\83}
\83b
\83v
\82É
\91Î
\82·
\82é
\95\
\8e¦
\88Ê
\92u
\82ð
\91I
\91ð
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F",
4377 msg ? "
\83\81\83b
\83Z
\81[
\83W" : "
\8fó
\91Ô");
4379 end_menu(tmpwin, abuf);
4380 if (select_menu(tmpwin, PICK_ONE, &window_pick) > 0) {
4382 iflags.wc_align_message = window_pick->item.a_int;
4384 iflags.wc_align_status = window_pick->item.a_int;
4385 free((genericptr_t) window_pick);
4387 destroy_nhwindow(tmpwin);
4388 } else if (!strcmp("number_pad", optname)) {
4389 static const char *npchoices[] = {
4391 " 0 (off)", " 1 (on)", " 2 (on, MSDOS compatible)",
4393 "0 (
\96³
\8cø)", "1 (
\97L
\8cø)", "2 (
\97L
\8cø
\81CMSDOS
\8cÝ
\8a·)",
4395 " 3 (on, phone-style digit layout)",
4397 " 3 (
\97L
\8cø
\81C
\93d
\98b
\8e®
\82Ì
\90\94\8e\9a\94z
\92u)",
4399 " 4 (on, phone-style layout, MSDOS compatible)",
4401 " 4 (
\97L
\8cø
\81C
\93d
\98b
\8e®
\82Ì
\94z
\92u
\81CMSDOS
\8cÝ
\8a·)",
4403 "-1 (off, 'z' to move upper-left, 'y' to zap wands)"
4405 "-1 (
\96³
\8cø
\81C'z'
\82Å
\8d¶
\8fã
\82É
\88Ú
\93®
\81C'y'
\82Å
\8fñ
\82ð
\90U
\82é)"
4407 menu_item *mode_pick = (menu_item *) 0;
4409 tmpwin = create_nhwindow(NHW_MENU);
4412 for (i = 0; i < SIZE(npchoices); i++) {
4414 add_menu(tmpwin, NO_GLYPH, &any, 'a' + i, 0, ATR_NONE,
4415 npchoices[i], MENU_UNSELECTED);
4418 end_menu(tmpwin, "Select number_pad mode:");
4420 end_menu(tmpwin, "number_pad
\83\82\81[
\83h
\82ð
\91I
\91ð
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F");
4421 if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) {
4422 switch (mode_pick->item.a_int - 1) {
4424 iflags.num_pad = FALSE;
4425 iflags.num_pad_mode = 0;
4428 iflags.num_pad = TRUE;
4429 iflags.num_pad_mode = 0;
4432 iflags.num_pad = TRUE;
4433 iflags.num_pad_mode = 1;
4436 iflags.num_pad = TRUE;
4437 iflags.num_pad_mode = 2;
4440 iflags.num_pad = TRUE;
4441 iflags.num_pad_mode = 3;
4443 /* last menu choice: number_pad == -1 */
4445 iflags.num_pad = FALSE;
4446 iflags.num_pad_mode = 1;
4449 reset_commands(FALSE);
4450 number_pad(iflags.num_pad ? 1 : 0);
4451 free((genericptr_t) mode_pick);
4453 destroy_nhwindow(tmpwin);
4454 } else if (!strcmp("menu_headings", optname)) {
4456 int mhattr = query_attr("How to highlight menu headings:");
4458 int mhattr = query_attr("
\83\81\83j
\83\85\81[
\83w
\83b
\83_
\82Ì
\8b
\92²
\95û
\96@
\82ð
\91I
\91ð
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F");
4461 iflags.menu_headings = mhattr;
4462 } else if (!strcmp("msgtype", optname)) {
4463 int opt_idx, nmt, mttyp;
4467 nmt = msgtype_count();
4468 opt_idx = handle_add_list_remove("message type", nmt);
4470 ; /* done--fall through to function exit */
4471 } else if (opt_idx == 0) { /* add new */
4472 getlin("What new message pattern?", mtbuf);
4473 if (*mtbuf == '\033' || !*mtbuf)
4474 goto msgtypes_again;
4475 mttyp = query_msgtype();
4477 goto msgtypes_again;
4478 if (!msgtype_add(mttyp, mtbuf)) {
4479 pline("Error adding the message type.");
4481 goto msgtypes_again;
4483 } else { /* list or remove */
4484 int pick_idx, pick_cnt;
4486 menu_item *pick_list = (menu_item *) 0;
4487 struct plinemsg_type *tmp = plinemsg_types;
4489 tmpwin = create_nhwindow(NHW_MENU);
4494 const char *mtype = msgtype2name(tmp->msgtype);
4496 any.a_int = ++mt_idx;
4497 Sprintf(mtbuf, "%-5s \"%s\"", mtype, tmp->pattern);
4498 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, mtbuf,
4502 Sprintf(mtbuf, "%s message types",
4503 (opt_idx == 1) ? "List of" : "Remove which");
4504 end_menu(tmpwin, mtbuf);
4505 pick_cnt = select_menu(tmpwin,
4506 (opt_idx == 1) ? PICK_NONE : PICK_ANY,
4509 for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx)
4510 free_one_msgtype(pick_list[pick_idx].item.a_int - 1
4512 free((genericptr_t) pick_list), pick_list = (menu_item *) 0;
4514 destroy_nhwindow(tmpwin);
4516 goto msgtypes_again;
4518 } else if (!strcmp("menucolors", optname)) {
4519 int opt_idx, nmc, mcclr, mcattr;
4523 nmc = count_menucolors();
4524 opt_idx = handle_add_list_remove("menucolor", nmc);
4526 ; /* done--fall through to function exit */
4527 } else if (opt_idx == 0) { /* add new */
4528 getlin("What new menucolor pattern?", mcbuf);
4529 if (*mcbuf == '\033' || !*mcbuf)
4530 goto menucolors_again;
4531 mcclr = query_color();
4533 goto menucolors_again;
4534 mcattr = query_attr(NULL);
4536 goto menucolors_again;
4537 if (!add_menu_coloring_parsed(mcbuf, mcclr, mcattr)) {
4538 pline("Error adding the menu color.");
4540 goto menucolors_again;
4542 } else { /* list or remove */
4543 int pick_idx, pick_cnt;
4545 menu_item *pick_list = (menu_item *) 0;
4546 struct menucoloring *tmp = menu_colorings;
4548 tmpwin = create_nhwindow(NHW_MENU);
4553 const char *sattr = attr2attrname(tmp->attr);
4554 const char *sclr = clr2colorname(tmp->color);
4556 any.a_int = (++mc_idx);
4557 Sprintf(mcbuf, "\"%s\"=%s%s%s", tmp->origstr, sclr,
4558 (tmp->attr != ATR_NONE) ? " & " : "",
4559 (tmp->attr != ATR_NONE) ? sattr : "");
4560 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, mcbuf,
4564 Sprintf(mcbuf, "%s menu colors",
4565 (opt_idx == 1) ? "List of" : "Remove which");
4566 end_menu(tmpwin, mcbuf);
4567 pick_cnt = select_menu(tmpwin,
4568 (opt_idx == 1) ? PICK_NONE : PICK_ANY,
4571 for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx)
4572 free_one_menu_coloring(pick_list[pick_idx].item.a_int - 1
4574 free((genericptr_t) pick_list), pick_list = (menu_item *) 0;
4576 destroy_nhwindow(tmpwin);
4578 goto menucolors_again;
4580 } else if (!strcmp("autopickup_exception", optname)) {
4581 int opt_idx, pass, totalapes = 0, numapes[2] = { 0, 0 };
4582 char apebuf[1 + BUFSZ]; /* so &apebuf[1] is BUFSZ long for getlin() */
4583 struct autopickup_exception *ape;
4586 totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]);
4587 opt_idx = handle_add_list_remove("autopickup exception", totalapes);
4589 ; /* done--fall through to function exit */
4590 } else if (opt_idx == 0) { /* add new */
4592 getlin("What new autopickup exception pattern?", &apebuf[1]);
4594 getlin("
\90V
\82µ
\82¢
\8e©
\93®
\8fE
\82¢
\97á
\8aO
\82Ì
\83p
\83^
\81[
\83\93\82ð
\93ü
\97Í
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F", &apebuf[1]);
4595 mungspaces(&apebuf[1]); /* regularize whitespace */
4596 if (apebuf[1] == '\033') {
4597 ; /* fall through to function exit */
4601 /* guarantee room for \" prefix and \"\0 suffix;
4602 -2 is good enough for apebuf[] but -3 makes
4603 sure the whole thing fits within normal BUFSZ */
4604 apebuf[sizeof apebuf - 3] = '\0';
4605 Strcat(apebuf, "\"");
4606 add_autopickup_exception(apebuf);
4610 } else { /* list or remove */
4611 int pick_idx, pick_cnt;
4612 menu_item *pick_list = (menu_item *) 0;
4614 tmpwin = create_nhwindow(NHW_MENU);
4616 for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
4617 if (numapes[pass] == 0)
4619 ape = iflags.autopickup_exceptions[pass];
4621 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
4623 (pass == 0) ? "Never pickup" : "Always pickup",
4625 (pass == 0) ? "
\8fí
\82É
\8fE
\82í
\82È
\82¢" : "
\8fí
\82É
\8fE
\82¤",
4627 for (i = 0; i < numapes[pass] && ape; i++) {
4628 any.a_void = (opt_idx == 1) ? 0 : ape;
4629 Sprintf(apebuf, "\"%s\"", ape->pattern);
4630 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, apebuf,
4636 Sprintf(apebuf, "%s autopickup exceptions",
4637 (opt_idx == 1) ? "List of" : "Remove which");
4639 Sprintf(apebuf, "%s
\8e©
\93®
\8fE
\82¢
\97á
\8aO%s",
4640 (opt_idx == 1) ? "" : "
\82Ç
\82Ì",
4641 (opt_idx == 1) ? "
\82Ì
\88ê
\97\97" : "
\82ð
\8dí
\8f\9c\82µ
\82Ü
\82·
\82©
\81H");
4643 end_menu(tmpwin, apebuf);
4644 pick_cnt = select_menu(tmpwin,
4645 (opt_idx == 1) ? PICK_NONE : PICK_ANY,
4648 for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx)
4649 remove_autopickup_exception(
4650 (struct autopickup_exception *)
4651 pick_list[pick_idx].item.a_void);
4652 free((genericptr_t) pick_list), pick_list = (menu_item *) 0;
4654 destroy_nhwindow(tmpwin);
4658 } else if (!strcmp("symset", optname)
4659 || !strcmp("roguesymset", optname)) {
4660 menu_item *symset_pick = (menu_item *) 0;
4661 boolean primaryflag = (*optname == 's'),
4662 rogueflag = (*optname == 'r'),
4663 ready_to_switch = FALSE,
4664 nothing_to_do = FALSE;
4665 char *symset_name, fmtstr[20];
4666 struct symsetentry *sl;
4667 int res, which_set, setcount = 0, chosen = -2;
4670 which_set = ROGUESET;
4672 which_set = PRIMARY;
4674 /* clear symset[].name as a flag to read_sym_file() to build list */
4675 symset_name = symset[which_set].name;
4676 symset[which_set].name = (char *) 0;
4677 symset_list = (struct symsetentry *) 0;
4679 res = read_sym_file(which_set);
4680 if (res && symset_list) {
4681 char symsetchoice[BUFSZ];
4682 int let = 'a', biggest = 0, thissize = 0;
4686 /* check restrictions */
4687 if ((!rogueflag && sl->rogue)
4688 || (!primaryflag && sl->primary)) {
4693 /* find biggest name */
4695 thissize = strlen(sl->name);
4696 if (thissize > biggest)
4701 pline("There are no appropriate %ssymbol sets available.",
4702 (rogueflag) ? "rogue level "
4703 : (primaryflag) ? "primary " : "");
4707 Sprintf(fmtstr, "%%-%ds %%s", biggest + 5);
4708 tmpwin = create_nhwindow(NHW_MENU);
4712 add_menu(tmpwin, NO_GLYPH, &any, let++, 0, ATR_NONE,
4713 "Default Symbols", MENU_UNSELECTED);
4717 /* check restrictions */
4718 if ((!rogueflag && sl->rogue)
4719 || (!primaryflag && sl->primary)) {
4724 any.a_int = sl->idx + 2;
4725 Sprintf(symsetchoice, fmtstr, sl->name,
4726 sl->desc ? sl->desc : "");
4727 add_menu(tmpwin, NO_GLYPH, &any, let, 0, ATR_NONE,
4728 symsetchoice, MENU_UNSELECTED);
4736 end_menu(tmpwin, "Select symbol set:");
4737 if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
4738 chosen = symset_pick->item.a_int - 2;
4739 free((genericptr_t) symset_pick);
4741 destroy_nhwindow(tmpwin);
4744 /* chose an actual symset name from file */
4747 if (sl->idx == chosen) {
4749 free((genericptr_t) symset_name);
4750 symset_name = (char *) 0;
4752 /* free the now stale attributes */
4753 clear_symsetentry(which_set, TRUE);
4755 /* transfer only the name of the symbol set */
4756 symset[which_set].name = dupstr(sl->name);
4757 ready_to_switch = TRUE;
4762 } else if (chosen == -1) {
4763 /* explicit selection of defaults */
4764 /* free the now stale symset attributes */
4766 free((genericptr_t) symset_name);
4767 symset_name = (char *) 0;
4769 clear_symsetentry(which_set, TRUE);
4771 nothing_to_do = TRUE;
4773 /* The symbols file could not be accessed */
4774 pline("Unable to access \"%s\" file.", SYMBOLS);
4776 } else if (!symset_list) {
4777 /* The symbols file was empty */
4778 pline("There were no symbol sets found in \"%s\".", SYMBOLS);
4783 while (symset_list) {
4786 free((genericptr_t) sl->name);
4787 sl->name = (char *) 0;
4790 free((genericptr_t) sl->desc);
4791 sl->desc = (char *) 0;
4793 symset_list = sl->next;
4794 free((genericptr_t) sl);
4800 if (!symset[which_set].name && symset_name)
4801 symset[which_set].name = symset_name; /* not dupstr() here */
4803 /* Set default symbols and clear the handling value */
4809 if (symset[which_set].name) {
4810 if (read_sym_file(which_set)) {
4811 ready_to_switch = TRUE;
4813 clear_symsetentry(which_set, TRUE);
4818 if (ready_to_switch)
4819 switch_symbols(TRUE);
4821 if (Is_rogue_level(&u.uz)) {
4823 assign_graphics(ROGUESET);
4824 } else if (!rogueflag)
4825 assign_graphics(PRIMARY);
4830 /* didn't match any of the special options */
4836 #define rolestring(val, array, field) \
4837 ((val >= 0) ? array[val].field : (val == ROLE_RANDOM) ? randomrole : none)
4839 /* This is ugly. We have all the option names in the compopt[] array,
4840 but we need to look at each option individually to get the value. */
4841 STATIC_OVL const char *
4842 get_compopt_value(optname, buf)
4843 const char *optname;
4846 char ocl[MAXOCLASSES + 1];
4848 static const char none[] = "(none)", randomrole[] = "random",
4849 to_be_done[] = "(to be done)", defopt[] = "default",
4852 static const char none[] = "(
\82È
\82µ)", randomrole[] = "
\83\89\83\93\83_
\83\80",
4853 to_be_done[] = "(
\96¢
\90Ý
\92è)", defopt[] = "
\83f
\83t
\83H
\83\8b\83g",
4859 if (!strcmp(optname, "align_message"))
4862 iflags.wc_align_message == ALIGN_TOP
4864 : iflags.wc_align_message == ALIGN_LEFT
4866 : iflags.wc_align_message == ALIGN_BOTTOM
4868 : iflags.wc_align_message == ALIGN_RIGHT
4873 iflags.wc_align_message == ALIGN_TOP
4875 : iflags.wc_align_message == ALIGN_LEFT
4877 : iflags.wc_align_message == ALIGN_BOTTOM
4879 : iflags.wc_align_message == ALIGN_RIGHT
4880 ? "
\89E
\91¤" : defopt);
4882 else if (!strcmp(optname, "align_status"))
4885 iflags.wc_align_status == ALIGN_TOP
4887 : iflags.wc_align_status == ALIGN_LEFT
4889 : iflags.wc_align_status == ALIGN_BOTTOM
4891 : iflags.wc_align_status == ALIGN_RIGHT
4896 iflags.wc_align_status == ALIGN_TOP
4898 : iflags.wc_align_status == ALIGN_LEFT
4900 : iflags.wc_align_status == ALIGN_BOTTOM
4902 : iflags.wc_align_status == ALIGN_RIGHT
4906 else if (!strcmp(optname, "align"))
4907 Sprintf(buf, "%s", rolestring(flags.initalign, aligns, adj));
4909 else if (!strcmp(optname, "altkeyhandler"))
4912 iflags.altkeyhandler[0] ? iflags.altkeyhandler : "default");
4914 iflags.altkeyhandler[0] ? iflags.altkeyhandler : defopt);
4916 #ifdef BACKWARD_COMPAT
4917 else if (!strcmp(optname, "boulder"))
4921 : showsyms[(int) objects[BOULDER].oc_class + SYM_OFF_O]);
4923 else if (!strcmp(optname, "catname"))
4924 Sprintf(buf, "%s", catname[0] ? catname : none);
4925 else if (!strcmp(optname, "disclose"))
4926 for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) {
4928 (void) strkitten(buf, ' ');
4929 (void) strkitten(buf, flags.end_disclose[i]);
4930 (void) strkitten(buf, disclosure_options[i]);
4932 else if (!strcmp(optname, "dogname"))
4933 Sprintf(buf, "%s", dogname[0] ? dogname : none);
4934 else if (!strcmp(optname, "dungeon"))
4935 Sprintf(buf, "%s", to_be_done);
4936 else if (!strcmp(optname, "effects"))
4937 Sprintf(buf, "%s", to_be_done);
4938 else if (!strcmp(optname, "font_map"))
4939 Sprintf(buf, "%s", iflags.wc_font_map ? iflags.wc_font_map : defopt);
4940 else if (!strcmp(optname, "font_message"))
4942 iflags.wc_font_message ? iflags.wc_font_message : defopt);
4943 else if (!strcmp(optname, "font_status"))
4945 iflags.wc_font_status ? iflags.wc_font_status : defopt);
4946 else if (!strcmp(optname, "font_menu"))
4948 iflags.wc_font_menu ? iflags.wc_font_menu : defopt);
4949 else if (!strcmp(optname, "font_text"))
4951 iflags.wc_font_text ? iflags.wc_font_text : defopt);
4952 else if (!strcmp(optname, "font_size_map")) {
4953 if (iflags.wc_fontsiz_map)
4954 Sprintf(buf, "%d", iflags.wc_fontsiz_map);
4956 Strcpy(buf, defopt);
4957 } else if (!strcmp(optname, "font_size_message")) {
4958 if (iflags.wc_fontsiz_message)
4959 Sprintf(buf, "%d", iflags.wc_fontsiz_message);
4961 Strcpy(buf, defopt);
4962 } else if (!strcmp(optname, "font_size_status")) {
4963 if (iflags.wc_fontsiz_status)
4964 Sprintf(buf, "%d", iflags.wc_fontsiz_status);
4966 Strcpy(buf, defopt);
4967 } else if (!strcmp(optname, "font_size_menu")) {
4968 if (iflags.wc_fontsiz_menu)
4969 Sprintf(buf, "%d", iflags.wc_fontsiz_menu);
4971 Strcpy(buf, defopt);
4972 } else if (!strcmp(optname, "font_size_text")) {
4973 if (iflags.wc_fontsiz_text)
4974 Sprintf(buf, "%d", iflags.wc_fontsiz_text);
4976 Strcpy(buf, defopt);
4977 } else if (!strcmp(optname, "fruit"))
4978 Sprintf(buf, "%s", pl_fruit);
4979 else if (!strcmp(optname, "gender"))
4980 Sprintf(buf, "%s", rolestring(flags.initgend, genders, adj));
4981 else if (!strcmp(optname, "horsename"))
4982 Sprintf(buf, "%s", horsename[0] ? horsename : none);
4983 else if (!strcmp(optname, "map_mode"))
4985 iflags.wc_map_mode == MAP_MODE_TILES
4987 : iflags.wc_map_mode == MAP_MODE_ASCII4x6
4989 : iflags.wc_map_mode == MAP_MODE_ASCII6x8
4991 : iflags.wc_map_mode == MAP_MODE_ASCII8x8
4993 : iflags.wc_map_mode == MAP_MODE_ASCII16x8
4995 : iflags.wc_map_mode == MAP_MODE_ASCII7x12
4997 : iflags.wc_map_mode == MAP_MODE_ASCII8x12
4999 : iflags.wc_map_mode
5000 == MAP_MODE_ASCII16x12
5002 : iflags.wc_map_mode
5003 == MAP_MODE_ASCII12x16
5005 : iflags.wc_map_mode
5006 == MAP_MODE_ASCII10x18
5008 : iflags.wc_map_mode
5009 == MAP_MODE_ASCII_FIT_TO_SCREEN
5012 else if (!strcmp(optname, "menustyle"))
5013 Sprintf(buf, "%s", menutype[(int) flags.menu_style]);
5014 else if (!strcmp(optname, "menu_deselect_all"))
5015 Sprintf(buf, "%s", to_be_done);
5016 else if (!strcmp(optname, "menu_deselect_page"))
5017 Sprintf(buf, "%s", to_be_done);
5018 else if (!strcmp(optname, "menu_first_page"))
5019 Sprintf(buf, "%s", to_be_done);
5020 else if (!strcmp(optname, "menu_invert_all"))
5021 Sprintf(buf, "%s", to_be_done);
5022 else if (!strcmp(optname, "menu_headings"))
5023 Sprintf(buf, "%s", attr2attrname(iflags.menu_headings));
5024 else if (!strcmp(optname, "menu_invert_page"))
5025 Sprintf(buf, "%s", to_be_done);
5026 else if (!strcmp(optname, "menu_last_page"))
5027 Sprintf(buf, "%s", to_be_done);
5028 else if (!strcmp(optname, "menu_next_page"))
5029 Sprintf(buf, "%s", to_be_done);
5030 else if (!strcmp(optname, "menu_previous_page"))
5031 Sprintf(buf, "%s", to_be_done);
5032 else if (!strcmp(optname, "menu_search"))
5033 Sprintf(buf, "%s", to_be_done);
5034 else if (!strcmp(optname, "menu_select_all"))
5035 Sprintf(buf, "%s", to_be_done);
5036 else if (!strcmp(optname, "menu_select_page"))
5037 Sprintf(buf, "%s", to_be_done);
5038 else if (!strcmp(optname, "monsters")) {
5039 Sprintf(buf, "%s", to_be_done);
5040 } else if (!strcmp(optname, "msghistory")) {
5041 Sprintf(buf, "%u", iflags.msg_history);
5043 } else if (!strcmp(optname, "msg_window")) {
5044 Sprintf(buf, "%s", (iflags.prevmsg_window == 's')
5046 : (iflags.prevmsg_window == 'c')
5048 : (iflags.prevmsg_window == 'f')
5052 } else if (!strcmp(optname, "name")) {
5053 Sprintf(buf, "%s", plname);
5054 } else if (!strcmp(optname, "number_pad")) {
5055 static const char *numpadmodes[] = {
5057 "0=off", "1=on", "2=on, MSDOS compatible",
5059 "0=
\96³
\8cø", "1=
\97L
\8cø", "2=
\97L
\8cø
\81CDOS
\8cÝ
\8a·",
5061 "3=on, phone-style layout",
5063 "3=
\97L
\8cø
\81C
\93d
\98b
\8e®
\82Ì
\90\94\8e\9a\94z
\92u",
5065 "4=on, phone layout, MSDOS compatible",
5067 "4=
\97L
\8cø
\81C
\93d
\98b
\8e®
\82Ì
\94z
\92u
\81CMSDOS
\8cÝ
\8a·",
5069 "-1=off, y & z swapped", /*[5]*/
5071 "-1=
\96³
\8cø
\81Cy
\82Æz
\82ð
\93ü
\82ê
\91Ö
\82¦", /*[5]*/
5074 int indx = Cmd.num_pad
5075 ? (Cmd.phone_layout ? (Cmd.pcHack_compat ? 4 : 3)
5076 : (Cmd.pcHack_compat ? 2 : 1))
5077 : Cmd.swap_yz ? 5 : 0;
5079 Strcpy(buf, numpadmodes[indx]);
5080 } else if (!strcmp(optname, "objects")) {
5081 Sprintf(buf, "%s", to_be_done);
5082 } else if (!strcmp(optname, "packorder")) {
5083 oc_to_str(flags.inv_order, ocl);
5084 Sprintf(buf, "%s", ocl);
5086 } else if (!strcmp(optname, "palette")) {
5087 Sprintf(buf, "%s", get_color_string());
5089 } else if (!strcmp(optname, "paranoid_confirmation")) {
5090 char tmpbuf[QBUFSZ];
5093 if (ParanoidConfirm)
5094 Strcat(tmpbuf, " Confirm");
5096 Strcat(tmpbuf, " quit");
5098 Strcat(tmpbuf, " die");
5100 Strcat(tmpbuf, " bones");
5102 Strcat(tmpbuf, " attack");
5104 Strcat(tmpbuf, " pray");
5106 Strcat(tmpbuf, " Remove");
5107 Strcpy(buf, tmpbuf[0] ? &tmpbuf[1] : "none");
5108 } else if (!strcmp(optname, "pettype")) {
5110 Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat"
5111 : (preferred_pet == 'd') ? "dog"
5112 : (preferred_pet == 'h') ? "horse"
5113 : (preferred_pet == 'n') ? "none"
5116 Sprintf(buf, "%s", (preferred_pet == 'c') ? "
\94L"
5117 : (preferred_pet == 'd') ? "
\8c¢"
5118 : (preferred_pet == 'h') ? "
\94n"
5119 : (preferred_pet == 'n') ? "
\82È
\82µ"
5120 : "
\83\89\83\93\83_
\83\80");
5122 } else if (!strcmp(optname, "pickup_burden")) {
5123 Sprintf(buf, "%s", burdentype[flags.pickup_burden]);
5124 } else if (!strcmp(optname, "pickup_types")) {
5125 oc_to_str(flags.pickup_types, ocl);
5126 Sprintf(buf, "%s", ocl[0] ? ocl : "all");
5127 } else if (!strcmp(optname, "pile_limit")) {
5128 Sprintf(buf, "%d", flags.pile_limit);
5129 } else if (!strcmp(optname, "playmode")) {
5130 Strcpy(buf, wizard ? "debug" : discover ? "explore" : "normal");
5131 } else if (!strcmp(optname, "race")) {
5132 Sprintf(buf, "%s", rolestring(flags.initrace, races, noun));
5133 } else if (!strcmp(optname, "roguesymset")) {
5135 symset[ROGUESET].name ? symset[ROGUESET].name : "default");
5136 if (currentgraphics == ROGUESET && symset[ROGUESET].name)
5137 Strcat(buf, ", active");
5138 } else if (!strcmp(optname, "role")) {
5139 Sprintf(buf, "%s", rolestring(flags.initrole, roles, name.m));
5140 } else if (!strcmp(optname, "runmode")) {
5141 Sprintf(buf, "%s", runmodes[flags.runmode]);
5142 } else if (!strcmp(optname, "scores")) {
5143 Sprintf(buf, "%d top/%d around%s", flags.end_top, flags.end_around,
5144 flags.end_own ? "/own" : "");
5145 } else if (!strcmp(optname, "scroll_amount")) {
5146 if (iflags.wc_scroll_amount)
5147 Sprintf(buf, "%d", iflags.wc_scroll_amount);
5149 Strcpy(buf, defopt);
5150 } else if (!strcmp(optname, "scroll_margin")) {
5151 if (iflags.wc_scroll_margin)
5152 Sprintf(buf, "%d", iflags.wc_scroll_margin);
5154 Strcpy(buf, defopt);
5155 } else if (!strcmp(optname, "sortloot")) {
5156 for (i = 0; i < SIZE(sortltype); i++)
5157 if (flags.sortloot == sortltype[i][0]) {
5158 Strcpy(buf, sortltype[i]);
5161 } else if (!strcmp(optname, "player_selection")) {
5163 Sprintf(buf, "%s", iflags.wc_player_selection ? "prompts" : "dialog");
5165 Sprintf(buf, "%s
\93ü
\97Í", iflags.wc_player_selection ? "
\83v
\83\8d\83\93\83v
\83g" : "
\83_
\83C
\83A
\83\8d\83O");
5168 } else if (!strcmp(optname, "soundcard")) {
5169 Sprintf(buf, "%s", to_be_done);
5171 } else if (!strcmp(optname, "suppress_alert")) {
5172 if (flags.suppress_alert == 0L)
5175 Sprintf(buf, "%lu.%lu.%lu", FEATURE_NOTICE_VER_MAJ,
5176 FEATURE_NOTICE_VER_MIN, FEATURE_NOTICE_VER_PATCH);
5177 } else if (!strcmp(optname, "symset")) {
5179 symset[PRIMARY].name ? symset[PRIMARY].name : "default");
5180 if (currentgraphics == PRIMARY && symset[PRIMARY].name)
5181 Strcat(buf, ", active");
5182 } else if (!strcmp(optname, "tile_file")) {
5184 iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
5185 } else if (!strcmp(optname, "tile_height")) {
5186 if (iflags.wc_tile_height)
5187 Sprintf(buf, "%d", iflags.wc_tile_height);
5189 Strcpy(buf, defopt);
5190 } else if (!strcmp(optname, "tile_width")) {
5191 if (iflags.wc_tile_width)
5192 Sprintf(buf, "%d", iflags.wc_tile_width);
5194 Strcpy(buf, defopt);
5195 } else if (!strcmp(optname, "traps")) {
5196 Sprintf(buf, "%s", to_be_done);
5197 } else if (!strcmp(optname, "vary_msgcount")) {
5198 if (iflags.wc_vary_msgcount)
5199 Sprintf(buf, "%d", iflags.wc_vary_msgcount);
5201 Strcpy(buf, defopt);
5203 } else if (!strcmp(optname, "video")) {
5204 Sprintf(buf, "%s", to_be_done);
5207 } else if (!strcmp(optname, "videoshades")) {
5208 Sprintf(buf, "%s-%s-%s", shade[0], shade[1], shade[2]);
5209 } else if (!strcmp(optname, "videocolors")) {
5210 Sprintf(buf, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d",
5211 ttycolors[CLR_RED], ttycolors[CLR_GREEN],
5212 ttycolors[CLR_BROWN], ttycolors[CLR_BLUE],
5213 ttycolors[CLR_MAGENTA], ttycolors[CLR_CYAN],
5214 ttycolors[CLR_ORANGE], ttycolors[CLR_BRIGHT_GREEN],
5215 ttycolors[CLR_YELLOW], ttycolors[CLR_BRIGHT_BLUE],
5216 ttycolors[CLR_BRIGHT_MAGENTA], ttycolors[CLR_BRIGHT_CYAN]);
5217 #endif /* VIDEOSHADES */
5218 } else if (!strcmp(optname, "windowtype")) {
5219 Sprintf(buf, "%s", windowprocs.name);
5220 } else if (!strcmp(optname, "windowcolors")) {
5222 buf, "%s/%s %s/%s %s/%s %s/%s",
5223 iflags.wc_foregrnd_menu ? iflags.wc_foregrnd_menu : defbrief,
5224 iflags.wc_backgrnd_menu ? iflags.wc_backgrnd_menu : defbrief,
5225 iflags.wc_foregrnd_message ? iflags.wc_foregrnd_message
5227 iflags.wc_backgrnd_message ? iflags.wc_backgrnd_message
5229 iflags.wc_foregrnd_status ? iflags.wc_foregrnd_status : defbrief,
5230 iflags.wc_backgrnd_status ? iflags.wc_backgrnd_status : defbrief,
5231 iflags.wc_foregrnd_text ? iflags.wc_foregrnd_text : defbrief,
5232 iflags.wc_backgrnd_text ? iflags.wc_backgrnd_text : defbrief);
5233 #ifdef PREFIXES_IN_USE
5235 for (i = 0; i < PREFIX_COUNT; ++i)
5236 if (!strcmp(optname, fqn_prefix_names[i]) && fqn_prefix[i])
5237 Sprintf(buf, "%s", fqn_prefix[i]);
5253 char buf[BUFSZ], ocl[MAXOCLASSES + 1];
5255 flags.pickup = !flags.pickup;
5257 oc_to_str(flags.pickup_types, ocl);
5259 Sprintf(buf, "ON, for %s objects%s", ocl[0] ? ocl : "all",
5260 (iflags.autopickup_exceptions[AP_LEAVE]
5261 || iflags.autopickup_exceptions[AP_GRAB])
5262 ? ((count_ape_maps((int *) 0, (int *) 0) == 1)
5263 ? ", with one exception"
5264 : ", with some exceptions")
5267 Sprintf(buf, "%s
\83A
\83C
\83e
\83\80\82É
\82Â
\82¢
\82Ä
\83I
\83\93%s", ocl[0] ? ocl : "
\91S
\82Ä
\82Ì",
5268 (iflags.autopickup_exceptions[AP_LEAVE]
5269 || iflags.autopickup_exceptions[AP_GRAB])
5270 ? "
\81C
\97á
\8aO
\82 \82è"
5277 Strcpy(buf, "
\83I
\83t");
5280 pline("Autopickup: %s.", buf);
5282 pline("
\8e©
\93®
\8fE
\82¢
\81F%s
\81D", buf);
5287 add_autopickup_exception(mapping)
5288 const char *mapping;
5290 struct autopickup_exception *ape, **apehead;
5291 char text[256], *text2;
5292 boolean grab = FALSE;
5294 if (sscanf(mapping, "\"%255[^\"]\"", text) == 1) {
5296 if (*text2 == '<') { /* force autopickup */
5299 } else if (*text2 == '>') { /* default - Do not pickup */
5303 apehead = (grab) ? &iflags.autopickup_exceptions[AP_GRAB]
5304 : &iflags.autopickup_exceptions[AP_LEAVE];
5305 ape = (struct autopickup_exception *) alloc(
5306 sizeof (struct autopickup_exception));
5307 ape->regex = regex_init();
5308 if (!regex_compile(text2, ape->regex)) {
5309 raw_print("regex error in AUTOPICKUP_EXCEPTION");
5310 regex_free(ape->regex);
5311 free((genericptr_t) ape);
5314 ape->pattern = (char *) alloc(strlen(text2) + 1);
5315 strcpy(ape->pattern, text2);
5317 ape->next = *apehead;
5320 raw_print("syntax error in AUTOPICKUP_EXCEPTION");
5327 remove_autopickup_exception(whichape)
5328 struct autopickup_exception *whichape;
5330 struct autopickup_exception *ape, *prev = 0;
5331 int chain = whichape->grab ? AP_GRAB : AP_LEAVE;
5333 for (ape = iflags.autopickup_exceptions[chain]; ape;) {
5334 if (ape == whichape) {
5335 struct autopickup_exception *freeape = ape;
5341 iflags.autopickup_exceptions[chain] = ape;
5342 regex_free(freeape->regex);
5343 free((genericptr_t) freeape->pattern);
5344 free((genericptr_t) freeape);
5353 count_ape_maps(leave, grab)
5356 struct autopickup_exception *ape;
5357 int pass, totalapes, numapes[2] = { 0, 0 };
5359 for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
5360 ape = iflags.autopickup_exceptions[pass];
5366 totalapes = numapes[AP_LEAVE] + numapes[AP_GRAB];
5368 *leave = numapes[AP_LEAVE];
5370 *grab = numapes[AP_GRAB];
5375 free_autopickup_exceptions()
5377 struct autopickup_exception *ape;
5380 for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
5381 while ((ape = iflags.autopickup_exceptions[pass]) != 0) {
5382 regex_free(ape->regex);
5383 free((genericptr_t) ape->pattern);
5384 iflags.autopickup_exceptions[pass] = ape->next;
5385 free((genericptr_t) ape);
5390 /* bundle some common usage into one easy-to-use routine */
5392 load_symset(s, which_set)
5396 clear_symsetentry(which_set, TRUE);
5398 if (symset[which_set].name)
5399 free((genericptr_t) symset[which_set].name);
5400 symset[which_set].name = dupstr(s);
5402 if (read_sym_file(which_set)) {
5403 switch_symbols(TRUE);
5405 clear_symsetentry(which_set, TRUE);
5414 clear_symsetentry(PRIMARY, TRUE);
5415 clear_symsetentry(ROGUESET, TRUE);
5417 /* symset_list is cleaned up as soon as it's used, so we shouldn't
5418 have to anything about it here */
5419 /* assert( symset_list == NULL ); */
5422 /* Parse the value of a SYMBOLS line from a config file */
5425 register char *opts;
5428 char *op, *symname, *strval;
5429 struct symparse *symp;
5431 if ((op = index(opts, ',')) != 0) {
5436 /* S_sample:string */
5438 strval = index(opts, ':');
5440 strval = index(opts, '=');
5445 /* strip leading and trailing white space from symname and strval */
5446 mungspaces(symname);
5449 symp = match_sym(symname);
5453 if (symp->range && symp->range != SYM_CONTROL) {
5454 val = sym_val(strval);
5455 update_l_symset(symp, val);
5463 size_t len = strlen(buf);
5464 const char *p = index(buf, ':'), *q = index(buf, '=');
5465 struct symparse *sp = loadsyms;
5467 if (!p || (q && q < p))
5470 /* note: there will be at most one space before the '='
5471 because caller has condensed buf[] with mungspaces() */
5472 if (p > buf && p[-1] == ' ')
5474 len = (int) (p - buf);
5477 if ((len >= strlen(sp->name)) && !strncmpi(buf, sp->name, len))
5481 return (struct symparse *) 0;
5490 escapes(strval, buf);
5494 /* data for option_help() */
5495 static const char *opt_intro[] = {
5497 "", " NetHack Options Help:", "",
5499 "", " NetHack
\83I
\83v
\83V
\83\87\83\93\83w
\83\8b\83v
\81F", "",
5500 #define CONFIG_SLOT 3 /* fill in next value at run-time */
5502 #if !defined(MICRO) && !defined(MAC)
5504 "or use `NETHACKOPTIONS=\"<options>\"' in your environment",
5506 "
\82Ü
\82½
\82Í
\8aÂ
\8b«
\95Ï
\90\94\82É`NETHACKOPTIONS=\"<options>\"'
\82Æ
\92è
\8b`
\82Å
\82«
\82Ü
\82·",
5509 "(<options> is a list of options separated by commas)",
5511 "(<options>
\82Í
\83J
\83\93\83}
\82Å
\8bæ
\90Ø
\82Á
\82½
\83I
\83v
\83V
\83\87\83\93\82Å
\82·)",
5514 "-- for example, $ DEFINE NETHACKOPTIONS \"noautopickup,fruit:kumquat\"",
5516 "--
\97á
\82¦
\82Î
\8e\9f\82Ì
\82æ
\82¤
\82É
\82µ
\82Ü
\82·
\81F$ DEFINE NETHACKOPTIONS \"noautopickup,fruit:kumquat\"",
5519 "or press \"O\" while playing and use the menu.", "",
5521 "
\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",
5523 "Boolean options (which can be negated by prefixing them with '!' or \"no\"):",
5525 "
\90^
\8bU
\92l
\83I
\83v
\83V
\83\87\83\93 (
\94Û
\92è
\82Ì
\92l
\82ð
\8ew
\92è
\82·
\82é
\8fê
\8d\87\81C'!'
\82à
\82µ
\82
\82Í\"no\"
\82ð
\90æ
\93ª
\82É
\95t
\89Á
\82µ
\82Ü
\82·):",
5529 static const char *opt_epilog[] = {
5532 "Some of the options can be set only before the game is started; those",
5534 "
\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",
5536 "items will not be selectable in the 'O' command's menu.", (char *) 0
5538 "
\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
5544 char buf[BUFSZ], buf2[BUFSZ];
5548 datawin = create_nhwindow(NHW_TEXT);
5550 Sprintf(buf, "Set options as OPTIONS=<options> in %s", lastconfigfile);
5552 Sprintf(buf, "
\83I
\83v
\83V
\83\87\83\93\82Í%s
\82Ì
\92\86\82ÅOPTIONS=<options>
\82Æ
\90Ý
\92è
\82µ
\82Ü
\82·", lastconfigfile);
5553 opt_intro[CONFIG_SLOT] = (const char *) buf;
5554 for (i = 0; opt_intro[i]; i++)
5555 putstr(datawin, 0, opt_intro[i]);
5557 /* Boolean options */
5558 for (i = 0; boolopt[i].name; i++) {
5559 if (boolopt[i].addr) {
5560 if (boolopt[i].addr == &iflags.sanity_check && !wizard)
5562 if (boolopt[i].addr == &iflags.menu_tab_sep && !wizard)
5564 next_opt(datawin, boolopt[i].name);
5567 next_opt(datawin, "");
5569 /* Compound options */
5571 putstr(datawin, 0, "Compound options:");
5573 putstr(datawin, 0, "
\95¶
\8e\9a\97ñ
\83I
\83v
\83V
\83\87\83\93:");
5574 for (i = 0; compopt[i].name; i++) {
5575 Sprintf(buf2, "`%s'", compopt[i].name);
5576 Sprintf(buf, "%-20s - %s%c", buf2, compopt[i].descr,
5577 compopt[i + 1].name ? ',' : '.');
5578 putstr(datawin, 0, buf);
5581 for (i = 0; opt_epilog[i]; i++)
5582 putstr(datawin, 0, opt_epilog[i]);
5584 display_nhwindow(datawin, FALSE);
5585 destroy_nhwindow(datawin);
5590 * prints the next boolean option, on the same line if possible, on a new
5591 * line if not. End with next_opt("").
5594 next_opt(datawin, str)
5598 static char *buf = 0;
5603 *(buf = (char *) alloc(BUFSZ)) = '\0';
5607 if (s > &buf[1] && s[-2] == ',')
5608 Strcpy(s - 2, "."); /* replace last ", " */
5609 i = COLNO; /* (greater than COLNO - 2) */
5611 i = strlen(buf) + strlen(str) + 2;
5614 if (i > COLNO - 2) { /* rule of thumb */
5615 putstr(datawin, 0, buf);
5622 putstr(datawin, 0, str);
5623 free((genericptr_t) buf), buf = 0;
5628 /* Returns the fid of the fruit type; if that type already exists, it
5629 * returns the fid of that one; if it does not exist, it adds a new fruit
5630 * type to the chain and returns the new one.
5631 * If replace_fruit is sent in, replace the fruit in the chain rather than
5632 * adding a new entry--for user specified fruits only.
5635 fruitadd(str, replace_fruit)
5637 struct fruit *replace_fruit;
5640 register struct fruit *f;
5641 int highest_fruit_id = 0;
5642 char buf[PL_FSIZ], altname[PL_FSIZ];
5643 boolean user_specified = (str == pl_fruit);
5644 /* if not user-specified, then it's a fruit name for a fruit on
5648 /* Note: every fruit has an id (kept in obj->spe) of at least 1;
5651 if (user_specified) {
5652 boolean found = FALSE, numeric = FALSE;
5654 /* force fruit to be singular; this handling is not
5655 needed--or wanted--for fruits from bones because
5656 they already received it in their original game */
5657 nmcpy(pl_fruit, makesingular(str), PL_FSIZ);
5658 /* assert( str == pl_fruit ); */
5660 /* disallow naming after other foods (since it'd be impossible
5661 * to tell the difference)
5664 for (i = bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) {
5665 if (!strcmp(OBJ_NAME(objects[i]), pl_fruit)) {
5675 for (c = pl_fruit; *c >= '0' && *c <= '9'; c++)
5677 if (isspace((uchar) *c) || *c == 0)
5680 if (found || numeric || !strncmp(str, "cursed ", 7)
5681 || !strncmp(str, "uncursed ", 9) || !strncmp(str, "blessed ", 8)
5682 || !strncmp(str, "partly eaten ", 13)
5683 || (!strncmp(str, "tin of ", 7)
5684 && (!strcmp(str + 7, "spinach")
5685 || name_to_mon(str + 7) >= LOW_PM))
5686 || !strcmp(str, "empty tin")
5687 || ((str_end_is(str, " corpse")
5688 || str_end_is(str, " egg"))
5689 && name_to_mon(str) >= LOW_PM)) {
5690 Strcpy(buf, pl_fruit);
5691 Strcpy(pl_fruit, "candied ");
5692 nmcpy(pl_fruit + 8, buf, PL_FSIZ - 8);
5695 /* This flag indicates that a fruit has been made since the
5696 * last time the user set the fruit. If it hasn't, we can
5697 * safely overwrite the current fruit, preventing the user from
5698 * setting many fruits in a row and overflowing.
5699 * Possible expansion: check for specific fruit IDs, not for
5702 flags.made_fruit = FALSE;
5703 if (replace_fruit) {
5704 for (f = ffruit; f; f = f->nextf) {
5705 if (f == replace_fruit) {
5706 copynchars(f->fname, str, PL_FSIZ - 1);
5712 /* not user_supplied, so assumed to be from bones */
5713 copynchars(altname, str, PL_FSIZ - 1);
5714 sanitize_name(altname);
5715 flags.made_fruit = TRUE; /* for safety. Any fruit name added from a
5716 bones level should exist anyway. */
5718 for (f = ffruit; f; f = f->nextf) {
5719 if (f->fid > highest_fruit_id)
5720 highest_fruit_id = f->fid;
5721 if (!strncmp(str, f->fname, PL_FSIZ - 1)
5722 || (*altname && !strcmp(altname, f->fname)))
5725 /* if adding another fruit would overflow spe, use a random
5726 fruit instead... we've got a lot to choose from.
5727 current_fruit remains as is. */
5728 if (highest_fruit_id >= 127)
5732 copynchars(f->fname, *altname ? altname : str, PL_FSIZ - 1);
5733 f->fid = ++highest_fruit_id;
5734 /* we used to go out of our way to add it at the end of the list,
5735 but the order is arbitrary so use simpler insertion at start */
5740 context.current_fruit = f->fid;
5745 * This is a somewhat generic menu for taking a list of NetHack style
5746 * class choices and presenting them via a description
5747 * rather than the traditional NetHack characters.
5748 * (Benefits users whose first exposure to NetHack is via tiles).
5751 * The title at the top of the menu.
5753 * category: 0 = monster class
5757 * FALSE = PICK_ONE, TRUE = PICK_ANY
5760 * a null terminated string containing the list of choices.
5763 * a null terminated string containing the selected characters.
5765 * Returns number selected.
5768 choose_classes_menu(prompt, category, way, class_list, class_select)
5775 menu_item *pick_list = (menu_item *) 0;
5781 int next_accelerator, accelerator;
5783 if (class_list == (char *) 0 || class_select == (char *) 0)
5786 next_accelerator = 'a';
5788 win = create_nhwindow(NHW_MENU);
5790 while (*class_list) {
5798 text = def_monsyms[def_char_to_monclass(*class_list)].explain;
5799 accelerator = *class_list;
5800 Sprintf(buf, "%s", text);
5803 text = def_oc_syms[def_char_to_objclass(*class_list)].explain;
5804 accelerator = next_accelerator;
5805 Sprintf(buf, "%c %s", *class_list, text);
5808 impossible("choose_classes_menu: invalid category %d", category);
5810 if (way && *class_select) { /* Selections there already */
5811 if (index(class_select, *class_list)) {
5815 any.a_int = *class_list;
5816 add_menu(win, NO_GLYPH, &any, accelerator, category ? *class_list : 0,
5817 ATR_NONE, buf, selected);
5821 if (next_accelerator == ('z' + 1))
5822 next_accelerator = 'A';
5823 if (next_accelerator == ('Z' + 1))
5827 end_menu(win, prompt);
5828 n = select_menu(win, way ? PICK_ANY : PICK_ONE, &pick_list);
5829 destroy_nhwindow(win);
5831 for (i = 0; i < n; ++i)
5832 *class_select++ = (char) pick_list[i].item.a_int;
5833 free((genericptr_t) pick_list);
5835 } else if (n == -1) {
5836 class_select = eos(class_select);
5840 *class_select = '\0';
5844 struct wc_Opt wc_options[] = { { "ascii_map", WC_ASCII_MAP },
5845 { "color", WC_COLOR },
5846 { "eight_bit_tty", WC_EIGHT_BIT_IN },
5847 { "hilite_pet", WC_HILITE_PET },
5848 { "popup_dialog", WC_POPUP_DIALOG },
5849 { "player_selection", WC_PLAYER_SELECTION },
5850 { "preload_tiles", WC_PRELOAD_TILES },
5851 { "tiled_map", WC_TILED_MAP },
5852 { "tile_file", WC_TILE_FILE },
5853 { "tile_width", WC_TILE_WIDTH },
5854 { "tile_height", WC_TILE_HEIGHT },
5855 { "use_inverse", WC_INVERSE },
5856 { "align_message", WC_ALIGN_MESSAGE },
5857 { "align_status", WC_ALIGN_STATUS },
5858 { "font_map", WC_FONT_MAP },
5859 { "font_menu", WC_FONT_MENU },
5860 { "font_message", WC_FONT_MESSAGE },
5862 {"perm_invent", WC_PERM_INVENT},
5864 { "font_size_map", WC_FONTSIZ_MAP },
5865 { "font_size_menu", WC_FONTSIZ_MENU },
5866 { "font_size_message", WC_FONTSIZ_MESSAGE },
5867 { "font_size_status", WC_FONTSIZ_STATUS },
5868 { "font_size_text", WC_FONTSIZ_TEXT },
5869 { "font_status", WC_FONT_STATUS },
5870 { "font_text", WC_FONT_TEXT },
5871 { "map_mode", WC_MAP_MODE },
5872 { "scroll_amount", WC_SCROLL_AMOUNT },
5873 { "scroll_margin", WC_SCROLL_MARGIN },
5874 { "splash_screen", WC_SPLASH_SCREEN },
5875 { "vary_msgcount", WC_VARY_MSGCOUNT },
5876 { "windowcolors", WC_WINDOWCOLORS },
5877 { "mouse_support", WC_MOUSE_SUPPORT },
5878 { (char *) 0, 0L } };
5880 struct wc_Opt wc2_options[] = { { "fullscreen", WC2_FULLSCREEN },
5881 { "softkeyboard", WC2_SOFTKEYBOARD },
5882 { "wraptext", WC2_WRAPTEXT },
5883 { "use_darkgray", WC2_DARKGRAY },
5884 #ifdef STATUS_VIA_WINDOWPORT
5885 { "hilite_status", WC2_HILITE_STATUS },
5887 { (char *) 0, 0L } };
5890 * If a port wants to change or ensure that the SET_IN_SYS,
5891 * SET_IN_FILE, DISP_IN_GAME, or SET_IN_GAME status of an option is
5892 * correct (for controlling its display in the option menu) call
5893 * set_option_mod_status()
5894 * with the appropriate second argument.
5897 set_option_mod_status(optnam, status)
5903 if (SET__IS_VALUE_VALID(status)) {
5904 impossible("set_option_mod_status: status out of range %d.", status);
5907 for (k = 0; boolopt[k].name; k++) {
5908 if (!strncmpi(boolopt[k].name, optnam, strlen(optnam))) {
5909 boolopt[k].optflags = status;
5913 for (k = 0; compopt[k].name; k++) {
5914 if (!strncmpi(compopt[k].name, optnam, strlen(optnam))) {
5915 compopt[k].optflags = status;
5922 * You can set several wc_options in one call to
5923 * set_wc_option_mod_status() by setting
5924 * the appropriate bits for each option that you
5925 * are setting in the optmask argument
5927 * example: set_wc_option_mod_status(WC_COLOR|WC_SCROLL_MARGIN,
5931 set_wc_option_mod_status(optmask, status)
5932 unsigned long optmask;
5937 if (SET__IS_VALUE_VALID(status)) {
5938 impossible("set_wc_option_mod_status: status out of range %d.",
5942 while (wc_options[k].wc_name) {
5943 if (optmask & wc_options[k].wc_bit) {
5944 set_option_mod_status(wc_options[k].wc_name, status);
5951 is_wc_option(optnam)
5956 while (wc_options[k].wc_name) {
5957 if (strcmp(wc_options[k].wc_name, optnam) == 0)
5965 wc_supported(optnam)
5970 while (wc_options[k].wc_name) {
5971 if (!strcmp(wc_options[k].wc_name, optnam)
5972 && (windowprocs.wincap & wc_options[k].wc_bit))
5980 * You can set several wc2_options in one call to
5981 * set_wc2_option_mod_status() by setting
5982 * the appropriate bits for each option that you
5983 * are setting in the optmask argument
5986 * set_wc2_option_mod_status(WC2_FULLSCREEN|WC2_SOFTKEYBOARD|WC2_WRAPTEXT,
5991 set_wc2_option_mod_status(optmask, status)
5992 unsigned long optmask;
5997 if (SET__IS_VALUE_VALID(status)) {
5998 impossible("set_wc2_option_mod_status: status out of range %d.",
6002 while (wc2_options[k].wc_name) {
6003 if (optmask & wc2_options[k].wc_bit) {
6004 set_option_mod_status(wc2_options[k].wc_name, status);
6011 is_wc2_option(optnam)
6016 while (wc2_options[k].wc_name) {
6017 if (strcmp(wc2_options[k].wc_name, optnam) == 0)
6025 wc2_supported(optnam)
6030 while (wc2_options[k].wc_name) {
6031 if (!strcmp(wc2_options[k].wc_name, optnam)
6032 && (windowprocs.wincap2 & wc2_options[k].wc_bit))
6040 wc_set_font_name(opttype, fontname)
6044 char **fn = (char **) 0;
6050 fn = &iflags.wc_font_map;
6052 case MESSAGE_OPTION:
6053 fn = &iflags.wc_font_message;
6056 fn = &iflags.wc_font_text;
6059 fn = &iflags.wc_font_menu;
6062 fn = &iflags.wc_font_status;
6069 free((genericptr_t) *fn);
6070 *fn = dupstr(fontname);
6076 wc_set_window_colors(op)
6080 * menu white/black message green/yellow status white/blue text
6085 char *wn, *tfg, *tbg, *newop;
6086 static const char *wnames[] = { "menu", "message", "status", "text" };
6087 static const char *shortnames[] = { "mnu", "msg", "sts", "txt" };
6088 static char **fgp[] = { &iflags.wc_foregrnd_menu,
6089 &iflags.wc_foregrnd_message,
6090 &iflags.wc_foregrnd_status,
6091 &iflags.wc_foregrnd_text };
6092 static char **bgp[] = { &iflags.wc_backgrnd_menu,
6093 &iflags.wc_backgrnd_message,
6094 &iflags.wc_backgrnd_status,
6095 &iflags.wc_backgrnd_text };
6098 newop = mungspaces(buf);
6099 while (newop && *newop) {
6100 wn = tfg = tbg = (char *) 0;
6102 /* until first non-space in case there's leading spaces - before
6111 /* until first space - colorname*/
6112 while (*newop && *newop != ' ')
6120 /* until first non-space - before foreground*/
6128 /* until slash - foreground */
6129 while (*newop && *newop != '/')
6137 /* until first non-space (in case there's leading space after slash) -
6138 * before background */
6146 /* until first space - background */
6147 while (*newop && *newop != ' ')
6152 for (j = 0; j < 4; ++j) {
6153 if (!strcmpi(wn, wnames[j]) || !strcmpi(wn, shortnames[j])) {
6154 if (tfg && !strstri(tfg, " ")) {
6156 free((genericptr_t) *fgp[j]);
6157 *fgp[j] = dupstr(tfg);
6159 if (tbg && !strstri(tbg, " ")) {
6161 free((genericptr_t) *bgp[j]);
6162 *bgp[j] = dupstr(tbg);
6171 /* set up for wizard mode if player or save file has requested to it;
6172 called from port-specific startup code to handle `nethack -D' or
6173 OPTIONS=playmode:debug, or from dorecover()'s restgamestate() if
6174 restoring a game which was saved in wizard mode */
6179 if (authorize_wizard_mode())
6180 Strcpy(plname, "wizard");
6182 wizard = FALSE; /* not allowed or not available */
6183 /* force explore mode if we didn't make it into wizard mode */
6185 iflags.deferred_X = FALSE;
6187 /* don't need to do anything special for explore mode or normal play */
6190 #endif /* OPTION_LISTS_ONLY */