Annotation of early-roguelike/rogue4/options.c, Revision 1.1
1.1 ! rubenllo 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.12 (Berkeley) 3/2/82
! 7: *
! 8: * Rogue: Exploring the Dungeons of Doom
! 9: * Copyright (C) 1980, 1981, 1982 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 <curses.h>
! 16: #include <ctype.h>
! 17: #include <string.h>
! 18: #include "rogue.h"
! 19:
! 20: #define EQSTR(a, b, c) (strncmp(a, b, c) == 0)
! 21:
! 22: #define NUM_OPTS (sizeof optlist / sizeof (OPTION))
! 23:
! 24: /*
! 25: * description of an option and what to do with it
! 26: */
! 27: struct optstruct {
! 28: char *o_name; /* option name */
! 29: char *o_prompt; /* prompt for interactive entry */
! 30: void *o_opt; /* pointer to thing to set */
! 31: void (*o_putfunc)(); /* function to print value */
! 32: int (*o_getfunc)(); /* function to get value interactively */
! 33: };
! 34:
! 35: typedef struct optstruct OPTION;
! 36:
! 37: int allowchange(OPTION *opt);
! 38:
! 39: void put_bool(bool *b);
! 40: void put_str(char *str);
! 41: int get_bool(bool *bp, WINDOW *win);
! 42: int get_str(char *opt, WINDOW *win);
! 43:
! 44: OPTION optlist[] = {
! 45: {"terse", "Terse output: ",
! 46: (void *) &terse, put_bool, get_bool },
! 47: {"flush", "Flush typeahead during battle: ",
! 48: (void *) &fight_flush, put_bool, get_bool },
! 49: {"jump", "Show position only at end of run: ",
! 50: (void *) &jump, put_bool, get_bool },
! 51: {"step", "Do inventories one line at a time: ",
! 52: (void *) &slow_invent, put_bool, get_bool },
! 53: {"askme", "Ask me about unidentified things: ",
! 54: (void *) &askme, put_bool, get_bool },
! 55: {"passgo", "Follow turnings in passageways: ",
! 56: (void *) &passgo, put_bool, get_bool },
! 57: {"name", "Name: ",
! 58: (void *) whoami, put_str, get_str },
! 59: {"fruit", "Fruit: ",
! 60: (void *) fruit, put_str, get_str },
! 61: {"file", "Save file: ",
! 62: (void *) file_name, put_str, get_str }
! 63: };
! 64:
! 65: /*
! 66: * option:
! 67: * Print and then set options from the terminal
! 68: */
! 69: void
! 70: option(void)
! 71: {
! 72: register OPTION *op;
! 73: register int retval;
! 74:
! 75: wclear(hw);
! 76: /*
! 77: * Display current values of options
! 78: */
! 79: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
! 80: {
! 81: if (allowchange(op))
! 82: {
! 83: waddstr(hw, op->o_prompt);
! 84: (*op->o_putfunc)(op->o_opt);
! 85: waddch(hw, '\n');
! 86: }
! 87: }
! 88: /*
! 89: * Set values
! 90: */
! 91: wmove(hw, 0, 0);
! 92: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
! 93: {
! 94: if (!allowchange(op))
! 95: continue;
! 96: waddstr(hw, op->o_prompt);
! 97: if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
! 98: {
! 99: if (retval == QUIT)
! 100: break;
! 101: #if 0 /* disable MINUS */
! 102: else if (op > optlist) { /* MINUS */
! 103: wmove(hw, (op - optlist) - 1, 0);
! 104: op -= 2;
! 105: }
! 106: else /* trying to back up beyond the top */
! 107: {
! 108: putchar('\007');
! 109: wmove(hw, 0, 0);
! 110: op--;
! 111: }
! 112: #else
! 113: break;
! 114: #endif
! 115: }
! 116: }
! 117: /*
! 118: * Switch back to original screen
! 119: */
! 120: mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
! 121: wrefresh(hw);
! 122: wait_for(' ');
! 123: clearok(curscr, TRUE);
! 124: touchwin(stdscr);
! 125: after = FALSE;
! 126: }
! 127:
! 128: /*
! 129: * put_bool
! 130: * Put out a boolean
! 131: */
! 132: void
! 133: put_bool(bool *b)
! 134: {
! 135: waddstr(hw, *b ? "True" : "False");
! 136: }
! 137:
! 138: /*
! 139: * put_str:
! 140: * Put out a string
! 141: */
! 142: void
! 143: put_str(char *str)
! 144: {
! 145: waddstr(hw, str);
! 146: }
! 147:
! 148: /*
! 149: * get_bool:
! 150: * Allow changing a boolean option and print it out
! 151: */
! 152: int
! 153: get_bool(bool *bp, WINDOW *win)
! 154: {
! 155: register int oy, ox;
! 156: register bool op_bad;
! 157:
! 158: op_bad = TRUE;
! 159: getyx(win, oy, ox);
! 160: waddstr(win, *bp ? "True" : "False");
! 161: while (op_bad)
! 162: {
! 163: wmove(win, oy, ox);
! 164: wrefresh(win);
! 165: switch (readcharw(win))
! 166: {
! 167: case 't':
! 168: case 'T':
! 169: *bp = TRUE;
! 170: op_bad = FALSE;
! 171: break;
! 172: case 'f':
! 173: case 'F':
! 174: *bp = FALSE;
! 175: op_bad = FALSE;
! 176: break;
! 177: case '\n':
! 178: case '\r':
! 179: op_bad = FALSE;
! 180: break;
! 181: case '\033':
! 182: case '\007':
! 183: return QUIT;
! 184: case '-':
! 185: return MINUS;
! 186: default:
! 187: mvwaddstr(win, oy, ox + 10, "(T or F)");
! 188: }
! 189: }
! 190: wmove(win, oy, ox);
! 191: waddstr(win, *bp ? "True" : "False");
! 192: waddch(win, '\n');
! 193: return NORM;
! 194: }
! 195:
! 196: /*
! 197: * get_str:
! 198: * Set a string option
! 199: */
! 200: #define MAXINP 50 /* max string to read from terminal or environment */
! 201:
! 202: int
! 203: get_str(char *opt, WINDOW *win)
! 204: {
! 205: register char *sp;
! 206: register int c, oy, ox;
! 207: char buf[MAXSTR];
! 208:
! 209: getyx(win, oy, ox);
! 210: wrefresh(win);
! 211: /*
! 212: * loop reading in the string, and put it in a temporary buffer
! 213: */
! 214: for (sp = buf; (c = readcharw(win)) != '\n' && c != '\r' && c != '\033';
! 215: wclrtoeol(win), wrefresh(win))
! 216: {
! 217: if (c == -1)
! 218: continue;
! 219: else if (c == md_erasechar()) /* process erase character */
! 220: {
! 221: if (sp > buf)
! 222: {
! 223: register int i;
! 224:
! 225: sp--;
! 226: for (i = strlen(unctrol(*sp)); i; i--)
! 227: waddch(win, '\b');
! 228: }
! 229: continue;
! 230: }
! 231: else if (c == md_killchar()) /* process kill character */
! 232: {
! 233: sp = buf;
! 234: wmove(win, oy, ox);
! 235: continue;
! 236: }
! 237: else if (sp == buf)
! 238: {
! 239: if (c == '-' && win != stdscr)
! 240: break;
! 241: else if (c == '~')
! 242: {
! 243: strcpy(buf, home);
! 244: waddstr(win, home);
! 245: sp += strlen(home);
! 246: continue;
! 247: }
! 248: }
! 249: if (sp >= &buf[MAXINP] || !(isprint(c) || c == ' '))
! 250: putchar(CTRL('G'));
! 251: else
! 252: {
! 253: *sp++ = c;
! 254: waddstr(win, unctrol(c));
! 255: }
! 256: }
! 257: *sp = '\0';
! 258: if (sp > buf) /* only change option if something has been typed */
! 259: strucpy(opt, buf, strlen(buf));
! 260: wmove(win, oy, ox);
! 261: waddstr(win, opt);
! 262: waddch(win, '\n');
! 263: wrefresh(win);
! 264: if (win == stdscr)
! 265: mpos += sp - buf;
! 266: if (c == '-')
! 267: return MINUS;
! 268: else if (c == '\033' || c == '\007')
! 269: return QUIT;
! 270: else
! 271: return NORM;
! 272: }
! 273:
! 274: #ifdef WIZARD
! 275: /*
! 276: * get_num:
! 277: * Get a numeric option
! 278: */
! 279: int
! 280: get_num(short *opt, WINDOW *win)
! 281: {
! 282: register int i;
! 283: char buf[MAXSTR];
! 284:
! 285: if ((i = get_str(buf, win)) == NORM)
! 286: *opt = atoi(buf);
! 287: return i;
! 288: }
! 289: #endif
! 290:
! 291: /*
! 292: * parse_opts:
! 293: * Parse options from string, usually taken from the environment.
! 294: * The string is a series of comma seperated values, with booleans
! 295: * being stated as "name" (true) or "noname" (false), and strings
! 296: * being "name=....", with the string being defined up to a comma
! 297: * or the end of the entire option string.
! 298: */
! 299: void
! 300: parse_opts(char *str)
! 301: {
! 302: register char *sp;
! 303: register OPTION *op;
! 304: register int len;
! 305:
! 306: while (*str)
! 307: {
! 308: /*
! 309: * Get option name
! 310: */
! 311: for (sp = str; isalpha(*sp); sp++)
! 312: continue;
! 313: len = sp - str;
! 314: /*
! 315: * Look it up and deal with it
! 316: */
! 317: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
! 318: {
! 319: /* If using system savefiles, changing your name or the
! 320: save file is not allowed. */
! 321: if (!allowchange(op))
! 322: continue;
! 323: if (EQSTR(str, op->o_name, len))
! 324: {
! 325: if (op->o_putfunc == put_bool) /* if option is a boolean */
! 326: *(bool *)op->o_opt = TRUE;
! 327: else /* string option */
! 328: {
! 329: register char *start;
! 330: /*
! 331: * Skip to start of string value
! 332: */
! 333: for (str = sp + 1; *str == '='; str++)
! 334: continue;
! 335: if (*str == '~')
! 336: {
! 337: strcpy((char *) op->o_opt, home);
! 338: start = (char *) op->o_opt + strlen(home);
! 339: while (*++str == '/')
! 340: continue;
! 341: }
! 342: else
! 343: start = (char *) op->o_opt;
! 344: /*
! 345: * Skip to end of string value
! 346: */
! 347: for (sp = str + 1; *sp && *sp != ','; sp++)
! 348: continue;
! 349: strucpy(start, str, sp - str);
! 350: }
! 351: break;
! 352: }
! 353: /*
! 354: * check for "noname" for booleans
! 355: */
! 356: else if (op->o_putfunc == put_bool
! 357: && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
! 358: {
! 359: *(bool *)op->o_opt = FALSE;
! 360: break;
! 361: }
! 362: }
! 363:
! 364: /*
! 365: * skip to start of next option name
! 366: */
! 367: while (*sp && !isalpha(*sp))
! 368: sp++;
! 369: str = sp;
! 370: }
! 371: }
! 372:
! 373: /*
! 374: * strucpy:
! 375: * Copy string using unctrol for things
! 376: */
! 377: void
! 378: strucpy(char *s1, char *s2, int len)
! 379: {
! 380: if (len > MAXINP)
! 381: len = MAXINP;
! 382: while (len--)
! 383: {
! 384: if (isprint(*s2) || *s2 == ' ')
! 385: *s1++ = *s2;
! 386: s2++;
! 387: }
! 388: *s1 = '\0';
! 389: }
! 390:
! 391: /* Tells whether the player is allowed to change the option. */
! 392: int allowchange(OPTION *opt)
! 393: {
! 394: if (!use_savedir)
! 395: return 1;
! 396: if (!strcmp(opt->o_name, "name"))
! 397: return 0;
! 398: if (!strcmp(opt->o_name, "file"))
! 399: return 0;
! 400: return 1;
! 401: }
! 402:
CVSweb