Source:NetHack 3.4.3/src/options.c

From NetHackWiki
Revision as of 14:42, 4 March 2008 by Kernigh bot (talk | contribs) (Options.c moved to Source:Options.c: Robot: moved page)
Jump to navigation Jump to search

Below is the full text to src/options.c from NetHack 3.4.3. To link to a particular line, write [[options.c#line123]], for example.

Top of file

1.    /*	SCCS Id: @(#)options.c	3.4	2003/11/14	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

5.    #ifdef OPTION_LISTS_ONLY	/* (AMIGA) external program for opt lists */
6.    #include "config.h"
7.    #include "objclass.h"
8.    #include "flag.h"
9.    NEARDATA struct flag flags;	/* provide linkage */
10.   NEARDATA struct instance_flags iflags;	/* provide linkage */
11.   #define static
12.   #else
13.   #include "hack.h"
14.   #include "tcap.h"
15.   #include <ctype.h>
16.   #endif
17.   
18.   #define WINTYPELEN 16
19.   
20.   #ifdef DEFAULT_WC_TILED_MAP
21.   #define PREFER_TILED TRUE
22.   #else
23.   #define PREFER_TILED FALSE
24.   #endif
25.   

Bool_Opt

26.   /*
27.    *  NOTE:  If you add (or delete) an option, please update the short
28.    *  options help (option_help()), the long options help (dat/opthelp),
29.    *  and the current options setting display function (doset()),
30.    *  and also the Guidebooks.
31.    *
32.    *  The order matters.  If an option is a an initial substring of another
33.    *  option (e.g. time and timed_delay) the shorter one must come first.
34.    */
35.   
36.   static struct Bool_Opt
37.   {
38.   	const char *name;
39.   	boolean	*addr, initvalue;
40.   	int optflags;
41.   } boolopt[] = {
42.   #ifdef AMIGA
43.   	{"altmeta", &flags.altmeta, TRUE, DISP_IN_GAME},
44.   #else
45.   	{"altmeta", (boolean *)0, TRUE, DISP_IN_GAME},
46.   #endif
47.   	{"ascii_map",     &iflags.wc_ascii_map, !PREFER_TILED, SET_IN_GAME},	/*WC*/
48.   #ifdef MFLOPPY
49.   	{"asksavedisk", &flags.asksavedisk, FALSE, SET_IN_GAME},
50.   #else
51.   	{"asksavedisk", (boolean *)0, FALSE, SET_IN_FILE},
52.   #endif
53.   	{"autodig", &flags.autodig, FALSE, SET_IN_GAME},
54.   	{"autopickup", &flags.pickup, TRUE, SET_IN_GAME},
55.   	{"autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME},
56.   #if defined(MICRO) && !defined(AMIGA)
57.   	{"BIOS", &iflags.BIOS, FALSE, SET_IN_FILE},
58.   #else
59.   	{"BIOS", (boolean *)0, FALSE, SET_IN_FILE},
60.   #endif
61.   #ifdef INSURANCE
62.   	{"checkpoint", &flags.ins_chkpt, TRUE, SET_IN_GAME},
63.   #else
64.   	{"checkpoint", (boolean *)0, FALSE, SET_IN_FILE},
65.   #endif
66.   #ifdef MFLOPPY
67.   	{"checkspace", &iflags.checkspace, TRUE, SET_IN_GAME},
68.   #else
69.   	{"checkspace", (boolean *)0, FALSE, SET_IN_FILE},
70.   #endif
71.   	{"cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME},
72.   # if defined(MICRO) || defined(WIN32)
73.   	{"color",         &iflags.wc_color,TRUE, SET_IN_GAME},		/*WC*/
74.   # else	/* systems that support multiple terminals, many monochrome */
75.   	{"color",         &iflags.wc_color, FALSE, SET_IN_GAME},	/*WC*/
76.   # endif
77.   	{"confirm",&flags.confirm, TRUE, SET_IN_GAME},
78.   #if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV)
79.   	{"DECgraphics", &iflags.DECgraphics, FALSE, SET_IN_GAME},
80.   #else
81.   	{"DECgraphics", (boolean *)0, FALSE, SET_IN_FILE},
82.   #endif
83.   	{"eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME},	/*WC*/
84.   #ifdef TTY_GRAPHICS
85.   	{"extmenu", &iflags.extmenu, FALSE, SET_IN_GAME},
86.   #else
87.   	{"extmenu", (boolean *)0, FALSE, SET_IN_FILE},
88.   #endif
89.   #ifdef OPT_DISPMAP
90.   	{"fast_map", &flags.fast_map, TRUE, SET_IN_GAME},
91.   #else
92.   	{"fast_map", (boolean *)0, TRUE, SET_IN_FILE},
93.   #endif
94.   	{"female", &flags.female, FALSE, DISP_IN_GAME},
95.   	{"fixinv", &flags.invlet_constant, TRUE, SET_IN_GAME},
96.   #ifdef AMIFLUSH
97.   	{"flush", &flags.amiflush, FALSE, SET_IN_GAME},
98.   #else
99.   	{"flush", (boolean *)0, FALSE, SET_IN_FILE},
100.  #endif
101.  	{"fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE},
102.  	{"help", &flags.help, TRUE, SET_IN_GAME},
103.  	{"hilite_pet",    &iflags.wc_hilite_pet, FALSE, SET_IN_GAME},	/*WC*/
104.  #ifdef ASCIIGRAPH
105.  	{"IBMgraphics", &iflags.IBMgraphics, FALSE, SET_IN_GAME},
106.  #else
107.  	{"IBMgraphics", (boolean *)0, FALSE, SET_IN_FILE},
108.  #endif
109.  #ifndef MAC
110.  	{"ignintr", &flags.ignintr, FALSE, SET_IN_GAME},
111.  #else
112.  	{"ignintr", (boolean *)0, FALSE, SET_IN_FILE},
113.  #endif
114.  	{"large_font", &iflags.obsolete, FALSE, SET_IN_FILE},	/* OBSOLETE */
115.  	{"legacy", &flags.legacy, TRUE, DISP_IN_GAME},
116.  	{"lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME},
117.  	{"lootabc", &iflags.lootabc, FALSE, SET_IN_GAME},
118.  #ifdef MAC_GRAPHICS_ENV
119.  	{"Macgraphics", &iflags.MACgraphics, TRUE, SET_IN_GAME},
120.  #else
121.  	{"Macgraphics", (boolean *)0, FALSE, SET_IN_FILE},
122.  #endif
123.  #ifdef MAIL
124.  	{"mail", &flags.biff, TRUE, SET_IN_GAME},
125.  #else
126.  	{"mail", (boolean *)0, TRUE, SET_IN_FILE},
127.  #endif
128.  #ifdef WIZARD
129.  	/* for menu debugging only*/
130.  	{"menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_GAME},
131.  #else
132.  	{"menu_tab_sep", (boolean *)0, FALSE, SET_IN_FILE},
133.  #endif
134.  	{"mouse_support", &iflags.wc_mouse_support, TRUE, DISP_IN_GAME},	/*WC*/
135.  #ifdef NEWS
136.  	{"news", &iflags.news, TRUE, DISP_IN_GAME},
137.  #else
138.  	{"news", (boolean *)0, FALSE, SET_IN_FILE},
139.  #endif
140.  	{"null", &flags.null, TRUE, SET_IN_GAME},
141.  #ifdef MAC
142.  	{"page_wait", &flags.page_wait, TRUE, SET_IN_GAME},
143.  #else
144.  	{"page_wait", (boolean *)0, FALSE, SET_IN_FILE},
145.  #endif
146.  	{"perm_invent", &flags.perm_invent, FALSE, SET_IN_GAME},
147.  	{"popup_dialog",  &iflags.wc_popup_dialog, FALSE, SET_IN_GAME},	/*WC*/
148.  	{"prayconfirm", &flags.prayconfirm, TRUE, SET_IN_GAME},
149.  	{"preload_tiles", &iflags.wc_preload_tiles, TRUE, DISP_IN_GAME},	/*WC*/
150.  	{"pushweapon", &flags.pushweapon, FALSE, SET_IN_GAME},
151.  #if defined(MICRO) && !defined(AMIGA)
152.  	{"rawio", &iflags.rawio, FALSE, DISP_IN_GAME},
153.  #else
154.  	{"rawio", (boolean *)0, FALSE, SET_IN_FILE},
155.  #endif
156.  	{"rest_on_space", &flags.rest_on_space, FALSE, SET_IN_GAME},
157.  	{"safe_pet", &flags.safe_dog, TRUE, SET_IN_GAME},
158.  #ifdef WIZARD
159.  	{"sanity_check", &iflags.sanity_check, FALSE, SET_IN_GAME},
160.  #else
161.  	{"sanity_check", (boolean *)0, FALSE, SET_IN_FILE},
162.  #endif
163.  #ifdef EXP_ON_BOTL
164.  	{"showexp", &flags.showexp, FALSE, SET_IN_GAME},
165.  #else
166.  	{"showexp", (boolean *)0, FALSE, SET_IN_FILE},
167.  #endif
168.  	{"showrace", &iflags.showrace, FALSE, SET_IN_GAME},
169.  #ifdef SCORE_ON_BOTL
170.  	{"showscore", &flags.showscore, FALSE, SET_IN_GAME},
171.  #else
172.  	{"showscore", (boolean *)0, FALSE, SET_IN_FILE},
173.  #endif
174.  	{"silent", &flags.silent, TRUE, SET_IN_GAME},
175.  	{"softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE},
176.  	{"sortpack", &flags.sortpack, TRUE, SET_IN_GAME},
177.  	{"sound", &flags.soundok, TRUE, SET_IN_GAME},
178.  	{"sparkle", &flags.sparkle, TRUE, SET_IN_GAME},
179.  	{"standout", &flags.standout, FALSE, SET_IN_GAME},
180.  	{"splash_screen",     &iflags.wc_splash_screen, TRUE, DISP_IN_GAME},	/*WC*/
181.  	{"tiled_map",     &iflags.wc_tiled_map, PREFER_TILED, DISP_IN_GAME},	/*WC*/
182.  	{"time", &flags.time, FALSE, SET_IN_GAME},
183.  #ifdef TIMED_DELAY
184.  	{"timed_delay", &flags.nap, TRUE, SET_IN_GAME},
185.  #else
186.  	{"timed_delay", (boolean *)0, FALSE, SET_IN_GAME},
187.  #endif
188.  	{"tombstone",&flags.tombstone, TRUE, SET_IN_GAME},
189.  	{"toptenwin",&flags.toptenwin, FALSE, SET_IN_GAME},
190.  	{"travel", &iflags.travelcmd, TRUE, SET_IN_GAME},
191.  #ifdef WIN32CON
192.  	{"use_inverse",   &iflags.wc_inverse, TRUE, SET_IN_GAME},		/*WC*/
193.  #else
194.  	{"use_inverse",   &iflags.wc_inverse, FALSE, SET_IN_GAME},		/*WC*/
195.  #endif
196.  	{"verbose", &flags.verbose, TRUE, SET_IN_GAME},
197.  	{"wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME},
198.  	{(char *)0, (boolean *)0, FALSE, 0}
199.  };
200.  

Comp_Opt

201.  /* compound options, for option_help() and external programs like Amiga
202.   * frontend */
203.  static struct Comp_Opt
204.  {
205.  	const char *name, *descr;
206.  	int size;	/* for frontends and such allocating space --
207.  			 * usually allowed size of data in game, but
208.  			 * occasionally maximum reasonable size for
209.  			 * typing when game maintains information in
210.  			 * a different format */
211.  	int optflags;
212.  } compopt[] = {
213.  	{ "align",    "your starting alignment (lawful, neutral, or chaotic)",
214.  						8, DISP_IN_GAME },
215.  	{ "align_message", "message window alignment", 20, DISP_IN_GAME }, 	/*WC*/
216.  	{ "align_status", "status window alignment", 20, DISP_IN_GAME }, 	/*WC*/
217.  	{ "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
218.  	{ "boulder",  "the symbol to use for displaying boulders",
219.  						1, SET_IN_GAME },
220.  	{ "catname",  "the name of your (first) cat (e.g., catname:Tabby)",
221.  						PL_PSIZ, DISP_IN_GAME },
222.  	{ "disclose", "the kinds of information to disclose at end of game",
223.  						sizeof(flags.end_disclose) * 2,
224.  						SET_IN_GAME },
225.  	{ "dogname",  "the name of your (first) dog (e.g., dogname:Fang)",
226.  						PL_PSIZ, DISP_IN_GAME },
227.  	{ "dungeon",  "the symbols to use in drawing the dungeon map",
228.  						MAXDCHARS+1, SET_IN_FILE },
229.  	{ "effects",  "the symbols to use in drawing special effects",
230.  						MAXECHARS+1, SET_IN_FILE },
231.  	{ "font_map", "the font to use in the map window", 40, DISP_IN_GAME },	/*WC*/
232.  	{ "font_menu", "the font to use in menus", 40, DISP_IN_GAME },		/*WC*/
233.  	{ "font_message", "the font to use in the message window",
234.  						40, DISP_IN_GAME },		/*WC*/
235.  	{ "font_size_map", "the size of the map font", 20, DISP_IN_GAME },	/*WC*/
236.  	{ "font_size_menu", "the size of the menu font", 20, DISP_IN_GAME },	/*WC*/
237.  	{ "font_size_message", "the size of the message font", 20, DISP_IN_GAME },	/*WC*/
238.  	{ "font_size_status", "the size of the status font", 20, DISP_IN_GAME },	/*WC*/
239.  	{ "font_size_text", "the size of the text font", 20, DISP_IN_GAME },	/*WC*/
240.  	{ "font_status", "the font to use in status window", 40, DISP_IN_GAME }, /*WC*/
241.  	{ "font_text", "the font to use in text windows", 40, DISP_IN_GAME },	/*WC*/
242.  	{ "fruit",    "the name of a fruit you enjoy eating",
243.  						PL_FSIZ, SET_IN_GAME },
244.  	{ "gender",   "your starting gender (male or female)",
245.  						8, DISP_IN_GAME },
246.  	{ "horsename", "the name of your (first) horse (e.g., horsename:Silver)",
247.  						PL_PSIZ, DISP_IN_GAME },
248.  	{ "map_mode", "map display mode under Windows", 20, DISP_IN_GAME },	/*WC*/
249.  	{ "menustyle", "user interface for object selection",
250.  						MENUTYPELEN, SET_IN_GAME },
251.  	{ "menu_deselect_all", "deselect all items in a menu", 4, SET_IN_FILE },
252.  	{ "menu_deselect_page", "deselect all items on this page of a menu",
253.  						4, SET_IN_FILE },
254.  	{ "menu_first_page", "jump to the first page in a menu",
255.  						4, SET_IN_FILE },
256.  	{ "menu_headings", "bold, inverse, or underline headings", 9, SET_IN_GAME },
257.  	{ "menu_invert_all", "invert all items in a menu", 4, SET_IN_FILE },
258.  	{ "menu_invert_page", "invert all items on this page of a menu",
259.  						4, SET_IN_FILE },
260.  	{ "menu_last_page", "jump to the last page in a menu", 4, SET_IN_FILE },
261.  	{ "menu_next_page", "goto the next menu page", 4, SET_IN_FILE },
262.  	{ "menu_previous_page", "goto the previous menu page", 4, SET_IN_FILE },
263.  	{ "menu_search", "search for a menu item", 4, SET_IN_FILE },
264.  	{ "menu_select_all", "select all items in a menu", 4, SET_IN_FILE },
265.  	{ "menu_select_page", "select all items on this page of a menu",
266.  						4, SET_IN_FILE },
267.  	{ "monsters", "the symbols to use for monsters",
268.  						MAXMCLASSES, SET_IN_FILE },
269.  	{ "msghistory", "number of top line messages to save",
270.  						5, DISP_IN_GAME },
271.  # ifdef TTY_GRAPHICS
272.  	{"msg_window", "the type of message window required",1, SET_IN_GAME},
273.  # else
274.  	{"msg_window", "the type of message window required", 1, SET_IN_FILE},
275.  # endif
276.  	{ "name",     "your character's name (e.g., name:Merlin-W)",
277.  						PL_NSIZ, DISP_IN_GAME },
278.  	{ "number_pad", "use the number pad", 1, SET_IN_GAME},
279.  	{ "objects",  "the symbols to use for objects",
280.  						MAXOCLASSES, SET_IN_FILE },
281.  	{ "packorder", "the inventory order of the items in your pack",
282.  						MAXOCLASSES, SET_IN_GAME },
283.  #ifdef CHANGE_COLOR
284.  	{ "palette",  "palette (00c/880/-fff is blue/yellow/reverse white)",
285.  						15 , SET_IN_GAME },
286.  # if defined(MAC)
287.  	{ "hicolor",  "same as palette, only order is reversed",
288.  						15, SET_IN_FILE },
289.  # endif
290.  #endif
291.  	{ "pettype",  "your preferred initial pet type", 4, DISP_IN_GAME },
292.  	{ "pickup_burden",  "maximum burden picked up before prompt",
293.  						20, SET_IN_GAME },
294.  	{ "pickup_types", "types of objects to pick up automatically",
295.  						MAXOCLASSES, SET_IN_GAME },
296.  	{ "player_selection", "choose character via dialog or prompts",
297.  						12, DISP_IN_GAME },
298.  	{ "race",     "your starting race (e.g., Human, Elf)",
299.  						PL_CSIZ, DISP_IN_GAME },
300.  	{ "role",     "your starting role (e.g., Barbarian, Valkyrie)",
301.  						PL_CSIZ, DISP_IN_GAME },
302.  	{ "runmode", "display frequency when `running' or `travelling'",
303.  						sizeof "teleport", SET_IN_GAME },
304.  	{ "scores",   "the parts of the score list you wish to see",
305.  						32, SET_IN_GAME },
306.  	{ "scroll_amount", "amount to scroll map when scroll_margin is reached",
307.  						20, DISP_IN_GAME }, /*WC*/
308.  	{ "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME }, /*WC*/
309.  #ifdef MSDOS
310.  	{ "soundcard", "type of sound card to use", 20, SET_IN_FILE },
311.  #endif
312.  	{ "suppress_alert", "suppress alerts about version-specific features",
313.  						8, SET_IN_GAME },
314.  	{ "tile_width", "width of tiles", 20, DISP_IN_GAME},	/*WC*/
315.  	{ "tile_height", "height of tiles", 20, DISP_IN_GAME},	/*WC*/
316.  	{ "tile_file", "name of tile file", 70, DISP_IN_GAME},	/*WC*/
317.  	{ "traps",    "the symbols to use in drawing traps",
318.  						MAXTCHARS+1, SET_IN_FILE },
319.  	{ "vary_msgcount", "show more old messages at a time", 20, DISP_IN_GAME }, /*WC*/
320.  #ifdef MSDOS
321.  	{ "video",    "method of video updating", 20, SET_IN_FILE },
322.  #endif
323.  #ifdef VIDEOSHADES
324.  	{ "videocolors", "color mappings for internal screen routines",
325.  						40, DISP_IN_GAME },
326.  	{ "videoshades", "gray shades to map to black/gray/white",
327.  						32, DISP_IN_GAME },
328.  #endif
329.  #ifdef WIN32CON
330.  	{"subkeyvalue", "override keystroke value", 7, SET_IN_FILE},
331.  #endif
332.  	{ "windowcolors",  "the foreground/background colors of windows",	/*WC*/
333.  						80, DISP_IN_GAME },
334.  	{ "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
335.  	{ (char *)0, (char *)0, 0, 0 }
336.  };
337.  
338.  #ifdef OPTION_LISTS_ONLY
339.  #undef static
340.  
341.  #else	/* use rest of file */
342.  
343.  static boolean need_redraw; /* for doset() */
344.  
345.  #if defined(TOS) && defined(TEXTCOLOR)
346.  extern boolean colors_changed;	/* in tos.c */
347.  #endif
348.  
349.  #ifdef VIDEOSHADES
350.  extern char *shade[3];		  /* in sys/msdos/video.c */
351.  extern char ttycolors[CLR_MAX];	  /* in sys/msdos/video.c */
352.  #endif
353.  
354.  static char def_inv_order[MAXOCLASSES] = {
355.  	COIN_CLASS, AMULET_CLASS, WEAPON_CLASS, ARMOR_CLASS, FOOD_CLASS,
356.  	SCROLL_CLASS, SPBOOK_CLASS, POTION_CLASS, RING_CLASS, WAND_CLASS,
357.  	TOOL_CLASS, GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0,
358.  };
359.  

Menu accelerators

360.  /*
361.   * Default menu manipulation command accelerators.  These may _not_ be:
362.   *
363.   *	+ a number - reserved for counts
364.   *	+ an upper or lower case US ASCII letter - used for accelerators
365.   *	+ ESC - reserved for escaping the menu
366.   *	+ NULL, CR or LF - reserved for commiting the selection(s).  NULL
367.   *	  is kind of odd, but the tty's xwaitforspace() will return it if
368.   *	  someone hits a <ret>.
369.   *	+ a default object class symbol - used for object class accelerators
370.   *
371.   * Standard letters (for now) are:
372.   *
373.   *		<  back 1 page
374.   *		>  forward 1 page
375.   *		^  first page
376.   *		|  last page
377.   *		:  search
378.   *
379.   *		page		all
380.   *		 ,    select	 .
381.   *		 \    deselect	 -
382.   *		 ~    invert	 @
383.   *
384.   * The command name list is duplicated in the compopt array.
385.   */
386.  typedef struct {
387.      const char *name;
388.      char cmd;
389.  } menu_cmd_t;
390.  
391.  #define NUM_MENU_CMDS 11
392.  static const menu_cmd_t default_menu_cmd_info[NUM_MENU_CMDS] = {
393.  /* 0*/	{ "menu_first_page",	MENU_FIRST_PAGE },
394.  	{ "menu_last_page",	MENU_LAST_PAGE },
395.  	{ "menu_next_page",	MENU_NEXT_PAGE },
396.  	{ "menu_previous_page",	MENU_PREVIOUS_PAGE },
397.  	{ "menu_select_all",	MENU_SELECT_ALL },
398.  /* 5*/	{ "menu_deselect_all",	MENU_UNSELECT_ALL },
399.  	{ "menu_invert_all",	MENU_INVERT_ALL },
400.  	{ "menu_select_page",	MENU_SELECT_PAGE },
401.  	{ "menu_deselect_page",	MENU_UNSELECT_PAGE },
402.  	{ "menu_invert_page",	MENU_INVERT_PAGE },
403.  /*10*/	{ "menu_search",		MENU_SEARCH },
404.  };
405.  
406.  /*
407.   * Allow the user to map incoming characters to various menu commands.
408.   * The accelerator list must be a valid C string.
409.   */
410.  #define MAX_MENU_MAPPED_CMDS 32	/* some number */
411.         char mapped_menu_cmds[MAX_MENU_MAPPED_CMDS+1];	/* exported */
412.  static char mapped_menu_op[MAX_MENU_MAPPED_CMDS+1];
413.  static short n_menu_mapped = 0;
414.  
415.  
416.  static boolean initial, from_file;
417.  
418.  STATIC_DCL void FDECL(doset_add_menu, (winid,const char *,int));
419.  STATIC_DCL void FDECL(nmcpy, (char *, const char *, int));
420.  STATIC_DCL void FDECL(escapes, (const char *, char *));
421.  STATIC_DCL void FDECL(rejectoption, (const char *));
422.  STATIC_DCL void FDECL(badoption, (const char *));
423.  STATIC_DCL char *FDECL(string_for_opt, (char *,BOOLEAN_P));
424.  STATIC_DCL char *FDECL(string_for_env_opt, (const char *, char *,BOOLEAN_P));
425.  STATIC_DCL void FDECL(bad_negation, (const char *,BOOLEAN_P));
426.  STATIC_DCL int FDECL(change_inv_order, (char *));
427.  STATIC_DCL void FDECL(oc_to_str, (char *, char *));
428.  STATIC_DCL void FDECL(graphics_opts, (char *,const char *,int,int));
429.  STATIC_DCL int FDECL(feature_alert_opts, (char *, const char *));
430.  STATIC_DCL const char *FDECL(get_compopt_value, (const char *, char *));
431.  STATIC_DCL boolean FDECL(special_handling, (const char *, BOOLEAN_P, BOOLEAN_P));
432.  STATIC_DCL void FDECL(warning_opts, (char *,const char *));
433.  STATIC_DCL void FDECL(duplicate_opt_detection, (const char *, int));
434.  
435.  STATIC_OVL void FDECL(wc_set_font_name, (int, char *));
436.  STATIC_OVL int FDECL(wc_set_window_colors, (char *));
437.  STATIC_OVL boolean FDECL(is_wc_option, (const char *));
438.  STATIC_OVL boolean FDECL(wc_supported, (const char *));
439.  STATIC_OVL boolean FDECL(is_wc2_option, (const char *));
440.  STATIC_OVL boolean FDECL(wc2_supported, (const char *));
441.  #ifdef AUTOPICKUP_EXCEPTIONS
442.  STATIC_DCL void FDECL(remove_autopickup_exception, (struct autopickup_exception *));
443.  STATIC_OVL int FDECL(count_ape_maps, (int *, int *));
444.  #endif
445.  

match_optname

446.  /* check whether a user-supplied option string is a proper leading
447.     substring of a particular option name; option string might have
448.     a colon or equals sign and arbitrary value appended to it */
449.  boolean
450.  match_optname(user_string, opt_name, min_length, val_allowed)
451.  const char *user_string, *opt_name;
452.  int min_length;
453.  boolean val_allowed;
454.  {
455.  	int len = (int)strlen(user_string);
456.  
457.  	if (val_allowed) {
458.  	    const char *p = index(user_string, ':'),
459.  		       *q = index(user_string, '=');
460.  
461.  	    if (!p || (q && q < p)) p = q;
462.  	    while(p && p > user_string && isspace(*(p-1))) p--;
463.  	    if (p) len = (int)(p - user_string);
464.  	}
465.  
466.  	return (len >= min_length) && !strncmpi(opt_name, user_string, len);
467.  }
468.  

nh_getenv

469.  /* most environment variables will eventually be printed in an error
470.   * message if they don't work, and most error message paths go through
471.   * BUFSZ buffers, which could be overflowed by a maliciously long
472.   * environment variable.  if a variable can legitimately be long, or
473.   * if it's put in a smaller buffer, the responsible code will have to
474.   * bounds-check itself.
475.   */
476.  char *
477.  nh_getenv(ev)
478.  const char *ev;
479.  {
480.  	char *getev = getenv(ev);
481.  
482.  	if (getev && strlen(getev) <= (BUFSZ / 2))
483.  		return getev;
484.  	else
485.  		return (char *)0;
486.  }
487.  

initoptions

488.  void
489.  initoptions()
490.  {
491.  #ifndef MAC
492.  	char *opts;
493.  #endif
494.  	int i;
495.  
496.  	/* initialize the random number generator */
497.  	setrandom();
498.  
499.  	/* for detection of configfile options specified multiple times */
500.  	iflags.opt_booldup = iflags.opt_compdup = (int *)0;
501.  	
502.  	for (i = 0; boolopt[i].name; i++) {
503.  		if (boolopt[i].addr)
504.  			*(boolopt[i].addr) = boolopt[i].initvalue;
505.  	}
506.  	flags.end_own = FALSE;
507.  	flags.end_top = 3;
508.  	flags.end_around = 2;
509.  	iflags.runmode = RUN_LEAP;
510.  	iflags.msg_history = 20;
511.  #ifdef TTY_GRAPHICS
512.  	iflags.prevmsg_window = 's';
513.  #endif
514.  	iflags.menu_headings = ATR_INVERSE;
515.  
516.  	/* Use negative indices to indicate not yet selected */
517.  	flags.initrole = -1;
518.  	flags.initrace = -1;
519.  	flags.initgend = -1;
520.  	flags.initalign = -1;
521.  
522.  	/* Set the default monster and object class symbols.  Don't use */
523.  	/* memcpy() --- sizeof char != sizeof uchar on some machines.	*/
524.  	for (i = 0; i < MAXOCLASSES; i++)
525.  		oc_syms[i] = (uchar) def_oc_syms[i];
526.  	for (i = 0; i < MAXMCLASSES; i++)
527.  		monsyms[i] = (uchar) def_monsyms[i];
528.  	for (i = 0; i < WARNCOUNT; i++)
529.  		warnsyms[i] = def_warnsyms[i].sym;
530.  	iflags.bouldersym = 0;
531.  	iflags.travelcc.x = iflags.travelcc.y = -1;
532.  	flags.warnlevel = 1;
533.  	flags.warntype = 0L;
534.  
535.       /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
536.  	(void)memcpy((genericptr_t)flags.inv_order,
537.  		     (genericptr_t)def_inv_order, sizeof flags.inv_order);
538.  	flags.pickup_types[0] = '\0';
539.  	flags.pickup_burden = MOD_ENCUMBER;
540.  
541.  	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
542.  		flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
543.  	switch_graphics(ASCII_GRAPHICS);	/* set default characters */
544.  #if defined(UNIX) && defined(TTY_GRAPHICS)
545.  	/*
546.  	 * Set defaults for some options depending on what we can
547.  	 * detect about the environment's capabilities.
548.  	 * This has to be done after the global initialization above
549.  	 * and before reading user-specific initialization via
550.  	 * config file/environment variable below.
551.  	 */
552.  	/* this detects the IBM-compatible console on most 386 boxes */
553.  	if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
554.  		switch_graphics(IBM_GRAPHICS);
555.  # ifdef TEXTCOLOR
556.  		iflags.use_color = TRUE;
557.  # endif
558.  	}
559.  #endif /* UNIX && TTY_GRAPHICS */
560.  #if defined(UNIX) || defined(VMS)
561.  # ifdef TTY_GRAPHICS
562.  	/* detect whether a "vt" terminal can handle alternate charsets */
563.  	if ((opts = nh_getenv("TERM")) &&
564.  	    !strncmpi(opts, "vt", 2) && AS && AE &&
565.  	    index(AS, '\016') && index(AE, '\017')) {
566.  		switch_graphics(DEC_GRAPHICS);
567.  	}
568.  # endif
569.  #endif /* UNIX || VMS */
570.  
571.  #ifdef MAC_GRAPHICS_ENV
572.  	switch_graphics(MAC_GRAPHICS);
573.  #endif /* MAC_GRAPHICS_ENV */
574.  	flags.menu_style = MENU_FULL;
575.  
576.  	/* since this is done before init_objects(), do partial init here */
577.  	objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
578.  	nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
579.  #ifndef MAC
580.  	opts = getenv("NETHACKOPTIONS");
581.  	if (!opts) opts = getenv("HACKOPTIONS");
582.  	if (opts) {
583.  		if (*opts == '/' || *opts == '\\' || *opts == '@') {
584.  			if (*opts == '@') opts++;	/* @filename */
585.  			/* looks like a filename */
586.  			if (strlen(opts) < BUFSZ/2)
587.  			    read_config_file(opts);
588.  		} else {
589.  			read_config_file((char *)0);
590.  			/* let the total length of options be long;
591.  			 * parseoptions() will check each individually
592.  			 */
593.  			parseoptions(opts, TRUE, FALSE);
594.  		}
595.  	} else
596.  #endif
597.  		read_config_file((char *)0);
598.  
599.  	(void)fruitadd(pl_fruit);
600.  	/* Remove "slime mold" from list of object names; this will	*/
601.  	/* prevent it from being wished unless it's actually present	*/
602.  	/* as a named (or default) fruit.  Wishing for "fruit" will	*/
603.  	/* result in the player's preferred fruit [better than "\033"].	*/
604.  	obj_descr[SLIME_MOLD].oc_name = "fruit";
605.  
606.  	return;
607.  }
608.  

nmcpy

609.  STATIC_OVL void
610.  nmcpy(dest, src, maxlen)
611.  	char	*dest;
612.  	const char *src;
613.  	int	maxlen;
614.  {
615.  	int	count;
616.  
617.  	for(count = 1; count < maxlen; count++) {
618.  		if(*src == ',' || *src == '\0') break; /*exit on \0 terminator*/
619.  		*dest++ = *src++;
620.  	}
621.  	*dest = 0;
622.  }
623.  

escapes

624.  /*
625.   * escapes: escape expansion for showsyms. C-style escapes understood include
626.   * \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal). The ^-prefix
627.   * for control characters is also understood, and \[mM] followed by any of the
628.   * previous forms or by a character has the effect of 'meta'-ing the value (so
629.   * that the alternate character set will be enabled).
630.   */
631.  STATIC_OVL void
632.  escapes(cp, tp)
633.  const char	*cp;
634.  char *tp;
635.  {
636.      while (*cp)
637.      {
638.  	int	cval = 0, meta = 0;
639.  
640.  	if (*cp == '\\' && index("mM", cp[1])) {
641.  		meta = 1;
642.  		cp += 2;
643.  	}
644.  	if (*cp == '\\' && index("0123456789xXoO", cp[1]))
645.  	{
646.  	    const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
647.  	    int dcount = 0;
648.  
649.  	    cp++;
650.  	    if (*cp == 'x' || *cp == 'X')
651.  		for (++cp; (dp = index(hex, *cp)) && (dcount++ < 2); cp++)
652.  		    cval = (cval * 16) + (dp - hex) / 2;
653.  	    else if (*cp == 'o' || *cp == 'O')
654.  		for (++cp; (index("01234567",*cp)) && (dcount++ < 3); cp++)
655.  		    cval = (cval * 8) + (*cp - '0');
656.  	    else
657.  		for (; (index("0123456789",*cp)) && (dcount++ < 3); cp++)
658.  		    cval = (cval * 10) + (*cp - '0');
659.  	}
660.  	else if (*cp == '\\')		/* C-style character escapes */
661.  	{
662.  	    switch (*++cp)
663.  	    {
664.  	    case '\\': cval = '\\'; break;
665.  	    case 'n': cval = '\n'; break;
666.  	    case 't': cval = '\t'; break;
667.  	    case 'b': cval = '\b'; break;
668.  	    case 'r': cval = '\r'; break;
669.  	    default: cval = *cp;
670.  	    }
671.  	    cp++;
672.  	}
673.  	else if (*cp == '^')		/* expand control-character syntax */
674.  	{
675.  	    cval = (*++cp & 0x1f);
676.  	    cp++;
677.  	}
678.  	else
679.  	    cval = *cp++;
680.  	if (meta)
681.  	    cval |= 0x80;
682.  	*tp++ = cval;
683.      }
684.      *tp = '\0';
685.  }
686.  

rejectoption

687.  STATIC_OVL void
688.  rejectoption(optname)
689.  const char *optname;
690.  {
691.  #ifdef MICRO
692.  	pline("\"%s\" settable only from %s.", optname, configfile);
693.  #else
694.  	pline("%s can be set only from NETHACKOPTIONS or %s.", optname,
695.  			configfile);
696.  #endif
697.  }
698.  

badoption

699.  STATIC_OVL void
700.  badoption(opts)
701.  const char *opts;
702.  {
703.  	if (!initial) {
704.  	    if (!strncmp(opts, "h", 1) || !strncmp(opts, "?", 1))
705.  		option_help();
706.  	    else
707.  		pline("Bad syntax: %s.  Enter \"?g\" for help.", opts);
708.  	    return;
709.  	}
710.  #ifdef MAC
711.  	else return;
712.  #endif
713.  
714.  	if(from_file)
715.  	    raw_printf("Bad syntax in OPTIONS in %s: %s.", configfile, opts);
716.  	else
717.  	    raw_printf("Bad syntax in NETHACKOPTIONS: %s.", opts);
718.  
719.  	wait_synch();
720.  }
721.  

string_for_opt

722.  STATIC_OVL char *
723.  string_for_opt(opts, val_optional)
724.  char *opts;
725.  boolean val_optional;
726.  {
727.  	char *colon, *equals;
728.  
729.  	colon = index(opts, ':');
730.  	equals = index(opts, '=');
731.  	if (!colon || (equals && equals < colon)) colon = equals;
732.  
733.  	if (!colon || !*++colon) {
734.  		if (!val_optional) badoption(opts);
735.  		return (char *)0;
736.  	}
737.  	return colon;
738.  }
739.  

string_for_env_opt

740.  STATIC_OVL char *
741.  string_for_env_opt(optname, opts, val_optional)
742.  const char *optname;
743.  char *opts;
744.  boolean val_optional;
745.  {
746.  	if(!initial) {
747.  		rejectoption(optname);
748.  		return (char *)0;
749.  	}
750.  	return string_for_opt(opts, val_optional);
751.  }
752.  

bad_negation

753.  STATIC_OVL void
754.  bad_negation(optname, with_parameter)
755.  const char *optname;
756.  boolean with_parameter;
757.  {
758.  	pline_The("%s option may not %sbe negated.",
759.  		optname,
760.  		with_parameter ? "both have a value and " : "");
761.  }
762.  

change_inv_order

763.  /*
764.   * Change the inventory order, using the given string as the new order.
765.   * Missing characters in the new order are filled in at the end from
766.   * the current inv_order, except for gold, which is forced to be first
767.   * if not explicitly present.
768.   *
769.   * This routine returns 1 unless there is a duplicate or bad char in
770.   * the string.
771.   */
772.  STATIC_OVL int
773.  change_inv_order(op)
774.  char *op;
775.  {
776.      int oc_sym, num;
777.      char *sp, buf[BUFSZ];
778.  
779.      num = 0;
780.  #ifndef GOLDOBJ
781.      if (!index(op, GOLD_SYM))
782.  	buf[num++] = COIN_CLASS;
783.  #else
784.      /*  !!!! probably unnecessary with gold as normal inventory */
785.  #endif
786.  
787.      for (sp = op; *sp; sp++) {
788.  	oc_sym = def_char_to_objclass(*sp);
789.  	/* reject bad or duplicate entries */
790.  	if (oc_sym == MAXOCLASSES ||
791.  		oc_sym == RANDOM_CLASS || oc_sym == ILLOBJ_CLASS ||
792.  		!index(flags.inv_order, oc_sym) || index(sp+1, *sp))
793.  	    return 0;
794.  	/* retain good ones */
795.  	buf[num++] = (char) oc_sym;
796.      }
797.      buf[num] = '\0';
798.  
799.      /* fill in any omitted classes, using previous ordering */
800.      for (sp = flags.inv_order; *sp; sp++)
801.  	if (!index(buf, *sp)) {
802.  	    buf[num++] = *sp;
803.  	    buf[num] = '\0';	/* explicitly terminate for next index() */
804.  	}
805.  
806.      Strcpy(flags.inv_order, buf);
807.      return 1;
808.  }
809.  

graphics_opts

810.  STATIC_OVL void
811.  graphics_opts(opts, optype, maxlen, offset)
812.  register char *opts;
813.  const char *optype;
814.  int maxlen, offset;
815.  {
816.  	uchar translate[MAXPCHARS+1];
817.  	int length, i;
818.  
819.  	if (!(opts = string_for_env_opt(optype, opts, FALSE)))
820.  		return;
821.  	escapes(opts, opts);
822.  
823.  	length = strlen(opts);
824.  	if (length > maxlen) length = maxlen;
825.  	/* match the form obtained from PC configuration files */
826.  	for (i = 0; i < length; i++)
827.  		translate[i] = (uchar) opts[i];
828.  	assign_graphics(translate, length, maxlen, offset);
829.  }
830.  

warning_opts

831.  STATIC_OVL void
832.  warning_opts(opts, optype)
833.  register char *opts;
834.  const char *optype;
835.  {
836.  	uchar translate[MAXPCHARS+1];
837.  	int length, i;
838.  
839.  	if (!(opts = string_for_env_opt(optype, opts, FALSE)))
840.  		return;
841.  	escapes(opts, opts);
842.  
843.  	length = strlen(opts);
844.  	if (length > WARNCOUNT) length = WARNCOUNT;
845.  	/* match the form obtained from PC configuration files */
846.  	for (i = 0; i < length; i++)
847.  	     translate[i] = (((i < WARNCOUNT) && opts[i]) ?
848.  			   (uchar) opts[i] : def_warnsyms[i].sym);
849.  	assign_warnings(translate);
850.  }
851.  

assign_warnings

852.  void
853.  assign_warnings(graph_chars)
854.  register uchar *graph_chars;
855.  {
856.  	int i;
857.  	for (i = 0; i < WARNCOUNT; i++)
858.  	    if (graph_chars[i]) warnsyms[i] = graph_chars[i];
859.  }
860.  

feature_alert_opts

861.  STATIC_OVL int
862.  feature_alert_opts(op, optn)
863.  char *op;
864.  const char *optn;
865.  {
866.  	char buf[BUFSZ];
867.  	boolean rejectver = FALSE;
868.  	unsigned long fnv = get_feature_notice_ver(op);		/* version.c */
869.  	if (fnv == 0L) return 0;
870.  	if (fnv > get_current_feature_ver())
871.  		rejectver = TRUE;
872.  	else
873.  		flags.suppress_alert = fnv;
874.  	if (rejectver) {
875.  		if (!initial)
876.  			You_cant("disable new feature alerts for future versions.");
877.  		else {
878.  			Sprintf(buf,
879.  				"\n%s=%s Invalid reference to a future version ignored",
880.  				optn, op);
881.  			badoption(buf);
882.  		}
883.  		return 0;
884.  	}
885.  	if (!initial) {
886.  		Sprintf(buf, "%lu.%lu.%lu", FEATURE_NOTICE_VER_MAJ,
887.  			FEATURE_NOTICE_VER_MIN, FEATURE_NOTICE_VER_PATCH);
888.  		pline("Feature change alerts disabled for NetHack %s features and prior.",
889.  			buf);
890.  	}
891.  	return 1;
892.  }
893.  

set_duplicate_opt_detection

894.  void
895.  set_duplicate_opt_detection(on_or_off)
896.  int on_or_off;
897.  {
898.  	int k, *optptr;
899.  	if (on_or_off != 0) {
900.  		/*-- ON --*/
901.  		if (iflags.opt_booldup)
902.  			impossible("iflags.opt_booldup already on (memory leak)");
903.  		iflags.opt_booldup = (int *)alloc(SIZE(boolopt) * sizeof(int));
904.  		optptr = iflags.opt_booldup;
905.  		for (k = 0; k < SIZE(boolopt); ++k)
906.  			*optptr++ = 0;
907.  			
908.  		if (iflags.opt_compdup)
909.  			impossible("iflags.opt_compdup already on (memory leak)");
910.  		iflags.opt_compdup = (int *)alloc(SIZE(compopt) * sizeof(int));
911.  		optptr = iflags.opt_compdup;
912.  		for (k = 0; k < SIZE(compopt); ++k)
913.  			*optptr++ = 0;
914.  	} else {
915.  		/*-- OFF --*/
916.  		if (iflags.opt_booldup) free((genericptr_t) iflags.opt_booldup);
917.  		iflags.opt_booldup = (int *)0;
918.  		if (iflags.opt_compdup) free((genericptr_t) iflags.opt_compdup);
919.  		iflags.opt_compdup = (int *)0;
920.  	} 
921.  }
922.  

duplicate_opt_detection

923.  STATIC_OVL void
924.  duplicate_opt_detection(opts, bool_or_comp)
925.  const char *opts;
926.  int bool_or_comp;	/* 0 == boolean option, 1 == compound */
927.  {
928.  	int i, *optptr;
929.  #if defined(MAC)
930.  	/* the Mac has trouble dealing with the output of messages while
931.  	 * processing the config file.  That should get fixed one day.
932.  	 * For now just return.
933.  	 */
934.  	return;
935.  #endif
936.  	if ((bool_or_comp == 0) && iflags.opt_booldup && initial && from_file) {
937.  	    for (i = 0; boolopt[i].name; i++) {
938.  		if (match_optname(opts, boolopt[i].name, 3, FALSE)) {
939.  			optptr = iflags.opt_booldup + i;
940.  			if (*optptr == 1) {
941.  			    raw_printf(
942.  				"\nWarning - Boolean option specified multiple times: %s.\n",
943.  					opts);
944.  			        wait_synch();
945.  			}
946.  			*optptr += 1;
947.  			break; /* don't match multiple options */
948.  		}
949.  	    }
950.  	} else if ((bool_or_comp == 1) && iflags.opt_compdup && initial && from_file) {
951.  	    for (i = 0; compopt[i].name; i++) {
952.  		if (match_optname(opts, compopt[i].name, strlen(compopt[i].name), TRUE)) {
953.  			optptr = iflags.opt_compdup + i;
954.  			if (*optptr == 1) {
955.  			    raw_printf(
956.  				"\nWarning - compound option specified multiple times: %s.\n",
957.  					compopt[i].name);
958.  			        wait_synch();
959.  			}
960.  			*optptr += 1;
961.  			break; /* don't match multiple options */
962.  		}
963.  	    }
964.  	}
965.  }
966.  

parseoptions

967.  void
968.  parseoptions(opts, tinitial, tfrom_file)
969.  register char *opts;
970.  boolean tinitial, tfrom_file;
971.  {
972.  	register char *op;
973.  	unsigned num;
974.  	boolean negated;
975.  	int i;
976.  	const char *fullname;
977.  
978.  	initial = tinitial;
979.  	from_file = tfrom_file;
980.  	if ((op = index(opts, ',')) != 0) {
981.  		*op++ = 0;
982.  		parseoptions(op, initial, from_file);
983.  	}
984.  	if (strlen(opts) > BUFSZ/2) {
985.  		badoption("option too long");
986.  		return;
987.  	}
988.  
989.  	/* strip leading and trailing white space */
990.  	while (isspace(*opts)) opts++;
991.  	op = eos(opts);
992.  	while (--op >= opts && isspace(*op)) *op = '\0';
993.  
994.  	if (!*opts) return;
995.  	negated = FALSE;
996.  	while ((*opts == '!') || !strncmpi(opts, "no", 2)) {
997.  		if (*opts == '!') opts++; else opts += 2;
998.  		negated = !negated;
999.  	}
1000. 
1001. 	/* variant spelling */
1002. 
1003. 	if (match_optname(opts, "colour", 5, FALSE))
1004. 		Strcpy(opts, "color");	/* fortunately this isn't longer */
1005. 
1006. 	if (!match_optname(opts, "subkeyvalue", 11, TRUE)) /* allow multiple */
1007. 	duplicate_opt_detection(opts, 1);	/* 1 means compound opts */
1008. 
1009. 	/* special boolean options */
1010. 
1011. 	if (match_optname(opts, "female", 3, FALSE)) {
1012. 		if(!initial && flags.female == negated)
1013. 			pline("That is not anatomically possible.");
1014. 		else
1015. 			flags.initgend = flags.female = !negated;
1016. 		return;
1017. 	}
1018. 
1019. 	if (match_optname(opts, "male", 4, FALSE)) {
1020. 		if(!initial && flags.female != negated)
1021. 			pline("That is not anatomically possible.");
1022. 		else
1023. 			flags.initgend = flags.female = negated;
1024. 		return;
1025. 	}
1026. 
1027. #if defined(MICRO) && !defined(AMIGA)
1028. 	/* included for compatibility with old NetHack.cnf files */
1029. 	if (match_optname(opts, "IBM_", 4, FALSE)) {
1030. 		iflags.BIOS = !negated;
1031. 		return;
1032. 	}
1033. #endif /* MICRO */
1034. 
1035. 	/* compound options */
1036. 
1037. 	fullname = "pettype";
1038. 	if (match_optname(opts, fullname, 3, TRUE)) {
1039. 		if ((op = string_for_env_opt(fullname, opts, negated)) != 0) {
1040. 		    if (negated) bad_negation(fullname, TRUE);
1041. 		    else switch (*op) {
1042. 			case 'd':	/* dog */
1043. 			case 'D':
1044. 			    preferred_pet = 'd';
1045. 			    break;
1046. 			case 'c':	/* cat */
1047. 			case 'C':
1048. 			case 'f':	/* feline */
1049. 			case 'F':
1050. 			    preferred_pet = 'c';
1051. 			    break;
1052. 			case 'n':	/* no pet */
1053. 			case 'N':
1054. 			    preferred_pet = 'n';
1055. 			    break;
1056. 			default:
1057. 			    pline("Unrecognized pet type '%s'.", op);
1058. 			    break;
1059. 		    }
1060. 		} else if (negated) preferred_pet = 'n';
1061. 		return;
1062. 	}
1063. 
1064. 	fullname = "catname";
1065. 	if (match_optname(opts, fullname, 3, TRUE)) {
1066. 		if (negated) bad_negation(fullname, FALSE);
1067. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1068. 			nmcpy(catname, op, PL_PSIZ);
1069. 		return;
1070. 	}
1071. 
1072. 	fullname = "dogname";
1073. 	if (match_optname(opts, fullname, 3, TRUE)) {
1074. 		if (negated) bad_negation(fullname, FALSE);
1075. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1076. 			nmcpy(dogname, op, PL_PSIZ);
1077. 		return;
1078. 	}
1079. 
1080. 	fullname = "horsename";
1081. 	if (match_optname(opts, fullname, 5, TRUE)) {
1082. 		if (negated) bad_negation(fullname, FALSE);
1083. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1084. 			nmcpy(horsename, op, PL_PSIZ);
1085. 		return;
1086. 	}
1087. 
1088. 	fullname = "number_pad";
1089. 	if (match_optname(opts, fullname, 10, TRUE)) {
1090. 		boolean compat = (strlen(opts) <= 10);
1091. 		number_pad(iflags.num_pad ? 1 : 0);
1092. 		op = string_for_opt(opts, (compat || !initial));
1093. 		if (!op) {
1094. 		    if (compat || negated || initial) {
1095. 			/* for backwards compatibility, "number_pad" without a
1096. 			   value is a synonym for number_pad:1 */
1097. 			iflags.num_pad = !negated;
1098. 			if (iflags.num_pad) iflags.num_pad_mode = 0;
1099. 		    }
1100. 		    return;
1101. 		}
1102. 		if (negated) {
1103. 		    bad_negation("number_pad", TRUE);
1104. 		    return;
1105. 		}
1106. 		if (*op == '1' || *op == '2') {
1107. 			iflags.num_pad = 1;
1108. 			if (*op == '2') iflags.num_pad_mode = 1;
1109. 			else iflags.num_pad_mode = 0;
1110. 		} else if (*op == '0') {
1111. 			iflags.num_pad = 0;
1112. 			iflags.num_pad_mode = 0;
1113. 		} else badoption(opts);
1114. 		return;
1115. 	}
1116. 
1117. 	fullname = "runmode";
1118. 	if (match_optname(opts, fullname, 4, TRUE)) {
1119. 		if (negated) {
1120. 			iflags.runmode = RUN_TPORT;
1121. 		} else if ((op = string_for_opt(opts, FALSE)) != 0) {
1122. 		    if (!strncmpi(op, "teleport", strlen(op)))
1123. 			iflags.runmode = RUN_TPORT;
1124. 		    else if (!strncmpi(op, "run", strlen(op)))
1125. 			iflags.runmode = RUN_LEAP;
1126. 		    else if (!strncmpi(op, "walk", strlen(op)))
1127. 			iflags.runmode = RUN_STEP;
1128. 		    else if (!strncmpi(op, "crawl", strlen(op)))
1129. 			iflags.runmode = RUN_CRAWL;
1130. 		    else
1131. 			badoption(opts);
1132. 		}
1133. 		return;
1134. 	}
1135. 
1136. 	fullname = "msghistory";
1137. 	if (match_optname(opts, fullname, 3, TRUE)) {
1138. 		op = string_for_env_opt(fullname, opts, negated);
1139. 		if ((negated && !op) || (!negated && op)) {
1140. 			iflags.msg_history = negated ? 0 : atoi(op);
1141. 		} else if (negated) bad_negation(fullname, TRUE);
1142. 		return;
1143. 	}
1144. 
1145. 	fullname="msg_window";
1146. 	/* msg_window:single, combo, full or reversed */
1147. 	if (match_optname(opts, fullname, 4, TRUE)) {
1148. 	/* allow option to be silently ignored by non-tty ports */
1149. #ifdef TTY_GRAPHICS
1150. 		int tmp;
1151. 		if (!(op = string_for_opt(opts, TRUE))) {
1152. 		    tmp = negated ? 's' : 'f';
1153. 		} else {
1154. 			  if (negated) {
1155. 			  	bad_negation(fullname, TRUE);
1156. 			  	return;
1157. 				  }
1158. 		    tmp = tolower(*op);
1159. 		}
1160. 		switch (tmp) {
1161. 			case 's':	/* single message history cycle (default if negated) */
1162. 				iflags.prevmsg_window = 's';
1163. 				break;
1164. 			case 'c':	/* combination: two singles, then full page reversed */
1165. 				iflags.prevmsg_window = 'c';
1166. 				break;
1167. 			case 'f':	/* full page (default if no opts) */
1168. 				iflags.prevmsg_window = 'f';
1169. 				break;
1170. 			case 'r':	/* full page (reversed) */
1171. 				iflags.prevmsg_window = 'r';
1172. 				break;
1173. 			default:
1174. 				badoption(opts);
1175. 		}
1176. #endif
1177. 		return;
1178. 	}
1179. 
1180. 	/* WINCAP
1181. 	 * setting font options  */
1182. 	fullname = "font";
1183. 	if (!strncmpi(opts, fullname, 4))
1184. 	{
1185. 		int wintype = -1;
1186. 		char *fontopts = opts + 4;
1187. 
1188. 		if (!strncmpi(fontopts, "map", 3) ||
1189. 		    !strncmpi(fontopts, "_map", 4))
1190. 			wintype = NHW_MAP;
1191. 		else if (!strncmpi(fontopts, "message", 7) ||
1192. 			 !strncmpi(fontopts, "_message", 8))
1193. 			wintype = NHW_MESSAGE;
1194. 		else if (!strncmpi(fontopts, "text", 4) ||
1195. 			 !strncmpi(fontopts, "_text", 5))
1196. 			wintype = NHW_TEXT;			
1197. 		else if (!strncmpi(fontopts, "menu", 4) ||
1198. 			 !strncmpi(fontopts, "_menu", 5))
1199. 			wintype = NHW_MENU;
1200. 		else if (!strncmpi(fontopts, "status", 6) ||
1201. 			 !strncmpi(fontopts, "_status", 7))
1202. 			wintype = NHW_STATUS;
1203. 		else if (!strncmpi(fontopts, "_size", 5)) {
1204. 			if (!strncmpi(fontopts, "_size_map", 8))
1205. 				wintype = NHW_MAP;
1206. 			else if (!strncmpi(fontopts, "_size_message", 12))
1207. 				wintype = NHW_MESSAGE;
1208. 			else if (!strncmpi(fontopts, "_size_text", 9))
1209. 				wintype = NHW_TEXT;
1210. 			else if (!strncmpi(fontopts, "_size_menu", 9))
1211. 				wintype = NHW_MENU;
1212. 			else if (!strncmpi(fontopts, "_size_status", 11))
1213. 				wintype = NHW_STATUS;
1214. 			else {
1215. 				badoption(opts);
1216. 				return;
1217. 			}
1218. 			if (wintype > 0 && !negated &&
1219. 			    (op = string_for_opt(opts, FALSE)) != 0) {
1220. 			    switch(wintype)  {
1221. 			    	case NHW_MAP:
1222. 					iflags.wc_fontsiz_map = atoi(op);
1223. 					break;
1224. 			    	case NHW_MESSAGE:
1225. 					iflags.wc_fontsiz_message = atoi(op);
1226. 					break;
1227. 			    	case NHW_TEXT:
1228. 					iflags.wc_fontsiz_text = atoi(op);
1229. 					break;
1230. 			    	case NHW_MENU:
1231. 					iflags.wc_fontsiz_menu = atoi(op);
1232. 					break;
1233. 			    	case NHW_STATUS:
1234. 					iflags.wc_fontsiz_status = atoi(op);
1235. 					break;
1236. 			    }
1237. 			}
1238. 			return;
1239. 		} else {
1240. 			badoption(opts);
1241. 		}
1242. 		if (wintype > 0 &&
1243. 		    (op = string_for_opt(opts, FALSE)) != 0) {
1244. 			wc_set_font_name(wintype, op);
1245. #ifdef MAC
1246. 			set_font_name (wintype, op);
1247. #endif
1248. 			return;
1249. 		} else if (negated) bad_negation(fullname, TRUE);
1250. 		return;
1251. 	}
1252. #ifdef CHANGE_COLOR
1253. 	if (match_optname(opts, "palette", 3, TRUE)
1254. # ifdef MAC
1255. 	    || match_optname(opts, "hicolor", 3, TRUE)
1256. # endif
1257. 							) {
1258. 	    int color_number, color_incr;
1259. 
1260. # ifdef MAC
1261. 	    if (match_optname(opts, "hicolor", 3, TRUE)) {
1262. 		if (negated) {
1263. 		    bad_negation("hicolor", FALSE);
1264. 		    return;
1265. 		}
1266. 		color_number = CLR_MAX + 4;	/* HARDCODED inverse number */
1267. 		color_incr = -1;
1268. 	    } else {
1269. # endif
1270. 		if (negated) {
1271. 		    bad_negation("palette", FALSE);
1272. 		    return;
1273. 		}
1274. 		color_number = 0;
1275. 		color_incr = 1;
1276. # ifdef MAC
1277. 	    }
1278. # endif
1279. 	    if ((op = string_for_opt(opts, FALSE)) != (char *)0) {
1280. 		char *pt = op;
1281. 		int cnt, tmp, reverse;
1282. 		long rgb;
1283. 
1284. 		while (*pt && color_number >= 0) {
1285. 		    cnt = 3;
1286. 		    rgb = 0L;
1287. 		    if (*pt == '-') {
1288. 			reverse = 1;
1289. 			pt++;
1290. 		    } else {
1291. 			reverse = 0;
1292. 		    }
1293. 		    while (cnt-- > 0) {
1294. 			if (*pt && *pt != '/') {
1295. # ifdef AMIGA
1296. 			    rgb <<= 4;
1297. # else
1298. 			    rgb <<= 8;
1299. # endif
1300. 			    tmp = *(pt++);
1301. 			    if (isalpha(tmp)) {
1302. 				tmp = (tmp + 9) & 0xf;	/* Assumes ASCII... */
1303. 			    } else {
1304. 				tmp &= 0xf;	/* Digits in ASCII too... */
1305. 			    }
1306. # ifndef AMIGA
1307. 			    /* Add an extra so we fill f -> ff and 0 -> 00 */
1308. 			    rgb += tmp << 4;
1309. # endif
1310. 			    rgb += tmp;
1311. 			}
1312. 		    }
1313. 		    if (*pt == '/') {
1314. 			pt++;
1315. 		    }
1316. 		    change_color(color_number, rgb, reverse);
1317. 		    color_number += color_incr;
1318. 		}
1319. 	    }
1320. 	    if (!initial) {
1321. 		need_redraw = TRUE;
1322. 	    }
1323. 	    return;
1324. 	}
1325. #endif /* CHANGE_COLOR */
1326. 
1327. 	if (match_optname(opts, "fruit", 2, TRUE)) {
1328. 		char empty_str = '\0';
1329. 		op = string_for_opt(opts, negated);
1330. 		if (negated) {
1331. 		    if (op) {
1332. 			bad_negation("fruit", TRUE);
1333. 			return;
1334. 		    }
1335. 		    op = &empty_str;
1336. 		    goto goodfruit;
1337. 		}
1338. 		if (!op) return;
1339. 		if (!initial) {
1340. 		    struct fruit *f;
1341. 
1342. 		    num = 0;
1343. 		    for(f=ffruit; f; f=f->nextf) {
1344. 			if (!strcmp(op, f->fname)) goto goodfruit;
1345. 			num++;
1346. 		    }
1347. 		    if (num >= 100) {
1348. 			pline("Doing that so many times isn't very fruitful.");
1349. 			return;
1350. 		    }
1351. 		}
1352. goodfruit:
1353. 		nmcpy(pl_fruit, op, PL_FSIZ);
1354. 	/* OBJ_NAME(objects[SLIME_MOLD]) won't work after initialization */
1355. 		if (!*pl_fruit)
1356. 		    nmcpy(pl_fruit, "slime mold", PL_FSIZ);
1357. 		if (!initial)
1358. 		    (void)fruitadd(pl_fruit);
1359. 		/* If initial, then initoptions is allowed to do it instead
1360. 		 * of here (initoptions always has to do it even if there's
1361. 		 * no fruit option at all.  Also, we don't want people
1362. 		 * setting multiple fruits in their options.)
1363. 		 */
1364. 		return;
1365. 	}
1366. 
1367. 	/* graphics:string */
1368. 	fullname = "graphics";
1369. 	if (match_optname(opts, fullname, 2, TRUE)) {
1370. 		if (negated) bad_negation(fullname, FALSE);
1371. 		else graphics_opts(opts, fullname, MAXPCHARS, 0);
1372. 		return;
1373. 	}
1374. 	fullname = "dungeon";
1375. 	if (match_optname(opts, fullname, 2, TRUE)) {
1376. 		if (negated) bad_negation(fullname, FALSE);
1377. 		else graphics_opts(opts, fullname, MAXDCHARS, 0);
1378. 		return;
1379. 	}
1380. 	fullname = "traps";
1381. 	if (match_optname(opts, fullname, 2, TRUE)) {
1382. 		if (negated) bad_negation(fullname, FALSE);
1383. 		else graphics_opts(opts, fullname, MAXTCHARS, MAXDCHARS);
1384. 		return;
1385. 	}
1386. 	fullname = "effects";
1387. 	if (match_optname(opts, fullname, 2, TRUE)) {
1388. 		if (negated) bad_negation(fullname, FALSE);
1389. 		else
1390. 		 graphics_opts(opts, fullname, MAXECHARS, MAXDCHARS+MAXTCHARS);
1391. 		return;
1392. 	}
1393. 
1394. 	/* objects:string */
1395. 	fullname = "objects";
1396. 	if (match_optname(opts, fullname, 7, TRUE)) {
1397. 		int length;
1398. 
1399. 		if (negated) {
1400. 		    bad_negation(fullname, FALSE);
1401. 		    return;
1402. 		}
1403. 		if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
1404. 			return;
1405. 		escapes(opts, opts);
1406. 
1407. 		/*
1408. 		 * Override the default object class symbols.  The first
1409. 		 * object in the object class is the "random object".  I
1410. 		 * don't want to use 0 as an object class, so the "random
1411. 		 * object" is basically a place holder.
1412. 		 *
1413. 		 * The object class symbols have already been initialized in
1414. 		 * initoptions().
1415. 		 */
1416. 		length = strlen(opts);
1417. 		if (length >= MAXOCLASSES)
1418. 		    length = MAXOCLASSES-1;	/* don't count RANDOM_OBJECT */
1419. 
1420. 		for (i = 0; i < length; i++)
1421. 		    oc_syms[i+1] = (uchar) opts[i];
1422. 		return;
1423. 	}
1424. 
1425. 	/* monsters:string */
1426. 	fullname = "monsters";
1427. 	if (match_optname(opts, fullname, 8, TRUE)) {
1428. 		int length;
1429. 
1430. 		if (negated) {
1431. 		    bad_negation(fullname, FALSE);
1432. 		    return;
1433. 		}
1434. 		if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
1435. 			return;
1436. 		escapes(opts, opts);
1437. 
1438. 		/* Override default mon class symbols set in initoptions(). */
1439. 		length = strlen(opts);
1440. 		if (length >= MAXMCLASSES)
1441. 		    length = MAXMCLASSES-1;	/* mon class 0 unused */
1442. 
1443. 		for (i = 0; i < length; i++)
1444. 		    monsyms[i+1] = (uchar) opts[i];
1445. 		return;
1446. 	}
1447. 	fullname = "warnings";
1448. 	if (match_optname(opts, fullname, 5, TRUE)) {
1449. 		if (negated) bad_negation(fullname, FALSE);
1450. 		else warning_opts(opts, fullname);
1451. 		return;
1452. 	}
1453. 	/* boulder:symbol */
1454. 	fullname = "boulder";
1455. 	if (match_optname(opts, fullname, 7, TRUE)) {
1456. 		int clash = 0;
1457. 		if (negated) {
1458. 		    bad_negation(fullname, FALSE);
1459. 		    return;
1460. 		}
1461. /*		if (!(opts = string_for_env_opt(fullname, opts, FALSE))) */
1462. 		if (!(opts = string_for_opt(opts, FALSE)))
1463. 			return;
1464. 		escapes(opts, opts);
1465. 		if (def_char_to_monclass(opts[0]) != MAXMCLASSES)
1466. 			clash = 1;
1467. 		else if (opts[0] >= '1' && opts[0] <= '5')
1468. 			clash = 2;
1469. 		if (clash) {
1470. 			/* symbol chosen matches a used monster or warning
1471. 			   symbol which is not good - reject it*/
1472. 			pline(
1473. 		  "Badoption - boulder symbol '%c' conflicts with a %s symbol.",
1474. 				opts[0], (clash == 1) ? "monster" : "warning");
1475. 		} else {
1476. 			/*
1477. 			 * Override the default boulder symbol.
1478. 			 */
1479. 			iflags.bouldersym = (uchar) opts[0];
1480. 		}
1481. 		if (!initial) need_redraw = TRUE;
1482. 		return;
1483. 	}
1484. 
1485. 	/* name:string */
1486. 	fullname = "name";
1487. 	if (match_optname(opts, fullname, 4, TRUE)) {
1488. 		if (negated) bad_negation(fullname, FALSE);
1489. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1490. 			nmcpy(plname, op, PL_NSIZ);
1491. 		return;
1492. 	}
1493. 
1494. 	/* role:string or character:string */
1495. 	fullname = "role";
1496. 	if (match_optname(opts, fullname, 4, TRUE) ||
1497. 	    match_optname(opts, (fullname = "character"), 4, TRUE)) {
1498. 		if (negated) bad_negation(fullname, FALSE);
1499. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1500. 			if ((flags.initrole = str2role(op)) == ROLE_NONE)
1501. 				badoption(opts);
1502. 			else  /* Backwards compatibility */
1503. 				nmcpy(pl_character, op, PL_NSIZ);
1504. 		}
1505. 		return;
1506. 	}
1507. 
1508. 	/* race:string */
1509. 	fullname = "race";
1510. 	if (match_optname(opts, fullname, 4, TRUE)) {
1511. 		if (negated) bad_negation(fullname, FALSE);
1512. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1513. 			if ((flags.initrace = str2race(op)) == ROLE_NONE)
1514. 				badoption(opts);
1515. 			else /* Backwards compatibility */
1516. 				pl_race = *op;
1517. 		}
1518. 		return;
1519. 	}
1520. 
1521. 	/* gender:string */
1522. 	fullname = "gender";
1523. 	if (match_optname(opts, fullname, 4, TRUE)) {
1524. 		if (negated) bad_negation(fullname, FALSE);
1525. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1526. 			if ((flags.initgend = str2gend(op)) == ROLE_NONE)
1527. 				badoption(opts);
1528. 			else
1529. 				flags.female = flags.initgend;
1530. 		}
1531. 		return;
1532. 	}
1533. 
1534. 	/* altkeyhandler:string */
1535. 	fullname = "altkeyhandler";
1536. 	if (match_optname(opts, fullname, 4, TRUE)) {
1537. 		if (negated) bad_negation(fullname, FALSE);
1538. 		else if ((op = string_for_opt(opts, negated))) {
1539. #ifdef WIN32CON
1540. 		    (void)strncpy(iflags.altkeyhandler, op, MAX_ALTKEYHANDLER - 5);
1541. 		    load_keyboard_handler();
1542. #endif
1543. 		}
1544. 		return;
1545. 	}
1546. 
1547. 	/* WINCAP
1548. 	 * align_status:[left|top|right|bottom] */
1549. 	fullname = "align_status";
1550. 	if (match_optname(opts, fullname, sizeof("align_status")-1, TRUE)) {
1551. 		op = string_for_opt(opts, negated);
1552. 		if (op && !negated) {
1553. 		    if (!strncmpi (op, "left", sizeof("left")-1))
1554. 			iflags.wc_align_status = ALIGN_LEFT;
1555. 		    else if (!strncmpi (op, "top", sizeof("top")-1))
1556. 			iflags.wc_align_status = ALIGN_TOP;
1557. 		    else if (!strncmpi (op, "right", sizeof("right")-1))
1558. 			iflags.wc_align_status = ALIGN_RIGHT;
1559. 		    else if (!strncmpi (op, "bottom", sizeof("bottom")-1))
1560. 			iflags.wc_align_status = ALIGN_BOTTOM;
1561. 		    else
1562. 			badoption(opts);
1563. 		} else if (negated) bad_negation(fullname, TRUE);
1564. 		return;
1565. 	}
1566. 	/* WINCAP
1567. 	 * align_message:[left|top|right|bottom] */
1568. 	fullname = "align_message";
1569. 	if (match_optname(opts, fullname, sizeof("align_message")-1, TRUE)) {
1570. 		op = string_for_opt(opts, negated);
1571. 		if (op && !negated) {
1572. 		    if (!strncmpi (op, "left", sizeof("left")-1))
1573. 			iflags.wc_align_message = ALIGN_LEFT;
1574. 		    else if (!strncmpi (op, "top", sizeof("top")-1))
1575. 			iflags.wc_align_message = ALIGN_TOP;
1576. 		    else if (!strncmpi (op, "right", sizeof("right")-1))
1577. 			iflags.wc_align_message = ALIGN_RIGHT;
1578. 		    else if (!strncmpi (op, "bottom", sizeof("bottom")-1))
1579. 			iflags.wc_align_message = ALIGN_BOTTOM;
1580. 		    else
1581. 			badoption(opts);
1582. 		} else if (negated) bad_negation(fullname, TRUE);
1583. 		return;
1584. 	}
1585. 	/* align:string */
1586. 	fullname = "align";
1587. 	if (match_optname(opts, fullname, sizeof("align")-1, TRUE)) {
1588. 		if (negated) bad_negation(fullname, FALSE);
1589. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0)
1590. 			if ((flags.initalign = str2align(op)) == ROLE_NONE)
1591. 				badoption(opts);
1592. 		return;
1593. 	}
1594. 
1595. 	/* the order to list the pack */
1596. 	fullname = "packorder";
1597. 	if (match_optname(opts, fullname, 4, TRUE)) {
1598. 		if (negated) {
1599. 		    bad_negation(fullname, FALSE);
1600. 		    return;
1601. 		} else if (!(op = string_for_opt(opts, FALSE))) return;
1602. 
1603. 		if (!change_inv_order(op))
1604. 			badoption(opts);
1605. 		return;
1606. 	}
1607. 
1608. 	/* maximum burden picked up before prompt (Warren Cheung) */
1609. 	fullname = "pickup_burden";
1610. 	if (match_optname(opts, fullname, 8, TRUE)) {
1611. 		if (negated) {
1612. 			bad_negation(fullname, FALSE);
1613. 			return;
1614. 		} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
1615. 		    switch (tolower(*op)) {
1616. 				/* Unencumbered */
1617. 				case 'u':
1618. 					flags.pickup_burden = UNENCUMBERED;
1619. 					break;
1620. 				/* Burdened (slight encumbrance) */
1621. 				case 'b':
1622. 					flags.pickup_burden = SLT_ENCUMBER;
1623. 					break;
1624. 				/* streSsed (moderate encumbrance) */
1625. 				case 's':
1626. 					flags.pickup_burden = MOD_ENCUMBER;
1627. 					break;
1628. 				/* straiNed (heavy encumbrance) */
1629. 				case 'n':
1630. 					flags.pickup_burden = HVY_ENCUMBER;
1631. 					break;
1632. 				/* OverTaxed (extreme encumbrance) */
1633. 				case 'o':
1634. 				case 't':
1635. 					flags.pickup_burden = EXT_ENCUMBER;
1636. 					break;
1637. 				/* overLoaded */
1638. 				case 'l':
1639. 					flags.pickup_burden = OVERLOADED;
1640. 					break;
1641. 				default:
1642. 				badoption(opts);
1643. 		    }
1644. 		}
1645. 		return;
1646. 	}
1647. 
1648. 	/* types of objects to pick up automatically */
1649. 	if (match_optname(opts, "pickup_types", 8, TRUE)) {
1650. 		char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1],
1651. 		     qbuf[QBUFSZ], abuf[BUFSZ];
1652. 		int oc_sym;
1653. 		boolean badopt = FALSE, compat = (strlen(opts) <= 6), use_menu;
1654. 
1655. 		oc_to_str(flags.pickup_types, tbuf);
1656. 		flags.pickup_types[0] = '\0';	/* all */
1657. 		op = string_for_opt(opts, (compat || !initial));
1658. 		if (!op) {
1659. 		    if (compat || negated || initial) {
1660. 			/* for backwards compatibility, "pickup" without a
1661. 			   value is a synonym for autopickup of all types
1662. 			   (and during initialization, we can't prompt yet) */
1663. 			flags.pickup = !negated;
1664. 			return;
1665. 		    }
1666. 		    oc_to_str(flags.inv_order, ocl);
1667. 		    use_menu = TRUE;
1668. 		    if (flags.menu_style == MENU_TRADITIONAL ||
1669. 			    flags.menu_style == MENU_COMBINATION) {
1670. 			use_menu = FALSE;
1671. 			Sprintf(qbuf, "New pickup_types: [%s am] (%s)",
1672. 				ocl, *tbuf ? tbuf : "all");
1673. 			getlin(qbuf, abuf);
1674. 			op = mungspaces(abuf);
1675. 			if (abuf[0] == '\0' || abuf[0] == '\033')
1676. 			    op = tbuf;		/* restore */
1677. 			else if (abuf[0] == 'm')
1678. 			    use_menu = TRUE;
1679. 		    }
1680. 		    if (use_menu) {
1681. 			(void) choose_classes_menu("Auto-Pickup what?", 1,
1682. 						   TRUE, ocl, tbuf);
1683. 			op = tbuf;
1684. 		    }
1685. 		}
1686. 		if (negated) {
1687. 		    bad_negation("pickup_types", TRUE);
1688. 		    return;
1689. 		}
1690. 		while (*op == ' ') op++;
1691. 		if (*op != 'a' && *op != 'A') {
1692. 		    num = 0;
1693. 		    while (*op) {
1694. 			oc_sym = def_char_to_objclass(*op);
1695. 			/* make sure all are valid obj symbols occuring once */
1696. 			if (oc_sym != MAXOCLASSES &&
1697. 			    !index(flags.pickup_types, oc_sym)) {
1698. 			    flags.pickup_types[num] = (char)oc_sym;
1699. 			    flags.pickup_types[++num] = '\0';
1700. 			} else
1701. 			    badopt = TRUE;
1702. 			op++;
1703. 		    }
1704. 		    if (badopt) badoption(opts);
1705. 		}
1706. 		return;
1707. 	}
1708. 	/* WINCAP
1709. 	 * player_selection: dialog | prompts */
1710. 	fullname = "player_selection";
1711. 	if (match_optname(opts, fullname, sizeof("player_selection")-1, TRUE)) {
1712. 		op = string_for_opt(opts, negated);
1713. 		if (op && !negated) {
1714. 		    if (!strncmpi (op, "dialog", sizeof("dialog")-1))
1715. 			iflags.wc_player_selection = VIA_DIALOG;
1716. 		    else if (!strncmpi (op, "prompt", sizeof("prompt")-1))
1717. 			iflags.wc_player_selection = VIA_PROMPTS;
1718. 		    else
1719. 		    	badoption(opts);
1720. 		} else if (negated) bad_negation(fullname, TRUE);
1721. 		return;
1722. 	}
1723. 
1724. 	/* things to disclose at end of game */
1725. 	if (match_optname(opts, "disclose", 7, TRUE)) {
1726. 		/*
1727. 		 * The order that the end_disclore options are stored:
1728. 		 * inventory, attribs, vanquished, genocided, conduct
1729. 		 * There is an array in flags:
1730. 		 *	end_disclose[NUM_DISCLOSURE_OPT];
1731. 		 * with option settings for the each of the following:
1732. 		 * iagvc [see disclosure_options in decl.c]:
1733. 		 * Legal setting values in that array are:
1734. 		 *	DISCLOSE_PROMPT_DEFAULT_YES  ask with default answer yes
1735. 		 *	DISCLOSE_PROMPT_DEFAULT_NO   ask with default answer no
1736. 		 *	DISCLOSE_YES_WITHOUT_PROMPT  always disclose and don't ask
1737. 		 *	DISCLOSE_NO_WITHOUT_PROMPT   never disclose and don't ask
1738. 		 *
1739. 		 * Those setting values can be used in the option
1740. 		 * string as a prefix to get the desired behaviour.
1741. 		 *
1742. 		 * For backward compatibility, no prefix is required,
1743. 		 * and the presence of a i,a,g,v, or c without a prefix
1744. 		 * sets the corresponding value to DISCLOSE_YES_WITHOUT_PROMPT.
1745. 		 */
1746. 		boolean badopt = FALSE;
1747. 		int idx, prefix_val;
1748. 
1749. 		op = string_for_opt(opts, TRUE);
1750. 		if (op && negated) {
1751. 			bad_negation("disclose", TRUE);
1752. 			return;
1753. 		}
1754. 		/* "disclose" without a value means "all with prompting"
1755. 		   and negated means "none without prompting" */
1756. 		if (!op || !strcmpi(op, "all") || !strcmpi(op, "none")) {
1757. 			if (op && !strcmpi(op, "none")) negated = TRUE;
1758. 			for (num = 0; num < NUM_DISCLOSURE_OPTIONS; num++)
1759. 			    flags.end_disclose[num] = negated ?
1760. 						DISCLOSE_NO_WITHOUT_PROMPT :
1761. 						DISCLOSE_PROMPT_DEFAULT_YES;
1762. 			return;
1763. 		}
1764. 
1765. 		num = 0;
1766. 		prefix_val = -1;
1767. 		while (*op && num < sizeof flags.end_disclose - 1) {
1768. 			register char c, *dop;
1769. 			static char valid_settings[] = {
1770. 				DISCLOSE_PROMPT_DEFAULT_YES,
1771. 				DISCLOSE_PROMPT_DEFAULT_NO,
1772. 				DISCLOSE_YES_WITHOUT_PROMPT,
1773. 				DISCLOSE_NO_WITHOUT_PROMPT,
1774. 				'\0'
1775. 			};
1776. 			c = lowc(*op);
1777. 			if (c == 'k') c = 'v';	/* killed -> vanquished */
1778. 			dop = index(disclosure_options, c);
1779. 			if (dop) {
1780. 				idx = dop - disclosure_options;
1781. 				if (idx < 0 || idx > NUM_DISCLOSURE_OPTIONS - 1) {
1782. 				    impossible("bad disclosure index %d %c",
1783. 							idx, c);
1784. 				    continue;
1785. 				}
1786. 				if (prefix_val != -1) {
1787. 				    flags.end_disclose[idx] = prefix_val;
1788. 				    prefix_val = -1;
1789. 				} else
1790. 				    flags.end_disclose[idx] = DISCLOSE_YES_WITHOUT_PROMPT;
1791. 			} else if (index(valid_settings, c)) {
1792. 				prefix_val = c;
1793. 			} else if (c == ' ') {
1794. 				/* do nothing */
1795. 			} else
1796. 				badopt = TRUE;				
1797. 			op++;
1798. 		}
1799. 		if (badopt) badoption(opts);
1800. 		return;
1801. 	}
1802. 
1803. 	/* scores:5t[op] 5a[round] o[wn] */
1804. 	if (match_optname(opts, "scores", 4, TRUE)) {
1805. 	    if (negated) {
1806. 		bad_negation("scores", FALSE);
1807. 		return;
1808. 	    }
1809. 	    if (!(op = string_for_opt(opts, FALSE))) return;
1810. 
1811. 	    while (*op) {
1812. 		int inum = 1;
1813. 
1814. 		if (digit(*op)) {
1815. 		    inum = atoi(op);
1816. 		    while (digit(*op)) op++;
1817. 		} else if (*op == '!') {
1818. 		    negated = !negated;
1819. 		    op++;
1820. 		}
1821. 		while (*op == ' ') op++;
1822. 
1823. 		switch (*op) {
1824. 		 case 't':
1825. 		 case 'T':  flags.end_top = inum;
1826. 			    break;
1827. 		 case 'a':
1828. 		 case 'A':  flags.end_around = inum;
1829. 			    break;
1830. 		 case 'o':
1831. 		 case 'O':  flags.end_own = !negated;
1832. 			    break;
1833. 		 default:   badoption(opts);
1834. 			    return;
1835. 		}
1836. 		while (letter(*++op) || *op == ' ') continue;
1837. 		if (*op == '/') op++;
1838. 	    }
1839. 	    return;
1840. 	}
1841. 
1842. 	fullname = "suppress_alert";
1843. 	if (match_optname(opts, fullname, 4, TRUE)) {
1844. 		op = string_for_opt(opts, negated);
1845. 		if (negated) bad_negation(fullname, FALSE);
1846. 		else if (op) (void) feature_alert_opts(op,fullname);
1847. 		return;
1848. 	}
1849. 	
1850. #ifdef VIDEOSHADES
1851. 	/* videocolors:string */
1852. 	fullname = "videocolors";
1853. 	if (match_optname(opts, fullname, 6, TRUE) ||
1854. 	    match_optname(opts, "videocolours", 10, TRUE)) {
1855. 		if (negated) {
1856. 			bad_negation(fullname, FALSE);
1857. 			return;
1858. 		}
1859. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
1860. 			return;
1861. 		}
1862. 		if (!assign_videocolors(opts))
1863. 			badoption(opts);
1864. 		return;
1865. 	}
1866. 	/* videoshades:string */
1867. 	fullname = "videoshades";
1868. 	if (match_optname(opts, fullname, 6, TRUE)) {
1869. 		if (negated) {
1870. 			bad_negation(fullname, FALSE);
1871. 			return;
1872. 		}
1873. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
1874. 			return;
1875. 		}
1876. 		if (!assign_videoshades(opts))
1877. 			badoption(opts);
1878. 		return;
1879. 	}
1880. #endif /* VIDEOSHADES */
1881. #ifdef MSDOS
1882. # ifdef NO_TERMS
1883. 	/* video:string -- must be after longer tests */
1884. 	fullname = "video";
1885. 	if (match_optname(opts, fullname, 5, TRUE)) {
1886. 		if (negated) {
1887. 			bad_negation(fullname, FALSE);
1888. 			return;
1889. 		}
1890. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
1891. 			return;
1892. 		}
1893. 		if (!assign_video(opts))
1894. 			badoption(opts);
1895. 		return;
1896. 	}
1897. # endif /* NO_TERMS */
1898. 	/* soundcard:string -- careful not to match boolean 'sound' */
1899. 	fullname = "soundcard";
1900. 	if (match_optname(opts, fullname, 6, TRUE)) {
1901. 		if (negated) {
1902. 			bad_negation(fullname, FALSE);
1903. 			return;
1904. 		}
1905. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
1906. 			return;
1907. 		}
1908. 		if (!assign_soundcard(opts))
1909. 			badoption(opts);
1910. 		return;
1911. 	}
1912. #endif /* MSDOS */
1913. 
1914. 	/* WINCAP
1915. 	 * map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12|ascii8x12|
1916. 			ascii16x12|ascii12x16|ascii10x18|fit_to_screen] */
1917. 	fullname = "map_mode";
1918. 	if (match_optname(opts, fullname, sizeof("map_mode")-1, TRUE)) {
1919. 		op = string_for_opt(opts, negated);
1920. 		if (op && !negated) {
1921. 		    if (!strncmpi (op, "tiles", sizeof("tiles")-1))
1922. 			iflags.wc_map_mode = MAP_MODE_TILES;
1923. 		    else if (!strncmpi (op, "ascii4x6", sizeof("ascii4x6")-1))
1924. 			iflags.wc_map_mode = MAP_MODE_ASCII4x6;
1925. 		    else if (!strncmpi (op, "ascii6x8", sizeof("ascii6x8")-1))
1926. 			iflags.wc_map_mode = MAP_MODE_ASCII6x8;
1927. 		    else if (!strncmpi (op, "ascii8x8", sizeof("ascii8x8")-1))
1928. 			iflags.wc_map_mode = MAP_MODE_ASCII8x8;
1929. 		    else if (!strncmpi (op, "ascii16x8", sizeof("ascii16x8")-1))
1930. 			iflags.wc_map_mode = MAP_MODE_ASCII16x8;
1931. 		    else if (!strncmpi (op, "ascii7x12", sizeof("ascii7x12")-1))
1932. 			iflags.wc_map_mode = MAP_MODE_ASCII7x12;
1933. 		    else if (!strncmpi (op, "ascii8x12", sizeof("ascii8x12")-1))
1934. 			iflags.wc_map_mode = MAP_MODE_ASCII8x12;
1935. 		    else if (!strncmpi (op, "ascii16x12", sizeof("ascii16x12")-1))
1936. 			iflags.wc_map_mode = MAP_MODE_ASCII16x12;
1937. 		    else if (!strncmpi (op, "ascii12x16", sizeof("ascii12x16")-1))
1938. 			iflags.wc_map_mode = MAP_MODE_ASCII12x16;
1939. 		    else if (!strncmpi (op, "ascii10x18", sizeof("ascii10x18")-1))
1940. 			iflags.wc_map_mode = MAP_MODE_ASCII10x18;
1941. 		    else if (!strncmpi (op, "fit_to_screen", sizeof("fit_to_screen")-1))
1942. 			iflags.wc_map_mode = MAP_MODE_ASCII_FIT_TO_SCREEN;
1943. 		    else
1944. 		    	badoption(opts);
1945. 		} else if (negated) bad_negation(fullname, TRUE);
1946. 		return;
1947. 	}
1948. 	/* WINCAP
1949. 	 * scroll_amount:nn */
1950. 	fullname = "scroll_amount";
1951. 	if (match_optname(opts, fullname, sizeof("scroll_amount")-1, TRUE)) {
1952. 		op = string_for_opt(opts, negated);
1953. 		if ((negated && !op) || (!negated && op)) {
1954. 			iflags.wc_scroll_amount = negated ? 1 : atoi(op);
1955. 		} else if (negated) bad_negation(fullname, TRUE);
1956. 		return;
1957. 	}
1958. 	/* WINCAP
1959. 	 * scroll_margin:nn */
1960. 	fullname = "scroll_margin";
1961. 	if (match_optname(opts, fullname, sizeof("scroll_margin")-1, TRUE)) {
1962. 		op = string_for_opt(opts, negated);
1963. 		if ((negated && !op) || (!negated && op)) {
1964. 			iflags.wc_scroll_margin = negated ? 5 : atoi(op);
1965. 		} else if (negated) bad_negation(fullname, TRUE);
1966. 		return;
1967. 	}
1968. 	fullname = "subkeyvalue";
1969. 	if (match_optname(opts, fullname, 5, TRUE)) {
1970. 		if (negated) bad_negation(fullname, FALSE);
1971. 		else {
1972. #if defined(WIN32CON)
1973. 			op = string_for_opt(opts, 0);
1974. 			map_subkeyvalue(op);
1975. #endif
1976. 		}
1977. 		return;
1978. 	}
1979. 	/* WINCAP
1980. 	 * tile_width:nn */
1981. 	fullname = "tile_width";
1982. 	if (match_optname(opts, fullname, sizeof("tile_width")-1, TRUE)) {
1983. 		op = string_for_opt(opts, negated);
1984. 		if ((negated && !op) || (!negated && op)) {
1985. 			iflags.wc_tile_width = negated ? 0 : atoi(op);
1986. 		} else if (negated) bad_negation(fullname, TRUE);
1987. 		return;
1988. 	}
1989. 	/* WINCAP
1990. 	 * tile_file:name */
1991. 	fullname = "tile_file";
1992. 	if (match_optname(opts, fullname, sizeof("tile_file")-1, TRUE)) {
1993. 		if ((op = string_for_opt(opts, FALSE)) != 0) {
1994. 			if (iflags.wc_tile_file) free(iflags.wc_tile_file);
1995. 			iflags.wc_tile_file = (char *)alloc(strlen(op) + 1);
1996. 			Strcpy(iflags.wc_tile_file, op);
1997. 		}
1998. 		return;
1999. 	}
2000. 	/* WINCAP
2001. 	 * tile_height:nn */
2002. 	fullname = "tile_height";
2003. 	if (match_optname(opts, fullname, sizeof("tile_height")-1, TRUE)) {
2004. 		op = string_for_opt(opts, negated);
2005. 		if ((negated && !op) || (!negated && op)) {
2006. 			iflags.wc_tile_height = negated ? 0 : atoi(op);
2007. 		} else if (negated) bad_negation(fullname, TRUE);
2008. 		return;
2009. 	}
2010. 	/* WINCAP
2011. 	 * vary_msgcount:nn */
2012. 	fullname = "vary_msgcount";
2013. 	if (match_optname(opts, fullname, sizeof("vary_msgcount")-1, TRUE)) {
2014. 		op = string_for_opt(opts, negated);
2015. 		if ((negated && !op) || (!negated && op)) {
2016. 			iflags.wc_vary_msgcount = negated ? 0 : atoi(op);
2017. 		} else if (negated) bad_negation(fullname, TRUE);
2018. 		return;
2019. 	}
2020. 	fullname = "windowtype";
2021. 	if (match_optname(opts, fullname, 3, TRUE)) {
2022. 	    if (negated) {
2023. 		bad_negation(fullname, FALSE);
2024. 		return;
2025. 	    } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
2026. 		char buf[WINTYPELEN];
2027. 		nmcpy(buf, op, WINTYPELEN);
2028. 		choose_windows(buf);
2029. 	    }
2030. 	    return;
2031. 	}
2032. 
2033. 	/* WINCAP
2034. 	 * setting window colors
2035.          * syntax: windowcolors=menu foregrnd/backgrnd text foregrnd/backgrnd
2036.          */
2037. 	fullname = "windowcolors";
2038. 	if (match_optname(opts, fullname, 7, TRUE)) {
2039. 		if ((op = string_for_opt(opts, FALSE)) != 0) {
2040. 			if (!wc_set_window_colors(op))
2041. 				badoption(opts);
2042. 		} else if (negated) bad_negation(fullname, TRUE);
2043. 		return;
2044. 	}
2045. 
2046. 	/* menustyle:traditional or combo or full or partial */
2047. 	if (match_optname(opts, "menustyle", 4, TRUE)) {
2048. 		int tmp;
2049. 		boolean val_required = (strlen(opts) > 5 && !negated);
2050. 
2051. 		if (!(op = string_for_opt(opts, !val_required))) {
2052. 		    if (val_required) return; /* string_for_opt gave feedback */
2053. 		    tmp = negated ? 'n' : 'f';
2054. 		} else {
2055. 		    tmp = tolower(*op);
2056. 		}
2057. 		switch (tmp) {
2058. 			case 'n':	/* none */
2059. 			case 't':	/* traditional */
2060. 				flags.menu_style = MENU_TRADITIONAL;
2061. 				break;
2062. 			case 'c':	/* combo: trad.class sel+menu */
2063. 				flags.menu_style = MENU_COMBINATION;
2064. 				break;
2065. 			case 'p':	/* partial: no class menu */
2066. 				flags.menu_style = MENU_PARTIAL;
2067. 				break;
2068. 			case 'f':	/* full: class menu + menu */
2069. 				flags.menu_style = MENU_FULL;
2070. 				break;
2071. 			default:
2072. 				badoption(opts);
2073. 		}
2074. 		return;
2075. 	}
2076. 
2077. 	fullname = "menu_headings";
2078. 	if (match_optname(opts, fullname, 12, TRUE)) {
2079. 		if (negated) {
2080. 			bad_negation(fullname, FALSE);
2081. 			return;
2082. 		}
2083. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
2084. 			return;
2085. 		}
2086. 		if (!strcmpi(opts,"bold"))
2087. 			iflags.menu_headings = ATR_BOLD;
2088. 		else if (!strcmpi(opts,"inverse"))
2089. 			iflags.menu_headings = ATR_INVERSE;
2090. 		else if (!strcmpi(opts,"underline"))
2091. 			iflags.menu_headings = ATR_ULINE;
2092. 		else
2093. 			badoption(opts);
2094. 		return;
2095. 	}
2096. 
2097. 	/* check for menu command mapping */
2098. 	for (i = 0; i < NUM_MENU_CMDS; i++) {
2099. 	    fullname = default_menu_cmd_info[i].name;
2100. 	    if (match_optname(opts, fullname, (int)strlen(fullname), TRUE)) {
2101. 		if (negated)
2102. 		    bad_negation(fullname, FALSE);
2103. 		else if ((op = string_for_opt(opts, FALSE)) != 0) {
2104. 		    int j;
2105. 		    char c, op_buf[BUFSZ];
2106. 		    boolean isbad = FALSE;
2107. 
2108. 		    escapes(op, op_buf);
2109. 		    c = *op_buf;
2110. 
2111. 		    if (c == 0 || c == '\r' || c == '\n' || c == '\033' ||
2112. 			    c == ' ' || digit(c) || (letter(c) && c != '@'))
2113. 			isbad = TRUE;
2114. 		    else	/* reject default object class symbols */
2115. 			for (j = 1; j < MAXOCLASSES; j++)
2116. 			    if (c == def_oc_syms[i]) {
2117. 				isbad = TRUE;
2118. 				break;
2119. 			    }
2120. 
2121. 		    if (isbad)
2122. 			badoption(opts);
2123. 		    else
2124. 			add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd);
2125. 		}
2126. 		return;
2127. 	    }
2128. 	}
2129. 
2130. 	/* OK, if we still haven't recognized the option, check the boolean
2131. 	 * options list
2132. 	 */
2133. 	for (i = 0; boolopt[i].name; i++) {
2134. 		if (match_optname(opts, boolopt[i].name, 3, FALSE)) {
2135. 			/* options that don't exist */
2136. 			if (!boolopt[i].addr) {
2137. 			    if (!initial && !negated)
2138. 				pline_The("\"%s\" option is not available.",
2139. 					boolopt[i].name);
2140. 			    return;
2141. 			}
2142. 			/* options that must come from config file */
2143. 			if (!initial && (boolopt[i].optflags == SET_IN_FILE)) {
2144. 			    rejectoption(boolopt[i].name);
2145. 			    return;
2146. 			}
2147. 
2148. 			*(boolopt[i].addr) = !negated;
2149. 
2150. 			duplicate_opt_detection(boolopt[i].name, 0);
2151. 
2152. #if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV)
2153. 			if (FALSE
2154. # ifdef TERMLIB
2155. 				 || (boolopt[i].addr) == &iflags.DECgraphics
2156. # endif
2157. # ifdef ASCIIGRAPH
2158. 				 || (boolopt[i].addr) == &iflags.IBMgraphics
2159. # endif
2160. # ifdef MAC_GRAPHICS_ENV
2161. 				 || (boolopt[i].addr) == &iflags.MACgraphics
2162. # endif
2163. 				) {
2164. # ifdef REINCARNATION
2165. 			    if (!initial && Is_rogue_level(&u.uz))
2166. 				assign_rogue_graphics(FALSE);
2167. # endif
2168. 			    need_redraw = TRUE;
2169. # ifdef TERMLIB
2170. 			    if ((boolopt[i].addr) == &iflags.DECgraphics)
2171. 				switch_graphics(iflags.DECgraphics ?
2172. 						DEC_GRAPHICS : ASCII_GRAPHICS);
2173. # endif
2174. # ifdef ASCIIGRAPH
2175. 			    if ((boolopt[i].addr) == &iflags.IBMgraphics)
2176. 				switch_graphics(iflags.IBMgraphics ?
2177. 						IBM_GRAPHICS : ASCII_GRAPHICS);
2178. # endif
2179. # ifdef MAC_GRAPHICS_ENV
2180. 			    if ((boolopt[i].addr) == &iflags.MACgraphics)
2181. 				switch_graphics(iflags.MACgraphics ?
2182. 						MAC_GRAPHICS : ASCII_GRAPHICS);
2183. # endif
2184. # ifdef REINCARNATION
2185. 			    if (!initial && Is_rogue_level(&u.uz))
2186. 				assign_rogue_graphics(TRUE);
2187. # endif
2188. 			}
2189. #endif /* TERMLIB || ASCIIGRAPH || MAC_GRAPHICS_ENV */
2190. 
2191. 			/* only do processing below if setting with doset() */
2192. 			if (initial) return;
2193. 
2194. 			if ((boolopt[i].addr) == &flags.time
2195. #ifdef EXP_ON_BOTL
2196. 			 || (boolopt[i].addr) == &flags.showexp
2197. #endif
2198. #ifdef SCORE_ON_BOTL
2199. 			 || (boolopt[i].addr) == &flags.showscore
2200. #endif
2201. 			    )
2202. 			    flags.botl = TRUE;
2203. 
2204. 			else if ((boolopt[i].addr) == &flags.invlet_constant) {
2205. 			    if (flags.invlet_constant) reassign();
2206. 			}
2207. #ifdef LAN_MAIL
2208. 			else if ((boolopt[i].addr) == &flags.biff) {
2209. 			    if (flags.biff) lan_mail_init();
2210. 			    else lan_mail_finish();
2211. 			}
2212. #endif
2213. 			else if ((boolopt[i].addr) == &flags.lit_corridor) {
2214. 			    /*
2215. 			     * All corridor squares seen via night vision or
2216. 			     * candles & lamps change.  Update them by calling
2217. 			     * newsym() on them.  Don't do this if we are
2218. 			     * initializing the options --- the vision system
2219. 			     * isn't set up yet.
2220. 			     */
2221. 			    vision_recalc(2);		/* shut down vision */
2222. 			    vision_full_recalc = 1;	/* delayed recalc */
2223. 			}
2224. 			else if ((boolopt[i].addr) == &iflags.use_inverse ||
2225. 					(boolopt[i].addr) == &iflags.showrace ||
2226. 					(boolopt[i].addr) == &iflags.hilite_pet) {
2227. 			    need_redraw = TRUE;
2228. 			}
2229. #ifdef TEXTCOLOR
2230. 			else if ((boolopt[i].addr) == &iflags.use_color) {
2231. 			    need_redraw = TRUE;
2232. # ifdef TOS
2233. 			    if ((boolopt[i].addr) == &iflags.use_color
2234. 				&& iflags.BIOS) {
2235. 				if (colors_changed)
2236. 				    restore_colors();
2237. 				else
2238. 				    set_colors();
2239. 			    }
2240. # endif
2241. 			}
2242. #endif
2243. 
2244. 			return;
2245. 		}
2246. 	}
2247. 
2248. 	/* out of valid options */
2249. 	badoption(opts);
2250. }
2251. 
2252. 
2253. static NEARDATA const char *menutype[] = {
2254. 	"traditional", "combination", "partial", "full"
2255. };
2256. 
2257. static NEARDATA const char *burdentype[] = {
2258. 	"unencumbered", "burdened", "stressed",
2259. 	"strained", "overtaxed", "overloaded"
2260. };
2261. 
2262. static NEARDATA const char *runmodes[] = {
2263. 	"teleport", "run", "walk", "crawl"
2264. };
2265. 

oc_to_str

2266. /*
2267.  * Convert the given string of object classes to a string of default object
2268.  * symbols.
2269.  */
2270. STATIC_OVL void
2271. oc_to_str(src,dest)
2272.     char *src, *dest;
2273. {
2274.     int i;
2275. 
2276.     while ((i = (int) *src++) != 0) {
2277. 	if (i < 0 || i >= MAXOCLASSES)
2278. 	    impossible("oc_to_str:  illegal object class %d", i);
2279. 	else
2280. 	    *dest++ = def_oc_syms[i];
2281.     }
2282.     *dest = '\0';
2283. }
2284. 

add_menu_cmd_alias

2285. /*
2286.  * Add the given mapping to the menu command map list.  Always keep the
2287.  * maps valid C strings.
2288.  */
2289. void
2290. add_menu_cmd_alias(from_ch, to_ch)
2291.     char from_ch, to_ch;
2292. {
2293.     if (n_menu_mapped >= MAX_MENU_MAPPED_CMDS)
2294. 	pline("out of menu map space.");
2295.     else {
2296. 	mapped_menu_cmds[n_menu_mapped] = from_ch;
2297. 	mapped_menu_op[n_menu_mapped] = to_ch;
2298. 	n_menu_mapped++;
2299. 	mapped_menu_cmds[n_menu_mapped] = 0;
2300. 	mapped_menu_op[n_menu_mapped] = 0;
2301.     }
2302. }
2303. 

map_menu_cmd

2304. /*
2305.  * Map the given character to its corresponding menu command.  If it
2306.  * doesn't match anything, just return the original.
2307.  */
2308. char
2309. map_menu_cmd(ch)
2310.     char ch;
2311. {
2312.     char *found = index(mapped_menu_cmds, ch);
2313.     if (found) {
2314. 	int idx = found - mapped_menu_cmds;
2315. 	ch = mapped_menu_op[idx];
2316.     }
2317.     return ch;
2318. }
2319. 
2320. 

doset_add_menu

2321. #if defined(MICRO) || defined(MAC) || defined(WIN32)
2322. # define OPTIONS_HEADING "OPTIONS"
2323. #else
2324. # define OPTIONS_HEADING "NETHACKOPTIONS"
2325. #endif
2326. 
2327. static char fmtstr_doset_add_menu[] = "%s%-15s [%s]   "; 
2328. static char fmtstr_doset_add_menu_tab[] = "%s\t[%s]";
2329. 
2330. STATIC_OVL void
2331. doset_add_menu(win, option, indexoffset)
2332.     winid win;			/* window to add to */
2333.     const char *option;		/* option name */
2334.     int indexoffset;		/* value to add to index in compopt[], or zero
2335. 				   if option cannot be changed */
2336. {
2337.     const char *value = "unknown";		/* current value */
2338.     char buf[BUFSZ], buf2[BUFSZ];
2339.     anything any;
2340.     int i;
2341. 
2342.     any.a_void = 0;
2343.     if (indexoffset == 0) {
2344. 	any.a_int = 0;
2345. 	value = get_compopt_value(option, buf2);
2346.     } else {
2347. 	for (i=0; compopt[i].name; i++)
2348. 	    if (strcmp(option, compopt[i].name) == 0) break;
2349. 
2350. 	if (compopt[i].name) {
2351. 	    any.a_int = i + 1 + indexoffset;
2352. 	    value = get_compopt_value(option, buf2);
2353. 	} else {
2354. 	    /* We are trying to add an option not found in compopt[].
2355. 	       This is almost certainly bad, but we'll let it through anyway
2356. 	       (with a zero value, so it can't be selected). */
2357. 	    any.a_int = 0;
2358. 	}
2359.     }
2360.     /* "    " replaces "a - " -- assumes menus follow that style */
2361.     if (!iflags.menu_tab_sep)
2362. 	Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : "    ", option, value);
2363.     else
2364. 	Sprintf(buf, fmtstr_doset_add_menu_tab, option, value);
2365.     add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
2366. }
2367. 

doset

2368. /* Changing options via menu by Per Liboriussen */
2369. int
2370. doset()
2371. {
2372. 	char buf[BUFSZ], buf2[BUFSZ];
2373. 	int i, pass, boolcount, pick_cnt, pick_idx, opt_indx;
2374. 	boolean *bool_p;
2375. 	winid tmpwin;
2376. 	anything any;
2377. 	menu_item *pick_list;
2378. 	int indexoffset, startpass, endpass;
2379. 	boolean setinitial = FALSE, fromfile = FALSE;
2380. 	int biggest_name = 0;
2381. 
2382. 	tmpwin = create_nhwindow(NHW_MENU);
2383. 	start_menu(tmpwin);
2384. 
2385. 	any.a_void = 0;
2386.  add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2387. 		 "Booleans (selecting will toggle value):", MENU_UNSELECTED);
2388. 	any.a_int = 0;
2389. 	/* first list any other non-modifiable booleans, then modifiable ones */
2390. 	for (pass = 0; pass <= 1; pass++)
2391. 	    for (i = 0; boolopt[i].name; i++)
2392. 		if ((bool_p = boolopt[i].addr) != 0 &&
2393. 			((boolopt[i].optflags == DISP_IN_GAME && pass == 0) ||
2394. 			 (boolopt[i].optflags == SET_IN_GAME && pass == 1))) {
2395. 		    if (bool_p == &flags.female) continue;  /* obsolete */
2396. #ifdef WIZARD
2397. 		    if (bool_p == &iflags.sanity_check && !wizard) continue;
2398. 		    if (bool_p == &iflags.menu_tab_sep && !wizard) continue;
2399. #endif
2400. 		    if (is_wc_option(boolopt[i].name) &&
2401. 			!wc_supported(boolopt[i].name)) continue;
2402. 		    if (is_wc2_option(boolopt[i].name) &&
2403. 			!wc2_supported(boolopt[i].name)) continue;
2404. 		    any.a_int = (pass == 0) ? 0 : i + 1;
2405. 		    if (!iflags.menu_tab_sep)
2406. 			Sprintf(buf, "%s%-13s [%s]",
2407. 			    pass == 0 ? "    " : "",
2408. 			    boolopt[i].name, *bool_p ? "true" : "false");
2409.  		    else
2410. 			Sprintf(buf, "%s\t[%s]",
2411. 			    boolopt[i].name, *bool_p ? "true" : "false");
2412. 		    add_menu(tmpwin, NO_GLYPH, &any, 0, 0,
2413. 			     ATR_NONE, buf, MENU_UNSELECTED);
2414. 		}
2415. 
2416. 	boolcount = i;
2417. 	indexoffset = boolcount;
2418. 	any.a_void = 0;
2419. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
2420.  add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2421. 		 "Compounds (selecting will prompt for new value):",
2422. 		 MENU_UNSELECTED);
2423. 
2424. 	startpass = DISP_IN_GAME;
2425. 	endpass = SET_IN_GAME;
2426. 
2427. 	/* spin through the options to find the biggest name
2428.            and adjust the format string accordingly if needed */
2429. 	biggest_name = 0;
2430. 	for (i = 0; compopt[i].name; i++)
2431. 		if (compopt[i].optflags >= startpass && compopt[i].optflags <= endpass &&
2432. 		    strlen(compopt[i].name) > (unsigned) biggest_name)
2433. 			biggest_name = (int) strlen(compopt[i].name);
2434. 	if (biggest_name > 30) biggest_name = 30;
2435. 	if (!iflags.menu_tab_sep)
2436. 		Sprintf(fmtstr_doset_add_menu, "%%s%%-%ds [%%s]", biggest_name);
2437. 	
2438. 	/* deliberately put `name', `role', `race', `gender' first */
2439. 	doset_add_menu(tmpwin, "name", 0);
2440. 	doset_add_menu(tmpwin, "role", 0);
2441. 	doset_add_menu(tmpwin, "race", 0);
2442. 	doset_add_menu(tmpwin, "gender", 0);
2443. 
2444. 	for (pass = startpass; pass <= endpass; pass++) 
2445. 	    for (i = 0; compopt[i].name; i++)
2446. 		if (compopt[i].optflags == pass) {
2447.  		    	if (!strcmp(compopt[i].name, "name") ||
2448. 		    	    !strcmp(compopt[i].name, "role") ||
2449. 		    	    !strcmp(compopt[i].name, "race") ||
2450. 		    	    !strcmp(compopt[i].name, "gender"))
2451. 		    	    	continue;
2452. 		    	else if (is_wc_option(compopt[i].name) &&
2453. 					!wc_supported(compopt[i].name))
2454. 		    		continue;
2455. 		    	else if (is_wc2_option(compopt[i].name) &&
2456. 					!wc2_supported(compopt[i].name))
2457. 		    		continue;
2458. 		    	else
2459. 				doset_add_menu(tmpwin, compopt[i].name,
2460. 					(pass == DISP_IN_GAME) ? 0 : indexoffset);
2461. 		}
2462. #ifdef AUTOPICKUP_EXCEPTIONS
2463. 	any.a_int = -1;
2464. 	Sprintf(buf, "autopickup exceptions (%d currently set)",
2465. 		count_ape_maps((int *)0, (int *)0));
2466. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED);
2467. 
2468. #endif /* AUTOPICKUP_EXCEPTIONS */
2469. #ifdef PREFIXES_IN_USE
2470. 	any.a_void = 0;
2471. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
2472. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2473. 		 "Variable playground locations:", MENU_UNSELECTED);
2474. 	for (i = 0; i < PREFIX_COUNT; i++)
2475. 		doset_add_menu(tmpwin, fqn_prefix_names[i], 0);
2476. #endif
2477. 	end_menu(tmpwin, "Set what options?");
2478. 	need_redraw = FALSE;
2479. 	if ((pick_cnt = select_menu(tmpwin, PICK_ANY, &pick_list)) > 0) {
2480. 	    /*
2481. 	     * Walk down the selection list and either invert the booleans
2482. 	     * or prompt for new values. In most cases, call parseoptions()
2483. 	     * to take care of options that require special attention, like
2484. 	     * redraws.
2485. 	     */
2486. 	    for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) {
2487. 		opt_indx = pick_list[pick_idx].item.a_int - 1;
2488. #ifdef AUTOPICKUP_EXCEPTIONS
2489. 		if (opt_indx == -2) {
2490. 		    special_handling("autopickup_exception",
2491. 		    			setinitial, fromfile);
2492. 		} else
2493. #endif
2494. 		if (opt_indx < boolcount) {
2495. 		    /* boolean option */
2496. 		    Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "",
2497. 			    boolopt[opt_indx].name);
2498. 		    parseoptions(buf, setinitial, fromfile);
2499. 		    if (wc_supported(boolopt[opt_indx].name) ||
2500. 		    	wc2_supported(boolopt[opt_indx].name))
2501. 			preference_update(boolopt[opt_indx].name);
2502. 		} else {
2503. 		    /* compound option */
2504. 		    opt_indx -= boolcount;
2505. 
2506. 		    if (!special_handling(compopt[opt_indx].name,
2507. 							setinitial, fromfile)) {
2508. 			Sprintf(buf, "Set %s to what?", compopt[opt_indx].name);
2509. 			getlin(buf, buf2);
2510. 			if (buf2[0] == '\033')
2511. 			    continue;
2512. 			Sprintf(buf, "%s:%s", compopt[opt_indx].name, buf2);
2513. 			/* pass the buck */
2514. 			parseoptions(buf, setinitial, fromfile);
2515. 		    }
2516. 		    if (wc_supported(compopt[opt_indx].name) ||
2517. 			wc2_supported(compopt[opt_indx].name))
2518. 			preference_update(compopt[opt_indx].name);
2519. 		}
2520. 	    }
2521. 	    free((genericptr_t)pick_list);
2522. 	    pick_list = (menu_item *)0;
2523. 	}
2524. 
2525. 	destroy_nhwindow(tmpwin);
2526. 	if (need_redraw)
2527. 	    (void) doredraw();
2528. 	return 0;
2529. }
2530. 

special_handling

2531. STATIC_OVL boolean
2532. special_handling(optname, setinitial, setfromfile)
2533. const char *optname;
2534. boolean setinitial,setfromfile;
2535. {
2536.     winid tmpwin;
2537.     anything any;
2538.     int i;
2539.     char buf[BUFSZ];
2540.     boolean retval = FALSE;
2541.     
2542.     /* Special handling of menustyle, pickup_burden, pickup_types,
2543.      * disclose, runmode, msg_window, menu_headings, and number_pad options.
2544. #ifdef AUTOPICKUP_EXCEPTIONS
2545.      * Also takes care of interactive autopickup_exception_handling changes.
2546. #endif
2547.      */
2548.     if (!strcmp("menustyle", optname)) {
2549. 	const char *style_name;
2550. 	menu_item *style_pick = (menu_item *)0;
2551.         tmpwin = create_nhwindow(NHW_MENU);
2552. 	start_menu(tmpwin);
2553. 	for (i = 0; i < SIZE(menutype); i++) {
2554. 		style_name = menutype[i];
2555.     		/* note: separate `style_name' variable used
2556. 		   to avoid an optimizer bug in VAX C V2.3 */
2557. 		any.a_int = i + 1;
2558. 		add_menu(tmpwin, NO_GLYPH, &any, *style_name, 0,
2559. 			 ATR_NONE, style_name, MENU_UNSELECTED);
2560.         }
2561. 	end_menu(tmpwin, "Select menustyle:");
2562. 	if (select_menu(tmpwin, PICK_ONE, &style_pick) > 0) {
2563. 		flags.menu_style = style_pick->item.a_int - 1;
2564. 		free((genericptr_t)style_pick);
2565.         }
2566. 	destroy_nhwindow(tmpwin);
2567.         retval = TRUE;
2568.     } else if (!strcmp("pickup_burden", optname)) {
2569. 	const char *burden_name, *burden_letters = "ubsntl";
2570. 	menu_item *burden_pick = (menu_item *)0;
2571.         tmpwin = create_nhwindow(NHW_MENU);
2572. 	start_menu(tmpwin);
2573. 	for (i = 0; i < SIZE(burdentype); i++) {
2574. 		burden_name = burdentype[i];
2575. 		any.a_int = i + 1;
2576. 		add_menu(tmpwin, NO_GLYPH, &any, burden_letters[i], 0,
2577. 			 ATR_NONE, burden_name, MENU_UNSELECTED);
2578.         }
2579. 	end_menu(tmpwin, "Select encumbrance level:");
2580. 	if (select_menu(tmpwin, PICK_ONE, &burden_pick) > 0) {
2581. 		flags.pickup_burden = burden_pick->item.a_int - 1;
2582. 		free((genericptr_t)burden_pick);
2583. 	}
2584. 	destroy_nhwindow(tmpwin);
2585. 	retval = TRUE;
2586.     } else if (!strcmp("pickup_types", optname)) {
2587. 	/* parseoptions will prompt for the list of types */
2588. 	parseoptions(strcpy(buf, "pickup_types"), setinitial, setfromfile);
2589. 	retval = TRUE;
2590.     } else if (!strcmp("disclose", optname)) {
2591. 	int pick_cnt, pick_idx, opt_idx;
2592. 	menu_item *disclosure_category_pick = (menu_item *)0;
2593. 	/*
2594. 	 * The order of disclose_names[]
2595.          * must correspond to disclosure_options in decl.h
2596.          */
2597. 	static const char *disclosure_names[] = {
2598. 		"inventory", "attributes", "vanquished", "genocides", "conduct"
2599. 	};
2600. 	int disc_cat[NUM_DISCLOSURE_OPTIONS];
2601. 	const char *disclosure_name;
2602. 
2603.         tmpwin = create_nhwindow(NHW_MENU);
2604. 	start_menu(tmpwin);
2605. 	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) {
2606. 		disclosure_name = disclosure_names[i];
2607. 		any.a_int = i + 1;
2608. 		add_menu(tmpwin, NO_GLYPH, &any, disclosure_options[i], 0,
2609. 			 ATR_NONE, disclosure_name, MENU_UNSELECTED);
2610. 		disc_cat[i] = 0;
2611.         }
2612. 	end_menu(tmpwin, "Change which disclosure options categories:");
2613. 	if ((pick_cnt = select_menu(tmpwin, PICK_ANY, &disclosure_category_pick)) > 0) {
2614. 	    for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) {
2615. 		opt_idx = disclosure_category_pick[pick_idx].item.a_int - 1;
2616. 		disc_cat[opt_idx] = 1;
2617. 	    }
2618. 	    free((genericptr_t)disclosure_category_pick);
2619. 	    disclosure_category_pick = (menu_item *)0;
2620. 	}
2621. 	destroy_nhwindow(tmpwin);
2622. 
2623. 	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) {
2624. 	    if (disc_cat[i]) {
2625. 	    	char dbuf[BUFSZ];
2626. 		menu_item *disclosure_option_pick = (menu_item *)0;
2627. 		Sprintf(dbuf, "Disclosure options for %s:", disclosure_names[i]);
2628. 	        tmpwin = create_nhwindow(NHW_MENU);
2629. 		start_menu(tmpwin);
2630. 		any.a_char = DISCLOSE_NO_WITHOUT_PROMPT;
2631. 		add_menu(tmpwin, NO_GLYPH, &any, 'a', 0,
2632. 			ATR_NONE,"Never disclose and don't prompt", MENU_UNSELECTED);
2633. 		any.a_void = 0;
2634. 		any.a_char = DISCLOSE_YES_WITHOUT_PROMPT;
2635. 		add_menu(tmpwin, NO_GLYPH, &any, 'b', 0,
2636. 			ATR_NONE,"Always disclose and don't prompt", MENU_UNSELECTED);
2637. 		any.a_void = 0;
2638. 		any.a_char = DISCLOSE_PROMPT_DEFAULT_NO;
2639. 		add_menu(tmpwin, NO_GLYPH, &any, 'c', 0,
2640. 			ATR_NONE,"Prompt and default answer to \"No\"", MENU_UNSELECTED);
2641. 		any.a_void = 0;
2642. 		any.a_char = DISCLOSE_PROMPT_DEFAULT_YES;
2643. 		add_menu(tmpwin, NO_GLYPH, &any, 'd', 0,
2644. 			ATR_NONE,"Prompt and default answer to \"Yes\"", MENU_UNSELECTED);
2645. 		end_menu(tmpwin, dbuf);
2646. 		if (select_menu(tmpwin, PICK_ONE, &disclosure_option_pick) > 0) {
2647. 			flags.end_disclose[i] = disclosure_option_pick->item.a_char;
2648. 			free((genericptr_t)disclosure_option_pick);
2649. 		}
2650. 		destroy_nhwindow(tmpwin);
2651. 	    }
2652. 	}
2653. 	retval = TRUE;
2654.     } else if (!strcmp("runmode", optname)) {
2655. 	const char *mode_name;
2656. 	menu_item *mode_pick = (menu_item *)0;
2657. 	tmpwin = create_nhwindow(NHW_MENU);
2658. 	start_menu(tmpwin);
2659. 	for (i = 0; i < SIZE(runmodes); i++) {
2660. 		mode_name = runmodes[i];
2661. 		any.a_int = i + 1;
2662. 		add_menu(tmpwin, NO_GLYPH, &any, *mode_name, 0,
2663. 			 ATR_NONE, mode_name, MENU_UNSELECTED);
2664. 	}
2665. 	end_menu(tmpwin, "Select run/travel display mode:");
2666. 	if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) {
2667. 		iflags.runmode = mode_pick->item.a_int - 1;
2668. 		free((genericptr_t)mode_pick);
2669. 	}
2670. 	destroy_nhwindow(tmpwin);
2671. 	retval = TRUE;
2672.     } 
2673. #ifdef TTY_GRAPHICS
2674.       else if (!strcmp("msg_window", optname)) {
2675. 	/* by Christian W. Cooper */
2676. 	menu_item *window_pick = (menu_item *)0;
2677. 	tmpwin = create_nhwindow(NHW_MENU);
2678. 	start_menu(tmpwin);
2679. 	any.a_char = 's';
2680. 	add_menu(tmpwin, NO_GLYPH, &any, 's', 0,
2681. 		ATR_NONE, "single", MENU_UNSELECTED);
2682. 	any.a_char = 'c';
2683. 	add_menu(tmpwin, NO_GLYPH, &any, 'c', 0,
2684. 		ATR_NONE, "combination", MENU_UNSELECTED);
2685. 	any.a_char = 'f';
2686. 	add_menu(tmpwin, NO_GLYPH, &any, 'f', 0,
2687. 		ATR_NONE, "full", MENU_UNSELECTED);
2688. 	any.a_char = 'r';
2689. 	add_menu(tmpwin, NO_GLYPH, &any, 'r', 0,
2690. 		ATR_NONE, "reversed", MENU_UNSELECTED);
2691. 	end_menu(tmpwin, "Select message history display type:");
2692. 	if (select_menu(tmpwin, PICK_ONE, &window_pick) > 0) {
2693. 		iflags.prevmsg_window = window_pick->item.a_char;
2694. 		free((genericptr_t)window_pick);
2695. 	}
2696. 	destroy_nhwindow(tmpwin);
2697.         retval = TRUE;
2698.     }
2699. #endif
2700.      else if (!strcmp("align_message", optname) ||
2701. 		!strcmp("align_status", optname)) {
2702. 	menu_item *window_pick = (menu_item *)0;
2703. 	char abuf[BUFSZ];
2704. 	boolean msg = (*(optname+6) == 'm');
2705. 
2706. 	tmpwin = create_nhwindow(NHW_MENU);
2707. 	start_menu(tmpwin);
2708. 	any.a_int = ALIGN_TOP;
2709. 	add_menu(tmpwin, NO_GLYPH, &any, 't', 0,
2710. 		ATR_NONE, "top", MENU_UNSELECTED);
2711. 	any.a_int = ALIGN_BOTTOM;
2712. 	add_menu(tmpwin, NO_GLYPH, &any, 'b', 0,
2713. 		ATR_NONE, "bottom", MENU_UNSELECTED);
2714. 	any.a_int = ALIGN_LEFT;
2715. 	add_menu(tmpwin, NO_GLYPH, &any, 'l', 0,
2716. 		ATR_NONE, "left", MENU_UNSELECTED);
2717. 	any.a_int = ALIGN_RIGHT;
2718. 	add_menu(tmpwin, NO_GLYPH, &any, 'r', 0,
2719. 		ATR_NONE, "right", MENU_UNSELECTED);
2720. 	Sprintf(abuf, "Select %s window placement relative to the map:",
2721. 		msg ? "message" : "status");
2722. 	end_menu(tmpwin, abuf);
2723. 	if (select_menu(tmpwin, PICK_ONE, &window_pick) > 0) {		
2724. 		if (msg) iflags.wc_align_message = window_pick->item.a_int;
2725. 		else iflags.wc_align_status = window_pick->item.a_int;
2726. 		free((genericptr_t)window_pick);
2727. 	}
2728. 	destroy_nhwindow(tmpwin);
2729.         retval = TRUE;
2730.     } else if (!strcmp("number_pad", optname)) {
2731. 	static const char *npchoices[3] =
2732. 		{"0 (off)", "1 (on)", "2 (on, DOS compatible)"};
2733. 	const char *npletters = "abc";
2734. 	menu_item *mode_pick = (menu_item *)0;
2735. 
2736. 	tmpwin = create_nhwindow(NHW_MENU);
2737. 	start_menu(tmpwin);
2738. 	for (i = 0; i < SIZE(npchoices); i++) {
2739. 		any.a_int = i + 1;
2740. 		add_menu(tmpwin, NO_GLYPH, &any, npletters[i], 0,
2741. 			 ATR_NONE, npchoices[i], MENU_UNSELECTED);
2742.         }
2743. 	end_menu(tmpwin, "Select number_pad mode:");
2744. 	if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) {
2745. 		int mode = mode_pick->item.a_int - 1;
2746. 		switch(mode) {
2747. 			case 2:
2748. 				iflags.num_pad = 1;
2749. 				iflags.num_pad_mode = 1;
2750. 				break;
2751. 			case 1:
2752. 				iflags.num_pad = 1;
2753. 				iflags.num_pad_mode = 0;
2754. 				break;
2755. 			case 0:
2756. 			default:
2757. 				iflags.num_pad = 0;
2758. 				iflags.num_pad_mode = 0;
2759. 		}
2760. 		free((genericptr_t)mode_pick);
2761.         }
2762. 	destroy_nhwindow(tmpwin);
2763.         retval = TRUE;
2764.     } else if (!strcmp("menu_headings", optname)) {
2765. 	static const char *mhchoices[3] = {"bold", "inverse", "underline"};
2766. 	const char *npletters = "biu";
2767. 	menu_item *mode_pick = (menu_item *)0;
2768. 
2769. 	tmpwin = create_nhwindow(NHW_MENU);
2770. 	start_menu(tmpwin);
2771. 	for (i = 0; i < SIZE(mhchoices); i++) {
2772. 		any.a_int = i + 1;
2773. 		add_menu(tmpwin, NO_GLYPH, &any, npletters[i], 0,
2774. 			 ATR_NONE, mhchoices[i], MENU_UNSELECTED);
2775.         }
2776. 	end_menu(tmpwin, "How to highlight menu headings:");
2777. 	if (select_menu(tmpwin, PICK_ONE, &mode_pick) > 0) {
2778. 		int mode = mode_pick->item.a_int - 1;
2779. 		switch(mode) {
2780. 			case 2:
2781. 				iflags.menu_headings = ATR_ULINE;
2782. 				break;
2783. 			case 0:
2784. 				iflags.menu_headings = ATR_BOLD;
2785. 				break;
2786. 			case 1:
2787. 			default:
2788. 				iflags.menu_headings = ATR_INVERSE;
2789. 		}
2790. 		free((genericptr_t)mode_pick);
2791.         }
2792. 	destroy_nhwindow(tmpwin);
2793.         retval = TRUE;
2794. #ifdef AUTOPICKUP_EXCEPTIONS
2795.     } else if (!strcmp("autopickup_exception", optname)) {
2796.     	boolean retval;
2797. 	int pick_cnt, pick_idx, opt_idx, pass;
2798. 	int totalapes = 0, numapes[2] = {0,0};
2799. 	menu_item *pick_list = (menu_item *)0;
2800. 	anything any;
2801. 	char apebuf[BUFSZ];
2802. 	struct autopickup_exception *ape;
2803. 	static const char *action_titles[] = {
2804. 		"a", "add new autopickup exception",
2805. 		"l", "list autopickup exceptions",
2806. 		"r", "remove existing autopickup exception",
2807. 		"e", "exit this menu",
2808. 	};
2809. ape_again:
2810. 	opt_idx = 0;
2811. 	totalapes = count_ape_maps(&numapes[AP_LEAVE], &numapes[AP_GRAB]);
2812. 	tmpwin = create_nhwindow(NHW_MENU);
2813. 	start_menu(tmpwin);
2814. 	any.a_int = 0;
2815. 	for (i = 0; i < SIZE(action_titles) ; i += 2) {
2816. 		any.a_int++;
2817. 		if (!totalapes && (i >= 2 && i < 6)) continue;
2818. 		add_menu(tmpwin, NO_GLYPH, &any, *action_titles[i],
2819. 		      0, ATR_NONE, action_titles[i+1], MENU_UNSELECTED);
2820.         }
2821. 	end_menu(tmpwin, "Do what?");
2822. 	if ((pick_cnt = select_menu(tmpwin, PICK_ONE, &pick_list)) > 0) {
2823. 		for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) {
2824. 			opt_idx = pick_list[pick_idx].item.a_int - 1;
2825. 		}
2826. 		free((genericptr_t)pick_list);
2827. 		pick_list = (menu_item *)0;
2828. 	}
2829. 	destroy_nhwindow(tmpwin);
2830. 	if (pick_cnt < 1) return FALSE;
2831. 
2832. 	if (opt_idx == 0) {	/* add new */
2833. 		getlin("What new autopickup exception pattern?", &apebuf[1]);
2834. 		if (apebuf[1] == '\033') return FALSE;
2835. 		apebuf[0] = '"';
2836. 		Strcat(apebuf,"\"");
2837. 		add_autopickup_exception(apebuf);
2838. 		goto ape_again;
2839. 	} else if (opt_idx == 3) {
2840. 		retval = TRUE;
2841. 	} else {	/* remove */
2842. 		tmpwin = create_nhwindow(NHW_MENU);
2843. 		start_menu(tmpwin);
2844. 		for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
2845. 		    if (numapes[pass] == 0) continue;
2846. 		    ape = iflags.autopickup_exceptions[pass];
2847. 		    any.a_void = 0;
2848. 		    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2849. 				(pass == 0) ? "Never pickup" : "Always pickup",
2850. 				MENU_UNSELECTED);
2851. 		    for (i = 0; i < numapes[pass] && ape; i++) {
2852. 			any.a_void = (opt_idx == 1) ? 0 : ape;
2853. 			Sprintf(apebuf, "\"%s\"", ape->pattern);
2854. 			add_menu(tmpwin, NO_GLYPH, &any,
2855. 				0, 0, ATR_NONE, apebuf, MENU_UNSELECTED);
2856. 			ape = ape->next;
2857. 		    }
2858. 		}
2859. 		Sprintf(apebuf, "%s autopickup exceptions",
2860. 			(opt_idx == 1) ? "List of" : "Remove which");
2861. 		end_menu(tmpwin, apebuf);
2862. 		pick_cnt = select_menu(tmpwin,
2863. 					(opt_idx == 1) ?  PICK_NONE : PICK_ANY,
2864. 					&pick_list);
2865. 		if (pick_cnt > 0) {
2866. 	    	    for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx)
2867. 			remove_autopickup_exception(
2868. 			 (struct autopickup_exception *)pick_list[pick_idx].item.a_void);
2869. 	        }
2870. 	        free((genericptr_t)pick_list);
2871. 	        pick_list = (menu_item *)0;
2872. 		destroy_nhwindow(tmpwin);
2873. 		goto ape_again;
2874. 	}
2875. 	retval = TRUE;
2876. #endif /* AUTOPICKUP_EXCEPTIONS */
2877.     }
2878.     return retval;
2879. }
2880. 

get_compopbt_value

2881. #define rolestring(val,array,field) ((val >= 0) ? array[val].field : \
2882. 				     (val == ROLE_RANDOM) ? randomrole : none)
2883. 
2884. /* This is ugly. We have all the option names in the compopt[] array,
2885.    but we need to look at each option individually to get the value. */
2886. STATIC_OVL const char *
2887. get_compopt_value(optname, buf)
2888. const char *optname;
2889. char *buf;
2890. {
2891. 	char ocl[MAXOCLASSES+1];
2892. 	static const char none[] = "(none)", randomrole[] = "random",
2893. 		     to_be_done[] = "(to be done)",
2894. 		     defopt[] = "default",
2895. 		     defbrief[] = "def";
2896. 	int i;
2897. 
2898. 	buf[0] = '\0';
2899. 	if (!strcmp(optname,"align_message"))
2900. 		Sprintf(buf, "%s", iflags.wc_align_message == ALIGN_TOP     ? "top" :
2901. 				   iflags.wc_align_message == ALIGN_LEFT    ? "left" :
2902. 				   iflags.wc_align_message == ALIGN_BOTTOM  ? "bottom" :
2903. 				   iflags.wc_align_message == ALIGN_RIGHT   ? "right" :
2904. 				   defopt);
2905. 	else if (!strcmp(optname,"align_status"))
2906. 		Sprintf(buf, "%s", iflags.wc_align_status == ALIGN_TOP     ? "top" :
2907. 				   iflags.wc_align_status == ALIGN_LEFT    ? "left" :
2908. 				   iflags.wc_align_status == ALIGN_BOTTOM  ? "bottom" :
2909. 				   iflags.wc_align_status == ALIGN_RIGHT   ? "right" :
2910. 				   defopt);
2911. 	else if (!strcmp(optname,"align"))
2912. 		Sprintf(buf, "%s", rolestring(flags.initalign, aligns, adj));
2913. #ifdef WIN32CON
2914. 	else if (!strcmp(optname,"altkeyhandler"))
2915. 		Sprintf(buf, "%s", iflags.altkeyhandler[0] ?
2916. 			iflags.altkeyhandler : "default");
2917. #endif
2918. 	else if (!strcmp(optname, "boulder"))
2919. 		Sprintf(buf, "%c", iflags.bouldersym ?
2920. 			iflags.bouldersym : oc_syms[(int)objects[BOULDER].oc_class]);
2921. 	else if (!strcmp(optname, "catname")) 
2922. 		Sprintf(buf, "%s", catname[0] ? catname : none );
2923. 	else if (!strcmp(optname, "disclose")) {
2924. 		for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) {
2925. 			char topt[2];
2926. 			if (i) Strcat(buf," ");
2927. 			topt[1] = '\0';
2928. 			topt[0] = flags.end_disclose[i];
2929. 			Strcat(buf, topt);
2930. 			topt[0] = disclosure_options[i];
2931. 			Strcat(buf, topt);
2932. 		}
2933. 	}
2934. 	else if (!strcmp(optname, "dogname")) 
2935. 		Sprintf(buf, "%s", dogname[0] ? dogname : none );
2936. 	else if (!strcmp(optname, "dungeon"))
2937. 		Sprintf(buf, "%s", to_be_done);
2938. 	else if (!strcmp(optname, "effects"))
2939. 		Sprintf(buf, "%s", to_be_done);
2940. 	else if (!strcmp(optname, "font_map"))
2941. 		Sprintf(buf, "%s", iflags.wc_font_map ? iflags.wc_font_map : defopt);
2942. 	else if (!strcmp(optname, "font_message"))
2943. 		Sprintf(buf, "%s", iflags.wc_font_message ? iflags.wc_font_message : defopt);
2944. 	else if (!strcmp(optname, "font_status"))
2945. 		Sprintf(buf, "%s", iflags.wc_font_status ? iflags.wc_font_status : defopt);
2946. 	else if (!strcmp(optname, "font_menu"))
2947. 		Sprintf(buf, "%s", iflags.wc_font_menu ? iflags.wc_font_menu : defopt);
2948. 	else if (!strcmp(optname, "font_text"))
2949. 		Sprintf(buf, "%s", iflags.wc_font_text ? iflags.wc_font_text : defopt);
2950. 	else if (!strcmp(optname, "font_size_map")) {
2951. 		if (iflags.wc_fontsiz_map) Sprintf(buf, "%d", iflags.wc_fontsiz_map);
2952. 		else Strcpy(buf, defopt);
2953. 	}
2954. 	else if (!strcmp(optname, "font_size_message")) {
2955. 		if (iflags.wc_fontsiz_message) Sprintf(buf, "%d",
2956. 							iflags.wc_fontsiz_message);
2957. 		else Strcpy(buf, defopt);
2958. 	}
2959. 	else if (!strcmp(optname, "font_size_status")) {
2960. 		if (iflags.wc_fontsiz_status) Sprintf(buf, "%d", iflags.wc_fontsiz_status);
2961. 		else Strcpy(buf, defopt);
2962. 	}
2963. 	else if (!strcmp(optname, "font_size_menu")) {
2964. 		if (iflags.wc_fontsiz_menu) Sprintf(buf, "%d", iflags.wc_fontsiz_menu);
2965. 		else Strcpy(buf, defopt);
2966. 	}
2967. 	else if (!strcmp(optname, "font_size_text")) {
2968. 		if (iflags.wc_fontsiz_text) Sprintf(buf, "%d",iflags.wc_fontsiz_text);
2969. 		else Strcpy(buf, defopt);
2970. 	}
2971. 	else if (!strcmp(optname, "fruit")) 
2972. 		Sprintf(buf, "%s", pl_fruit);
2973. 	else if (!strcmp(optname, "gender"))
2974. 		Sprintf(buf, "%s", rolestring(flags.initgend, genders, adj));
2975. 	else if (!strcmp(optname, "horsename")) 
2976. 		Sprintf(buf, "%s", horsename[0] ? horsename : none);
2977. 	else if (!strcmp(optname, "map_mode"))
2978. 		Sprintf(buf, "%s",
2979. 			iflags.wc_map_mode == MAP_MODE_TILES      ? "tiles" :
2980. 			iflags.wc_map_mode == MAP_MODE_ASCII4x6   ? "ascii4x6" :
2981. 			iflags.wc_map_mode == MAP_MODE_ASCII6x8   ? "ascii6x8" :
2982. 			iflags.wc_map_mode == MAP_MODE_ASCII8x8   ? "ascii8x8" :
2983. 			iflags.wc_map_mode == MAP_MODE_ASCII16x8  ? "ascii16x8" :
2984. 			iflags.wc_map_mode == MAP_MODE_ASCII7x12  ? "ascii7x12" :
2985. 			iflags.wc_map_mode == MAP_MODE_ASCII8x12  ? "ascii8x12" :
2986. 			iflags.wc_map_mode == MAP_MODE_ASCII16x12 ? "ascii16x12" :
2987. 			iflags.wc_map_mode == MAP_MODE_ASCII12x16 ? "ascii12x16" :
2988. 			iflags.wc_map_mode == MAP_MODE_ASCII10x18 ? "ascii10x18" :
2989. 			iflags.wc_map_mode == MAP_MODE_ASCII_FIT_TO_SCREEN ?
2990. 			"fit_to_screen" : defopt);
2991. 	else if (!strcmp(optname, "menustyle")) 
2992. 		Sprintf(buf, "%s", menutype[(int)flags.menu_style] );
2993. 	else if (!strcmp(optname, "menu_deselect_all"))
2994. 		Sprintf(buf, "%s", to_be_done);
2995. 	else if (!strcmp(optname, "menu_deselect_page"))
2996. 		Sprintf(buf, "%s", to_be_done);
2997. 	else if (!strcmp(optname, "menu_first_page"))
2998. 		Sprintf(buf, "%s", to_be_done);
2999. 	else if (!strcmp(optname, "menu_invert_all"))
3000. 		Sprintf(buf, "%s", to_be_done);
3001. 	else if (!strcmp(optname, "menu_headings")) {
3002. 		Sprintf(buf, "%s", (iflags.menu_headings == ATR_BOLD) ?
3003. 			"bold" :   (iflags.menu_headings == ATR_INVERSE) ?
3004. 			"inverse" :   (iflags.menu_headings == ATR_ULINE) ?
3005. 			"underline" : "unknown");
3006. 	}
3007. 	else if (!strcmp(optname, "menu_invert_page"))
3008. 		Sprintf(buf, "%s", to_be_done);
3009. 	else if (!strcmp(optname, "menu_last_page"))
3010. 		Sprintf(buf, "%s", to_be_done);
3011. 	else if (!strcmp(optname, "menu_next_page"))
3012. 		Sprintf(buf, "%s", to_be_done);
3013. 	else if (!strcmp(optname, "menu_previous_page"))
3014. 		Sprintf(buf, "%s", to_be_done);
3015. 	else if (!strcmp(optname, "menu_search"))
3016. 		Sprintf(buf, "%s", to_be_done);
3017. 	else if (!strcmp(optname, "menu_select_all"))
3018. 		Sprintf(buf, "%s", to_be_done);
3019. 	else if (!strcmp(optname, "menu_select_page"))
3020. 		Sprintf(buf, "%s", to_be_done);
3021. 	else if (!strcmp(optname, "monsters"))
3022. 		Sprintf(buf, "%s", to_be_done);
3023. 	else if (!strcmp(optname, "msghistory"))
3024. 		Sprintf(buf, "%u", iflags.msg_history);
3025. #ifdef TTY_GRAPHICS
3026. 	else if (!strcmp(optname, "msg_window"))
3027. 		Sprintf(buf, "%s", (iflags.prevmsg_window=='s') ? "single" :
3028. 					(iflags.prevmsg_window=='c') ? "combination" :
3029. 					(iflags.prevmsg_window=='f') ? "full" : "reversed");
3030. #endif
3031. 	else if (!strcmp(optname, "name"))
3032. 		Sprintf(buf, "%s", plname);
3033. 	else if (!strcmp(optname, "number_pad"))
3034. 		Sprintf(buf, "%s",
3035. 			(!iflags.num_pad) ? "0=off" :
3036. 			(iflags.num_pad_mode) ? "2=on, DOS compatible" : "1=on");
3037. 	else if (!strcmp(optname, "objects"))
3038. 		Sprintf(buf, "%s", to_be_done);
3039. 	else if (!strcmp(optname, "packorder")) {
3040. 		oc_to_str(flags.inv_order, ocl);
3041. 		Sprintf(buf, "%s", ocl);
3042. 	     }
3043. #ifdef CHANGE_COLOR
3044. 	else if (!strcmp(optname, "palette")) 
3045. 		Sprintf(buf, "%s", get_color_string());
3046. #endif
3047. 	else if (!strcmp(optname, "pettype")) 
3048. 		Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat" :
3049. 				(preferred_pet == 'd') ? "dog" :
3050. 				(preferred_pet == 'n') ? "none" : "random");
3051. 	else if (!strcmp(optname, "pickup_burden"))
3052. 		Sprintf(buf, "%s", burdentype[flags.pickup_burden] );
3053. 	else if (!strcmp(optname, "pickup_types")) {
3054. 		oc_to_str(flags.pickup_types, ocl);
3055. 		Sprintf(buf, "%s", ocl[0] ? ocl : "all" );
3056. 	     }
3057. 	else if (!strcmp(optname, "race"))
3058. 		Sprintf(buf, "%s", rolestring(flags.initrace, races, noun));
3059. 	else if (!strcmp(optname, "role"))
3060. 		Sprintf(buf, "%s", rolestring(flags.initrole, roles, name.m));
3061. 	else if (!strcmp(optname, "runmode"))
3062. 		Sprintf(buf, "%s", runmodes[iflags.runmode]);
3063. 	else if (!strcmp(optname, "scores")) {
3064. 		Sprintf(buf, "%d top/%d around%s", flags.end_top,
3065. 				flags.end_around, flags.end_own ? "/own" : "");
3066. 	}
3067. 	else if (!strcmp(optname, "scroll_amount")) {
3068. 		if (iflags.wc_scroll_amount) Sprintf(buf, "%d",iflags.wc_scroll_amount);
3069. 		else Strcpy(buf, defopt);
3070. 	}
3071. 	else if (!strcmp(optname, "scroll_margin")) {
3072. 		if (iflags.wc_scroll_margin) Sprintf(buf, "%d",iflags.wc_scroll_margin);
3073. 		else Strcpy(buf, defopt);
3074. 	}
3075. 	else if (!strcmp(optname, "player_selection"))
3076. 		Sprintf(buf, "%s", iflags.wc_player_selection ? "prompts" : "dialog");
3077. #ifdef MSDOS
3078. 	else if (!strcmp(optname, "soundcard"))
3079. 		Sprintf(buf, "%s", to_be_done);
3080. #endif
3081. 	else if (!strcmp(optname, "suppress_alert")) {
3082. 	    if (flags.suppress_alert == 0L)
3083. 		Strcpy(buf, none);
3084. 	    else
3085. 		Sprintf(buf, "%lu.%lu.%lu",
3086. 			FEATURE_NOTICE_VER_MAJ,
3087. 			FEATURE_NOTICE_VER_MIN,
3088. 			FEATURE_NOTICE_VER_PATCH);
3089. 	}
3090. 	else if (!strcmp(optname, "tile_file"))
3091. 		Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
3092. 	else if (!strcmp(optname, "tile_height")) {
3093. 		if (iflags.wc_tile_height) Sprintf(buf, "%d",iflags.wc_tile_height);
3094. 		else Strcpy(buf, defopt);
3095. 	}
3096. 	else if (!strcmp(optname, "tile_width")) {
3097. 		if (iflags.wc_tile_width) Sprintf(buf, "%d",iflags.wc_tile_width);
3098. 		else Strcpy(buf, defopt);
3099. 	}
3100. 	else if (!strcmp(optname, "traps"))
3101. 		Sprintf(buf, "%s", to_be_done);
3102. 	else if (!strcmp(optname, "vary_msgcount")) {
3103. 		if (iflags.wc_vary_msgcount) Sprintf(buf, "%d",iflags.wc_vary_msgcount);
3104. 		else Strcpy(buf, defopt);
3105. 	}
3106. #ifdef MSDOS
3107. 	else if (!strcmp(optname, "video"))
3108. 		Sprintf(buf, "%s", to_be_done);
3109. #endif
3110. #ifdef VIDEOSHADES
3111. 	else if (!strcmp(optname, "videoshades"))
3112. 		Sprintf(buf, "%s-%s-%s", shade[0],shade[1],shade[2]);
3113. 	else if (!strcmp(optname, "videocolors"))
3114. 		Sprintf(buf, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d",
3115. 			ttycolors[CLR_RED], ttycolors[CLR_GREEN],
3116. 			ttycolors[CLR_BROWN], ttycolors[CLR_BLUE],
3117. 			ttycolors[CLR_MAGENTA], ttycolors[CLR_CYAN],
3118. 			ttycolors[CLR_ORANGE], ttycolors[CLR_BRIGHT_GREEN],
3119. 			ttycolors[CLR_YELLOW], ttycolors[CLR_BRIGHT_BLUE],
3120. 			ttycolors[CLR_BRIGHT_MAGENTA],
3121. 			ttycolors[CLR_BRIGHT_CYAN]);
3122. #endif /* VIDEOSHADES */
3123. 	else if (!strcmp(optname, "windowtype"))
3124. 		Sprintf(buf, "%s", windowprocs.name);
3125. 	else if (!strcmp(optname, "windowcolors"))
3126. 		Sprintf(buf, "%s/%s %s/%s %s/%s %s/%s",
3127. 			iflags.wc_foregrnd_menu    ? iflags.wc_foregrnd_menu : defbrief,
3128. 			iflags.wc_backgrnd_menu    ? iflags.wc_backgrnd_menu : defbrief,
3129. 			iflags.wc_foregrnd_message ? iflags.wc_foregrnd_message : defbrief,
3130. 			iflags.wc_backgrnd_message ? iflags.wc_backgrnd_message : defbrief,
3131. 			iflags.wc_foregrnd_status  ? iflags.wc_foregrnd_status : defbrief,
3132. 			iflags.wc_backgrnd_status  ? iflags.wc_backgrnd_status : defbrief,
3133. 			iflags.wc_foregrnd_text    ? iflags.wc_foregrnd_text : defbrief,
3134. 			iflags.wc_backgrnd_text    ? iflags.wc_backgrnd_text : defbrief);
3135. #ifdef PREFIXES_IN_USE
3136. 	else {
3137. 	    for (i = 0; i < PREFIX_COUNT; ++i)
3138. 		if (!strcmp(optname, fqn_prefix_names[i]) && fqn_prefix[i])
3139. 			Sprintf(buf, "%s", fqn_prefix[i]);
3140. 	}
3141. #endif
3142. 
3143. 	if (buf[0]) return buf;
3144. 	else return "unknown";
3145. }
3146. 

dotogglepickup

3147. int
3148. dotogglepickup()
3149. {
3150. 	char buf[BUFSZ], ocl[MAXOCLASSES+1];
3151. 
3152. 	flags.pickup = !flags.pickup;
3153. 	if (flags.pickup) {
3154. 	    oc_to_str(flags.pickup_types, ocl);
3155. 	    Sprintf(buf, "ON, for %s objects%s", ocl[0] ? ocl : "all",
3156. #ifdef AUTOPICKUP_EXCEPTIONS
3157. 			(iflags.autopickup_exceptions[AP_LEAVE] ||
3158. 			 iflags.autopickup_exceptions[AP_GRAB]) ?
3159. 			 ((count_ape_maps((int *)0, (int *)0) == 1) ?
3160. 			    ", with one exception" : ", with some exceptions") :
3161. #endif
3162. 			"");
3163. 	} else {
3164. 	    Strcpy(buf, "OFF");
3165. 	}
3166. 	pline("Autopickup: %s.", buf);
3167. 	return 0;
3168. }
3169. 

add_autopickup_exception

3170. #ifdef AUTOPICKUP_EXCEPTIONS
3171. int
3172. add_autopickup_exception(mapping)
3173. const char *mapping;
3174. {
3175. 	struct autopickup_exception *ape, **apehead;
3176. 	char text[256], *text2;
3177. 	int textsize = 0;
3178. 	boolean grab = FALSE;
3179. 
3180. 	if (sscanf(mapping, "\"%255[^\"]\"", text) == 1) {
3181. 		text2 = &text[0];
3182. 		if (*text2 == '<') {		/* force autopickup */
3183. 			grab = TRUE;
3184. 			++text2;
3185. 		} else if (*text2 == '>') {	/* default - Do not pickup */
3186. 			grab = FALSE;
3187. 			++text2;
3188. 		}
3189. 		textsize = strlen(text2);
3190. 		apehead = (grab) ? &iflags.autopickup_exceptions[AP_GRAB] :
3191. 				   &iflags.autopickup_exceptions[AP_LEAVE];
3192. 		ape = (struct autopickup_exception *)
3193. 				alloc(sizeof(struct autopickup_exception));
3194. 		ape->pattern = (char *) alloc(textsize+1);
3195. 		Strcpy(ape->pattern, text2);
3196. 		ape->grab = grab;
3197. 		if (!*apehead) ape->next = (struct autopickup_exception *)0;
3198. 		else ape->next = *apehead;
3199. 		*apehead = ape;
3200. 	} else {
3201. 	    raw_print("syntax error in AUTOPICKUP_EXCEPTION");
3202. 	    return 0;
3203. 	}
3204. 	return 1;
3205. }
3206. 

remove_autopickuo_exception

3207. STATIC_OVL void
3208. remove_autopickup_exception(whichape)
3209. struct autopickup_exception *whichape;
3210. {
3211.     struct autopickup_exception *ape, *prev = 0;
3212.     int chain = whichape->grab ? AP_GRAB : AP_LEAVE;
3213. 
3214.     for (ape = iflags.autopickup_exceptions[chain]; ape;) {
3215. 	if (ape == whichape) {
3216. 	    struct autopickup_exception *freeape = ape;
3217. 	    ape = ape->next;
3218. 	    if (prev) prev->next = ape;
3219. 	    else iflags.autopickup_exceptions[chain] = ape;
3220. 	    free(freeape->pattern);
3221. 	    free(freeape);
3222. 	} else {
3223. 	    prev = ape;
3224. 	    ape = ape->next;
3225. 	}
3226.     }
3227. }
3228. 

count_ape_maps

3229. STATIC_OVL int
3230. count_ape_maps(leave, grab)
3231. int *leave, *grab;
3232. {
3233. 	struct autopickup_exception *ape;
3234. 	int pass, totalapes, numapes[2] = {0,0};
3235. 
3236. 	for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
3237. 		ape = iflags.autopickup_exceptions[pass];
3238. 		while(ape) {
3239. 			ape = ape->next;
3240. 			numapes[pass]++;
3241. 		}
3242. 	}
3243. 	totalapes = numapes[AP_LEAVE] + numapes[AP_GRAB];
3244. 	if (leave) *leave = numapes[AP_LEAVE];
3245. 	if (grab) *grab = numapes[AP_GRAB];
3246. 	return totalapes;
3247. }
3248. 

free_autopickup_exceptions

3249. void
3250. free_autopickup_exceptions()
3251. {
3252. 	struct autopickup_exception *ape;
3253. 	int pass;
3254. 
3255. 	for (pass = AP_LEAVE; pass <= AP_GRAB; ++pass) {
3256. 		while((ape = iflags.autopickup_exceptions[pass]) != 0) {
3257. 			free(ape->pattern);
3258. 			iflags.autopickup_exceptions[pass] = ape->next;
3259. 			free(ape);
3260. 		}
3261. 	}
3262. }
3263. #endif /* AUTOPICKUP_EXCEPTIONS */
3264. 

option_help

3265. /* data for option_help() */
3266. static const char *opt_intro[] = {
3267. 	"",
3268. 	"                 NetHack Options Help:",
3269. 	"",
3270. #define CONFIG_SLOT 3	/* fill in next value at run-time */
3271. 	(char *)0,
3272. #if !defined(MICRO) && !defined(MAC)
3273. 	"or use `NETHACKOPTIONS=\"<options>\"' in your environment",
3274. #endif
3275. 	"(<options> is a list of options separated by commas)",
3276. #ifdef VMS
3277. 	"-- for example, $ DEFINE NETHACKOPTIONS \"noautopickup,fruit:kumquat\"",
3278. #endif
3279. 	"or press \"O\" while playing and use the menu.",
3280. 	"",
3281.  "Boolean options (which can be negated by prefixing them with '!' or \"no\"):",
3282. 	(char *)0
3283. };
3284. 
3285. static const char *opt_epilog[] = {
3286. 	"",
3287.  "Some of the options can be set only before the game is started; those",
3288. 	"items will not be selectable in the 'O' command's menu.",
3289. 	(char *)0
3290. };
3291. 
3292. void
3293. option_help()
3294. {
3295.     char buf[BUFSZ], buf2[BUFSZ];
3296.     register int i;
3297.     winid datawin;
3298. 
3299.     datawin = create_nhwindow(NHW_TEXT);
3300.     Sprintf(buf, "Set options as OPTIONS=<options> in %s", configfile);
3301.     opt_intro[CONFIG_SLOT] = (const char *) buf;
3302.     for (i = 0; opt_intro[i]; i++)
3303. 	putstr(datawin, 0, opt_intro[i]);
3304. 
3305.     /* Boolean options */
3306.     for (i = 0; boolopt[i].name; i++) {
3307. 	if (boolopt[i].addr) {
3308. #ifdef WIZARD
3309. 	    if (boolopt[i].addr == &iflags.sanity_check && !wizard) continue;
3310. 	    if (boolopt[i].addr == &iflags.menu_tab_sep && !wizard) continue;
3311. #endif
3312. 	    next_opt(datawin, boolopt[i].name);
3313. 	}
3314.     }
3315.     next_opt(datawin, "");
3316. 
3317.     /* Compound options */
3318.     putstr(datawin, 0, "Compound options:");
3319.     for (i = 0; compopt[i].name; i++) {
3320. 	Sprintf(buf2, "`%s'", compopt[i].name);
3321. 	Sprintf(buf, "%-20s - %s%c", buf2, compopt[i].descr,
3322. 		compopt[i+1].name ? ',' : '.');
3323. 	putstr(datawin, 0, buf);
3324.     }
3325. 
3326.     for (i = 0; opt_epilog[i]; i++)
3327. 	putstr(datawin, 0, opt_epilog[i]);
3328. 
3329.     display_nhwindow(datawin, FALSE);
3330.     destroy_nhwindow(datawin);
3331.     return;
3332. }
3333. 

next_opt

3334. /*
3335.  * prints the next boolean option, on the same line if possible, on a new
3336.  * line if not. End with next_opt("").
3337.  */
3338. void
3339. next_opt(datawin, str)
3340. winid datawin;
3341. const char *str;
3342. {
3343. 	static char *buf = 0;
3344. 	int i;
3345. 	char *s;
3346. 
3347. 	if (!buf) *(buf = (char *)alloc(BUFSZ)) = '\0';
3348. 
3349. 	if (!*str) {
3350. 		s = eos(buf);
3351. 		if (s > &buf[1] && s[-2] == ',')
3352. 		    Strcpy(s - 2, ".");	/* replace last ", " */
3353. 		i = COLNO;	/* (greater than COLNO - 2) */
3354. 	} else {
3355. 		i = strlen(buf) + strlen(str) + 2;
3356. 	}
3357. 
3358. 	if (i > COLNO - 2) { /* rule of thumb */
3359. 		putstr(datawin, 0, buf);
3360. 		buf[0] = 0;
3361. 	}
3362. 	if (*str) {
3363. 		Strcat(buf, str);
3364. 		Strcat(buf, ", ");
3365. 	} else {
3366. 		putstr(datawin, 0, str);
3367. 		free(buf),  buf = 0;
3368. 	}
3369. 	return;
3370. }
3371. 

fruitadd

3372. /* Returns the fid of the fruit type; if that type already exists, it
3373.  * returns the fid of that one; if it does not exist, it adds a new fruit
3374.  * type to the chain and returns the new one.
3375.  */
3376. int
3377. fruitadd(str)
3378. char *str;
3379. {
3380. 	register int i;
3381. 	register struct fruit *f;
3382. 	struct fruit *lastf = 0;
3383. 	int highest_fruit_id = 0;
3384. 	char buf[PL_FSIZ];
3385. 	boolean user_specified = (str == pl_fruit);
3386. 	/* if not user-specified, then it's a fruit name for a fruit on
3387. 	 * a bones level...
3388. 	 */
3389. 
3390. 	/* Note: every fruit has an id (spe for fruit objects) of at least
3391. 	 * 1; 0 is an error.
3392. 	 */
3393. 	if (user_specified) {
3394. 		/* disallow naming after other foods (since it'd be impossible
3395. 		 * to tell the difference)
3396. 		 */
3397. 
3398. 		boolean found = FALSE, numeric = FALSE;
3399. 
3400. 		for (i = bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS;
3401. 						i++) {
3402. 			if (!strcmp(OBJ_NAME(objects[i]), pl_fruit)) {
3403. 				found = TRUE;
3404. 				break;
3405. 			}
3406. 		}
3407. 		{
3408. 		    char *c;
3409. 
3410. 		    c = pl_fruit;
3411. 
3412. 		    for(c = pl_fruit; *c >= '0' && *c <= '9'; c++)
3413. 			;
3414. 		    if (isspace(*c) || *c == 0) numeric = TRUE;
3415. 		}
3416. 		if (found || numeric ||
3417. 		    !strncmp(str, "cursed ", 7) ||
3418. 		    !strncmp(str, "uncursed ", 9) ||
3419. 		    !strncmp(str, "blessed ", 8) ||
3420. 		    !strncmp(str, "partly eaten ", 13) ||
3421. 		    (!strncmp(str, "tin of ", 7) &&
3422. 			(!strcmp(str+7, "spinach") ||
3423. 			 name_to_mon(str+7) >= LOW_PM)) ||
3424. 		    !strcmp(str, "empty tin") ||
3425. 		    ((!strncmp(eos(str)-7," corpse",7) ||
3426. 			    !strncmp(eos(str)-4, " egg",4)) &&
3427. 			name_to_mon(str) >= LOW_PM))
3428. 			{
3429. 				Strcpy(buf, pl_fruit);
3430. 				Strcpy(pl_fruit, "candied ");
3431. 				nmcpy(pl_fruit+8, buf, PL_FSIZ-8);
3432. 		}
3433. 	}
3434. 	for(f=ffruit; f; f = f->nextf) {
3435. 		lastf = f;
3436. 		if(f->fid > highest_fruit_id) highest_fruit_id = f->fid;
3437. 		if(!strncmp(str, f->fname, PL_FSIZ))
3438. 			goto nonew;
3439. 	}
3440. 	/* if adding another fruit would overflow spe, use a random
3441. 	   fruit instead... we've got a lot to choose from. */
3442. 	if (highest_fruit_id >= 127) return rnd(127);
3443. 	highest_fruit_id++;
3444. 	f = newfruit();
3445. 	if (ffruit) lastf->nextf = f;
3446. 	else ffruit = f;
3447. 	Strcpy(f->fname, str);
3448. 	f->fid = highest_fruit_id;
3449. 	f->nextf = 0;
3450. nonew:
3451. 	if (user_specified) current_fruit = highest_fruit_id;
3452. 	return f->fid;
3453. }
3454. 

choose_classes_menu

3455. /*
3456.  * This is a somewhat generic menu for taking a list of NetHack style
3457.  * class choices and presenting them via a description
3458.  * rather than the traditional NetHack characters.
3459.  * (Benefits users whose first exposure to NetHack is via tiles).
3460.  *
3461.  * prompt
3462.  *	     The title at the top of the menu.
3463.  *
3464.  * category: 0 = monster class
3465.  *           1 = object  class
3466.  *
3467.  * way
3468.  *	     FALSE = PICK_ONE, TRUE = PICK_ANY
3469.  *
3470.  * class_list
3471.  *	     a null terminated string containing the list of choices.
3472.  *
3473.  * class_selection
3474.  *	     a null terminated string containing the selected characters.
3475.  *
3476.  * Returns number selected.
3477.  */
3478. int
3479. choose_classes_menu(prompt, category, way, class_list, class_select)
3480. const char *prompt;
3481. int category;
3482. boolean way;
3483. char *class_list;
3484. char *class_select;
3485. {
3486.     menu_item *pick_list = (menu_item *)0;
3487.     winid win;
3488.     anything any;
3489.     char buf[BUFSZ];
3490.     int i, n;
3491.     int ret;
3492.     int next_accelerator, accelerator;
3493. 
3494.     if (class_list == (char *)0 || class_select == (char *)0) return 0;
3495.     accelerator = 0;
3496.     next_accelerator = 'a';
3497.     any.a_void = 0;
3498.     win = create_nhwindow(NHW_MENU);
3499.     start_menu(win);
3500.     while (*class_list) {
3501. 	const char *text;
3502. 	boolean selected;
3503. 
3504. 	text = (char *)0;
3505. 	selected = FALSE;
3506. 	switch (category) {
3507. 		case 0:
3508. 			text = monexplain[def_char_to_monclass(*class_list)];
3509. 			accelerator = *class_list;
3510. 			Sprintf(buf, "%s", text);
3511. 			break;
3512. 		case 1:
3513. 			text = objexplain[def_char_to_objclass(*class_list)];
3514. 			accelerator = next_accelerator;
3515. 			Sprintf(buf, "%c  %s", *class_list, text);
3516. 			break;
3517. 		default:
3518. 			impossible("choose_classes_menu: invalid category %d",
3519. 					category);
3520. 	}
3521. 	if (way && *class_select) {	/* Selections there already */
3522. 		if (index(class_select, *class_list)) {
3523. 			selected = TRUE;
3524. 		}
3525. 	}
3526. 	any.a_int = *class_list;
3527. 	add_menu(win, NO_GLYPH, &any, accelerator,
3528. 		  category ? *class_list : 0,
3529. 		  ATR_NONE, buf, selected);
3530. 	++class_list;
3531. 	if (category > 0) {
3532. 		++next_accelerator;
3533. 		if (next_accelerator == ('z' + 1)) next_accelerator = 'A';
3534. 		if (next_accelerator == ('Z' + 1)) break;
3535. 	}
3536.     }
3537.     end_menu(win, prompt);
3538.     n = select_menu(win, way ? PICK_ANY : PICK_ONE, &pick_list);
3539.     destroy_nhwindow(win);
3540.     if (n > 0) {
3541. 	for (i = 0; i < n; ++i)
3542. 	    *class_select++ = (char)pick_list[i].item.a_int;
3543. 	free((genericptr_t)pick_list);
3544. 	ret = n;
3545.     } else if (n == -1) {
3546. 	class_select = eos(class_select);
3547. 	ret = -1;
3548.     } else
3549. 	ret = 0;
3550.     *class_select = '\0';
3551.     return ret;
3552. }
3553. 
3554. struct wc_Opt wc_options[] = {
3555. 	{"ascii_map", WC_ASCII_MAP},
3556. 	{"color", WC_COLOR},
3557. 	{"eight_bit_tty", WC_EIGHT_BIT_IN},
3558. 	{"hilite_pet", WC_HILITE_PET},
3559. 	{"popup_dialog", WC_POPUP_DIALOG},
3560. 	{"player_selection", WC_PLAYER_SELECTION},
3561. 	{"preload_tiles", WC_PRELOAD_TILES},
3562. 	{"tiled_map", WC_TILED_MAP},
3563. 	{"tile_file", WC_TILE_FILE},
3564. 	{"tile_width", WC_TILE_WIDTH},
3565. 	{"tile_height", WC_TILE_HEIGHT},
3566. 	{"use_inverse", WC_INVERSE},
3567. 	{"align_message", WC_ALIGN_MESSAGE},
3568. 	{"align_status", WC_ALIGN_STATUS},
3569. 	{"font_map", WC_FONT_MAP},
3570. 	{"font_menu", WC_FONT_MENU},
3571. 	{"font_message",WC_FONT_MESSAGE},
3572. #if 0
3573. 	{"perm_invent",WC_PERM_INVENT},
3574. #endif
3575. 	{"font_size_map", WC_FONTSIZ_MAP},
3576. 	{"font_size_menu", WC_FONTSIZ_MENU},
3577. 	{"font_size_message", WC_FONTSIZ_MESSAGE},
3578. 	{"font_size_status", WC_FONTSIZ_STATUS},
3579. 	{"font_size_text", WC_FONTSIZ_TEXT},
3580. 	{"font_status", WC_FONT_STATUS},
3581. 	{"font_text", WC_FONT_TEXT},
3582. 	{"map_mode", WC_MAP_MODE},
3583. 	{"scroll_amount", WC_SCROLL_AMOUNT},
3584. 	{"scroll_margin", WC_SCROLL_MARGIN},
3585. 	{"splash_screen", WC_SPLASH_SCREEN},
3586. 	{"vary_msgcount",WC_VARY_MSGCOUNT},
3587. 	{"windowcolors", WC_WINDOWCOLORS},
3588. 	{"mouse_support", WC_MOUSE_SUPPORT},
3589. 	{(char *)0, 0L}
3590. };
3591. 
3592. struct wc_Opt wc2_options[] = {
3593. 	{"fullscreen", WC2_FULLSCREEN},
3594. 	{"softkeyboard", WC2_SOFTKEYBOARD},
3595. 	{"wraptext", WC2_WRAPTEXT},
3596. 	{(char *)0, 0L}
3597. };
3598. 
3599. 

set_option_mod_status

3600. /*
3601.  * If a port wants to change or ensure that the
3602.  * SET_IN_FILE, DISP_IN_GAME, or SET_IN_GAME status of an option is
3603.  * correct (for controlling its display in the option menu) call
3604.  * set_option_mod_status()
3605.  * with the second argument of 0,2, or 3 respectively.
3606.  */
3607. void
3608. set_option_mod_status(optnam, status)
3609. const char *optnam;
3610. int status;
3611. {
3612. 	int k;
3613. 	if (status < SET_IN_FILE || status > SET_IN_GAME) {
3614. 		impossible("set_option_mod_status: status out of range %d.",
3615. 			   status);
3616. 		return;
3617. 	}
3618. 	for (k = 0; boolopt[k].name; k++) {
3619. 		if (!strncmpi(boolopt[k].name, optnam, strlen(optnam))) {
3620. 			boolopt[k].optflags = status;
3621. 			return;
3622. 		}
3623. 	}
3624. 	for (k = 0; compopt[k].name; k++) {
3625. 		if (!strncmpi(compopt[k].name, optnam, strlen(optnam))) {
3626. 			compopt[k].optflags = status;
3627. 			return;
3628. 		}
3629. 	}
3630. }
3631. 

set_wc_option_mod_status

3632. /*
3633.  * You can set several wc_options in one call to
3634.  * set_wc_option_mod_status() by setting
3635.  * the appropriate bits for each option that you
3636.  * are setting in the optmask argument
3637.  * prior to calling.
3638.  *    example: set_wc_option_mod_status(WC_COLOR|WC_SCROLL_MARGIN, SET_IN_GAME);
3639.  */
3640. void
3641. set_wc_option_mod_status(optmask, status)
3642. unsigned long optmask;
3643. int status;
3644. {
3645. 	int k = 0;
3646. 	if (status < SET_IN_FILE || status > SET_IN_GAME) {
3647. 		impossible("set_wc_option_mod_status: status out of range %d.",
3648. 			   status);
3649. 		return;
3650. 	}
3651. 	while (wc_options[k].wc_name) {
3652. 		if (optmask & wc_options[k].wc_bit) {
3653. 			set_option_mod_status(wc_options[k].wc_name, status);
3654. 		}
3655. 		k++;
3656. 	}
3657. }
3658. 

is_wc_option

3659. STATIC_OVL boolean
3660. is_wc_option(optnam)
3661. const char *optnam;
3662. {
3663. 	int k = 0;
3664. 	while (wc_options[k].wc_name) {
3665. 		if (strcmp(wc_options[k].wc_name, optnam) == 0)
3666. 			return TRUE;
3667. 		k++;
3668. 	}
3669. 	return FALSE;
3670. }
3671. 

wc_supported

3672. STATIC_OVL boolean
3673. wc_supported(optnam)
3674. const char *optnam;
3675. {
3676. 	int k = 0;
3677. 	while (wc_options[k].wc_name) {
3678. 		if (!strcmp(wc_options[k].wc_name, optnam) &&
3679. 		    (windowprocs.wincap & wc_options[k].wc_bit))
3680. 			return TRUE;
3681. 		k++;
3682. 	}
3683. 	return FALSE;
3684. }
3685. 
3686. 

set_wc2_option_mod_status

3687. /*
3688.  * You can set several wc2_options in one call to
3689.  * set_wc2_option_mod_status() by setting
3690.  * the appropriate bits for each option that you
3691.  * are setting in the optmask argument
3692.  * prior to calling.
3693.  *    example: set_wc2_option_mod_status(WC2_FULLSCREEN|WC2_SOFTKEYBOARD|WC2_WRAPTEXT, SET_IN_FILE);
3694.  */
3695. 
3696. void
3697. set_wc2_option_mod_status(optmask, status)
3698. unsigned long optmask;
3699. int status;
3700. {
3701. 	int k = 0;
3702. 	if (status < SET_IN_FILE || status > SET_IN_GAME) {
3703. 		impossible("set_wc2_option_mod_status: status out of range %d.",
3704. 			   status);
3705. 		return;
3706. 	}
3707. 	while (wc2_options[k].wc_name) {
3708. 		if (optmask & wc2_options[k].wc_bit) {
3709. 			set_option_mod_status(wc2_options[k].wc_name, status);
3710. 		}
3711. 		k++;
3712. 	}
3713. }
3714. 

is_wc2_option

3715. STATIC_OVL boolean
3716. is_wc2_option(optnam)
3717. const char *optnam;
3718. {
3719. 	int k = 0;
3720. 	while (wc2_options[k].wc_name) {
3721. 		if (strcmp(wc2_options[k].wc_name, optnam) == 0)
3722. 			return TRUE;
3723. 		k++;
3724. 	}
3725. 	return FALSE;
3726. }
3727. 

wc2_supported

3728. STATIC_OVL boolean
3729. wc2_supported(optnam)
3730. const char *optnam;
3731. {
3732. 	int k = 0;
3733. 	while (wc2_options[k].wc_name) {
3734. 		if (!strcmp(wc2_options[k].wc_name, optnam) &&
3735. 		    (windowprocs.wincap2 & wc2_options[k].wc_bit))
3736. 			return TRUE;
3737. 		k++;
3738. 	}
3739. 	return FALSE;
3740. }
3741. 
3742. 

wc_set_font_name

3743. STATIC_OVL void
3744. wc_set_font_name(wtype, fontname)
3745. int wtype;
3746. char *fontname;
3747. {
3748. 	char **fn = (char **)0;
3749. 	if (!fontname) return;
3750. 	switch(wtype) {
3751. 	    case NHW_MAP:
3752. 	    		fn = &iflags.wc_font_map;
3753. 			break;
3754. 	    case NHW_MESSAGE:
3755. 	    		fn = &iflags.wc_font_message;
3756. 			break;
3757. 	    case NHW_TEXT:
3758. 	    		fn = &iflags.wc_font_text;
3759. 			break;
3760. 	    case NHW_MENU:
3761. 	    		fn = &iflags.wc_font_menu;
3762. 			break;
3763. 	    case NHW_STATUS:
3764. 	    		fn = &iflags.wc_font_status;
3765. 			break;
3766. 	    default:
3767. 	    		return;
3768. 	}
3769. 	if (fn) {
3770. 		if (*fn) free(*fn);
3771. 		*fn = (char *)alloc(strlen(fontname) + 1);
3772. 		Strcpy(*fn, fontname);
3773. 	}
3774. 	return;
3775. }
3776. 

wc_set_window_colors

3777. STATIC_OVL int
3778. wc_set_window_colors(op)
3779. char *op;
3780. {
3781. 	/* syntax:
3782. 	 *  menu white/black message green/yellow status white/blue text white/black
3783. 	 */
3784. 
3785. 	int j;
3786. 	char buf[BUFSZ];
3787. 	char *wn, *tfg, *tbg, *newop;
3788. 	static const char *wnames[] = { "menu", "message", "status", "text" };
3789. 	static const char *shortnames[] = { "mnu", "msg", "sts", "txt" };
3790. 	static char **fgp[] = {
3791. 		&iflags.wc_foregrnd_menu,
3792. 		&iflags.wc_foregrnd_message,
3793. 		&iflags.wc_foregrnd_status,
3794. 		&iflags.wc_foregrnd_text
3795. 	};
3796. 	static char **bgp[] = {
3797. 		&iflags.wc_backgrnd_menu,
3798. 		&iflags.wc_backgrnd_message,
3799. 		&iflags.wc_backgrnd_status,
3800. 		&iflags.wc_backgrnd_text
3801. 	};
3802. 
3803. 	Strcpy(buf, op);
3804. 	newop = mungspaces(buf);
3805. 	while (newop && *newop) {
3806. 
3807. 		wn = tfg = tbg = (char *)0;
3808. 
3809. 		/* until first non-space in case there's leading spaces - before colorname*/
3810. 		while(*newop && isspace(*newop)) newop++;
3811. 		if (*newop) wn = newop;
3812. 		else return 0;
3813. 
3814. 		/* until first space - colorname*/
3815. 		while(*newop && !isspace(*newop)) newop++;
3816. 		if (*newop) *newop = '\0';
3817. 		else return 0;
3818. 		newop++;
3819. 
3820. 		/* until first non-space - before foreground*/
3821. 		while(*newop && isspace(*newop)) newop++;
3822. 		if (*newop) tfg = newop;
3823. 		else return 0;
3824. 
3825. 		/* until slash - foreground */
3826. 		while(*newop && *newop != '/') newop++;
3827. 		if (*newop) *newop = '\0';
3828. 		else return 0;
3829. 		newop++;
3830. 
3831. 		/* until first non-space (in case there's leading space after slash) - before background */
3832. 		while(*newop && isspace(*newop)) newop++;
3833. 		if (*newop) tbg = newop;
3834. 		else return 0;
3835. 
3836. 		/* until first space - background */
3837. 		while(*newop && !isspace(*newop)) newop++;
3838. 		if (*newop) *newop++ = '\0';
3839. 
3840. 		for (j = 0; j < 4; ++j) {
3841. 			if (!strcmpi(wn, wnames[j]) ||
3842. 			    !strcmpi(wn, shortnames[j])) {
3843. 				if (tfg && !strstri(tfg, " ")) {
3844. 					if (*fgp[j]) free(*fgp[j]);
3845. 					*fgp[j] = (char *)alloc(strlen(tfg) + 1);
3846. 					Strcpy(*fgp[j], tfg);
3847. 				}
3848. 				if (tbg && !strstri(tbg, " ")) {
3849. 					if (*bgp[j]) free(*bgp[j]);
3850. 					*bgp[j] = (char *)alloc(strlen(tbg) + 1);
3851. 					Strcpy(*bgp[j], tbg);
3852. 				}
3853.  				break;
3854. 			}
3855. 		}
3856. 	}
3857. 	return 1;
3858. }
3859. 
3860. #endif	/* OPTION_LISTS_ONLY */
3861. 
3862. /*options.c*/