Wikia

Wikihack

Source:Options.c

2,032pages on
this wiki
Talk0

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 Edit

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.
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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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 Edit

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*/

Around Wikia's network

Random Wiki