Mercurial > hg > early-roguelike
comparison rogue5/options.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Mon, 24 May 2010 20:10:59 +0000 |
| parents | |
| children | 655c317b6237 |
comparison
equal
deleted
inserted
replaced
| 32:2dcd75e6a736 | 33:f502bf60e6e4 |
|---|---|
| 1 /* | |
| 2 * This file has all the code for the option command. I would rather | |
| 3 * this command were not necessary, but it is the only way to keep the | |
| 4 * wolves off of my back. | |
| 5 * | |
| 6 * @(#)options.c 4.24 (Berkeley) 05/10/83 | |
| 7 * | |
| 8 * Rogue: Exploring the Dungeons of Doom | |
| 9 * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman | |
| 10 * All rights reserved. | |
| 11 * | |
| 12 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 13 */ | |
| 14 | |
| 15 #include <stdlib.h> | |
| 16 #include <curses.h> | |
| 17 #include <ctype.h> | |
| 18 #include <string.h> | |
| 19 #include "rogue.h" | |
| 20 | |
| 21 #define EQSTR(a, b, c) (strncmp(a, b, c) == 0) | |
| 22 | |
| 23 #define NUM_OPTS (sizeof optlist / sizeof (OPTION)) | |
| 24 | |
| 25 /* | |
| 26 * description of an option and what to do with it | |
| 27 */ | |
| 28 struct optstruct { | |
| 29 char *o_name; /* option name */ | |
| 30 char *o_prompt; /* prompt for interactive entry */ | |
| 31 void *o_opt; /* pointer to thing to set */ | |
| 32 /* function to print value */ | |
| 33 void (*o_putfunc)(void *opt); | |
| 34 /* function to get value interactively */ | |
| 35 int (*o_getfunc)(void *opt, WINDOW *win); | |
| 36 }; | |
| 37 | |
| 38 typedef struct optstruct OPTION; | |
| 39 | |
| 40 void pr_optname(const OPTION *op); | |
| 41 | |
| 42 static const OPTION optlist[] = { | |
| 43 {"terse", "Terse output", | |
| 44 &terse, put_bool, get_bool }, | |
| 45 {"flush", "Flush typeahead during battle", | |
| 46 &fight_flush, put_bool, get_bool }, | |
| 47 {"jump", "Show position only at end of run", | |
| 48 &jump, put_bool, get_bool }, | |
| 49 {"seefloor", "Show the lamp-illuminated floor", | |
| 50 &see_floor, put_bool, get_sf }, | |
| 51 {"passgo", "Follow turnings in passageways", | |
| 52 &passgo, put_bool, get_bool }, | |
| 53 {"tombstone", "Print out tombstone when killed", | |
| 54 &tombstone, put_bool, get_bool }, | |
| 55 {"inven", "Inventory style", | |
| 56 &inv_type, put_inv_t, get_inv_t }, | |
| 57 {"name", "Name", | |
| 58 whoami, put_str, get_str }, | |
| 59 {"fruit", "Fruit", | |
| 60 fruit, put_str, get_str }, | |
| 61 {"file", "Save file", | |
| 62 file_name, put_str, get_str } | |
| 63 }; | |
| 64 | |
| 65 /* | |
| 66 * option: | |
| 67 * Print and then set options from the terminal | |
| 68 */ | |
| 69 | |
| 70 void | |
| 71 option(void) | |
| 72 { | |
| 73 const OPTION *op; | |
| 74 int retval; | |
| 75 | |
| 76 wclear(hw); | |
| 77 /* | |
| 78 * Display current values of options | |
| 79 */ | |
| 80 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++) | |
| 81 { | |
| 82 pr_optname(op); | |
| 83 (*op->o_putfunc)(op->o_opt); | |
| 84 waddch(hw, '\n'); | |
| 85 } | |
| 86 /* | |
| 87 * Set values | |
| 88 */ | |
| 89 wmove(hw, 0, 0); | |
| 90 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++) | |
| 91 { | |
| 92 pr_optname(op); | |
| 93 retval = (*op->o_getfunc)(op->o_opt, hw); | |
| 94 if (retval) | |
| 95 { | |
| 96 if (retval == QUIT) | |
| 97 break; | |
| 98 else if (op > optlist) { /* MINUS */ | |
| 99 wmove(hw, (int)(op - optlist) - 1, 0); | |
| 100 op -= 2; | |
| 101 } | |
| 102 else /* trying to back up beyond the top */ | |
| 103 { | |
| 104 putchar('\007'); | |
| 105 wmove(hw, 0, 0); | |
| 106 op--; | |
| 107 } | |
| 108 } | |
| 109 } | |
| 110 /* | |
| 111 * Switch back to original screen | |
| 112 */ | |
| 113 wmove(hw, LINES - 1, 0); | |
| 114 waddstr(hw, "--Press space to continue--"); | |
| 115 wrefresh(hw); | |
| 116 wait_for(hw, ' '); | |
| 117 clearok(curscr, TRUE); | |
| 118 touchwin(stdscr); | |
| 119 after = FALSE; | |
| 120 } | |
| 121 | |
| 122 /* | |
| 123 * pr_optname: | |
| 124 * Print out the option name prompt | |
| 125 */ | |
| 126 | |
| 127 void | |
| 128 pr_optname(const OPTION *op) | |
| 129 { | |
| 130 wprintw(hw, "%s (\"%s\"): ", op->o_prompt, op->o_name); | |
| 131 } | |
| 132 | |
| 133 /* | |
| 134 * put_bool | |
| 135 * Put out a boolean | |
| 136 */ | |
| 137 | |
| 138 void | |
| 139 put_bool(void *b) | |
| 140 { | |
| 141 waddstr(hw, *(int *) b ? "True" : "False"); | |
| 142 } | |
| 143 | |
| 144 /* | |
| 145 * put_str: | |
| 146 * Put out a string | |
| 147 */ | |
| 148 | |
| 149 void | |
| 150 put_str(void *str) | |
| 151 { | |
| 152 waddstr(hw, (char *) str); | |
| 153 } | |
| 154 | |
| 155 /* | |
| 156 * put_inv_t: | |
| 157 * Put out an inventory type | |
| 158 */ | |
| 159 | |
| 160 void | |
| 161 put_inv_t(void *ip) | |
| 162 { | |
| 163 waddstr(hw, inv_t_name[*(int *) ip]); | |
| 164 } | |
| 165 | |
| 166 /* | |
| 167 * get_bool: | |
| 168 * Allow changing a boolean option and print it out | |
| 169 */ | |
| 170 int | |
| 171 get_bool(void *vp, WINDOW *win) | |
| 172 { | |
| 173 int *bp = (int *) vp; | |
| 174 int oy, ox; | |
| 175 int op_bad; | |
| 176 | |
| 177 op_bad = TRUE; | |
| 178 getyx(win, oy, ox); | |
| 179 waddstr(win, *bp ? "True" : "False"); | |
| 180 while (op_bad) | |
| 181 { | |
| 182 wmove(win, oy, ox); | |
| 183 wrefresh(win); | |
| 184 switch (wreadchar(win)) | |
| 185 { | |
| 186 case 't': | |
| 187 case 'T': | |
| 188 *bp = TRUE; | |
| 189 op_bad = FALSE; | |
| 190 break; | |
| 191 case 'f': | |
| 192 case 'F': | |
| 193 *bp = FALSE; | |
| 194 op_bad = FALSE; | |
| 195 break; | |
| 196 case '\n': | |
| 197 case '\r': | |
| 198 op_bad = FALSE; | |
| 199 break; | |
| 200 case ESCAPE: | |
| 201 return QUIT; | |
| 202 case '-': | |
| 203 return MINUS; | |
| 204 default: | |
| 205 wmove(win, oy, ox + 10); | |
| 206 waddstr(win, "(T or F)"); | |
| 207 } | |
| 208 } | |
| 209 wmove(win, oy, ox); | |
| 210 waddstr(win, *bp ? "True" : "False"); | |
| 211 waddch(win, '\n'); | |
| 212 return NORM; | |
| 213 } | |
| 214 | |
| 215 /* | |
| 216 * get_sf: | |
| 217 * Change value and handle transition problems from see_floor to | |
| 218 * !see_floor. | |
| 219 */ | |
| 220 int | |
| 221 get_sf(void *vp, WINDOW *win) | |
| 222 { | |
| 223 int *bp = (int *) vp; | |
| 224 int was_sf; | |
| 225 int retval; | |
| 226 | |
| 227 was_sf = see_floor; | |
| 228 retval = get_bool(bp, win); | |
| 229 if (retval == QUIT) return(QUIT); | |
| 230 if (was_sf != see_floor) | |
| 231 { | |
| 232 if (!see_floor) { | |
| 233 see_floor = TRUE; | |
| 234 erase_lamp(&hero, proom); | |
| 235 see_floor = FALSE; | |
| 236 } | |
| 237 else | |
| 238 look(FALSE); | |
| 239 } | |
| 240 return(NORM); | |
| 241 } | |
| 242 | |
| 243 /* | |
| 244 * get_str: | |
| 245 * Set a string option | |
| 246 */ | |
| 247 #define MAXINP 50 /* max string to read from terminal or environment */ | |
| 248 | |
| 249 int | |
| 250 get_str(void *vopt, WINDOW *win) | |
| 251 { | |
| 252 char *opt = (char *) vopt; | |
| 253 char *sp; | |
| 254 int oy, ox; | |
| 255 size_t i; | |
| 256 int c; | |
| 257 static char buf[MAXSTR]; | |
| 258 | |
| 259 getyx(win, oy, ox); | |
| 260 wrefresh(win); | |
| 261 /* | |
| 262 * loop reading in the string, and put it in a temporary buffer | |
| 263 */ | |
| 264 for (sp = buf; (c = wreadchar(win)) != '\n' && c != '\r' && c != ESCAPE; | |
| 265 wclrtoeol(win), wrefresh(win)) | |
| 266 { | |
| 267 if (c == -1) | |
| 268 continue; | |
| 269 else if (c == erasechar()) /* process erase character */ | |
| 270 { | |
| 271 if (sp > buf) | |
| 272 { | |
| 273 sp--; | |
| 274 for (i = strlen(unctrl(*sp)); i; i--) | |
| 275 waddch(win, '\b'); | |
| 276 } | |
| 277 continue; | |
| 278 } | |
| 279 else if (c == killchar()) /* process kill character */ | |
| 280 { | |
| 281 sp = buf; | |
| 282 wmove(win, oy, ox); | |
| 283 continue; | |
| 284 } | |
| 285 else if (sp == buf) | |
| 286 { | |
| 287 if (c == '-' && win != stdscr) | |
| 288 break; | |
| 289 else if (c == '~') | |
| 290 { | |
| 291 strcpy(buf, home); | |
| 292 waddstr(win, home); | |
| 293 sp += strlen(home); | |
| 294 continue; | |
| 295 } | |
| 296 } | |
| 297 if (sp >= &buf[MAXINP] || !(isprint(c) || c == ' ')) | |
| 298 putchar(CTRL('G')); | |
| 299 else | |
| 300 { | |
| 301 *sp++ = (char) c; | |
| 302 waddstr(win, unctrl(c)); | |
| 303 } | |
| 304 } | |
| 305 *sp = '\0'; | |
| 306 if (sp > buf) /* only change option if something has been typed */ | |
| 307 strucpy(opt, buf, strlen(buf)); | |
| 308 mvwprintw(win, oy, ox, "%s\n", opt); | |
| 309 wrefresh(win); | |
| 310 if (win == stdscr) | |
| 311 mpos += (int)(sp - buf); | |
| 312 if (c == '-') | |
| 313 return MINUS; | |
| 314 else if (c == ESCAPE) | |
| 315 return QUIT; | |
| 316 else | |
| 317 return NORM; | |
| 318 } | |
| 319 | |
| 320 /* | |
| 321 * get_inv_t | |
| 322 * Get an inventory type name | |
| 323 */ | |
| 324 int | |
| 325 get_inv_t(void *vp, WINDOW *win) | |
| 326 { | |
| 327 int *ip = (int *) vp; | |
| 328 int oy, ox; | |
| 329 int op_bad; | |
| 330 | |
| 331 op_bad = TRUE; | |
| 332 getyx(win, oy, ox); | |
| 333 waddstr(win, inv_t_name[*ip]); | |
| 334 while (op_bad) | |
| 335 { | |
| 336 wmove(win, oy, ox); | |
| 337 wrefresh(win); | |
| 338 switch (wreadchar(win)) | |
| 339 { | |
| 340 case 'o': | |
| 341 case 'O': | |
| 342 *ip = INV_OVER; | |
| 343 op_bad = FALSE; | |
| 344 break; | |
| 345 case 's': | |
| 346 case 'S': | |
| 347 *ip = INV_SLOW; | |
| 348 op_bad = FALSE; | |
| 349 break; | |
| 350 case 'c': | |
| 351 case 'C': | |
| 352 *ip = INV_CLEAR; | |
| 353 op_bad = FALSE; | |
| 354 break; | |
| 355 case '\n': | |
| 356 case '\r': | |
| 357 op_bad = FALSE; | |
| 358 break; | |
| 359 case ESCAPE: | |
| 360 return QUIT; | |
| 361 case '-': | |
| 362 return MINUS; | |
| 363 default: | |
| 364 wmove(win, oy, ox + 15); | |
| 365 waddstr(win, "(O, S, or C)"); | |
| 366 } | |
| 367 } | |
| 368 mvwprintw(win, oy, ox, "%s\n", inv_t_name[*ip]); | |
| 369 return NORM; | |
| 370 } | |
| 371 | |
| 372 | |
| 373 #ifdef MASTER | |
| 374 /* | |
| 375 * get_num: | |
| 376 * Get a numeric option | |
| 377 */ | |
| 378 int | |
| 379 get_num(void *vp, WINDOW *win) | |
| 380 { | |
| 381 int *opt = (int *) vp; | |
| 382 int i; | |
| 383 static char buf[MAXSTR]; | |
| 384 | |
| 385 if ((i = get_str(buf, win)) == NORM) | |
| 386 *opt = atoi(buf); | |
| 387 return i; | |
| 388 } | |
| 389 #endif | |
| 390 | |
| 391 /* | |
