Source:NetHack 3.4.0/options.c

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

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)options.c	3.4	2002/02/07	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     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  16. #endif 17.   18.   #define WINTYPELEN 16 19.   20.   /*  21.    *  NOTE:  If you add (or delete) an option, please update the short 22.   *  options help (option_help), the long options help (dat/opthelp), 23.   *  and the current options setting display function (doset), 24.   *  and also the Guidebooks. 25.   *  26.    *  The order matters. If an option is a an initial substring of another 27.   *  option (e.g. time and timed_delay) the shorter one must come first. 28.   */  29.    30.   static struct Bool_Opt 31.  {  32.   	const char *name; 33.  	boolean	*addr, initvalue; 34.  	int optflags; 35.  } boolopt[] = { 36.  #ifdef AMIGA 37.  	{"altmeta", &flags.altmeta, TRUE, DISP_IN_GAME}, 38.  #else 39.  	{"altmeta", (boolean *)0, TRUE, DISP_IN_GAME}, 40.  #endif 41.  	{"ascii_map",     &iflags.wc_ascii_map, TRUE, SET_IN_GAME},	/*WC*/ 42.  #ifdef MFLOPPY 43.  	{"asksavedisk", &flags.asksavedisk, FALSE, SET_IN_GAME}, 44.  #else 45.  	{"asksavedisk", (boolean *)0, FALSE, SET_IN_FILE}, 46.  #endif 47.  	{"autodig", &flags.autodig, FALSE, SET_IN_GAME}, 48.  	{"autopickup", &flags.pickup, TRUE, SET_IN_GAME}, 49.  	{"autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME}, 50.  #if defined(MICRO) && !defined(AMIGA) 51.  	{"BIOS", &iflags.BIOS, FALSE, SET_IN_FILE}, 52.  #else 53.  	{"BIOS", (boolean *)0, FALSE, SET_IN_FILE}, 54.  #endif 55.  #ifdef INSURANCE 56.  	{"checkpoint", &flags.ins_chkpt, TRUE, SET_IN_GAME}, 57.  #else 58.  	{"checkpoint", (boolean *)0, FALSE, SET_IN_FILE}, 59.  #endif 60.  #ifdef MFLOPPY 61.  	{"checkspace", &iflags.checkspace, TRUE, SET_IN_GAME}, 62.  #else 63.  	{"checkspace", (boolean *)0, FALSE, SET_IN_FILE}, 64.  #endif 65.  # ifdef MICRO 66.  	{"color",         &iflags.wc_color,TRUE, SET_IN_GAME},		/*WC*/ 67.  # else	/* systems that support multiple terminals, many monochrome */ 68.  	{"color",         &iflags.wc_color, FALSE, SET_IN_GAME},	/*WC*/ 69.  # endif 70.  	{"confirm",&flags.confirm, TRUE, SET_IN_GAME}, 71.  #if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV) 72.  	{"DECgraphics", &iflags.DECgraphics, FALSE, SET_IN_GAME}, 73.  #else 74.  	{"DECgraphics", (boolean *)0, FALSE, SET_IN_FILE}, 75.  #endif 76.  	{"eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME},	/*WC*/ 77.  #ifdef TTY_GRAPHICS 78.  	{"extmenu", &iflags.extmenu, FALSE, SET_IN_GAME}, 79.  #else 80.  	{"extmenu", (boolean *)0, FALSE, SET_IN_FILE}, 81.  #endif 82.  #ifdef OPT_DISPMAP 83.  	{"fast_map", &flags.fast_map, TRUE, SET_IN_GAME}, 84.  #else 85.  	{"fast_map", (boolean *)0, TRUE, SET_IN_FILE}, 86.  #endif 87.  	{"female", &flags.female, FALSE, DISP_IN_GAME}, 88.  	{"fixinv", &flags.invlet_constant, TRUE, SET_IN_GAME}, 89.  #ifdef AMIFLUSH 90.  	{"flush", &flags.amiflush, FALSE, SET_IN_GAME}, 91.  #else 92.  	{"flush", (boolean *)0, FALSE, SET_IN_FILE}, 93.  #endif 94.  	{"help", &flags.help, TRUE, SET_IN_GAME}, 95.  	{"hilite_pet",    &iflags.wc_hilite_pet, FALSE, SET_IN_GAME},	/*WC*/ 96.  #ifdef ASCIIGRAPH 97.  	{"IBMgraphics", &iflags.IBMgraphics, FALSE, SET_IN_GAME}, 98.  #else 99.  	{"IBMgraphics", (boolean *)0, FALSE, SET_IN_FILE}, 100. #endif 101. #ifndef MAC 102. 	{"ignintr", &flags.ignintr, FALSE, SET_IN_GAME}, 103. #else 104. 	{"ignintr", (boolean *)0, FALSE, SET_IN_FILE}, 105. #endif 106. 	{"large_font", &iflags.wc_large_font, FALSE, SET_IN_FILE},	/*WC*/ 107. 	{"legacy", &flags.legacy, TRUE, DISP_IN_GAME}, 108. 	{"lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME}, 109. #ifdef MAC_GRAPHICS_ENV 110. 	{"Macgraphics", &iflags.MACgraphics, TRUE, SET_IN_GAME}, 111. #else 112. 	{"Macgraphics", (boolean *)0, FALSE, SET_IN_FILE}, 113. #endif 114. #ifdef MAIL 115. 	{"mail", &flags.biff, TRUE, SET_IN_GAME}, 116. #else 117. 	{"mail", (boolean *)0, TRUE, SET_IN_FILE}, 118. #endif 119. #ifdef WIZARD 120. 	/* for menu debugging only*/ 121. 	{"menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_GAME}, 122. #else 123. 	{"menu_tab_sep", (boolean *)0, FALSE, SET_IN_FILE}, 124. #endif 125. #ifdef TTY_GRAPHICS 126. 	{"msg_window", &iflags.prevmsg_window, FALSE, SET_IN_GAME}, 127. #else 128. 	{"msg_window", (boolean *)0, FALSE, SET_IN_FILE}, 129. #endif 130. #ifdef NEWS 131. 	{"news", &iflags.news, TRUE, DISP_IN_GAME}, 132. #else 133. 	{"news", (boolean *)0, FALSE, SET_IN_FILE}, 134. #endif 135. 	{"null", &flags.null, TRUE, SET_IN_GAME}, 136. 	{"number_pad", &iflags.num_pad, FALSE, SET_IN_GAME}, 137. #ifdef MAC 138. 	{"page_wait", &flags.page_wait, TRUE, SET_IN_GAME}, 139. #else 140. 	{"page_wait", (boolean *)0, FALSE, SET_IN_FILE}, 141. #endif 142. 	{"perm_invent", &flags.perm_invent, FALSE, SET_IN_GAME}, 143. 	{"popup_dialog",  &iflags.wc_popup_dialog, FALSE, SET_IN_GAME},	/*WC*/ 144. 	{"prayconfirm", &flags.prayconfirm, TRUE, SET_IN_GAME}, 145. 	{"preload_tiles", &iflags.wc_preload_tiles, TRUE, DISP_IN_GAME},	/*WC*/ 146. 	{"pushweapon", &flags.pushweapon, FALSE, SET_IN_GAME}, 147. #if defined(MICRO) && !defined(AMIGA) && !defined(MSWIN_GRAPHICS) 148. 	{"rawio", &iflags.rawio, FALSE, DISP_IN_GAME}, 149. #else 150. 	{"rawio", (boolean *)0, FALSE, SET_IN_FILE}, 151. #endif 152. 	{"rest_on_space", &flags.rest_on_space, FALSE, SET_IN_GAME}, 153. 	{"safe_pet", &flags.safe_dog, TRUE, SET_IN_GAME}, 154. #ifdef WIZARD 155. 	{"sanity_check", &iflags.sanity_check, FALSE, SET_IN_GAME}, 156. #else 157. 	{"sanity_check", (boolean *)0, FALSE, SET_IN_FILE}, 158. #endif 159. #ifdef EXP_ON_BOTL 160. 	{"showexp", &flags.showexp, FALSE, SET_IN_GAME}, 161. #else 162. 	{"showexp", (boolean *)0, FALSE, SET_IN_FILE}, 163. #endif 164. #ifdef SCORE_ON_BOTL 165. 	{"showscore", &flags.showscore, FALSE, SET_IN_GAME}, 166. #else 167. 	{"showscore", (boolean *)0, FALSE, SET_IN_FILE}, 168. #endif 169. 	{"silent", &flags.silent, TRUE, SET_IN_GAME}, 170. 	{"sortpack", &flags.sortpack, TRUE, SET_IN_GAME}, 171. 	{"sound", &flags.soundok, TRUE, SET_IN_GAME}, 172. 	{"sparkle", &flags.sparkle, TRUE, SET_IN_GAME}, 173. 	{"standout", &flags.standout, FALSE, SET_IN_GAME}, 174. 	{"splash_screen",     &iflags.wc_splash_screen, TRUE, DISP_IN_GAME},	/*WC*/ 175. 	{"tiled_map",     &iflags.wc_tiled_map, FALSE, DISP_IN_GAME},	/*WC*/ 176. 	{"time", &flags.time, FALSE, SET_IN_GAME}, 177. #ifdef TIMED_DELAY 178. 	{"timed_delay", &flags.nap, TRUE, SET_IN_GAME}, 179. #else 180. 	{"timed_delay", (boolean *)0, FALSE, SET_IN_GAME}, 181. #endif 182. 	{"tombstone",&flags.tombstone, TRUE, SET_IN_GAME}, 183. 	{"toptenwin",&flags.toptenwin, FALSE, SET_IN_GAME}, 184. 	{"use_inverse",   &iflags.wc_inverse, FALSE, SET_IN_GAME},		/*WC*/ 185. 	{"verbose", &flags.verbose, TRUE, SET_IN_GAME}, 186. 	{(char *)0, (boolean *)0, FALSE, 0} 187. };  188.   189.  /* compound options, for option_help and external programs like Amiga 190.  * frontend */ 191. static struct Comp_Opt 192. {  193.  	const char *name, *descr; 194. 	int size;	/* for frontends and such allocating space -- 195. 			 * usually allowed size of data in game, but 196. 			 * occasionally maximum reasonable size for 197. 			 * typing when game maintains information in  198. * a different format */ 199. 	int optflags; 200. } compopt[] = { 201. 	{ "align",    "your starting alignment (lawful, neutral, or chaotic)", 202. 						8, DISP_IN_GAME }, 203. 	{ "align_message", "message window alignment", 20, DISP_IN_GAME }, 	/*WC*/ 204. 	{ "align_status", "status window alignment", 20, DISP_IN_GAME }, 	/*WC*/ 205. #ifdef MAC 206. 	{ "background", "the color of the background (black or white)", 207. 						6, SET_IN_FILE }, 208. #endif 209. 	{ "boulder",  "the symbol to use for displaying boulders", 210. 						1, SET_IN_GAME }, 211. 	{ "catname",  "the name of your (first) cat (e.g., catname:Tabby)", 212. 						PL_PSIZ, DISP_IN_GAME }, 213. 	{ "disclose", "the kinds of information to disclose at end of game", 214. 						sizeof(flags.end_disclose) * 2, 215. 						SET_IN_GAME }, 216. 	{ "dogname",  "the name of your (first) dog (e.g., dogname:Fang)", 217. 						PL_PSIZ, DISP_IN_GAME }, 218. 	{ "dungeon",  "the symbols to use in drawing the dungeon map", 219. 						MAXDCHARS+1, SET_IN_FILE }, 220. 	{ "effects",  "the symbols to use in drawing special effects", 221. 						MAXECHARS+1, SET_IN_FILE }, 222. 	{ "font_map", "the font to use in the map window", 40, DISP_IN_GAME },	/*WC*/ 223. 	{ "font_menu", "the font to use in menus", 40, DISP_IN_GAME },		/*WC*/ 224. 	{ "font_message", "the font to use in the message window", 225. 						40, DISP_IN_GAME },		/*WC*/ 226. 	{ "font_size_map", "the size of the map font", 20, DISP_IN_GAME },	/*WC*/ 227. 	{ "font_size_menu", "the size of the map font", 20, DISP_IN_GAME },	/*WC*/ 228. 	{ "font_size_message", "the size of the map font", 20, DISP_IN_GAME },	/*WC*/ 229. 	{ "font_size_status", "the size of the map font", 20, DISP_IN_GAME },	/*WC*/ 230. 	{ "font_size_text", "the size of the map font", 20, DISP_IN_GAME },	/*WC*/ 231. 	{ "font_status", "the font to use in status window", 40, DISP_IN_GAME }, /*WC*/ 232. 	{ "font_text", "the font to use in text windows", 40, DISP_IN_GAME },	/*WC*/ 233. 	{ "fruit",    "the name of a fruit you enjoy eating", 234. 						PL_FSIZ, SET_IN_GAME }, 235. 	{ "gender",   "your starting gender (male or female)", 236. 						8, DISP_IN_GAME }, 237. 	{ "horsename", "the name of your (first) horse (e.g., horsename:Silver)", 238. 						PL_PSIZ, DISP_IN_GAME }, 239. 	{ "map_mode", "map display mode under Windows", 20, DISP_IN_GAME },	/*WC*/ 240. 	{ "menustyle", "user interface for object selection", 241. 						MENUTYPELEN, SET_IN_GAME }, 242. 	{ "menu_deselect_all", "deselect all items in a menu", 4, SET_IN_FILE }, 243. 	{ "menu_deselect_page", "deselect all items on this page of a menu", 244. 						4, SET_IN_FILE }, 245. 	{ "menu_first_page", "jump to the first page in a menu", 246. 						4, SET_IN_FILE }, 247. 	{ "menu_invert_all", "invert all items in a menu", 4, SET_IN_FILE }, 248. 	{ "menu_invert_page", "invert all items on this page of a menu", 249. 						4, SET_IN_FILE }, 250. 	{ "menu_last_page", "jump to the last page in a menu", 4, SET_IN_FILE }, 251. 	{ "menu_next_page", "goto the next menu page", 4, SET_IN_FILE }, 252. 	{ "menu_previous_page", "goto the previous menu page", 4, SET_IN_FILE }, 253. 	{ "menu_search", "search for a menu item", 4, SET_IN_FILE }, 254. 	{ "menu_select_all", "select all items in a menu", 4, SET_IN_FILE }, 255. 	{ "menu_select_page", "select all items on this page of a menu", 256. 						4, SET_IN_FILE }, 257. 	{ "monsters", "the symbols to use for monsters", 258. 						MAXMCLASSES, SET_IN_FILE }, 259. 	{ "msghistory", "number of top line messages to save", 260. 						5, DISP_IN_GAME }, 261. 	{ "name",     "your character's name (e.g., name:Merlin-W)", 262. 						PL_NSIZ, DISP_IN_GAME }, 263. 	{ "objects",  "the symbols to use for objects", 264. 						MAXOCLASSES, SET_IN_FILE }, 265. 	{ "packorder", "the inventory order of the items in your pack", 266. 						MAXOCLASSES, SET_IN_GAME }, 267. #ifdef CHANGE_COLOR 268. 	{ "palette",  "palette (00c/880/-fff is blue/yellow/reverse white)", 269. 						15, SET_IN_GAME }, 270. # if defined(MAC) 271. 	{ "hicolor",  "same as palette, only order is reversed", 272. 						15, SET_IN_FILE }, 273. # endif 274. #endif 275. 	{ "pettype",  "your preferred initial pet type", 4, DISP_IN_GAME }, 276. 	{ "pickup_burden",  "maximum burden picked up before prompt", 277. 						20, SET_IN_GAME }, 278. 	{ "pickup_types", "types of objects to pick up automatically", 279. 						MAXOCLASSES, SET_IN_GAME }, 280. 	{ "player_selection", "choose character via dialog or prompts", 281. 						12, DISP_IN_GAME }, 282. 	{ "race",     "your starting race (e.g., Human, Elf)", 283. 						PL_CSIZ, DISP_IN_GAME }, 284. 	{ "role",     "your starting role (e.g., Barbarian, Valkyrie)", 285. 						PL_CSIZ, DISP_IN_GAME }, 286. 	{ "scores",   "the parts of the score list you wish to see", 287. 						32, SET_IN_GAME }, 288. 	{ "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME }, /*WC*/ 289. #ifdef MSDOS 290. 	{ "soundcard", "type of sound card to use", 20, SET_IN_FILE }, 291. #endif 292. 	{ "suppress_alert", "suppress alerts about version-specific features", 293. 						8, SET_IN_GAME }, 294. 	{ "tile_width", "width of tiles", 20, DISP_IN_GAME},	/*WC*/ 295. 	{ "tile_height", "height of tiles", 20, DISP_IN_GAME},	/*WC*/ 296. 	{ "tile_file", "name of tile file", 70, DISP_IN_GAME},	/*WC*/ 297. 	{ "traps",    "the symbols to use in drawing traps", 298. 						MAXTCHARS+1, SET_IN_FILE }, 299. #ifdef MAC 300. 	{"use_stone", "use stone background patterns", 8, SET_IN_FILE }, 301. #endif 302. 	{ "vary_msgcount", "show more old messages at a time", 20, DISP_IN_GAME }, /*WC*/ 303. #ifdef MSDOS 304. 	{ "video",    "method of video updating", 20, SET_IN_FILE }, 305. #endif 306. #ifdef VIDEOSHADES 307. 	{ "videocolors", "color mappings for internal screen routines", 308. 						40, DISP_IN_GAME }, 309. 	{ "videoshades", "gray shades to map to black/gray/white", 310. 						32, DISP_IN_GAME }, 311. #endif 312. 	{ "windowcolors",  "the foreground/background colors of windows",	/*WC*/ 313. 						80, DISP_IN_GAME }, 314. 	{ "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, 315. 	{ (char *)0, (char *)0, 0, 0 } 316. };  317.   318.  #ifdef OPTION_LISTS_ONLY 319. #undef static 320.  321.  #else	/* use rest of file */ 322.  323.  static boolean need_redraw; /* for doset */ 324.  325.  #if defined(TOS) && defined(TEXTCOLOR) 326. extern boolean colors_changed;	/* in tos.c */ 327. #endif 328.  329.  #ifdef VIDEOSHADES 330. extern char *shade[3];		  /* in sys/msdos/video.c */ 331. extern char ttycolors[CLR_MAX];	  /* in sys/msdos/video.c */ 332. #endif 333.  334.  static char def_inv_order[MAXOCLASSES] = { 335. 	GOLD_CLASS, AMULET_CLASS, WEAPON_CLASS, ARMOR_CLASS, FOOD_CLASS, 336. 	SCROLL_CLASS, SPBOOK_CLASS, POTION_CLASS, RING_CLASS, WAND_CLASS, 337. 	TOOL_CLASS, GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0, 338. };  339.   340.  /*  341.   * Default menu manipulation command accelerators. These may _not_ be: 342.  *  343.   *	+ a number - reserved for counts 344.  *	+ an upper or lower case US ASCII letter - used for accelerators 345.  *	+ ESC - reserved for escaping the menu 346.  *	+ NULL, CR or LF - reserved for commiting the selection(s). NULL 347.  *	  is kind of odd, but the tty's xwaitforspace will return it if  348. *	 someone hits a. 349.  *	+ a default object class symbol - used for object class accelerators 350.  *  351.   * Standard letters (for now) are: 352.  *  353.   *		<  back 1 page 354.  *		>  forward 1 page 355.  *		^  first page 356.  *		|  last page 357.  *		:  search 358.  *  359.   *		page		all 360.  *		,    select	. 361.  *		 \    deselect	 - 362.  *		 ~    invert	 @ 363.  *  364.   * The command name list is duplicated in the compopt array. 365.  */  366.  typedef struct { 367.     const char *name; 368.     char cmd; 369. } menu_cmd_t; 370.  371.  #define NUM_MENU_CMDS 11 372. static const menu_cmd_t default_menu_cmd_info[NUM_MENU_CMDS] = { 373. /* 0*/	{ "menu_first_page",	MENU_FIRST_PAGE }, 374. 	{ "menu_last_page",	MENU_LAST_PAGE }, 375. 	{ "menu_next_page",	MENU_NEXT_PAGE }, 376. 	{ "menu_previous_page",	MENU_PREVIOUS_PAGE }, 377. 	{ "menu_select_all",	MENU_SELECT_ALL }, 378. /* 5*/	{ "menu_deselect_all",	MENU_UNSELECT_ALL }, 379. 	{ "menu_invert_all",	MENU_INVERT_ALL }, 380. 	{ "menu_select_page",	MENU_SELECT_PAGE }, 381. 	{ "menu_deselect_page",	MENU_UNSELECT_PAGE }, 382. 	{ "menu_invert_page",	MENU_INVERT_PAGE }, 383. /*10*/	{ "menu_search",		MENU_SEARCH }, 384. };  385.   386.  /*  387.   * Allow the user to map incoming characters to various menu commands. 388.  * The accelerator list must be a valid C string. 389.  */  390.  #define MAX_MENU_MAPPED_CMDS 32	/* some number */ 391.        char mapped_menu_cmds[MAX_MENU_MAPPED_CMDS+1];	/* exported */ 392. static char mapped_menu_op[MAX_MENU_MAPPED_CMDS+1]; 393. static short n_menu_mapped = 0; 394.  395.   396.  static boolean initial, from_file; 397.  398.  STATIC_DCL void FDECL(doset_add_menu, (winid,const char *,int)); 399. STATIC_DCL void FDECL(nmcpy, (char *, const char *, int)); 400. STATIC_DCL void FDECL(escapes, (const char *, char *)); 401. STATIC_DCL void FDECL(rejectoption, (const char *)); 402. STATIC_DCL void FDECL(badoption, (const char *)); 403. STATIC_DCL char *FDECL(string_for_opt, (char *,BOOLEAN_P)); 404. STATIC_DCL char *FDECL(string_for_env_opt, (const char *, char *,BOOLEAN_P)); 405. STATIC_DCL void FDECL(bad_negation, (const char *,BOOLEAN_P)); 406. STATIC_DCL int FDECL(change_inv_order, (char *)); 407. STATIC_DCL void FDECL(oc_to_str, (char *, char *)); 408. STATIC_DCL void FDECL(graphics_opts, (char *,const char *,int,int)); 409. STATIC_DCL int FDECL(feature_alert_opts, (char *, const char *)); 410. STATIC_DCL const char *FDECL(get_compopt_value, (const char *, char *)); 411. STATIC_DCL boolean FDECL(special_handling, (const char *, BOOLEAN_P, BOOLEAN_P)); 412. STATIC_DCL void FDECL(warning_opts, (char *,const char *)); 413. STATIC_DCL void FDECL(duplicate_opt_detection, (const char *, int)); 414.  415.  STATIC_OVL void FDECL(wc_set_font_name, (int, char *)); 416. STATIC_OVL int FDECL(wc_set_window_colors, (char *)); 417. STATIC_OVL boolean FDECL(is_wc_option, (const char *)); 418. STATIC_OVL boolean FDECL(wc_supported, (const char *)); 419.  420.  /* check whether a user-supplied option string is a proper leading 421.    substring of a particular option name; option string might have 422.    a colon or equals sign and arbitrary value appended to it */ 423. boolean 424. match_optname(user_string, opt_name, min_length, val_allowed) 425. const char *user_string, *opt_name; 426. int min_length; 427. boolean val_allowed; 428. {  429.  	int len = (int)strlen(user_string); 430.  431.  	if (val_allowed) { 432. 	    const char *p = index(user_string, ':'), 433. 		       *q = index(user_string, '='); 434.  435.  	    if (!p || (q && q < p)) p = q;  436. while(p && p > user_string && isspace(*(p-1))) p--; 437. 	    if (p) len = (int)(p - user_string); 438. 	}  439.   440.  	return (len >= min_length) && !strncmpi(opt_name, user_string, len); 441. }  442.   443.  /* most environment variables will eventually be printed in an error 444.  * message if they don't work, and most error message paths go through 445.  * BUFSZ buffers, which could be overflowed by a maliciously long 446.  * environment variable. if a variable can legitimately be long, or 447. * if it's put in a smaller buffer, the responsible code will have to 448. * bounds-check itself. 449.  */  450.  char * 451. nh_getenv(ev) 452. const char *ev; 453. {  454.  	char *getev = getenv(ev); 455.  456.  	if (getev && strlen(getev) <= (BUFSZ / 2)) 457. 		return getev; 458. 	else 459. 		return (char *)0; 460. }  461.   462.  void 463. initoptions 464. {  465.  	char *opts; 466. 	int i;  467. 468. 	/* initialize the random number generator */ 469. 	setrandom; 470.  471.  	/* for detection of configfile options specified multiple times */ 472. 	iflags.opt_booldup = iflags.opt_compdup = (int *)0; 473. 	  474.  	for (i = 0; boolopt[i].name; i++) { 475. 		if (boolopt[i].addr) 476. 			*(boolopt[i].addr) = boolopt[i].initvalue; 477. 	}  478.  	flags.end_own = FALSE; 479. 	flags.end_top = 3; 480. 	flags.end_around = 2; 481. 	iflags.msg_history = 20; 482.  483.  	/* Use negative indices to indicate not yet selected */ 484. 	flags.initrole = -1; 485. 	flags.initrace = -1; 486. 	flags.initgend = -1; 487. 	flags.initalign = -1; 488.  489.  	/* Set the default monster and object class symbols. Don't use */ 490. 	/* memcpy --- sizeof char != sizeof uchar on some machines. */ 491.  	for (i = 0; i < MAXOCLASSES; i++) 492. 		oc_syms[i] = (uchar) def_oc_syms[i]; 493. 	for (i = 0; i < MAXMCLASSES; i++) 494. 		monsyms[i] = (uchar) def_monsyms[i]; 495. 	for (i = 0; i < WARNCOUNT; i++) 496. 		warnsyms[i] = def_warnsyms[i].sym; 497. 	iflags.bouldersym = 0; 498. 	flags.warnlevel = 1; 499. 	flags.warntype = 0L; 500.  501.       /* assert( sizeof flags.inv_order == sizeof def_inv_order ); */ 502. 	(void)memcpy((genericptr_t)flags.inv_order,  503.  		     (genericptr_t)def_inv_order, sizeof flags.inv_order); 504. 	flags.pickup_types[0] = '\0'; 505. 	flags.pickup_burden = MOD_ENCUMBER; 506.  507.  	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) 508. 		flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO; 509. 	switch_graphics(ASCII_GRAPHICS);	/* set default characters */ 510. #if defined(UNIX) && defined(TTY_GRAPHICS) 511. 	/*  512.  	 * Set defaults for some options depending on what we can 513. 	 * detect about the environment's capabilities. 514. 	 * This has to be done after the global initialization above 515. 	 * and before reading user-specific initialization via 516. 	 * config file/environment variable below. 517. 	 */  518.  	/* this detects the IBM-compatible console on most 386 boxes */ 519. 	if (!strncmp(nh_getenv("TERM"), "AT", 2)) { 520. 		switch_graphics(IBM_GRAPHICS); 521. # ifdef TEXTCOLOR 522. 		iflags.use_color = TRUE; 523. # endif 524. 	}  525.  #endif /* UNIX && TTY_GRAPHICS */ 526. #if defined(UNIX) || defined(VMS) 527. # ifdef TTY_GRAPHICS 528. 	/* detect whether a "vt" terminal can handle alternate charsets */ 529. 	if (!strncmpi(nh_getenv("TERM"), "vt", 2) && (AS && AE) &&  530.  	    index(AS, '\016') && index(AE, '\017')) { 531. 		switch_graphics(DEC_GRAPHICS); 532. 	}  533.  # endif 534. #endif /* UNIX || VMS */ 535.  536.  #ifdef MAC_GRAPHICS_ENV 537. 	switch_graphics(MAC_GRAPHICS); 538. #endif /* MAC_GRAPHICS_ENV */ 539. 	flags.menu_style = MENU_FULL; 540.  541.  	/* since this is done before init_objects, do partial init here */ 542. 	objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD; 543. 	nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ); 544. #ifndef MAC 545. 	opts = getenv("NETHACKOPTIONS"); 546. 	if (!opts) opts = getenv("HACKOPTIONS"); 547. 	if (opts) { 548. 		if (*opts == '/' || *opts == '\\' || *opts == '@') { 549. 			if (*opts == '@') opts++;	/* @filename */ 550. 			/* looks like a filename */ 551. 			if (strlen(opts) < BUFSZ/2) 552. 			    read_config_file(opts); 553. 		} else { 554. 			read_config_file((char *)0); 555. 			/* let the total length of options be long; 556. 			 * parseoptions will check each individually 557. 			 */  558.  			parseoptions(opts, TRUE, FALSE); 559. 		}  560.  	} else 561. #endif 562. 		read_config_file((char *)0); 563.  564.  	(void)fruitadd(pl_fruit); 565. 	/* Remove "slime mold" from list of object names; this will	*/ 566. 	/* prevent it from being wished unless it's actually present	*/ 567. 	/* as a named (or default) fruit. Wishing for "fruit" will	*/ 568. 	/* result in the player's preferred fruit [better than "\033"]. */ 569.  	obj_descr[SLIME_MOLD].oc_name = "fruit"; 570.  571.  	return; 572. }  573.   574.  STATIC_OVL void 575. nmcpy(dest, src, maxlen) 576. 	char	*dest; 577. 	const char *src; 578. 	int	maxlen; 579. {  580.  	int	count; 581.  582.  	for(count = 1; count < maxlen; count++) { 583. 		if(*src == ',' || *src == '\0') break; /*exit on \0 terminator*/ 584. 		*dest++ = *src++; 585. 	}  586.  	*dest = 0; 587. }  588.   589.  /*  590.   * escapes: escape expansion for showsyms. C-style escapes understood include 591.  * \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal). The ^-prefix 592.  * for control characters is also understood, and \[mM] followed by any of the 593.  * previous forms or by a character has the effect of 'meta'-ing the value (so  594.   * that the alternate character set will be enabled). 595.  */  596.  STATIC_OVL void 597. escapes(cp, tp) 598. const char	*cp; 599. char *tp; 600. {  601.      while (*cp) 602.     {  603.  	int	cval = 0, meta = 0; 604.  605.  	if (*cp == '\\' && index("mM", cp[1])) { 606. 		meta = 1; 607. 		cp += 2; 608. 	}  609.  	if (*cp == '\\' && index("0123456789xXoO", cp[1])) 610. 	{  611.  	    const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF"; 612. 	    int dcount = 0; 613.  614.  	    cp++; 615. 	    if (*cp == 'x' || *cp == 'X') 616. 		for (++cp; (dp = index(hex, *cp)) && (dcount++ < 2); cp++) 617. 		    cval = (cval * 16) + (dp - hex) / 2; 618. 	    else if (*cp == 'o' || *cp == 'O') 619. 		for (++cp; (index("01234567",*cp)) && (dcount++ < 3); cp++) 620. 		    cval = (cval * 8) + (*cp - '0'); 621. 	    else 622. 		for ((index("0123456789",*cp)) && (dcount++ < 3); cp++) 623. 		    cval = (cval * 10) + (*cp - '0'); 624. 	}  625.  	else if (*cp == '\\')		/* C-style character escapes */ 626. 	{  627.  	    switch (*++cp) 628. 	    {  629.  	    case '\\': cval = '\\'; break; 630. 	    case 'n': cval = '\n'; break; 631. 	    case 't': cval = '\t'; break; 632. 	    case 'b': cval = '\b'; break; 633. 	    case 'r': cval = '\r'; break; 634. 	    default: cval = *cp; 635. 	    }  636.  	    cp++; 637. 	}  638.  	else if (*cp == '^')		/* expand control-character syntax */ 639. 	{  640.  	    cval = (*++cp & 0x1f); 641. 	    cp++; 642. 	}  643.  	else 644. 	    cval = *cp++; 645. 	if (meta) 646. 	    cval |= 0x80; 647. 	*tp++ = cval; 648.     }  649.      *tp = '\0'; 650. }  651.   652.  STATIC_OVL void 653. rejectoption(optname) 654. const char *optname; 655. {  656.  #ifdef MICRO 657. 	pline("\"%s\" settable only from %s.", optname, configfile); 658. #else 659. 	pline("%s can be set only from NETHACKOPTIONS or %s.", optname,  660.  			configfile); 661. #endif 662. }  663.   664.  STATIC_OVL void 665. badoption(opts) 666. const char *opts; 667. {  668.  	if (!initial) { 669. 	    if (!strncmp(opts, "h", 1) || !strncmp(opts, "?", 1)) 670. 		option_help; 671. 	    else 672. 		pline("Bad syntax: %s.  Enter \"?g\" for help.", opts); 673. 	    return; 674. 	}  675.  #ifdef MAC 676. 	else return; 677. #endif 678.  679.  	if(from_file) 680. 	    raw_printf("Bad syntax in OPTIONS in %s: %s.", configfile, opts); 681. 	else 682. 	    raw_printf("Bad syntax in NETHACKOPTIONS: %s.", opts); 683.  684.  	wait_synch; 685. }  686.   687.  STATIC_OVL char * 688. string_for_opt(opts, val_optional) 689. char *opts; 690. boolean val_optional; 691. {  692.  	char *colon, *equals; 693.  694.  	colon = index(opts, ':'); 695. 	equals = index(opts, '='); 696. 	if (!colon || (equals && equals < colon)) colon = equals; 697.  698.  	if (!colon || !*++colon) { 699. 		if (!val_optional) badoption(opts); 700. 		return (char *)0; 701. 	}  702.  	return colon; 703. }  704.   705.  STATIC_OVL char * 706. string_for_env_opt(optname, opts, val_optional) 707. const char *optname; 708. char *opts; 709. boolean val_optional; 710. {  711.  	if(!initial) { 712. 		rejectoption(optname); 713. 		return (char *)0; 714. 	}  715.  	return string_for_opt(opts, val_optional); 716. }  717.   718.  STATIC_OVL void 719. bad_negation(optname, with_parameter) 720. const char *optname; 721. boolean with_parameter; 722. {  723.  	pline_The("%s option may not %sbe negated.",  724.  		optname,  725.  		with_parameter ? "both have a value and " : ""); 726. }  727.   728.  /*  729.   * Change the inventory order, using the given string as the new order. 730.  * Missing characters in the new order are filled in at the end from 731.  * the current inv_order, except for gold, which is forced to be first 732.  * if not explicitly present. 733.  *  734.   * This routine returns 1 unless there is a duplicate or bad char in  735. * the string. 736.  */  737.  STATIC_OVL int 738. change_inv_order(op) 739. char *op; 740. {  741.      int oc_sym, num; 742.     char *sp, buf[BUFSZ]; 743.  744.      num = 0; 745. #ifndef GOLDOBJ 746.     if (!index(op, GOLD_SYM)) 747. 	buf[num++] = GOLD_CLASS; 748. #else 749.     /*  !!!! probably unnecessary with gold as normal inventory */ 750. #endif 751.  752.      for (sp = op; *sp; sp++) { 753. 	oc_sym = def_char_to_objclass(*sp); 754. 	/* reject bad or duplicate entries */ 755. 	if (oc_sym == MAXOCLASSES ||  756.  		oc_sym == RANDOM_CLASS || oc_sym == ILLOBJ_CLASS ||  757.  		!index(flags.inv_order, oc_sym) || index(sp+1, *sp)) 758. 	    return 0; 759. 	/* retain good ones */ 760. 	buf[num++] = (char) oc_sym; 761.     }  762.      buf[num] = '\0'; 763.  764.      /* fill in any omitted classes, using previous ordering */ 765.     for (sp = flags.inv_order; *sp; sp++) 766. 	if (!index(buf, *sp)) { 767. 	    buf[num++] = *sp; 768. 	    buf[num] = '\0';	/* explicitly terminate for next index */ 769. 	}  770.   771.      Strcpy(flags.inv_order, buf); 772.     return 1; 773. }  774.   775.  STATIC_OVL void 776. graphics_opts(opts, optype, maxlen, offset) 777. register char *opts; 778. const char *optype; 779. int maxlen, offset; 780. {  781.  	uchar translate[MAXPCHARS+1]; 782. 	int length, i;  783. 784. 	if (!(opts = string_for_env_opt(optype, opts, FALSE))) 785. 		return; 786. 	escapes(opts, opts); 787.  788.  	length = strlen(opts); 789. 	if (length > maxlen) length = maxlen; 790. 	/* match the form obtained from PC configuration files */ 791. 	for (i = 0; i < length; i++) 792. 		translate[i] = (uchar) opts[i]; 793. 	assign_graphics(translate, length, maxlen, offset); 794. }  795.   796.  STATIC_OVL void 797. warning_opts(opts, optype) 798. register char *opts; 799. const char *optype; 800. {  801.  	uchar translate[MAXPCHARS+1]; 802. 	int length, i;  803. 804. 	if (!(opts = string_for_env_opt(optype, opts, FALSE))) 805. 		return; 806. 	escapes(opts, opts); 807.  808.  	length = strlen(opts); 809. 	if (length > WARNCOUNT) length = WARNCOUNT; 810. 	/* match the form obtained from PC configuration files */ 811. 	for (i = 0; i < length; i++) 812. 	     translate[i] = (((i < WARNCOUNT) && opts[i]) ?  813.  			   (uchar) opts[i] : def_warnsyms[i].sym); 814. 	assign_warnings(translate); 815. }  816.   817.  void 818. assign_warnings(graph_chars) 819. register uchar *graph_chars; 820. {  821.  	int i;  822. for (i = 0; i < WARNCOUNT; i++) 823. 	    warnsyms[i] = graph_chars[i]; 824. }  825.   826.  STATIC_OVL int 827. feature_alert_opts(op, optn) 828. char *op; 829. const char *optn; 830. {  831.  	char buf[BUFSZ]; 832. 	boolean rejectver = FALSE; 833. 	unsigned long fnv = get_feature_notice_ver(op);		/* version.c */ 834. 	if (fnv == 0L) return 0; 835. 	if (fnv > get_current_feature_ver) 836. 		rejectver = TRUE; 837. 	else 838. 		flags.suppress_alert = fnv; 839. 	if (rejectver) { 840. 		if (!initial) 841. 			You_cant("disable new feature alerts for future versions."); 842. 		else { 843. 			Sprintf(buf,  844.  				"\n%s=%s Invalid reference to a future version ignored",  845.  				optn, op); 846. 			badoption(buf); 847. 		}  848.  		return 0; 849. 	}  850.  	if (!initial) { 851. 		Sprintf(buf, "%lu.%lu.%lu", FEATURE_NOTICE_VER_MAJ,  852.  			FEATURE_NOTICE_VER_MIN, FEATURE_NOTICE_VER_PATCH); 853. 		pline("Feature change alerts disabled for NetHack %s features and prior.",  854.  			buf); 855. 	}  856.  	return 1; 857. }  858.   859.  void 860. set_duplicate_opt_detection(on_or_off) 861. int on_or_off; 862. {  863.  	int k, *optptr; 864. 	if (on_or_off != 0) { 865. 		/*-- ON --*/ 866. 		if (iflags.opt_booldup) 867. 			impossible("iflags.opt_booldup already on (memory leak)"); 868. 		iflags.opt_booldup = (int *)alloc(SIZE(boolopt) * sizeof(int)); 869. 		optptr = iflags.opt_booldup; 870. 		for (k = 0; k < SIZE(boolopt); ++k) 871. 			*optptr++ = 0; 872. 			  873.  		if (iflags.opt_compdup) 874. 			impossible("iflags.opt_compdup already on (memory leak)"); 875. 		iflags.opt_compdup = (int *)alloc(SIZE(compopt) * sizeof(int)); 876. 		optptr = iflags.opt_compdup; 877. 		for (k = 0; k < SIZE(compopt); ++k) 878. 			*optptr++ = 0; 879. 	} else { 880. 		/*-- OFF --*/ 881. 		if (iflags.opt_booldup) free((genericptr_t) iflags.opt_booldup); 882. 		iflags.opt_booldup = (int *)0; 883. 		if (iflags.opt_compdup) free((genericptr_t) iflags.opt_compdup); 884. 		iflags.opt_compdup = (int *)0; 885. 	}  886.  }  887.   888.  STATIC_OVL void 889. duplicate_opt_detection(opts, bool_or_comp) 890. const char *opts; 891. int bool_or_comp;	/* 0 == boolean option, 1 == compound */ 892. {  893.  	int i, *optptr; 894. #if defined(MAC) 895. 	/* the Mac has trouble dealing with the output of messages while 896. 	 * processing the config file. That should get fixed one day. 897. 	 * For now just return. 898. 	 */  899.  	return; 900. #endif 901. 	if ((bool_or_comp == 0) && iflags.opt_booldup && initial && from_file) { 902. 	    for (i = 0; boolopt[i].name; i++) { 903. 		if (match_optname(opts, boolopt[i].name, 3, FALSE)) { 904. 			optptr = iflags.opt_booldup + i;  905. if (*optptr == 1) { 906. 			    raw_printf(  907.  				"\nWarning - Boolean option specified multiple times: %s.\n",  908.  					opts); 909. 			        wait_synch; 910. 			}  911.  			*optptr += 1; 912. 			break; /* don't match multiple options */ 913. 		}  914.  	    }  915.  	} else if ((bool_or_comp == 1) && iflags.opt_compdup && initial && from_file) { 916. 	    for (i = 0; compopt[i].name; i++) { 917. 		if (match_optname(opts, compopt[i].name, strlen(compopt[i].name), TRUE)) { 918. 			optptr = iflags.opt_compdup + i;  919. if (*optptr == 1) { 920. 			    raw_printf(  921.  				"\nWarning - compound option specified multiple times: %s.\n",  922.  					compopt[i].name); 923. 			        wait_synch; 924. 			}  925.  			*optptr += 1; 926. 			break; /* don't match multiple options */ 927. 		}  928.  	    }  929.  	}  930.  }  931.   932.  void 933. parseoptions(opts, tinitial, tfrom_file) 934. register char *opts; 935. boolean tinitial, tfrom_file; 936. {  937.  	register char *op; 938. 	unsigned num; 939. 	boolean negated; 940. 	int i;  941. const char *fullname; 942.  943.  	initial = tinitial; 944. 	from_file = tfrom_file; 945. 	if ((op = index(opts, ',')) != 0) { 946. 		*op++ = 0; 947. 		parseoptions(op, initial, from_file); 948. 	}  949.  	if (strlen(opts) > BUFSZ/2) { 950. 		badoption("option too long"); 951. 		return; 952. 	}  953.   954.  	/* strip leading and trailing white space */ 955. 	while (isspace(*opts)) opts++; 956. 	op = eos(opts); 957. 	while (--op >= opts && isspace(*op)) *op = '\0'; 958.  959.  	if (!*opts) return; 960. 	negated = FALSE; 961. 	while ((*opts == '!') || !strncmpi(opts, "no", 2)) { 962. 		if (*opts == '!') opts++; else opts += 2; 963. 		negated = !negated; 964. 	}  965.   966.  	/* variant spelling */ 967.  968.  	if (match_optname(opts, "colour", 5, FALSE)) 969. 		Strcpy(opts, "color");	/* fortunately this isn't longer */ 970.  971.  	duplicate_opt_detection(opts, 1);	/* 1 means compound opts */ 972.  973.  	/* special boolean options */ 974.  975.  	if (match_optname(opts, "female", 3, FALSE)) { 976. 		if(!initial && flags.female == negated) 977. 			pline("That is not anatomically possible."); 978. 		else 979. 			flags.initgend = flags.female = !negated; 980. 		return; 981. 	}  982.   983.  	if (match_optname(opts, "male", 4, FALSE)) { 984. 		if(!initial && flags.female != negated) 985. 			pline("That is not anatomically possible."); 986. 		else 987. 			flags.initgend = flags.female = negated; 988. 		return; 989. 	}  990.   991.  #if defined(MICRO) && !defined(AMIGA) 992. 	/* included for compatibility with old NetHack.cnf files */ 993. 	if (match_optname(opts, "IBM_", 4, FALSE)) { 994. 		iflags.BIOS = !negated; 995. 		return; 996. 	}  997.  #endif /* MICRO */ 998.  999.  	/* compound options */ 1000. 1001. 	fullname = "pettype"; 1002. 	if (match_optname(opts, fullname, 3, TRUE)) { 1003. 		if ((op = string_for_env_opt(fullname, opts, negated)) != 0) { 1004. 		   if (negated) bad_negation(fullname, TRUE); 1005. 		   else switch (*op) { 1006. 			case 'd':	/* dog */ 1007. 			case 'D': 1008. 			   preferred_pet = 'd'; 1009. 			   break; 1010. 			case 'c':	/* cat */ 1011. 			case 'C': 1012. 			case 'f':	/* feline */ 1013. 			case 'F': 1014. 			   preferred_pet = 'c'; 1015. 			   break; 1016. 			case 'n':	/* no pet */ 1017. 			case 'N': 1018. 			   preferred_pet = 'n'; 1019. 			   break; 1020. 			default: 1021. 			   pline("Unrecognized pet type '%s'", op); 1022. 			   break; 1023. 		   }  1024. 		} else if (negated) preferred_pet = 'n'; 1025. 		return; 1026. 	} 1027.  1028. 	fullname = "catname"; 1029. 	if (match_optname(opts, fullname, 3, TRUE)) { 1030. 		if (negated) bad_negation(fullname, FALSE); 1031. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) 1032. 			nmcpy(catname, op, PL_PSIZ); 1033. 		return; 1034. 	} 1035.  1036. 	fullname = "dogname"; 1037. 	if (match_optname(opts, fullname, 3, TRUE)) { 1038. 		if (negated) bad_negation(fullname, FALSE); 1039. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) 1040. 			nmcpy(dogname, op, PL_PSIZ); 1041. 		return; 1042. 	} 1043.  1044. 	fullname = "horsename"; 1045. 	if (match_optname(opts, fullname, 5, TRUE)) { 1046. 		if (negated) bad_negation(fullname, FALSE); 1047. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) 1048. 			nmcpy(horsename, op, PL_PSIZ); 1049. 		return; 1050. 	} 1051.  1052. 	fullname = "msghistory"; 1053. 	if (match_optname(opts, fullname, 3, TRUE)) { 1054. 		op = string_for_env_opt(fullname, opts, negated); 1055. 		if ((negated && !op) || (!negated && op)) { 1056. 			iflags.msg_history = negated ? 0 : atoi(op); 1057. 		} else if (negated) bad_negation(fullname, TRUE); 1058. 		return; 1059. 	} 1060.  1061. 	/* WINCAP 1062. 	 * setting font options */ 1063. 	fullname = "font"; 1064. 	if (!strncmpi(opts, fullname, 4)) 1065. 	{ 1066. 		int wintype = -1; 1067. 		char *fontopts = opts + 4; 1068. 1069. 		if (!strncmpi(fontopts, "map", 3) ||  1070. 		    !strncmpi(fontopts, "_map", 4)) 1071. 			wintype = NHW_MAP; 1072. 		else if (!strncmpi(fontopts, "message", 7) || 1073. 			 !strncmpi(fontopts, "_message", 8)) 1074. 			wintype = NHW_MESSAGE; 1075. 		else if (!strncmpi(fontopts, "text", 4) || 1076. 			 !strncmpi(fontopts, "_text", 5)) 1077. 			wintype = NHW_TEXT; 1078. 		else if (!strncmpi(fontopts, "menu", 4) || 1079. 			 !strncmpi(fontopts, "_menu", 5)) 1080. 			wintype = NHW_MENU; 1081. 		else if (!strncmpi(fontopts, "status", 6) || 1082. 			 !strncmpi(fontopts, "_status", 7)) 1083. 			wintype = NHW_STATUS; 1084. 		else if (!strncmpi(fontopts, "_size", 5)) { 1085. 			if (!strncmpi(fontopts, "_size_map", 8)) 1086. 				wintype = NHW_MAP; 1087. 			else if (!strncmpi(fontopts, "_size_message", 12)) 1088. 				wintype = NHW_MESSAGE; 1089. 			else if (!strncmpi(fontopts, "_size_text", 9)) 1090. 				wintype = NHW_TEXT; 1091. 			else if (!strncmpi(fontopts, "_size_menu", 9)) 1092. 				wintype = NHW_MENU; 1093. 			else if (!strncmpi(fontopts, "_size_status", 11)) 1094. 				wintype = NHW_STATUS; 1095. 			else { 1096. 				badoption(opts); 1097. 				return; 1098. 			} 1099. 			if (wintype > 0 && !negated &&  1100. 			    (op = string_for_opt(opts, FALSE)) != 0) { 1101. 			   switch(wintype)  { 1102. 			   	case NHW_MAP: 1103. 					iflags.wc_fontsiz_map = atoi(op); 1104. 					break; 1105. 			   	case NHW_MESSAGE: 1106. 					iflags.wc_fontsiz_message = atoi(op); 1107. 					break; 1108. 			   	case NHW_TEXT: 1109. 					iflags.wc_fontsiz_text = atoi(op); 1110. 					break; 1111. 			   	case NHW_MENU: 1112. 					iflags.wc_fontsiz_menu = atoi(op); 1113. 					break; 1114. 			   	case NHW_STATUS: 1115. 					iflags.wc_fontsiz_status = atoi(op); 1116. 					break; 1117. 			   }  1118. 			}  1119. 			return; 1120. 		} else { 1121. 			badoption(opts); 1122. 		} 1123. 		if (wintype > 0 &&  1124. 		    (op = string_for_opt(opts, FALSE)) != 0) { 1125. 			wc_set_font_name(wintype, op); 1126. #ifdef MAC 1127. 			set_font_name (wintype, op); 1128. #endif 1129. 			return; 1130. 		} else if (negated) bad_negation(fullname, TRUE); 1131. 		return; 1132. 	} 1133. #ifdef CHANGE_COLOR 1134. #ifdef MAC 1135. 	fullname = "use_stone"; 1136. 	if (match_optname(opts, fullname, 6, TRUE)) { 1137. 		op = string_for_env_opt(fullname, opts, negated); 1138. 		if ((negated && !op) || (!negated && op)) { 1139. 			iflags.use_stone = negated ? 0 : atoi(op); 1140. 		} else if (negated) bad_negation(fullname, TRUE); 1141. 		return; 1142. 	} 1143.  1144. 	fullname = "background"; 1145. 	if (match_optname(opts, fullname, 5,TRUE)) 1146. 	{ 1147. 		if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) 1148. 		{ 1149. 			if (!strncmpi (op, "white", 5)) 1150. 				change_background (1); 1151. 			else if (!strncmpi (op, "black", 5)) 1152. 				change_background (0); 1153. 		} 1154. 		return; 1155. 	} 1156. #endif 1157. 1158. 	if (match_optname(opts, "palette", 3, TRUE)  1159. # ifdef MAC  1160. 	    || match_optname(opts, "hicolor", 3, TRUE)  1161. # endif  1162. 							) { 1163. 	   int color_number, color_incr; 1164. 1165. # ifdef MAC 1166. 	   if (match_optname(opts, "hicolor", 3, TRUE)) { 1167. 		if (negated) { 1168. 		   bad_negation("hicolor", FALSE); 1169. 		   return; 1170. 		} 1171. 		color_number = CLR_MAX + 4;	/* HARDCODED inverse number */ 1172. 		color_incr = -1; 1173. 	   } else { 1174. # endif 1175. 		if (negated) { 1176. 		   bad_negation("palette", FALSE); 1177. 		   return; 1178. 		} 1179. 		color_number = 0; 1180. 		color_incr = 1; 1181. # ifdef MAC 1182. 	   }  1183. # endif 1184. 	   if ((op = string_for_opt(opts, FALSE)) != (char *)0) { 1185. 		char *pt = op; 1186. 		int cnt, tmp, reverse; 1187. 		long rgb; 1188. 1189. 		while (*pt && color_number >= 0) { 1190. 		   cnt = 3; 1191. 		   rgb = 0L; 1192. 		   if (*pt == '-') { 1193. 			reverse = 1; 1194. 			pt++; 1195. 		   } else { 1196. 			reverse = 0; 1197. 		   }  1198. 		    while (cnt-- > 0) { 1199. 			if (*pt && *pt != '/') { 1200. # ifdef AMIGA 1201. 			   rgb <<= 4; 1202. # else 1203. 			   rgb <<= 8; 1204. # endif 1205. 			   tmp = *(pt++); 1206. 			   if (isalpha(tmp)) { 1207. 				tmp = (tmp + 9) & 0xf;	/* Assumes ASCII... */ 1208. 			    } else { 1209. 				tmp &= 0xf;	/* Digits in ASCII too... */ 1210. 			    }  1211. # ifndef AMIGA 1212. 			   /* Add an extra so we fill f -> ff and 0 -> 00 */ 1213. 			   rgb += tmp << 4; 1214. # endif 1215. 			   rgb += tmp; 1216. 			} 1217. 		    }  1218. 		    if (*pt == '/') { 1219. 			pt++; 1220. 		   }  1221. 		    change_color(color_number, rgb, reverse); 1222. 		   color_number += color_incr; 1223. 		} 1224. 	    }  1225. 	    if (!initial) { 1226. 		need_redraw = TRUE; 1227. 	   }  1228. 	    return; 1229. 	} 1230. #endif /* CHANGE_COLOR */ 1231. 1232. 	if (match_optname(opts, "fruit", 2, TRUE)) { 1233. 		char empty_str = '\0'; 1234. 		op = string_for_opt(opts, negated); 1235. 		if (negated) { 1236. 		   if (op) { 1237. 			bad_negation("fruit", TRUE); 1238. 			return; 1239. 		   }  1240. 		    op = &empty_str; 1241. 		   goto goodfruit; 1242. 		} 1243. 		if (!op) return; 1244. 		if (!initial) { 1245. 		   struct fruit *f; 1246. 1247. 		    num = 0; 1248. 		   for(f=ffruit; f; f=f->nextf) { 1249. 			if (!strcmp(op, f->fname)) goto goodfruit; 1250. 			num++; 1251. 		   }  1252. 		    if (num >= 100) { 1253. 			pline("Doing that so many times isn't very fruitful."); 1254. 			return; 1255. 		   }  1256. 		}  1257. goodfruit: 1258. 		nmcpy(pl_fruit, op, PL_FSIZ); 1259. 	/* OBJ_NAME(objects[SLIME_MOLD]) won't work after initialization */ 1260. 		if (!*pl_fruit) 1261. 		   nmcpy(pl_fruit, "slime mold", PL_FSIZ); 1262. 		if (!initial) 1263. 		   (void)fruitadd(pl_fruit); 1264. 		/* If initial, then initoptions is allowed to do it instead 1265. 		 * of here (initoptions always has to do it even if there's 1266. 		 * no fruit option at all.  Also, we don't want people  1267. 		 * setting multiple fruits in their options.) 1268. 		 */ 1269. 		return; 1270. 	} 1271.  1272. 	/* graphics:string */ 1273. 	fullname = "graphics"; 1274. 	if (match_optname(opts, fullname, 2, TRUE)) { 1275. 		if (negated) bad_negation(fullname, FALSE); 1276. 		else graphics_opts(opts, fullname, MAXPCHARS, 0); 1277. 		return; 1278. 	} 1279. 	fullname = "dungeon"; 1280. 	if (match_optname(opts, fullname, 2, TRUE)) { 1281. 		if (negated) bad_negation(fullname, FALSE); 1282. 		else graphics_opts(opts, fullname, MAXDCHARS, 0); 1283. 		return; 1284. 	} 1285. 	fullname = "traps"; 1286. 	if (match_optname(opts, fullname, 2, TRUE)) { 1287. 		if (negated) bad_negation(fullname, FALSE); 1288. 		else graphics_opts(opts, fullname, MAXTCHARS, MAXDCHARS); 1289. 		return; 1290. 	} 1291. 	fullname = "effects"; 1292. 	if (match_optname(opts, fullname, 2, TRUE)) { 1293. 		if (negated) bad_negation(fullname, FALSE); 1294. 		else 1295. 		 graphics_opts(opts, fullname, MAXECHARS, MAXDCHARS+MAXTCHARS); 1296. 		return; 1297. 	} 1298.  1299. 	/* objects:string */ 1300. 	fullname = "objects"; 1301. 	if (match_optname(opts, fullname, 7, TRUE)) { 1302. 		int length; 1303. 1304. 		if (negated) { 1305. 		   bad_negation(fullname, FALSE); 1306. 		   return; 1307. 		} 1308. 		if (!(opts = string_for_env_opt(fullname, opts, FALSE))) 1309. 			return; 1310. 		escapes(opts, opts); 1311. 1312. 		/*  1313. 		 * Override the default object class symbols. The first 1314. 		 * object in the object class is the "random object". I 1315. * don't want to use 0 as an object class, so the "random 1316. 		 * object" is basically a place holder. 1317. 		 * 1318. 		 * The object class symbols have already been initialized in  1319. * initoptions. 1320. 		 */ 1321. 		length = strlen(opts); 1322. 		if (length >= MAXOCLASSES) 1323. 		   length = MAXOCLASSES-1;	/* don't count RANDOM_OBJECT */ 1324. 1325. 		for (i = 0; i < length; i++) 1326. 		   oc_syms[i+1] = (uchar) opts[i]; 1327. 		return; 1328. 	} 1329.  1330. 	/* monsters:string */ 1331. 	fullname = "monsters"; 1332. 	if (match_optname(opts, fullname, 8, TRUE)) { 1333. 		int length; 1334. 1335. 		if (negated) { 1336. 		   bad_negation(fullname, FALSE); 1337. 		   return; 1338. 		} 1339. 		if (!(opts = string_for_env_opt(fullname, opts, FALSE))) 1340. 			return; 1341. 		escapes(opts, opts); 1342. 1343. 		/* Override default mon class symbols set in initoptions. */ 1344. 		length = strlen(opts); 1345. 		if (length >= MAXMCLASSES) 1346. 		   length = MAXMCLASSES-1;	/* mon class 0 unused */ 1347. 1348. 		for (i = 0; i < length; i++) 1349. 		   monsyms[i+1] = (uchar) opts[i]; 1350. 		return; 1351. 	} 1352. 	fullname = "warnings"; 1353. 	if (match_optname(opts, fullname, 5, TRUE)) { 1354. 		if (negated) bad_negation(fullname, FALSE); 1355. 		else warning_opts(opts, fullname); 1356. 		return; 1357. 	} 1358. 	/* boulder:symbol */ 1359. 	fullname = "boulder"; 1360. 	if (match_optname(opts, fullname, 7, TRUE)) { 1361. 		if (negated) { 1362. 		   bad_negation(fullname, FALSE); 1363. 		   return; 1364. 		} 1365. /*		if (!(opts = string_for_env_opt(fullname, opts, FALSE))) */ 1366. 		if (!(opts = string_for_opt(opts, FALSE))) 1367. 			return; 1368. 		escapes(opts, opts); 1369. 1370. 		/*  1371. 		 * Override the default boulder symbol. 1372. 		 */ 1373. 		iflags.bouldersym = (uchar) opts[0]; 1374. 		if (!initial) need_redraw = TRUE; 1375. 		return; 1376. 	} 1377.  1378. 	/* name:string */ 1379. 	fullname = "name"; 1380. 	if (match_optname(opts, fullname, 4, TRUE)) { 1381. 		if (negated) bad_negation(fullname, FALSE); 1382. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) 1383. 			nmcpy(plname, op, PL_NSIZ); 1384. 		return; 1385. 	} 1386.  1387. 	/* role:string or character:string */ 1388. 	fullname = "role"; 1389. 	if (match_optname(opts, fullname, 4, TRUE) || 1390. 	    match_optname(opts, (fullname = "character"), 4, TRUE)) { 1391. 		if (negated) bad_negation(fullname, FALSE); 1392. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) { 1393. 			if ((flags.initrole = str2role(op)) == ROLE_NONE) 1394. 				badoption(opts); 1395. 			else /* Backwards compatibility */ 1396. 				nmcpy(pl_character, op, PL_NSIZ); 1397. 		} 1398. 		return; 1399. 	} 1400.  1401. 	/* race:string */ 1402. 	fullname = "race"; 1403. 	if (match_optname(opts, fullname, 4, TRUE)) { 1404. 		if (negated) bad_negation(fullname, FALSE); 1405. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) { 1406. 			if ((flags.initrace = str2race(op)) == ROLE_NONE) 1407. 				badoption(opts); 1408. 			else /* Backwards compatibility */ 1409. 				pl_race = *op; 1410. 		} 1411. 		return; 1412. 	} 1413.  1414. 	/* gender:string */ 1415. 	fullname = "gender"; 1416. 	if (match_optname(opts, fullname, 4, TRUE)) { 1417. 		if (negated) bad_negation(fullname, FALSE); 1418. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) { 1419. 			if ((flags.initgend = str2gend(op)) == ROLE_NONE) 1420. 				badoption(opts); 1421. 			else 1422. 				flags.female = flags.initgend; 1423. 		} 1424. 		return; 1425. 	} 1426.  1427. 	/* WINCAP 1428. 	 * align_status:[left|top|right|bottom] */ 1429. 	fullname = "align_status"; 1430. 	if (match_optname(opts, fullname, sizeof("align_status")-1, TRUE)) { 1431. 		op = string_for_opt(opts, negated); 1432. 		if (op && !negated) { 1433. 		   if (!strncmpi (op, "left", sizeof("left")-1)) 1434. 			iflags.wc_align_status = ALIGN_LEFT; 1435. 		   else if (!strncmpi (op, "top", sizeof("top")-1)) 1436. 			iflags.wc_align_status = ALIGN_TOP; 1437. 		   else if (!strncmpi (op, "right", sizeof("right")-1)) 1438. 			iflags.wc_align_status = ALIGN_RIGHT; 1439. 		   else if (!strncmpi (op, "bottom", sizeof("bottom")-1)) 1440. 			iflags.wc_align_status = ALIGN_BOTTOM; 1441. 		   else 1442. 			badoption(opts); 1443. 		} else if (negated) bad_negation(fullname, TRUE); 1444. 		return; 1445. 	} 1446. 	/* WINCAP 1447. 	 * align_message:[left|top|right|bottom] */ 1448. 	fullname = "align_message"; 1449. 	if (match_optname(opts, fullname, sizeof("align_message")-1, TRUE)) { 1450. 		op = string_for_opt(opts, negated); 1451. 		if (op && !negated) { 1452. 		   if (!strncmpi (op, "left", sizeof("left")-1)) 1453. 			iflags.wc_align_message = ALIGN_LEFT; 1454. 		   else if (!strncmpi (op, "top", sizeof("top")-1)) 1455. 			iflags.wc_align_message = ALIGN_TOP; 1456. 		   else if (!strncmpi (op, "right", sizeof("right")-1)) 1457. 			iflags.wc_align_message = ALIGN_RIGHT; 1458. 		   else if (!strncmpi (op, "bottom", sizeof("bottom")-1)) 1459. 			iflags.wc_align_message = ALIGN_BOTTOM; 1460. 		   else 1461. 			badoption(opts); 1462. 		} else if (negated) bad_negation(fullname, TRUE); 1463. 		return; 1464. 	} 1465. 	/* align:string */ 1466. 	fullname = "align"; 1467. 	if (match_optname(opts, fullname, sizeof("align")-1, TRUE)) { 1468. 		if (negated) bad_negation(fullname, FALSE); 1469. 		else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) 1470. 			if ((flags.initalign = str2align(op)) == ROLE_NONE) 1471. 				badoption(opts); 1472. 		return; 1473. 	} 1474.  1475. 	/* the order to list the pack */ 1476. 	fullname = "packorder"; 1477. 	if (match_optname(opts, fullname, 4, TRUE)) { 1478. 		if (negated) { 1479. 		   bad_negation(fullname, FALSE); 1480. 		   return; 1481. 		} else if (!(op = string_for_opt(opts, FALSE))) return; 1482. 1483. 		if (!change_inv_order(op)) 1484. 			badoption(opts); 1485. 		return; 1486. 	} 1487.  1488. 	/* maximum burden picked up before prompt (Warren Cheung) */ 1489. 	fullname = "pickup_burden"; 1490. 	if (match_optname(opts, fullname, 8, TRUE)) { 1491. 		if (negated) { 1492. 			bad_negation(fullname, FALSE); 1493. 			return; 1494. 		} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) { 1495. 		   switch (tolower(*op)) { 1496. 				/* Unencumbered */ 1497. 				case 'u': 1498. 					flags.pickup_burden = UNENCUMBERED; 1499. 					break; 1500. 				/* Burdened (slight encumbrance) */ 1501. 				case 'b': 1502. 					flags.pickup_burden = SLT_ENCUMBER; 1503. 					break; 1504. 				/* streSsed (moderate encumbrance) */ 1505. 				case 's': 1506. 					flags.pickup_burden = MOD_ENCUMBER; 1507. 					break; 1508. 				/* straiNed (heavy encumbrance) */ 1509. 				case 'n': 1510. 					flags.pickup_burden = HVY_ENCUMBER; 1511. 					break; 1512. 				/* OverTaxed (extreme encumbrance) */ 1513. 				case 'o': 1514. 				case 't': 1515. 					flags.pickup_burden = EXT_ENCUMBER; 1516. 					break; 1517. 				/* overLoaded */ 1518. 				case 'l': 1519. 					flags.pickup_burden = OVERLOADED; 1520. 					break; 1521. 				default: 1522. 				badoption(opts); 1523. 		   }  1524. 		}  1525. 		return; 1526. 	} 1527.  1528. 	/* types of objects to pick up automatically */ 1529. 	if (match_optname(opts, "pickup_types", 8, TRUE)) { 1530. 		char ocl[MAXOCLASSES + 1], tbuf[MAXOCLASSES + 1], 1531. 		    qbuf[QBUFSZ], abuf[BUFSZ]; 1532. 		int oc_sym; 1533. 		boolean badopt = FALSE, compat = (strlen(opts) <= 6), use_menu; 1534. 1535. 		oc_to_str(flags.pickup_types, tbuf); 1536. 		flags.pickup_types[0] = '\0';	/* all */ 1537. 		op = string_for_opt(opts, (compat || !initial)); 1538. 		if (!op) { 1539. 		   if (compat || negated || initial) { 1540. 			/* for backwards compatibility, "pickup" without a 1541. value is a synonym for autopickup of all types 1542. 			  (and during initialization, we can't prompt yet) */ 1543. 			flags.pickup = !negated; 1544. 			return; 1545. 		   }  1546. 		    oc_to_str(flags.inv_order, ocl); 1547. 		   use_menu = TRUE; 1548. 		   if (flags.menu_style == MENU_TRADITIONAL ||  1549. 			    flags.menu_style == MENU_COMBINATION) { 1550. 			use_menu = FALSE; 1551. 			Sprintf(qbuf, "New pickup_types: [%s am] (%s)", 1552. 				ocl, *tbuf ? tbuf : "all"); 1553. 			getlin(qbuf, abuf); 1554. 			op = mungspaces(abuf); 1555. 			if (abuf[0] == '\0' || abuf[0] == '\033') 1556. 			   op = tbuf;		/* restore */ 1557. 			else if (abuf[0] == 'm') 1558. 			   use_menu = TRUE; 1559. 		   }  1560. 		    if (use_menu) { 1561. 			(void) choose_classes_menu("Auto-Pickup what?", 1, 1562. 						   TRUE, ocl, tbuf); 1563. 			op = tbuf; 1564. 		   }  1565. 		}  1566. 		if (negated) { 1567. 		   bad_negation("pickup_types", TRUE); 1568. 		   return; 1569. 		} 1570. 		while (*op == ' ') op++; 1571. 		if (*op != 'a' && *op != 'A') { 1572. 		   num = 0; 1573. 		   while (*op) { 1574. 			oc_sym = def_char_to_objclass(*op); 1575. 			/* make sure all are valid obj symbols occuring once */ 1576. 			if (oc_sym != MAXOCLASSES && 1577. 			    !index(flags.pickup_types, oc_sym)) { 1578. 			   flags.pickup_types[num] = (char)oc_sym; 1579. 			   flags.pickup_types[++num] = '\0'; 1580. 			} else 1581. 			   badopt = TRUE; 1582. 			op++; 1583. 		   }  1584. 		    if (badopt) badoption(opts); 1585. 		} 1586. 		return; 1587. 	} 1588. 	/* WINCAP 1589. 	 * player_selection: dialog | prompts */ 1590. 	fullname = "player_selection"; 1591. 	if (match_optname(opts, fullname, sizeof("player_selection")-1, TRUE)) { 1592. 		op = string_for_opt(opts, negated); 1593. 		if (op && !negated) { 1594. 		   if (!strncmpi (op, "dialog", sizeof("dialog")-1)) 1595. 			iflags.wc_player_selection = VIA_DIALOG; 1596. 		   else if (!strncmpi (op, "prompt", sizeof("prompt")-1)) 1597. 			iflags.wc_player_selection = VIA_PROMPTS; 1598. 		   else 1599. 		   	badoption(opts); 1600. 		} else if (negated) bad_negation(fullname, TRUE); 1601. 		return; 1602. 	} 1603.  1604. 	/* things to disclose at end of game */ 1605. 	if (match_optname(opts, "disclose", 7, TRUE)) { 1606. 		/* 1607. 		 * The order that the end_disclore options are stored: 1608. 		 * inventory, attribs, vanquished, genocided, conduct 1609. 		 * There is an array in flags: 1610. 		 *	end_disclose[NUM_DISCLOSURE_OPT]; 1611. 		 * with option settings for the each of the following: 1612. 		 * iagvc [see disclosure_options in decl.c]: 1613. 		 * Legal setting values in that array are: 1614. 		 *	DISCLOSE_PROMPT_DEFAULT_YES ask with default answer yes 1615. 		 *	DISCLOSE_PROMPT_DEFAULT_NO  ask with default answer no  1616. *	DISCLOSE_YES_WITHOUT_PROMPT always disclose and don't ask 1617. 		 *	DISCLOSE_NO_WITHOUT_PROMPT  never disclose and don't ask 1618. 		 * 1619. 		 * Those setting values can be used in the option 1620. 		 * string as a prefix to get the desired behaviour. 1621. 		 * 1622. 		 * For backward compatibility, no prefix is required, 1623. 		 * and the presence of a i,a,g,v, or c without a 1624. * prefix sets the corresponding value to DISCLOSE_YES_WITHOUT_PROMPT; 1625. 		 */ 1626. 		boolean badopt = FALSE; 1627. 		int idx, prefix_val; 1628. 		if (!(op = string_for_opt(opts, TRUE))) { 1629. 			/* for backwards compatibility, "disclose" without a 1630. * value means all (was inventory and attributes, 1631. 			 * the only things available then), but negated 1632. 			 * it means "none" 1633. 			 * (note "none" contains none of "iavkgc") 1634. 			 */ 1635. 			for (num = 0; num < NUM_DISCLOSURE_OPTIONS; num++) { 1636. 				if (negated) 1637. 				   flags.end_disclose[num] = DISCLOSE_NO_WITHOUT_PROMPT; 1638. 			 	else flags.end_disclose[num] = DISCLOSE_PROMPT_DEFAULT_YES; 1639. 			} 1640. 			return; 1641. 		} 1642. 		if (negated) { 1643. 			bad_negation("disclose", TRUE); 1644. 			return; 1645. 		} 1646. 		num = 0; 1647. 		prefix_val = -1; 1648. 		while (*op && num < sizeof flags.end_disclose - 1) { 1649. 			register char c, *dop; 1650. 			static char valid_settings[] = { 1651. 				DISCLOSE_PROMPT_DEFAULT_YES, 1652. 				DISCLOSE_PROMPT_DEFAULT_NO, 1653. 				DISCLOSE_YES_WITHOUT_PROMPT, 1654. 				DISCLOSE_NO_WITHOUT_PROMPT, 1655. 				'\0' 1656. 			};  1657. 			c = lowc(*op); 1658. 			if (c == 'k') c = 'v';	/* killed -> vanquished */ 1659. 			dop = index(disclosure_options, c); 1660. 			if (dop) { 1661. 				idx = dop - disclosure_options; 1662. 				if (idx < 0 || idx > NUM_DISCLOSURE_OPTIONS - 1) { 1663. 				   impossible("bad disclosure index %d %c",  1664. 							idx, c); 1665. 				   continue; 1666. 				} 1667. 				if (prefix_val != -1) { 1668. 				   flags.end_disclose[idx] = prefix_val; 1669. 				   prefix_val = -1; 1670. 				} else 1671. 				   flags.end_disclose[idx] = DISCLOSE_YES_WITHOUT_PROMPT; 1672. 			} else if (index(valid_settings, c)) { 1673. 				prefix_val = c; 1674. } else if (c == ' ') { 1675. 				/* do nothing */ 1676. 			} else 1677. 				badopt = TRUE; 1678. 			op++; 1679. 		} 1680. 		if (badopt) badoption(opts); 1681. 		return; 1682. 	} 1683.  1684. 	/* scores:5t[op] 5a[round] o[wn] */ 1685. 	if (match_optname(opts, "scores", 4, TRUE)) { 1686. 	   if (negated) { 1687. 		bad_negation("scores", FALSE); 1688. 		return; 1689. 	   }  1690. 	    if (!(op = string_for_opt(opts, FALSE))) return; 1691. 1692. 	    while (*op) { 1693. 		int inum = 1; 1694. 1695. 		if (digit(*op)) { 1696. 		   inum = atoi(op); 1697. 		   while (digit(*op)) op++; 1698. 		} else if (*op == '!') { 1699. 		   negated = !negated; 1700. 		   op++; 1701. 		} 1702. 		while (*op == ' ') op++; 1703. 1704. 		switch (*op) { 1705. 		 case 't': 1706. 		 case 'T': flags.end_top = inum; 1707. 			   break; 1708. 		 case 'a': 1709. 		 case 'A': flags.end_around = inum; 1710. 			   break; 1711. 		 case 'o': 1712. 		 case 'O': flags.end_own = !negated; 1713. 			   break; 1714. 		 default:  badoption(opts); 1715. 			   return; 1716. 		} 1717. 		while (letter(*++op) || *op == ' ') continue; 1718. 		if (*op == '/') op++; 1719. 	   }  1720. 	    return; 1721. 	} 1722.  1723. 	fullname = "suppress_alert"; 1724. 	if (match_optname(opts, fullname, 4, TRUE)) { 1725. 		op = string_for_opt(opts, negated); 1726. 		if (negated) bad_negation(fullname, FALSE); 1727. 		else if (op) (void) feature_alert_opts(op,fullname); 1728. 		return; 1729. 	} 1730. 	  1731. #ifdef VIDEOSHADES 1732. 	/* videocolors:string */ 1733. 	fullname = "videocolors"; 1734. 	if (match_optname(opts, fullname, 6, TRUE) || 1735. 	    match_optname(opts, "videocolours", 10, TRUE)) { 1736. 		if (negated) { 1737. 			bad_negation(fullname, FALSE); 1738. 			return; 1739. 		} 1740. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { 1741. 			return; 1742. 		} 1743. 		if (!assign_videocolors(opts)) 1744. 			badoption(opts); 1745. 		return; 1746. 	} 1747. 	/* videoshades:string */ 1748. 	fullname = "videoshades"; 1749. 	if (match_optname(opts, fullname, 6, TRUE)) { 1750. 		if (negated) { 1751. 			bad_negation(fullname, FALSE); 1752. 			return; 1753. 		} 1754. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { 1755. 			return; 1756. 		} 1757. 		if (!assign_videoshades(opts)) 1758. 			badoption(opts); 1759. 		return; 1760. 	} 1761. #endif /* VIDEOSHADES */ 1762. #ifdef MSDOS 1763. # ifdef NO_TERMS 1764. 	/* video:string -- must be after longer tests */ 1765. 	fullname = "video"; 1766. 	if (match_optname(opts, fullname, 5, TRUE)) { 1767. 		if (negated) { 1768. 			bad_negation(fullname, FALSE); 1769. 			return; 1770. 		} 1771. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { 1772. 			return; 1773. 		} 1774. 		if (!assign_video(opts)) 1775. 			badoption(opts); 1776. 		return; 1777. 	} 1778. # endif /* NO_TERMS */ 1779. 	/* soundcard:string -- careful not to match boolean 'sound' */ 1780. 	fullname = "soundcard"; 1781. 	if (match_optname(opts, fullname, 6, TRUE)) { 1782. 		if (negated) { 1783. 			bad_negation(fullname, FALSE); 1784. 			return; 1785. 		} 1786. 		else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { 1787. 			return; 1788. 		} 1789. 		if (!assign_soundcard(opts)) 1790. 			badoption(opts); 1791. 		return; 1792. 	} 1793. #endif /* MSDOS */ 1794. 1795. 	/* WINCAP 1796. 	 * map_mode:[tiles|ascii4x6|ascii6x8|ascii8x8|ascii16x8|ascii7x12|ascii8x12| 1797. 			ascii16x12|ascii12x16|ascii10x18|fit_to_screen] */ 1798. 	fullname = "map_mode"; 1799. 	if (match_optname(opts, fullname, sizeof("map_mode")-1, TRUE)) { 1800. 		op = string_for_opt(opts, negated); 1801. 		if (op && !negated) { 1802. 		   if (!strncmpi (op, "tiles", sizeof("tiles")-1)) 1803. 			iflags.wc_map_mode = MAP_MODE_TILES; 1804. 		   else if (!strncmpi (op, "ascii4x6", sizeof("ascii4x6")-1)) 1805. 			iflags.wc_map_mode = MAP_MODE_ASCII4x6; 1806. 		   else if (!strncmpi (op, "ascii6x8", sizeof("ascii6x8")-1)) 1807. 			iflags.wc_map_mode = MAP_MODE_ASCII6x8; 1808. 		   else if (!strncmpi (op, "ascii8x8", sizeof("ascii8x8")-1)) 1809. 			iflags.wc_map_mode = MAP_MODE_ASCII8x8; 1810. 		   else if (!strncmpi (op, "ascii16x8", sizeof("ascii16x8")-1)) 1811. 			iflags.wc_map_mode = MAP_MODE_ASCII16x8; 1812. 		   else if (!strncmpi (op, "ascii7x12", sizeof("ascii7x12")-1)) 1813. 			iflags.wc_map_mode = MAP_MODE_ASCII7x12; 1814. 		   else if (!strncmpi (op, "ascii8x12", sizeof("ascii8x12")-1)) 1815. 			iflags.wc_map_mode = MAP_MODE_ASCII8x12; 1816. 		   else if (!strncmpi (op, "ascii16x12", sizeof("ascii16x12")-1)) 1817. 			iflags.wc_map_mode = MAP_MODE_ASCII16x12; 1818. 		   else if (!strncmpi (op, "ascii12x16", sizeof("ascii12x16")-1)) 1819. 			iflags.wc_map_mode = MAP_MODE_ASCII12x16; 1820. 		   else if (!strncmpi (op, "ascii10x18", sizeof("ascii10x18")-1)) 1821. 			iflags.wc_map_mode = MAP_MODE_ASCII10x18; 1822. 		   else if (!strncmpi (op, "fit_to_screen", sizeof("fit_to_screen")-1)) 1823. 			iflags.wc_map_mode = MAP_MODE_ASCII_FIT_TO_SCREEN; 1824. 		   else 1825. 		   	badoption(opts); 1826. 		} else if (negated) bad_negation(fullname, TRUE); 1827. 		return; 1828. 	} 1829. 	/* WINCAP 1830. 	 * scroll_margin:nn */ 1831. 	fullname = "scroll_margin"; 1832. 	if (match_optname(opts, fullname, sizeof("scroll_margin")-1, TRUE)) { 1833. 		op = string_for_opt(opts, negated); 1834. 		if ((negated && !op) || (!negated && op)) { 1835. 			iflags.wc_scroll_margin = negated ? 5 : atoi(op); 1836. 		} else if (negated) bad_negation(fullname, TRUE); 1837. 		return; 1838. 	} 1839. 	/* WINCAP 1840. 	 * tile_width:nn */ 1841. 	fullname = "tile_width"; 1842. 	if (match_optname(opts, fullname, sizeof("tile_width")-1, TRUE)) { 1843. 		op = string_for_opt(opts, negated); 1844. 		if ((negated && !op) || (!negated && op)) { 1845. 			iflags.wc_tile_width = negated ? 0 : atoi(op); 1846. 		} else if (negated) bad_negation(fullname, TRUE); 1847. 		return; 1848. 	} 1849. 	/* WINCAP 1850. 	 * tile_file:name */ 1851. 	fullname = "tile_file"; 1852. 	if (match_optname(opts, fullname, sizeof("tile_file")-1, TRUE)) { 1853. 		if ((op = string_for_opt(opts, FALSE)) != 0) { 1854. 			if (iflags.wc_tile_file) free(iflags.wc_tile_file); 1855. 			iflags.wc_tile_file = (char *)alloc(strlen(op) + 1); 1856. 			Strcpy(iflags.wc_tile_file, op); 1857. 		} 1858. 		return; 1859. 	} 1860. 	/* WINCAP 1861. 	 * tile_height:nn */ 1862. 	fullname = "tile_height"; 1863. 	if (match_optname(opts, fullname, sizeof("tile_height")-1, TRUE)) { 1864. 		op = string_for_opt(opts, negated); 1865. 		if ((negated && !op) || (!negated && op)) { 1866. 			iflags.wc_tile_height = negated ? 0 : atoi(op); 1867. 		} else if (negated) bad_negation(fullname, TRUE); 1868. 		return; 1869. 	} 1870. 	/* WINCAP 1871. 	 * vary_msgcount:nn */ 1872. 	fullname = "vary_msgcount"; 1873. 	if (match_optname(opts, fullname, sizeof("vary_msgcount")-1, TRUE)) { 1874. 		op = string_for_opt(opts, negated); 1875. 		if ((negated && !op) || (!negated && op)) { 1876. 			iflags.wc_vary_msgcount = negated ? 0 : atoi(op); 1877. 		} else if (negated) bad_negation(fullname, TRUE); 1878. 		return; 1879. 	} 1880.  1881. 	fullname = "windowtype"; 1882. 	if (match_optname(opts, fullname, 3, TRUE)) { 1883. 	   if (negated) { 1884. 		bad_negation(fullname, FALSE); 1885. 		return; 1886. 	   } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) { 1887. 		char buf[WINTYPELEN]; 1888. 		nmcpy(buf, op, WINTYPELEN); 1889. 		choose_windows(buf); 1890. 	   }  1891. 	    return; 1892. 	} 1893.  1894. 	/* WINCAP 1895. 	 * setting window colors 1896.         * syntax: windowcolors=menu foregrnd/backgrnd text foregrnd/backgrnd 1897.         */  1898. 	fullname = "windowcolors"; 1899. 	if (match_optname(opts, fullname, 7, TRUE)) { 1900. 		if ((op = string_for_opt(opts, FALSE)) != 0) { 1901. 			if (!wc_set_window_colors(op)) 1902. 				badoption(opts); 1903. 		} else if (negated) bad_negation(fullname, TRUE); 1904. 		return; 1905. 	} 1906.  1907. 	/* menustyle:traditional or combo or full or partial */ 1908. 	if (match_optname(opts, "menustyle", 4, TRUE)) { 1909. 		int tmp; 1910. 		boolean val_required = (strlen(opts) > 5 && !negated); 1911. 1912. 		if (!(op = string_for_opt(opts, !val_required))) { 1913. 		   if (val_required) return; /* string_for_opt gave feedback */ 1914. 		   tmp = negated ? 'n' : 'f'; 1915. 		} else { 1916. 		   tmp = tolower(*op); 1917. 		} 1918. 		switch (tmp) { 1919. 			case 'n':	/* none */ 1920. 			case 't':	/* traditional */ 1921. 				flags.menu_style = MENU_TRADITIONAL; 1922. 				break; 1923. 			case 'c':	/* combo: trad.class sel+menu */ 1924. 				flags.menu_style = MENU_COMBINATION; 1925. 				break; 1926. 			case 'p':	/* partial: no class menu */ 1927. 				flags.menu_style = MENU_PARTIAL; 1928. 				break; 1929. 			case 'f':	/* full: class menu + menu */ 1930. 				flags.menu_style = MENU_FULL; 1931. 				break; 1932. 			default: 1933. 				badoption(opts); 1934. 		} 1935. 		return; 1936. 	} 1937.  1938. 	/* check for menu command mapping */ 1939. 	for (i = 0; i < NUM_MENU_CMDS; i++) { 1940. 	   fullname = default_menu_cmd_info[i].name; 1941. 	   if (match_optname(opts, fullname, (int)strlen(fullname), TRUE)) { 1942. 		if (negated) 1943. 		   bad_negation(fullname, FALSE); 1944. 		else if ((op = string_for_opt(opts, FALSE)) != 0) { 1945. 		   int j;  1946. char c, op_buf[BUFSZ]; 1947. 		   boolean isbad = FALSE; 1948. 1949. 		    escapes(op, op_buf); 1950. 		   c = *op_buf; 1951. 1952. 		    if (c == 0 || c == '\r' || c == '\n' || c == '\033' ||  1953. 			    c == ' ' || digit(c) || (letter(c) && c != '@')) 1954. 			isbad = TRUE; 1955. 		   else	/* reject default object class symbols */ 1956. 			for (j = 1; j < MAXOCLASSES; j++) 1957. 			   if (c == def_oc_syms[i]) { 1958. 				isbad = TRUE; 1959. 				break; 1960. 			   }  1961.  1962. 		    if (isbad) 1963. 			badoption(opts); 1964. 		   else 1965. 			add_menu_cmd_alias(c, default_menu_cmd_info[i].cmd); 1966. 		} 1967. 		return; 1968. 	   }  1969. 	}  1970.  1971. 	/* OK, if we still haven't recognized the option, check the boolean 1972. 	 * options list 1973. 	 */ 1974. 	for (i = 0; boolopt[i].name; i++) { 1975. 		if (match_optname(opts, boolopt[i].name, 3, FALSE)) { 1976. 			/* options that don't exist */ 1977. 			if (!boolopt[i].addr) { 1978. 			   if (!initial && !negated) 1979. 				pline_The("\"%s\" option is not available.", 1980. 					boolopt[i].name); 1981. 			   return; 1982. 			} 1983. 			/* options that must come from config file */ 1984. 			if (!initial && (boolopt[i].optflags == SET_IN_FILE)) { 1985. 			   rejectoption(boolopt[i].name); 1986. 			   return; 1987. 			} 1988.  1989. 			*(boolopt[i].addr) = !negated; 1990. 1991. 			duplicate_opt_detection(boolopt[i].name, 0); 1992. 1993. #if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV) 1994. 			if (FALSE 1995. # ifdef TERMLIB  1996. 				 || (boolopt[i].addr) == &iflags.DECgraphics  1997. # endif  1998. # ifdef ASCIIGRAPH  1999. 				 || (boolopt[i].addr) == &iflags.IBMgraphics  2000. # endif  2001. # ifdef MAC_GRAPHICS_ENV  2002. 				 || (boolopt[i].addr) == &iflags.MACgraphics  2003. # endif  2004. 				) { 2005. # ifdef REINCARNATION 2006. 			   if (!initial && Is_rogue_level(&u.uz)) 2007. 				assign_rogue_graphics(FALSE); 2008. # endif 2009. 			   need_redraw = TRUE; 2010. # ifdef TERMLIB 2011. 			   if ((boolopt[i].addr) == &iflags.DECgraphics) 2012. 				switch_graphics(iflags.DECgraphics ? 2013. 						DEC_GRAPHICS : ASCII_GRAPHICS); 2014. # endif 2015. # ifdef ASCIIGRAPH 2016. 			   if ((boolopt[i].addr) == &iflags.IBMgraphics) 2017. 				switch_graphics(iflags.IBMgraphics ? 2018. 						IBM_GRAPHICS : ASCII_GRAPHICS); 2019. # endif 2020. # ifdef MAC_GRAPHICS_ENV 2021. 			   if ((boolopt[i].addr) == &iflags.MACgraphics) 2022. 				switch_graphics(iflags.MACgraphics ? 2023. 						MAC_GRAPHICS : ASCII_GRAPHICS); 2024. # endif 2025. # ifdef REINCARNATION 2026. 			   if (!initial && Is_rogue_level(&u.uz)) 2027. 				assign_rogue_graphics(TRUE); 2028. # endif 2029. 			} 2030. #endif /* TERMLIB || ASCIIGRAPH || MAC_GRAPHICS_ENV */ 2031. 2032. 			/* only do processing below if setting with doset */ 2033. 			if (initial) return; 2034. 2035. 			if ((boolopt[i].addr) == &flags.time  2036. #ifdef EXP_ON_BOTL  2037. 			 || (boolopt[i].addr) == &flags.showexp  2038. #endif  2039. #ifdef SCORE_ON_BOTL  2040. 			 || (boolopt[i].addr) == &flags.showscore  2041. #endif  2042. 			    ) 2043. 			   flags.botl = TRUE; 2044. 2045. 			else if ((boolopt[i].addr) == &flags.invlet_constant) { 2046. 			   if (flags.invlet_constant) reassign; 2047. 			} 2048. #ifdef LAN_MAIL 2049. 			else if ((boolopt[i].addr) == &flags.biff) { 2050. 			   if (flags.biff) lan_mail_init; 2051. 			   else lan_mail_finish; 2052. 			} 2053. #endif 2054. 			else if ((boolopt[i].addr) == &iflags.num_pad) 2055. 			   number_pad(iflags.num_pad ? 1 : 0); 2056. 2057. 			else if ((boolopt[i].addr) == &flags.lit_corridor) { 2058. 			   /*  2059. 			     * All corridor squares seen via night vision or  2060. * candles & lamps change. Update them by calling 2061. 			    * newsym on them. Don't do this if we are 2062. 			    * initializing the options --- the vision system 2063. 			    * isn't set up yet. 2064. 			    */  2065. 			    vision_recalc(2);		/* shut down vision */ 2066. 			   vision_full_recalc = 1;	/* delayed recalc */ 2067. 			} 2068. 			else if ((boolopt[i].addr) == &iflags.use_inverse) { 2069. 			   need_redraw = TRUE; 2070. 			} 2071. 			else if ((boolopt[i].addr) == &iflags.hilite_pet) { 2072. 			   need_redraw = TRUE; 2073. 			} 2074. #ifdef TEXTCOLOR 2075. 			else if ((boolopt[i].addr) == &iflags.use_color) { 2076. 			   need_redraw = TRUE; 2077. # ifdef TOS 2078. 			   if ((boolopt[i].addr) == &iflags.use_color  2079. 				&& iflags.BIOS) { 2080. 				if (colors_changed) 2081. 				   restore_colors; 2082. 				else 2083. 				   set_colors; 2084. 			   }  2085. # endif 2086. 			} 2087. #endif 2088. 2089. 			return; 2090. 		} 2091. 	}  2092.  2093. 	/* out of valid options */ 2094. 	badoption(opts); 2095. } 2096.  2097.  2098. static NEARDATA const char *menutype[] = { 2099. 	"traditional", "combination", "partial", "full" 2100. }; 2101.  2102. static NEARDATA const char *burdentype[] = { 2103. 	"unencumbered", "burdened", "stressed", 2104. 	"strained", "overtaxed", "overloaded" 2105. }; 2106.  2107.  2108. /*  2109.  * Convert the given string of object classes to a string of default object 2110. * symbols. 2111. */  2112. STATIC_OVL void 2113. oc_to_str(src,dest) 2114.    char *src, *dest; 2115. { 2116.     int i;  2117. 2118.    while ((i = (int) *src++) != 0) { 2119. 	if (i < 0 || i >= MAXOCLASSES) 2120. 	   impossible("oc_to_str:  illegal object class %d", i); 2121. 	else 2122. 	   *dest++ = def_oc_syms[i]; 2123.    }  2124.     *dest = '\0'; 2125. } 2126.  2127. /*  2128.  * Add the given mapping to the menu command map list. Always keep the 2129. * maps valid C strings. 2130. */  2131. void 2132. add_menu_cmd_alias(from_ch, to_ch) 2133.    char from_ch, to_ch; 2134. { 2135.     if (n_menu_mapped >= MAX_MENU_MAPPED_CMDS) 2136. 	pline("out of menu map space"); 2137.    else { 2138. 	mapped_menu_cmds[n_menu_mapped] = from_ch; 2139. 	mapped_menu_op[n_menu_mapped] = to_ch; 2140. 	n_menu_mapped++; 2141. 	mapped_menu_cmds[n_menu_mapped] = 0; 2142. 	mapped_menu_op[n_menu_mapped] = 0; 2143.    }  2144. }  2145.  2146. /*  2147.  * Map the given character to its corresponding menu command. If it 2148. * doesn't match anything, just return the original. 2149. */  2150. char 2151. map_menu_cmd(ch) 2152.    char ch; 2153. { 2154.     char *found = index(mapped_menu_cmds, ch); 2155.    if (found) { 2156. 	int idx = found - mapped_menu_cmds; 2157. 	ch = mapped_menu_op[idx]; 2158.    }  2159.     return ch; 2160. } 2161.  2162.  2163. #if defined(MICRO) || defined(MAC) 2164. # define OPTIONS_HEADING "OPTIONS" 2165. #else 2166. # define OPTIONS_HEADING "NETHACKOPTIONS" 2167. #endif 2168. 2169. static char fmtstr_doset_add_menu[] = "%s%-15s [%s]   "; 2170. static char fmtstr_doset_add_menu_tab[] = "%s\t[%s]"; 2171. 2172. STATIC_OVL void 2173. doset_add_menu(win, option, indexoffset) 2174.    winid win;			/* window to add to */ 2175.    const char *option;		/* option name */ 2176.    int indexoffset;		/* value to add to index in compopt[], or zero 2177. 				  if option cannot be changed */ 2178. { 2179.     const char *value = "unknown";		/* current value */ 2180.    char buf[BUFSZ], buf2[BUFSZ]; 2181.    anything any; 2182.    int i;  2183. 2184.    any.a_void = 0; 2185.    if (indexoffset == 0) { 2186. 	any.a_int = 0; 2187. 	value = get_compopt_value(option, buf2); 2188.    } else { 2189. 	for (i=0; compopt[i].name; i++) 2190. 	   if (strcmp(option, compopt[i].name) == 0) break; 2191. 2192. 	if (compopt[i].name) { 2193. 	   any.a_int = i + 1 + indexoffset; 2194. 	   value = get_compopt_value(option, buf2); 2195. 	} else { 2196. 	   /* We are trying to add an option not found in compopt[]. 2197. 	      This is almost certainly bad, but we'll let it through anyway 2198. 	      (with a zero value, so it can't be selected). */ 2199. 	    any.a_int = 0; 2200. 	} 2201.     }  2202.     /* "    " replaces "a - " -- assumes menus follow that style */ 2203.    if (!iflags.menu_tab_sep) 2204. 	Sprintf(buf, fmtstr_doset_add_menu, any.a_int ? "" : "   ", option, value); 2205.    else 2206. 	Sprintf(buf, fmtstr_doset_add_menu_tab, option, value); 2207.    add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED); 2208. } 2209.  2210. /* Changing options via menu by Per Liboriussen */ 2211. int 2212. doset 2213. { 2214. 	char buf[BUFSZ], buf2[BUFSZ]; 2215. 	int i, pass, boolcount, pick_cnt, pick_idx, opt_indx; 2216. 	boolean *bool_p; 2217. 	winid tmpwin; 2218. 	anything any; 2219. 	menu_item *pick_list; 2220. 	int indexoffset, startpass, endpass; 2221. 	boolean setinitial = FALSE, fromfile = FALSE; 2222. 	int biggest_name = 0; 2223. 2224. 	tmpwin = create_nhwindow(NHW_MENU); 2225. 	start_menu(tmpwin); 2226. 2227. 	any.a_void = 0; 2228. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, 2229. 		 "Booleans (selecting will toggle value):", MENU_UNSELECTED); 2230. 	any.a_int = 0; 2231. 	/* first list any other non-modifiable booleans, then modifiable ones */ 2232. 	for (pass = 0; pass <= 1; pass++) 2233. 	   for (i = 0; boolopt[i].name; i++) 2234. 		if ((bool_p = boolopt[i].addr) != 0 && 2235. 			((boolopt[i].optflags == DISP_IN_GAME && pass == 0) || 2236. 			 (boolopt[i].optflags == SET_IN_GAME && pass == 1))) { 2237. 		   if (bool_p == &flags.female) continue;  /* obsolete */ 2238. #ifdef WIZARD 2239. 		   if (bool_p == &iflags.sanity_check && !wizard) continue; 2240. 		   if (bool_p == &iflags.menu_tab_sep && !wizard) continue; 2241. #endif 2242. 		   if (is_wc_option(boolopt[i].name) &&  2243. 			!wc_supported(boolopt[i].name)) continue; 2244. 		   any.a_int = (pass == 0) ? 0 : i + 1; 2245. 		   if (!iflags.menu_tab_sep) 2246. 			Sprintf(buf, "%s%-13s [%s]", 2247. 			    pass == 0 ? "    " : "",  2248. 			    boolopt[i].name, *bool_p ? "true" : "false"); 2249. 		    else 2250. 			Sprintf(buf, "%s\t[%s]", 2251. 			    boolopt[i].name, *bool_p ? "true" : "false"); 2252. 		   add_menu(tmpwin, NO_GLYPH, &any, 0, 0,  2253. 			     ATR_NONE, buf, MENU_UNSELECTED); 2254. 		} 2255.  2256. 	boolcount = i;  2257. indexoffset = boolcount; 2258. 	any.a_void = 0; 2259. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED); 2260. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, 2261. 		 "Compounds (selecting will prompt for new value):",  2262. 		 MENU_UNSELECTED); 2263. 2264. 	startpass = DISP_IN_GAME; 2265. 	endpass = SET_IN_GAME; 2266. 2267. 	/* spin through the options to find the biggest name 2268.           and adjust the format string accordingly if needed */ 2269. 	biggest_name = 0; 2270. 	for (i = 0; compopt[i].name; i++) 2271. 		if (compopt[i].optflags >= startpass && compopt[i].optflags <= endpass && 2272. 		    strlen(compopt[i].name) > (unsigned) biggest_name) 2273. 			biggest_name = (int) strlen(compopt[i].name); 2274. 	if (biggest_name > 30) biggest_name = 30; 2275. 	if (!iflags.menu_tab_sep) 2276. 		Sprintf(fmtstr_doset_add_menu, "%%s%%-%ds [%%s]", biggest_name); 2277. 	 2278. 	/* deliberately put `name', `role', `race', `gender' first */ 2279. 	doset_add_menu(tmpwin, "name", 0); 2280. 	doset_add_menu(tmpwin, "role", 0); 2281. 	doset_add_menu(tmpwin, "race", 0); 2282. 	doset_add_menu(tmpwin, "gender", 0); 2283. 2284. 	for (pass = startpass; pass <= endpass; pass++) 2285. 	   for (i = 0; compopt[i].name; i++) 2286. 		if (compopt[i].optflags == pass) { 2287. 		    	if (!strcmp(compopt[i].name, "name") ||  2288. 		    	    !strcmp(compopt[i].name, "role") ||  2289. 		    	    !strcmp(compopt[i].name, "race") ||  2290. 		    	    !strcmp(compopt[i].name, "gender")) 2291. 		   	    	continue; 2292. 		   	else if (is_wc_option(compopt[i].name) &&  2293. 					!wc_supported(compopt[i].name)) 2294. 		   		continue; 2295. 		   	else 2296. 				doset_add_menu(tmpwin, compopt[i].name, 2297. 					(pass == DISP_IN_GAME) ? 0 : indexoffset); 2298. 		} 2299. #ifdef PREFIXES_IN_USE 2300. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED); 2301. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, 2302. 		 "Variable playground locations:", MENU_UNSELECTED); 2303. 	for (i = 0; i < PREFIX_COUNT; i++) 2304. 		doset_add_menu(tmpwin, fqn_prefix_names[i], 0); 2305. #endif 2306. 	end_menu(tmpwin, "Set what options?"); 2307. 	need_redraw = FALSE; 2308. 	if ((pick_cnt = select_menu(tmpwin, PICK_ANY, &pick_list)) > 0) { 2309. 	   /*  2310. 	     * Walk down the selection list and either invert the booleans 2311. 	    * or prompt for new values. In most cases, call parseoptions 2312. 	    * to take care of options that require special attention, like 2313. 	    * redraws. 2314. 	    */  2315. 	    for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) { 2316. 		opt_indx = pick_list[pick_idx].item.a_int - 1; 2317. 		if (opt_indx < boolcount) { 2318. 		   /* boolean option */ 2319. 		   Sprintf(buf, "%s%s", *boolopt[opt_indx].addr ? "!" : "",  2320. 			    boolopt[opt_indx].name); 2321. 		   parseoptions(buf, setinitial, fromfile); 2322. 		   if (wc_supported(boolopt[opt_indx].name)) 2323. 			preference_update(boolopt[opt_indx].name); 2324. 		} else { 2325. 		   /* compound option */ 2326. 		   opt_indx -= boolcount; 2327. 2328. 		    if (!special_handling(compopt[opt_indx].name, 2329. 							setinitial, fromfile)) { 2330. 			Sprintf(buf, "Set %s to what?", compopt[opt_indx].name); 2331. 			getlin(buf, buf2); 2332. 			Sprintf(buf, "%s:%s", compopt[opt_indx].name, buf2); 2333. 			/* pass the buck */ 2334. 			parseoptions(buf, setinitial, fromfile); 2335. 		   }  2336. 		    if (wc_supported(compopt[opt_indx].name)) 2337. 			preference_update(compopt[opt_indx].name); 2338. 		} 2339. 	    }  2340. 	    free((genericptr_t)pick_list); 2341. 	   pick_list = (menu_item *)0; 2342. 	} 2343.  2344. 	destroy_nhwindow(tmpwin); 2345. 	if (need_redraw) 2346. 	   (void) doredraw; 2347. 	return 0; 2348. } 2349.  2350. STATIC_OVL boolean 2351. special_handling(optname, setinitial, setfromfile) 2352. const char *optname; 2353. boolean setinitial,setfromfile; 2354. { 2355.     winid tmpwin; 2356.    anything any; 2357.    int i;  2358. char buf[BUFSZ]; 2359.    boolean retval = FALSE; 2360.     2361.     /* Special handling of menustyle, pickup_burden, and pickup_types, disclose options. */ 2362.     if (!strcmp("menustyle", optname)) { 2363. 	const char *style_name; 2364. 	menu_item *style_pick = (menu_item *)0; 2365.        tmpwin = create_nhwindow(NHW_MENU); 2366. 	start_menu(tmpwin); 2367. 	for (i = 0; i < SIZE(menutype); i++) { 2368. 		style_name = menutype[i]; 2369.    		/* note: separate `style_name' variable used 2370. 		  to avoid an optimizer bug in VAX C V2.3 */ 2371. 		any.a_int = i + 1; 2372. 		add_menu(tmpwin, NO_GLYPH, &any, *style_name, 0, 2373. 			 ATR_NONE, style_name, MENU_UNSELECTED); 2374.        }  2375. 	end_menu(tmpwin, "Select menustyle:"); 2376. 	if (select_menu(tmpwin, PICK_ONE, &style_pick) > 0) { 2377. 		flags.menu_style = style_pick->item.a_int - 1; 2378. 		free((genericptr_t)style_pick); 2379.        }  2380. 	destroy_nhwindow(tmpwin); 2381.        retval = TRUE; 2382.    } else if (!strcmp("pickup_burden", optname)) { 2383. 	const char *burden_name, *burden_letters = "ubsntl"; 2384. 	menu_item *burden_pick = (menu_item *)0; 2385.        tmpwin = create_nhwindow(NHW_MENU); 2386. 	start_menu(tmpwin); 2387. 	for (i = 0; i < SIZE(burdentype); i++) { 2388. 		burden_name = burdentype[i]; 2389. 		any.a_int = i + 1; 2390. 		add_menu(tmpwin, NO_GLYPH, &any, burden_letters[i], 0, 2391. 			 ATR_NONE, burden_name, MENU_UNSELECTED); 2392.        }  2393. 	end_menu(tmpwin, "Select encumbrance level:"); 2394. 	if (select_menu(tmpwin, PICK_ONE, &burden_pick) > 0) { 2395. 		flags.pickup_burden = burden_pick->item.a_int - 1; 2396. 		free((genericptr_t)burden_pick); 2397. 	} 2398. 	destroy_nhwindow(tmpwin); 2399. 	retval = TRUE; 2400.    } else if (!strcmp("pickup_types", optname)) { 2401. 	/* parseoptions will prompt for the list of types */ 2402. 	parseoptions(strcpy(buf, "pickup_types"), setinitial, setfromfile); 2403. 	retval = TRUE; 2404.    } else if (!strcmp("disclose", optname)) { 2405. 	int pick_cnt, pick_idx, opt_idx; 2406. 	menu_item *disclosure_category_pick = (menu_item *)0; 2407. 	/* 2408. 	 * The order of disclose_names[] 2409.         * must correspond to disclosure_options in decl.h  2410. */ 2411. 	static const char *disclosure_names[] = { 2412. 		"inventory", "attributes", "vanquished", "genocides", "conduct" 2413. 	}; 2414. 	int disc_cat[NUM_DISCLOSURE_OPTIONS]; 2415. 	const char *disclosure_name; 2416. 2417.         tmpwin = create_nhwindow(NHW_MENU); 2418. 	start_menu(tmpwin); 2419. 	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) { 2420. 		disclosure_name = disclosure_names[i]; 2421. 		any.a_int = i + 1; 2422. 		add_menu(tmpwin, NO_GLYPH, &any, disclosure_options[i], 0, 2423. 			 ATR_NONE, disclosure_name, MENU_UNSELECTED); 2424. 		disc_cat[i] = 0; 2425.        }  2426. 	end_menu(tmpwin, "Change which disclosure options categories:"); 2427. 	if ((pick_cnt = select_menu(tmpwin, PICK_ANY, &disclosure_category_pick)) > 0) { 2428. 	   for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) { 2429. 		opt_idx = disclosure_category_pick[pick_idx].item.a_int - 1; 2430. 		disc_cat[opt_idx] = 1; 2431. 	   }  2432. 	    free((genericptr_t)disclosure_category_pick); 2433. 	   disclosure_category_pick = (menu_item *)0; 2434. 	} 2435. 	destroy_nhwindow(tmpwin); 2436. 2437. 	for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) { 2438. 	   if (disc_cat[i]) { 2439. 	   	char dbuf[BUFSZ]; 2440. 		menu_item *disclosure_option_pick = (menu_item *)0; 2441. 		Sprintf(dbuf, "Disclosure options for %s:", disclosure_names[i]); 2442. 	       tmpwin = create_nhwindow(NHW_MENU); 2443. 		start_menu(tmpwin); 2444. 		any.a_char = DISCLOSE_NO_WITHOUT_PROMPT; 2445. 		add_menu(tmpwin, NO_GLYPH, &any, 'a', 0, 2446. 			ATR_NONE,"Never disclose and don't prompt", MENU_UNSELECTED); 2447. 		any.a_void = 0; 2448. 		any.a_char = DISCLOSE_YES_WITHOUT_PROMPT; 2449. 		add_menu(tmpwin, NO_GLYPH, &any, 'b', 0, 2450. 			ATR_NONE,"Always disclose and don't prompt", MENU_UNSELECTED); 2451. 		any.a_void = 0; 2452. 		any.a_char = DISCLOSE_PROMPT_DEFAULT_NO; 2453. 		add_menu(tmpwin, NO_GLYPH, &any, 'c', 0, 2454. 			ATR_NONE,"Prompt and default answer to \"No\"", MENU_UNSELECTED); 2455. 		any.a_void = 0; 2456. 		any.a_char = DISCLOSE_PROMPT_DEFAULT_YES; 2457. 		add_menu(tmpwin, NO_GLYPH, &any, 'd', 0, 2458. 			ATR_NONE,"Prompt and default answer to \"Yes\"", MENU_UNSELECTED); 2459. 		end_menu(tmpwin, dbuf); 2460. 		if (select_menu(tmpwin, PICK_ONE, &disclosure_option_pick) > 0) { 2461. 			flags.end_disclose[i] = disclosure_option_pick->item.a_char; 2462. 			free((genericptr_t)disclosure_option_pick); 2463. 		} 2464. 		destroy_nhwindow(tmpwin); 2465. 	   }  2466. 	}  2467. 	retval = TRUE; 2468.    }  2469.     return retval; 2470. } 2471.  2472. #define rolestring(val,array,field) ((val >= 0) ? array[val].field : \  2473. 				     (val == ROLE_RANDOM) ? randomrole : none) 2474. 2475. /* This is ugly. We have all the option names in the compopt[] array, 2476.   but we need to look at each option individually to get the value. */ 2477. STATIC_OVL const char * 2478. get_compopt_value(optname, buf) 2479. const char *optname; 2480. char *buf; 2481. { 2482. 	char ocl[MAXOCLASSES+1]; 2483. 	static const char none[] = "(none)", randomrole[] = "random", 2484. 		    to_be_done[] = "(to be done)", 2485. 		    defopt[] = "default", 2486. 		    defbrief[] = "def"; 2487. 	int i; 2488. 2489. 	buf[0] = '\0'; 2490. 	if (!strcmp(optname,"align_message")) 2491. 		Sprintf(buf, "%s", iflags.wc_align_message == ALIGN_TOP    ? "top" :  2492. 				   iflags.wc_align_message == ALIGN_LEFT    ? "left" :  2493. 				   iflags.wc_align_message == ALIGN_BOTTOM  ? "bottom" :  2494. 				   iflags.wc_align_message == ALIGN_RIGHT   ? "right" :  2495. 				   defopt); 2496. 	else if (!strcmp(optname,"align_status")) 2497. 		Sprintf(buf, "%s", iflags.wc_align_status == ALIGN_TOP    ? "top" :  2498. 				   iflags.wc_align_status == ALIGN_LEFT    ? "left" :  2499. 				   iflags.wc_align_status == ALIGN_BOTTOM  ? "bottom" :  2500. 				   iflags.wc_align_status == ALIGN_RIGHT   ? "right" :  2501. 				   defopt); 2502. 	else if (!strcmp(optname,"align")) 2503. 		Sprintf(buf, "%s", rolestring(flags.initalign, aligns, adj)); 2504. 	else if (!strcmp(optname, "boulder")) 2505. 		Sprintf(buf, "%c", iflags.bouldersym ? 2506. 			iflags.bouldersym : oc_syms[(int)objects[BOULDER].oc_class]); 2507. 	else if (!strcmp(optname, "catname")) 2508. 		Sprintf(buf, "%s", catname[0] ? catname : none ); 2509. 	else if (!strcmp(optname, "disclose")) { 2510. 		for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) { 2511. 			char topt[2]; 2512. 			if (i) Strcat(buf," "); 2513. 			topt[1] = '\0'; 2514. 			topt[0] = flags.end_disclose[i]; 2515. 			Strcat(buf, topt); 2516. 			topt[0] = disclosure_options[i]; 2517. 			Strcat(buf, topt); 2518. 		} 2519. 	}  2520. 	else if (!strcmp(optname, "dogname")) 2521. 		Sprintf(buf, "%s", dogname[0] ? dogname : none ); 2522. 	else if (!strcmp(optname, "dungeon")) 2523. 		Sprintf(buf, "%s", to_be_done); 2524. 	else if (!strcmp(optname, "effects")) 2525. 		Sprintf(buf, "%s", to_be_done); 2526. 	else if (!strcmp(optname, "font_map")) 2527. 		Sprintf(buf, "%s", iflags.wc_font_map ? iflags.wc_font_map : defopt); 2528. 	else if (!strcmp(optname, "font_message")) 2529. 		Sprintf(buf, "%s", iflags.wc_font_message ? iflags.wc_font_message : defopt); 2530. 	else if (!strcmp(optname, "font_status")) 2531. 		Sprintf(buf, "%s", iflags.wc_font_status ? iflags.wc_font_status : defopt); 2532. 	else if (!strcmp(optname, "font_menu")) 2533. 		Sprintf(buf, "%s", iflags.wc_font_menu ? iflags.wc_font_menu : defopt); 2534. 	else if (!strcmp(optname, "font_text")) 2535. 		Sprintf(buf, "%s", iflags.wc_font_text ? iflags.wc_font_text : defopt); 2536. 	else if (!strcmp(optname, "font_size_map")) { 2537. 		if (iflags.wc_fontsiz_map) Sprintf(buf, "%d", iflags.wc_fontsiz_map); 2538. 		else Strcpy(buf, defopt); 2539. 	} 2540. 	else if (!strcmp(optname, "font_size_message")) { 2541. 		if (iflags.wc_fontsiz_message) Sprintf(buf, "%d", 2542. 							iflags.wc_fontsiz_message); 2543. 		else Strcpy(buf, defopt); 2544. 	} 2545. 	else if (!strcmp(optname, "font_size_status")) { 2546. 		if (iflags.wc_fontsiz_status) Sprintf(buf, "%d", iflags.wc_fontsiz_status); 2547. 		else Strcpy(buf, defopt); 2548. 	} 2549. 	else if (!strcmp(optname, "font_size_menu")) { 2550. 		if (iflags.wc_fontsiz_menu) Sprintf(buf, "%d", iflags.wc_fontsiz_menu); 2551. 		else Strcpy(buf, defopt); 2552. 	} 2553. 	else if (!strcmp(optname, "font_size_text")) { 2554. 		if (iflags.wc_fontsiz_text) Sprintf(buf, "%d",iflags.wc_fontsiz_text); 2555. 		else Strcpy(buf, defopt); 2556. 	} 2557. 	else if (!strcmp(optname, "fruit")) 2558. 		Sprintf(buf, "%s", pl_fruit); 2559. 	else if (!strcmp(optname, "gender")) 2560. 		Sprintf(buf, "%s", rolestring(flags.initgend, genders, adj)); 2561. 	else if (!strcmp(optname, "horsename")) 2562. 		Sprintf(buf, "%s", horsename[0] ? horsename : none); 2563. 	else if (!strcmp(optname, "map_mode")) 2564. 		Sprintf(buf, "%s", 2565. 			iflags.wc_map_mode == MAP_MODE_TILES      ? "tiles" :  2566. 			iflags.wc_map_mode == MAP_MODE_ASCII4x6   ? "ascii4x6" :  2567. 			iflags.wc_map_mode == MAP_MODE_ASCII6x8   ? "ascii6x8" :  2568. 			iflags.wc_map_mode == MAP_MODE_ASCII8x8   ? "ascii8x8" :  2569. 			iflags.wc_map_mode == MAP_MODE_ASCII16x8  ? "ascii16x8" :  2570. 			iflags.wc_map_mode == MAP_MODE_ASCII7x12  ? "ascii7x12" :  2571. 			iflags.wc_map_mode == MAP_MODE_ASCII8x12  ? "ascii8x12" :  2572. 			iflags.wc_map_mode == MAP_MODE_ASCII16x12 ? "ascii16x12" :  2573. 			iflags.wc_map_mode == MAP_MODE_ASCII12x16 ? "ascii12x16" :  2574. 			iflags.wc_map_mode == MAP_MODE_ASCII10x18 ? "ascii10x18" :  2575. 			iflags.wc_map_mode == MAP_MODE_ASCII_FIT_TO_SCREEN ?  2576. 			"fit_to_screen" : defopt); 2577. 	else if (!strcmp(optname, "menustyle")) 2578. 		Sprintf(buf, "%s", menutype[(int)flags.menu_style] ); 2579. 	else if (!strcmp(optname, "menu_deselect_all")) 2580. 		Sprintf(buf, "%s", to_be_done); 2581. 	else if (!strcmp(optname, "menu_deselect_page")) 2582. 		Sprintf(buf, "%s", to_be_done); 2583. 	else if (!strcmp(optname, "menu_first_page")) 2584. 		Sprintf(buf, "%s", to_be_done); 2585. 	else if (!strcmp(optname, "menu_invert_all")) 2586. 		Sprintf(buf, "%s", to_be_done); 2587. 	else if (!strcmp(optname, "menu_invert_page")) 2588. 		Sprintf(buf, "%s", to_be_done); 2589. 	else if (!strcmp(optname, "menu_last_page")) 2590. 		Sprintf(buf, "%s", to_be_done); 2591. 	else if (!strcmp(optname, "menu_next_page")) 2592. 		Sprintf(buf, "%s", to_be_done); 2593. 	else if (!strcmp(optname, "menu_previous_page")) 2594. 		Sprintf(buf, "%s", to_be_done); 2595. 	else if (!strcmp(optname, "menu_search")) 2596. 		Sprintf(buf, "%s", to_be_done); 2597. 	else if (!strcmp(optname, "menu_select_all")) 2598. 		Sprintf(buf, "%s", to_be_done); 2599. 	else if (!strcmp(optname, "menu_select_page")) 2600. 		Sprintf(buf, "%s", to_be_done); 2601. 	else if (!strcmp(optname, "monsters")) 2602. 		Sprintf(buf, "%s", to_be_done); 2603. 	else if (!strcmp(optname, "msghistory")) 2604. 		Sprintf(buf, "%u", iflags.msg_history); 2605. 	else if (!strcmp(optname, "name")) 2606. 		Sprintf(buf, "%s", plname); 2607. 	else if (!strcmp(optname, "objects")) 2608. 		Sprintf(buf, "%s", to_be_done); 2609. 	else if (!strcmp(optname, "packorder")) { 2610. 		oc_to_str(flags.inv_order, ocl); 2611. 		Sprintf(buf, "%s", ocl); 2612. 	    }  2613. #ifdef CHANGE_COLOR 2614. 	else if (!strcmp(optname, "palette")) 2615. 		Sprintf(buf, "%s", get_color_string); 2616. #endif 2617. 	else if (!strcmp(optname, "pettype")) 2618. 		Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat" : 2619. 				(preferred_pet == 'd') ? "dog" :  2620. 				(preferred_pet == 'n') ? "none" : "random"); 2621. 	else if (!strcmp(optname, "pickup_burden")) 2622. 		Sprintf(buf, "%s", burdentype[flags.pickup_burden] ); 2623. 	else if (!strcmp(optname, "pickup_types")) { 2624. 		oc_to_str(flags.pickup_types, ocl); 2625. 		Sprintf(buf, "%s", ocl[0] ? ocl : "all" ); 2626. 	    }  2627. 	else if (!strcmp(optname, "race")) 2628. 		Sprintf(buf, "%s", rolestring(flags.initrace, races, noun)); 2629. 	else if (!strcmp(optname, "role")) 2630. 		Sprintf(buf, "%s", rolestring(flags.initrole, roles, name.m)); 2631. 	else if (!strcmp(optname, "scores")) { 2632. 		Sprintf(buf, "%d top/%d around%s", flags.end_top, 2633. 				flags.end_around, flags.end_own ? "/own" : ""); 2634. 	} 2635. 	else if (!strcmp(optname, "scroll_margin")) { 2636. 		if (iflags.wc_scroll_margin) Sprintf(buf, "%d",iflags.wc_scroll_margin); 2637. 		else Strcpy(buf, defopt); 2638. 	} 2639. 	else if (!strcmp(optname, "player_selection")) 2640. 		Sprintf(buf, "%s", iflags.wc_player_selection ? "prompts" : "dialog"); 2641. #ifdef MSDOS 2642. 	else if (!strcmp(optname, "soundcard")) 2643. 		Sprintf(buf, "%s", to_be_done); 2644. #endif 2645. 	else if (!strcmp(optname, "suppress_alert")) { 2646. 	   if (flags.suppress_alert == 0L) 2647. 		Strcpy(buf, none); 2648. 	   else 2649. 		Sprintf(buf, "%lu.%lu.%lu", 2650. 			FEATURE_NOTICE_VER_MAJ,  2651. 			FEATURE_NOTICE_VER_MIN,  2652. 			FEATURE_NOTICE_VER_PATCH); 2653. 	} 2654. 	else if (!strcmp(optname, "tile_file")) 2655. 		Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt); 2656. 	else if (!strcmp(optname, "tile_height")) { 2657. 		if (iflags.wc_tile_height) Sprintf(buf, "%d",iflags.wc_tile_height); 2658. 		else Strcpy(buf, defopt); 2659. 	} 2660. 	else if (!strcmp(optname, "tile_width")) { 2661. 		if (iflags.wc_tile_width) Sprintf(buf, "%d",iflags.wc_tile_width); 2662. 		else Strcpy(buf, defopt); 2663. 	} 2664. 	else if (!strcmp(optname, "traps")) 2665. 		Sprintf(buf, "%s", to_be_done); 2666. 	else if (!strcmp(optname, "vary_msgcount")) { 2667. 		if (iflags.wc_vary_msgcount) Sprintf(buf, "%d",iflags.wc_vary_msgcount); 2668. 		else Strcpy(buf, defopt); 2669. 	} 2670. #ifdef MSDOS 2671. 	else if (!strcmp(optname, "video")) 2672. 		Sprintf(buf, "%s", to_be_done); 2673. #endif 2674. #ifdef VIDEOSHADES 2675. 	else if (!strcmp(optname, "videoshades")) 2676. 		Sprintf(buf, "%s-%s-%s", shade[0],shade[1],shade[2]); 2677. 	else if (!strcmp(optname, "videocolors")) 2678. 		Sprintf(buf, "%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d-%d", 2679. 			ttycolors[CLR_RED], ttycolors[CLR_GREEN],  2680. 			ttycolors[CLR_BROWN], ttycolors[CLR_BLUE],  2681. 			ttycolors[CLR_MAGENTA], ttycolors[CLR_CYAN],  2682. 			ttycolors[CLR_ORANGE], ttycolors[CLR_BRIGHT_GREEN],  2683. 			ttycolors[CLR_YELLOW], ttycolors[CLR_BRIGHT_BLUE],  2684. 			ttycolors[CLR_BRIGHT_MAGENTA],  2685. 			ttycolors[CLR_BRIGHT_CYAN]); 2686. #endif /* VIDEOSHADES */ 2687. 	else if (!strcmp(optname, "windowtype")) 2688. 		Sprintf(buf, "%s", windowprocs.name); 2689. 	else if (!strcmp(optname, "windowcolors")) 2690. 		Sprintf(buf, "%s/%s %s/%s %s/%s %s/%s", 2691. 			iflags.wc_foregrnd_menu    ? iflags.wc_foregrnd_menu : defbrief,  2692. 			iflags.wc_backgrnd_menu    ? iflags.wc_backgrnd_menu : defbrief,  2693. 			iflags.wc_foregrnd_message ? iflags.wc_foregrnd_message : defbrief,  2694. 			iflags.wc_backgrnd_message ? iflags.wc_backgrnd_message : defbrief,  2695. 			iflags.wc_foregrnd_status  ? iflags.wc_foregrnd_status : defbrief,  2696. 			iflags.wc_backgrnd_status  ? iflags.wc_backgrnd_status : defbrief,  2697. 			iflags.wc_foregrnd_text    ? iflags.wc_foregrnd_text : defbrief,  2698. 			iflags.wc_backgrnd_text    ? iflags.wc_backgrnd_text : defbrief); 2699. #ifdef PREFIXES_IN_USE 2700. 	else { 2701. 	   for (i = 0; i < PREFIX_COUNT; ++i) 2702. 		if (!strcmp(optname, fqn_prefix_names[i]) && fqn_prefix[i]) 2703. 			Sprintf(buf, "%s", fqn_prefix[i]); 2704. 	} 2705. #endif 2706. 2707. 	if (buf[0]) return buf; 2708. 	else return "unknown"; 2709. } 2710.  2711. int 2712. dotogglepickup 2713. { 2714. 	char buf[BUFSZ], ocl[MAXOCLASSES+1]; 2715. 2716. 	flags.pickup = !flags.pickup; 2717. 	if (flags.pickup) { 2718. 	   oc_to_str(flags.pickup_types, ocl); 2719. 	   Sprintf(buf, "ON, for %s objects", ocl[0] ? ocl : "all"); 2720. 	} else { 2721. 	   Strcpy(buf, "OFF"); 2722. 	} 2723. 	pline("Autopickup: %s.", buf); 2724. 	return 0; 2725. } 2726.  2727. /* data for option_help */ 2728. static const char *opt_intro[] = { 2729. 	"", 2730. 	"                 NetHack Options Help:", 2731. 	"", 2732. #define CONFIG_SLOT 3	/* fill in next value at run-time */ 2733. 	(char *)0, 2734. #if !defined(MICRO) && !defined(MAC) 2735. 	"or use `NETHACKOPTIONS=\" \"' in your environment", 2736. #endif 2737. 	"( is a list of options separated by commas)", 2738. #ifdef VMS 2739. 	"-- for example, $ DEFINE NETHACKOPTIONS \"noautopickup,fruit:kumquat\"", 2740. #endif 2741. 	"or press \"O\" while playing and use the menu.", 2742. 	"", 2743.  "Boolean options (which can be negated by prefixing them with '!' or \"no\"):", 2744. 	(char *)0 2745. }; 2746.  2747. static const char *opt_epilog[] = { 2748. 	"", 2749.  "Some of the options can be set only before the game is started; those", 2750. 	"items will not be selectable in the 'O' command's menu.", 2751. 	(char *)0 2752. }; 2753.  2754. void 2755. option_help 2756. { 2757.     char buf[BUFSZ], buf2[BUFSZ]; 2758.    register int i;  2759. winid datawin; 2760. 2761.     datawin = create_nhwindow(NHW_TEXT); 2762.    Sprintf(buf, "Set options as OPTIONS= in %s", configfile); 2763.    opt_intro[CONFIG_SLOT] = (const char *) buf; 2764.    for (i = 0; opt_intro[i]; i++) 2765. 	putstr(datawin, 0, opt_intro[i]); 2766. 2767.     /* Boolean options */ 2768.    for (i = 0; boolopt[i].name; i++) { 2769. 	if (boolopt[i].addr) { 2770. #ifdef WIZARD 2771. 	   if (boolopt[i].addr == &iflags.sanity_check && !wizard) continue; 2772. 	   if (boolopt[i].addr == &iflags.menu_tab_sep && !wizard) continue; 2773. #endif 2774. 	   next_opt(datawin, boolopt[i].name); 2775. 	} 2776.     }  2777.     next_opt(datawin, ""); 2778. 2779.     /* Compound options */ 2780.    putstr(datawin, 0, "Compound options:"); 2781.    for (i = 0; compopt[i].name; i++) { 2782. 	Sprintf(buf2, "`%s'", compopt[i].name); 2783. 	Sprintf(buf, "%-20s - %s%c", buf2, compopt[i].descr, 2784. 		compopt[i+1].name ? ',' : '.'); 2785. 	putstr(datawin, 0, buf); 2786.    }  2787.  2788.     for (i = 0; opt_epilog[i]; i++) 2789. 	putstr(datawin, 0, opt_epilog[i]); 2790. 2791.     display_nhwindow(datawin, FALSE); 2792.    destroy_nhwindow(datawin); 2793.    return; 2794. } 2795.  2796. /*  2797.  * prints the next boolean option, on the same line if possible, on a new 2798. * line if not. End with next_opt(""). 2799. */  2800. void 2801. next_opt(datawin, str) 2802. winid datawin; 2803. const char *str; 2804. { 2805. 	static char *buf = 0; 2806. 	int i; 2807. char *s; 2808. 2809. 	if (!buf) *(buf = (char *)alloc(BUFSZ)) = '\0'; 2810. 2811. 	if (!*str) { 2812. 		s = eos(buf); 2813. 		if (s > &buf[1] && s[-2] == ',') 2814. 		   Strcpy(s - 2, ".");	/* replace last ", " */ 2815. 		i = COLNO;	/* (greater than COLNO - 2) */ 2816. 	} else { 2817. 		i = strlen(buf) + strlen(str) + 2; 2818. 	} 2819.  2820. 	if (i > COLNO - 2) { /* rule of thumb */ 2821. 		putstr(datawin, 0, buf); 2822. 		buf[0] = 0; 2823. 	} 2824. 	if (*str) { 2825. 		Strcat(buf, str); 2826. 		Strcat(buf, ", "); 2827. 	} else { 2828. 		putstr(datawin, 0, str); 2829. 		free(buf), buf = 0; 2830. 	} 2831. 	return; 2832. } 2833.  2834. /* Returns the fid of the fruit type; if that type already exists, it  2835. * returns the fid of that one; if it does not exist, it adds a new fruit 2836. * type to the chain and returns the new one. 2837. */  2838. int 2839. fruitadd(str) 2840. char *str; 2841. { 2842. 	register int i;  2843. register struct fruit *f; 2844. 	struct fruit *lastf = 0; 2845. 	int highest_fruit_id = 0; 2846. 	char buf[PL_FSIZ]; 2847. 	boolean user_specified = (str == pl_fruit); 2848. 	/* if not user-specified, then it's a fruit name for a fruit on 2849. * a bones level... 2850. */ 2851.  2852. 	/* Note: every fruit has an id (spe for fruit objects) of at least 2853. 	 * 1; 0 is an error. 2854. 	 */ 2855. 	if (user_specified) { 2856. 		/* disallow naming after other foods (since it'd be impossible 2857. 		 * to tell the difference) 2858. 		 */ 2859.  2860. 		boolean found = FALSE, numeric = FALSE; 2861. 2862. 		for (i = bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS;  2863. 						i++) { 2864. 			if (!strcmp(OBJ_NAME(objects[i]), pl_fruit)) { 2865. 				found = TRUE; 2866. 				break; 2867. 			} 2868. 		}  2869. 		{  2870. 		    char *c; 2871. 2872. 		    c = pl_fruit; 2873. 2874. 		    for(c = pl_fruit; *c >= '0' && *c <= '9'; c++) 2875. 			; 2876. 		    if (isspace(*c) || *c == 0) numeric = TRUE; 2877. 		} 2878. 		if (found || numeric ||  2879. 		    !strncmp(str, "cursed ", 7) ||  2880. 		    !strncmp(str, "uncursed ", 9) ||  2881. 		    !strncmp(str, "blessed ", 8) ||  2882. 		    !strncmp(str, "partly eaten ", 13) ||  2883. 		    (!strncmp(str, "tin of ", 7) && 2884. 			(!strcmp(str+7, "spinach") || 2885. 			 name_to_mon(str+7) >= LOW_PM)) ||  2886. 		    !strcmp(str, "empty tin") ||  2887. 		    ((!strncmp(eos(str)-7," corpse",7) ||  2888. 			    !strncmp(eos(str)-4, " egg",4)) && 2889. 			name_to_mon(str) >= LOW_PM)) 2890. 			{ 2891. 				Strcpy(buf, pl_fruit); 2892. 				Strcpy(pl_fruit, "candied "); 2893. 				nmcpy(pl_fruit+8, buf, PL_FSIZ-8); 2894. 		} 2895. 	}  2896. 	for(f=ffruit; f; f = f->nextf) { 2897. 		lastf = f; 2898. if(f->fid > highest_fruit_id) highest_fruit_id = f->fid; 2899. 		if(!strncmp(str, f->fname, PL_FSIZ)) 2900. 			goto nonew; 2901. 	} 2902. 	/* if adding another fruit would overflow spe, use a random 2903. 	  fruit instead... we've got a lot to choose from. */ 2904. 	if (highest_fruit_id >= 127) return rnd(127); 2905. 	highest_fruit_id++; 2906. 	f = newfruit; 2907. 	if (ffruit) lastf->nextf = f; 2908. else ffruit = f; 2909. Strcpy(f->fname, str); 2910. 	f->fid = highest_fruit_id; 2911. 	f->nextf = 0; 2912. nonew: 2913. 	if (user_specified) current_fruit = highest_fruit_id; 2914. 	return f->fid; 2915. } 2916.  2917. /*  2918.  * This is a somewhat generic menu for taking a list of NetHack style 2919. * class choices and presenting them via a description 2920. * rather than the traditional NetHack characters. 2921. * (Benefits users whose first exposure to NetHack is via tiles). 2922. *  2923.  * prompt 2924. *	     The title at the top of the menu. 2925. *  2926.  * category: 0 = monster class 2927. *           1 = object  class 2928. *  2929.  * way 2930. *	     FALSE = PICK_ONE, TRUE = PICK_ANY 2931. *  2932.  * class_list 2933. *	     a null terminated string containing the list of choices. 2934. *  2935.  * class_selection 2936. *	     a null terminated string containing the selected characters. 2937. *  2938.  * Returns number selected. 2939. */  2940. int 2941. choose_classes_menu(prompt, category, way, class_list, class_select) 2942. const char *prompt; 2943. int category; 2944. boolean way; 2945. char *class_list; 2946. char *class_select; 2947. { 2948.     menu_item *pick_list = (menu_item *)0; 2949.    winid win; 2950.    anything any; 2951.    char buf[BUFSZ]; 2952.    int i, n;  2953. int ret; 2954.    int next_accelerator, accelerator; 2955. 2956.     if (class_list == (char *)0 || class_select == (char *)0) return 0; 2957.    accelerator = 0; 2958.    next_accelerator = 'a'; 2959.    any.a_void = 0; 2960.    win = create_nhwindow(NHW_MENU); 2961.    start_menu(win); 2962.    while (*class_list) { 2963. 	const char *text; 2964. 	boolean selected; 2965. 2966. 	text = (char *)0; 2967. 	selected = FALSE; 2968. 	switch (category) { 2969. 		case 0: 2970. 			text = monexplain[def_char_to_monclass(*class_list)]; 2971. 			accelerator = *class_list; 2972. 			Sprintf(buf, "%s", text); 2973. 			break; 2974. 		case 1: 2975. 			text = objexplain[def_char_to_objclass(*class_list)]; 2976. 			accelerator = next_accelerator; 2977. 			Sprintf(buf, "%c %s", *class_list, text); 2978. 			break; 2979. 		default: 2980. 			impossible("choose_classes_menu: invalid category %d", 2981. 					category); 2982. 	} 2983. 	if (way && *class_select) {	/* Selections there already */ 2984. 		if (index(class_select, *class_list)) { 2985. 			selected = TRUE; 2986. 		} 2987. 	}  2988. 	any.a_int = *class_list; 2989. 	add_menu(win, NO_GLYPH, &any, accelerator, 2990. 		  category ? *class_list : 0,  2991. 		  ATR_NONE, buf, selected); 2992. 	++class_list; 2993. 	if (category > 0) { 2994. 		++next_accelerator; 2995. 		if (next_accelerator == ('z' + 1)) next_accelerator = 'A'; 2996. 		if (next_accelerator == ('Z' + 1)) break; 2997. 	} 2998.     }  2999.     end_menu(win, prompt); 3000.    n = select_menu(win, way ? PICK_ANY : PICK_ONE, &pick_list); 3001.    destroy_nhwindow(win); 3002.    if (n > 0) { 3003. 	for (i = 0; i < n; ++i) 3004. 	   *class_select++ = (char)pick_list[i].item.a_int; 3005. 	free((genericptr_t)pick_list); 3006. 	ret = n; 3007. } else if (n == -1) { 3008. 	class_select = eos(class_select); 3009. 	ret = -1; 3010.    } else 3011. 	ret = 0; 3012.    *class_select = '\0'; 3013.    return ret; 3014. } 3015.  3016. struct wc_Opt wc_options[] = { 3017. 	{"ascii_map", WC_ASCII_MAP}, 3018. 	{"color", WC_COLOR}, 3019. 	{"eight_bit_tty", WC_EIGHT_BIT_IN}, 3020. 	{"hilite_pet", WC_HILITE_PET}, 3021. 	{"large_font", WC_LARGE_FONT},	/* now obsolete */ 3022. 	{"popup_dialog", WC_POPUP_DIALOG}, 3023. 	{"preload_tiles", WC_PRELOAD_TILES}, 3024. 	{"tiled_map", WC_TILED_MAP}, 3025. 	{"tile_file", WC_TILE_FILE}, 3026. 	{"tile_width", WC_TILE_WIDTH}, 3027. 	{"tile_height", WC_TILE_HEIGHT}, 3028. 	{"use_inverse", WC_INVERSE}, 3029. 	{"align_message", WC_ALIGN_MESSAGE}, 3030. 	{"align_status", WC_ALIGN_STATUS}, 3031. 	{"font_map", WC_FONT_MAP}, 3032. 	{"font_menu", WC_FONT_MENU}, 3033. 	{"font_message",WC_FONT_MESSAGE}, 3034. #if 0 3035. 	{"perm_invent",WC_PERM_INVENT}, 3036. #endif 3037. 	{"font_size_map", WC_FONTSIZ_MAP}, 3038. 	{"font_size_menu", WC_FONTSIZ_MENU}, 3039. 	{"font_size_message", WC_FONTSIZ_MESSAGE}, 3040. 	{"font_size_status", WC_FONTSIZ_STATUS}, 3041. 	{"font_size_text", WC_FONTSIZ_TEXT}, 3042. 	{"font_status", WC_FONT_STATUS}, 3043. 	{"font_text", WC_FONT_TEXT}, 3044. 	{"map_mode", WC_MAP_MODE}, 3045. 	{"scroll_margin", WC_SCROLL_MARGIN}, 3046. 	{"vary_msgcount",WC_VARY_MSGCOUNT}, 3047. 	{(char *)0, 0L} 3048. }; 3049.  3050.  3051. /*  3052.  * If a port wants to change or ensure that the 3053. * SET_IN_FILE, DISP_IN_GAME, or SET_IN_GAME status of an option is  3054. * correct (for controlling its display in the option menu) call 3055. * set_option_mod_status 3056. * with the second argument of 0,2, or 3 respectively. 3057. */  3058. void 3059. set_option_mod_status(optnam, status) 3060. char *optnam; 3061. int status; 3062. { 3063. 	int k;  3064. if (status < SET_IN_FILE || status > SET_IN_GAME) { 3065. 		impossible("set_option_mod_status: status out of range %d.", status); 3066. 		return; 3067. 	} 3068. 	for (k = 0; boolopt[k].name; k++) { 3069. 		if (!strncmpi(boolopt[k].name, optnam, strlen(optnam))) { 3070. 			boolopt[k].optflags = status; 3071. 			return; 3072. 		} 3073. 	}  3074. 	for (k = 0; compopt[k].name; k++) { 3075. 		if (!strncmpi(compopt[k].name, optnam, strlen(optnam))) { 3076. 			compopt[k].optflags = status; 3077. 			return; 3078. 		} 3079. 	}  3080. }  3081.  3082. /*  3083.  * You can set several wc_options in one call to  3084. * set_wc_option_mod_status by setting 3085. * the appropriate bits for each option that you 3086. * are setting in the optmask argument 3087. * prior to calling. 3088. *    example: set_wc_option_mod_status(WC_COLOR|WC_SCROLL_MARGIN, SET_IN_GAME); 3089. */  3090. void 3091. set_wc_option_mod_status(optmask, status) 3092. unsigned long optmask; 3093. int status; 3094. { 3095. 	int k = 0; 3096. 	if (status < SET_IN_FILE || status > SET_IN_GAME) { 3097. 		impossible("set_option_mod_status: status out of range %d.", status); 3098. 		return; 3099. 	} 3100. 	while (wc_options[k].wc_name) { 3101. 		if (optmask & wc_options[k].wc_bit) { 3102. 			set_option_mod_status(wc_options[k].wc_name, status); 3103. 		} 3104. 		k++; 3105. 	} 3106. }  3107.  3108. STATIC_OVL boolean 3109. is_wc_option(optnam) 3110. const char *optnam; 3111. { 3112. 	int k = 0; 3113. 	while (wc_options[k].wc_name) { 3114. 		if (strcmp(wc_options[k].wc_name, optnam) == 0) 3115. 			return TRUE; 3116. 		k++; 3117. 	} 3118. 	return FALSE; 3119. } 3120.  3121. STATIC_OVL boolean 3122. wc_supported(optnam) 3123. const char *optnam; 3124. { 3125. 	int k = 0; 3126. 	while (wc_options[k].wc_name) { 3127. 		if (!strcmp(wc_options[k].wc_name, optnam) && 3128. 		    (windowprocs.wincap & wc_options[k].wc_bit)) 3129. 			return TRUE; 3130. 		k++; 3131. 	} 3132. 	return FALSE; 3133. } 3134.  3135. STATIC_OVL void 3136. wc_set_font_name(wtype, fontname) 3137. int wtype; 3138. char *fontname; 3139. { 3140. 	char **fn = (char **)0; 3141. 	if (!fontname) return; 3142. 	switch(wtype) { 3143. 	   case NHW_MAP: 3144. 	   		fn = &iflags.wc_font_map; 3145. 			break; 3146. 	   case NHW_MESSAGE: 3147. 	   		fn = &iflags.wc_font_message; 3148. 			break; 3149. 	   case NHW_TEXT: 3150. 	   		fn = &iflags.wc_font_text; 3151. 			break; 3152. 	   case NHW_MENU: 3153. 	   		fn = &iflags.wc_font_menu; 3154. 			break; 3155. 	   case NHW_STATUS: 3156. 	   		fn = &iflags.wc_font_status; 3157. 			break; 3158. 	   default: 3159. 	   		return; 3160. 	} 3161. 	if (fn) { 3162. 		if (*fn) free(*fn); 3163. 		*fn = (char *)alloc(strlen(fontname) + 1); 3164. 		Strcpy(*fn, fontname); 3165. 	} 3166. 	return; 3167. } 3168.  3169. STATIC_OVL int 3170. wc_set_window_colors(op) 3171. char *op; 3172. { 3173. 	/* syntax: 3174. 	 * menu white/black message green/yellow status white/blue text white/black 3175. 	 */ 3176.  3177. 	int j;  3178. char buf[BUFSZ]; 3179. 	char *wn, *tfg, *tbg, *newop; 3180. 	static char *wnames[] = {"menu", "message", "status", "text"}; 3181. 	static char *shortnames[] = {"mnu", "msg", "sts", "txt"}; 3182. 	static char **fgp[] = { 3183. 		&iflags.wc_foregrnd_menu, 3184. 		&iflags.wc_foregrnd_message, 3185. 		&iflags.wc_foregrnd_status, 3186. 		&iflags.wc_foregrnd_text 3187. 	}; 3188. 	static char **bgp[] = { 3189. 		&iflags.wc_backgrnd_menu, 3190. 		&iflags.wc_backgrnd_message, 3191. 		&iflags.wc_backgrnd_status, 3192. 		&iflags.wc_backgrnd_text 3193. 	}; 3194.  3195. 	Strcpy(buf, op); 3196. 	newop = mungspaces(buf); 3197. 	while (newop && *newop) { 3198. 3199. 		wn = tfg = tbg = (char *)0; 3200. 3201. 		/* until first non-space in case there's leading spaces - before colorname*/ 3202. 		while(*newop && isspace(*newop)) newop++; 3203. 		if (*newop) wn = newop; 3204. 		else return 0; 3205. 3206. 		/* until first space - colorname*/ 3207. 		while(*newop && !isspace(*newop)) newop++; 3208. 		if (*newop) *newop = '\0'; 3209. 		else return 0; 3210. 		newop++; 3211. 3212. 		/* until first non-space - before foreground*/ 3213. 		while(*newop && isspace(*newop)) newop++; 3214. 		if (*newop) tfg = newop; 3215. 		else return 0; 3216. 3217. 		/* until slash - foreground */ 3218. 		while(*newop && *newop != '/') newop++; 3219. 		if (*newop) *newop = '\0'; 3220. 		else return 0; 3221. 		newop++; 3222. 3223. 		/* until first non-space (in case there's leading space after slash) - before background */ 3224. 		while(*newop && isspace(*newop)) newop++; 3225. 		if (*newop) tbg = newop; 3226. 		else return 0; 3227. 3228. 		/* until first space - background */ 3229. 		while(*newop && !isspace(*newop)) newop++; 3230. 		if (*newop) *newop++ = '\0'; 3231. 3232. 		for (j = 0; j < 4; ++j) { 3233. 			if (!strcmpi(wn, wnames[j]) || 3234. 			    !strcmpi(wn, shortnames[j])) { 3235. 				if (tfg && !strstri(tfg, " ")) { 3236. 					if (*fgp[j]) free(*fgp[j]); 3237. 					*fgp[j] = (char *)alloc(strlen(tfg) + 1); 3238. 					Strcpy(*fgp[j], tfg); 3239. 				} 3240. 				if (tbg && !strstri(tbg, " ")) { 3241. 					if (*bgp[j]) free(*bgp[j]); 3242. 					*bgp[j] = (char *)alloc(strlen(tbg) + 1); 3243. 					Strcpy(*bgp[j], tbg); 3244. 				} 3245.  				break; 3246. 			} 3247. 		}  3248. 	}  3249. 	return 1; 3250. } 3251.  3252. #endif	/* OPTION_LISTS_ONLY */ 3253. 3254. /*options.c*/