Source:Options.c

Below is the full text to src/options.c from NetHack 3.4.3. To link to a particular line, write [[options.c#line123 ]], for example. 1.   /*	SCCS Id: @(#)options.c	3.4	2003/11/14	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.

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