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