Annotation of early-roguelike/urogue/options.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: options.c - This file has all the code for the option command
! 3:
! 4: UltraRogue: The Ultimate Adventure in the Dungeons of Doom
! 5: Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
! 6: All rights reserved.
! 7:
! 8: Based on "Advanced Rogue"
! 9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
! 10: All rights reserved.
! 11:
! 12: Based on "Rogue: Exploring the Dungeons of Doom"
! 13: Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 14: All rights reserved.
! 15:
! 16: See the file LICENSE.TXT for full copyright and licensing information.
! 17: */
! 18:
! 19: #include <string.h>
! 20: #include <ctype.h>
! 21: #include "rogue.h"
! 22:
! 23: #define NUM_OPTS (sizeof optlist / sizeof (OPTION))
! 24: #define EQSTR(a, b, c) (strncmp(a, b, c) == 0)
! 25:
! 26: int get_restr(opt_arg *opt, WINDOW *win);
! 27: int get_score(opt_arg *opt, WINDOW *win);
! 28:
! 29: /* description of an option and what to do with it */
! 30: static OPTION optlist[] =
! 31: {
! 32: {"jump","Show position only at end of run (jump): ", { &jump },
! 33: put_bool, get_bool},
! 34: {"inven","Style of inventories (inven): ", { &inv_type },
! 35: put_inv, get_inv},
! 36: {"askme","Ask me about unidentified things (askme): ", { &askme},
! 37: put_bool, get_bool},
! 38: {"doorstop","Stop running when adjacent (doorstop): ", { &doorstop },
! 39: put_bool, get_bool},
! 40: {"name", "Name (name): ", { &whoami }, put_str, get_restr},
! 41: {"fruit", "Fruit (fruit): ", { &fruit }, put_str, get_str},
! 42: {"file", "Save file (file): ", { &file_name }, put_str, get_restr},
! 43: {"score", "Score file (score): ", { &score_file }, put_str, get_score},
! 44: {"class", "Character class (class): ", { &char_type }, put_abil, get_abil}
! 45: };
! 46:
! 47: /*
! 48: option()
! 49: print and then set options from the terminal
! 50: */
! 51:
! 52: void
! 53: option(void)
! 54: {
! 55: OPTION *op;
! 56: int retval;
! 57:
! 58: wclear(hw);
! 59: touchwin(hw);
! 60:
! 61: /* Display current values of options */
! 62:
! 63: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
! 64: {
! 65: waddstr(hw, op->o_prompt);
! 66: (*op->o_putfunc)(&op->o_opt, hw);
! 67: waddch(hw, '\n');
! 68: }
! 69:
! 70: /* Set values */
! 71:
! 72: wmove(hw, 0, 0);
! 73:
! 74: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
! 75: {
! 76: waddstr(hw, op->o_prompt);
! 77:
! 78: retval = (*op->o_getfunc)(&op->o_opt, hw);
! 79:
! 80: if (retval)
! 81: if (retval == QUIT)
! 82: break;
! 83: else if (op > optlist) /* MINUS */
! 84: {
! 85: wmove(hw, (int)(op - optlist) - 1, 0);
! 86: op -= 2;
! 87: }
! 88: else /* trying to back up beyond the top */
! 89: {
! 90: putchar('\007');
! 91: wmove(hw, 0, 0);
! 92: op--;
! 93: }
! 94: }
! 95:
! 96: /* Switch back to original screen */
! 97:
! 98: mvwaddstr(hw, LINES - 1, 0, spacemsg);
! 99: wrefresh(hw);
! 100: wait_for(' ');
! 101: clearok(cw, TRUE);
! 102: touchwin(cw);
! 103: }
! 104:
! 105: /*
! 106: put_bool()
! 107: put out a boolean
! 108: */
! 109:
! 110: void
! 111: put_bool(opt_arg *opt, WINDOW *win)
! 112: {
! 113: waddstr(win, *opt->iarg ? "True" : "False");
! 114: }
! 115:
! 116: /*
! 117: put_str()
! 118: put out a string
! 119: */
! 120:
! 121: void
! 122: put_str(opt_arg *opt, WINDOW *win)
! 123: {
! 124: waddstr(win, opt->str);
! 125: }
! 126:
! 127: /*
! 128: put_abil()
! 129: print the character type
! 130: */
! 131:
! 132: void
! 133: put_abil(opt_arg *opt, WINDOW *win)
! 134: {
! 135: char *abil;
! 136:
! 137: switch(*opt->iarg)
! 138: {
! 139: case C_FIGHTER:
! 140: abil = "Fighter";
! 141: break;
! 142: case C_MAGICIAN:
! 143: abil = "Magic User";
! 144: break;
! 145: case C_CLERIC:
! 146: abil = "Cleric";
! 147: break;
! 148: case C_THIEF:
! 149: abil = "Thief";
! 150: break;
! 151: case C_PALADIN:
! 152: abil = "Paladin";
! 153: break;
! 154: case C_RANGER:
! 155: abil = "Ranger";
! 156: break;
! 157: case C_ILLUSION:
! 158: abil = "Illusionist";
! 159: break;
! 160: case C_ASSASIN:
! 161: abil = "Assasin";
! 162: break;
! 163: case C_NINJA:
! 164: abil = "Ninja";
! 165: break;
! 166: case C_DRUID:
! 167: abil = "Druid";
! 168: break;
! 169: default:
! 170: abil = "(unknown)";
! 171: }
! 172: waddstr(win, abil);
! 173: }
! 174:
! 175:
! 176: /*
! 177: get_bool()
! 178: allow changing a boolean option and print it out
! 179: */
! 180:
! 181: int
! 182: get_bool(opt_arg *opt, WINDOW *win)
! 183: {
! 184: int oy, ox;
! 185: int op_bad;
! 186:
! 187: op_bad = TRUE;
! 188: getyx(win, oy, ox);
! 189: waddstr(win, *opt->iarg ? "True" : "False");
! 190:
! 191: while(op_bad)
! 192: {
! 193: wmove(win, oy, ox);
! 194: wrefresh(win);
! 195:
! 196: switch (readcharw(win))
! 197: {
! 198: case 't':
! 199: case 'T':
! 200: *opt->iarg = TRUE;
! 201: op_bad = FALSE;
! 202: break;
! 203:
! 204: case 'f':
! 205: case 'F':
! 206: *opt->iarg = FALSE;
! 207: op_bad = FALSE;
! 208: break;
! 209:
! 210: case '\n':
! 211: case '\r':
! 212: op_bad = FALSE;
! 213: break;
! 214:
! 215: case '\033':
! 216: case '\007':
! 217: return QUIT;
! 218:
! 219: case '-':
! 220: return MINUS;
! 221:
! 222: default:
! 223: mvwaddstr(win, oy, ox + 10, "(T or F)");
! 224: }
! 225: }
! 226:
! 227: wmove(win, oy, ox);
! 228: wclrtoeol(win);
! 229: waddstr(win, *opt->iarg ? "True" : "False");
! 230: waddch(win, '\n');
! 231:
! 232: return(NORM);
! 233: }
! 234:
! 235: /*
! 236: get_str()
! 237: set a string option
! 238: */
! 239:
! 240: int
! 241: get_str(opt_arg *opt, WINDOW *win)
! 242: {
! 243: return( get_string(opt->str, win) );
! 244: }
! 245:
! 246: /*
! 247: get_abil()
! 248: The ability field is read-only
! 249: */
! 250:
! 251: int
! 252: get_abil(opt_arg *opt, WINDOW *win)
! 253: {
! 254: int oy, ox, ny, nx;
! 255: int op_bad;
! 256:
! 257: op_bad = TRUE;
! 258: getyx(win, oy, ox);
! 259: put_abil(opt, win);
! 260: getyx(win, ny, nx);
! 261:
! 262: while(op_bad)
! 263: {
! 264: wmove(win, oy, ox);
! 265: wrefresh(win);
! 266:
! 267: switch(readcharw(win))
! 268: {
! 269: case '\n':
! 270: case '\r':
! 271: op_bad = FALSE;
! 272: break;
! 273:
! 274: case '\033':
! 275: case '\007':
! 276: return(QUIT);
! 277:
! 278: case '-':
! 279: return(MINUS);
! 280:
! 281: default:
! 282: mvwaddstr(win, ny, nx + 5, "(no change allowed)");
! 283: }
! 284: }
! 285:
! 286: wmove(win, ny, nx + 5);
! 287: wclrtoeol(win);
! 288: wmove(win, ny, nx);
! 289: waddch(win, '\n');
! 290:
! 291: return(NORM);
! 292: }
! 293:
! 294:
! 295: /*
! 296: parse_opts()
! 297: parse options from string, usually taken from the environment. the
! 298: string is a series of comma seperated values, with booleans being
! 299: stated as "name" (true) or "noname" (false), and strings being
! 300: "name=....", with the string being defined up to a comma or the
! 301: end of the entire option string.
! 302: */
! 303:
! 304: void
! 305: parse_opts(char *str)
! 306: {
! 307: char *sp;
! 308: const OPTION *op;
! 309: size_t len;
! 310:
! 311: while (*str)
! 312: {
! 313: for (sp = str; isalpha(*sp); sp++)
! 314: continue;
! 315:
! 316: len = sp - str;
! 317:
! 318: /* Look it up and deal with it */
! 319:
! 320: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
! 321: {
! 322: if (EQSTR(str, op->o_name, len))
! 323: {
! 324: if (op->o_putfunc == put_bool)
! 325: *op->o_opt.iarg = TRUE;
! 326: else /* string option */
! 327: {
! 328: char *start;
! 329: char value[80];
! 330:
! 331: /* Skip to start of string value */
! 332:
! 333: for (str = sp + 1; *str == '='; str++)
! 334: continue;
! 335:
! 336: start = (char *) value;
! 337:
! 338: /* Skip to end of string value */
! 339:
! 340: for (sp = str + 1; *sp && *sp != ','; sp++)
! 341: continue;
! 342:
! 343: strncpy(start, str, sp - str);
! 344:
! 345: /* Some options can't be changed. */
! 346: if (use_savedir &&
! 347: (op->o_opt.str == whoami ||
! 348: op->o_opt.str == file_name ||
! 349: op->o_opt.str == score_file))
! 350: break;
! 351:
! 352: /* Put the value into the option field */
! 353:
! 354: if (op->o_putfunc != put_abil &&
! 355: op->o_putfunc != put_inv)
! 356: strcpy(op->o_opt.str, value);
! 357:
! 358: if (op->o_putfunc == put_inv)
! 359: {
! 360: int *opt = op->o_opt.iarg;
! 361:
! 362: len = strlen(value);
! 363:
! 364: if (isupper(value[0]))
! 365: value[0] = (char) tolower(value[0]);
! 366: if (EQSTR(value, "overwrite",len))
! 367: *opt = INV_OVER;
! 368: if (EQSTR(value, "slow", len))
! 369: *opt = INV_SLOW;
! 370: if (EQSTR(value, "clear", len))
! 371: *opt = INV_CLEAR;
! 372: }
! 373: else if (*op->o_opt.iarg == -1)
! 374: {
! 375: int *opt = op->o_opt.iarg;
! 376:
! 377: len = strlen(value);
! 378:
! 379: if (isupper(value[0]))
! 380: value[0] = (char) tolower(value[0]);
! 381: if (EQSTR(value, "fighter", len))
! 382: *opt = C_FIGHTER;
! 383: else if (EQSTR(value, "magic", min(len, 5)))
! 384: *opt = C_MAGICIAN;
! 385: else if (EQSTR(value, "illus", min(len, 5)))
! 386: *opt = C_ILLUSION;
! 387: else if (EQSTR(value, "cleric", len))
! 388: *opt = C_CLERIC;
! 389: else if (EQSTR(value, "thief", len))
! 390: *opt = C_THIEF;
! 391: else if (EQSTR(value, "paladin", len))
! 392: *opt = C_PALADIN;
! 393: else if (EQSTR(value, "ranger", len))
! 394: *opt = C_RANGER;
! 395: else if (EQSTR(value, "assasin", len))
! 396: *opt = C_ASSASIN;
! 397: else if (EQSTR(value, "druid", len))
! 398: *opt = C_DRUID;
! 399: else if (EQSTR(value, "ninja", len))
! 400: *opt = C_NINJA;
! 401: }
! 402: }
! 403: break;
! 404: }
! 405: else if (op->o_putfunc == put_bool
! 406: && EQSTR(str, "no", 2) &&
! 407: EQSTR(str + 2, op->o_name, len - 2))
! 408: {
! 409: *op->o_opt.iarg = FALSE;
! 410: break;
! 411: }
! 412: }
! 413:
! 414: /* skip to start of next option name */
! 415:
! 416: while (*sp && !isalpha(*sp))
! 417: sp++;
! 418:
! 419: str = sp;
! 420: }
! 421: }
! 422:
! 423: /*
! 424: put_inv()
! 425: print the inventory type
! 426: */
! 427:
! 428: void
! 429: put_inv(opt_arg *opt, WINDOW *win)
! 430: {
! 431: char *style;
! 432:
! 433: switch(*opt->iarg)
! 434: {
! 435: case INV_OVER:
! 436: style = "Overwrite";
! 437: break;
! 438:
! 439: case INV_SLOW:
! 440: style = "Slow";
! 441: break;
! 442:
! 443: case INV_CLEAR:
! 444: style = "Clear Screen";
! 445: break;
! 446:
! 447: default:
! 448: style = "(unknown)";
! 449: }
! 450:
! 451: waddstr(win, style);
! 452: }
! 453:
! 454: /*
! 455: get_inv()
! 456: The inventory field.
! 457: */
! 458:
! 459: int
! 460: get_inv(opt_arg *opt, WINDOW *win)
! 461: {
! 462: int oy, ox, ny, nx;
! 463: int op_bad;
! 464:
! 465: op_bad = TRUE;
! 466: getyx(win, oy, ox);
! 467: put_inv(opt, win);
! 468: getyx(win, ny, nx);
! 469:
! 470: while(op_bad)
! 471: {
! 472: wmove(win, oy, ox);
! 473: wrefresh(win);
! 474:
! 475: switch(readcharw(win))
! 476: {
! 477: case '\n':
! 478: case '\r':
! 479: op_bad = FALSE;
! 480: break;
! 481:
! 482: case '\033':
! 483: case '\007':
! 484: return(QUIT);
! 485:
! 486: case '-':
! 487: return(MINUS);
! 488:
! 489: case 'O':
! 490: case 'o':
! 491: *opt->iarg = INV_OVER;
! 492: op_bad = FALSE;
! 493: break;
! 494:
! 495: case 'S':
! 496: case 's':
! 497: *opt->iarg = INV_SLOW;
! 498: op_bad = FALSE;
! 499: break;
! 500:
! 501: case 'C':
! 502: case 'c':
! 503: *opt->iarg = INV_CLEAR;
! 504: op_bad = FALSE;
! 505: break;
! 506:
! 507: default:
! 508: mvwaddstr(win, ny, nx + 5, "(Use: o, s, or c)");
! 509: }
! 510: }
! 511:
! 512: wmove(win, oy, ox);
! 513: wclrtoeol(win);
! 514:
! 515: switch(*opt->iarg)
! 516: {
! 517: case INV_SLOW:
! 518: waddstr(win, "Slow\n");
! 519: break;
! 520:
! 521: case INV_CLEAR:
! 522: waddstr(win, "Clear Screen\n");
! 523: break;
! 524:
! 525: case INV_OVER:
! 526: waddstr(win, "Overwrite\n");
! 527: break;
! 528:
! 529: default:
! 530: waddstr(win, "Unknown\n");
! 531: break;
! 532: }
! 533:
! 534: return(NORM);
! 535: }
! 536:
! 537: /*
! 538: * get_restr()
! 539: *
! 540: * Gets strings that cannot be changed when use_savedir is set.
! 541: * get_abil() can't be repurposed to do this without ugliness.
! 542: *
! 543: */
! 544: int
! 545: get_restr(opt_arg *opt, WINDOW *win)
! 546: {
! 547: int oy, ox, ny, nx;
! 548: int keep_up;
! 549:
! 550: keep_up = TRUE;
! 551: getyx(win, oy, ox);
! 552: put_str(opt, win);
! 553:
! 554: if (!use_savedir) {
! 555: wmove(win, oy, ox);
! 556: return get_str(opt, win);
! 557: }
! 558:
! 559: getyx(win, ny, nx);
! 560: while(keep_up)
! 561: {
! 562: wmove(win, oy, ox);
! 563: wrefresh(win);
! 564:
! 565: switch(readcharw(win))
! 566: {
! 567: case '\n':
! 568: case '\r':
! 569: keep_up = FALSE;
! 570: break;
! 571:
! 572: case '\033':
! 573: case '\007':
! 574: return(QUIT);
! 575:
! 576: case '-':
! 577: return(MINUS);
! 578:
! 579: default:
! 580: mvwaddstr(win, ny, nx + 5, "(no change allowed)");
! 581: }
! 582: }
! 583:
! 584: wmove(win, ny, nx + 5);
! 585: wclrtoeol(win);
! 586: wmove(win, ny, nx);
! 587: waddch(win, '\n');
! 588:
! 589: return(NORM);
! 590: }
! 591:
! 592: int
! 593: get_score(opt_arg *opt, WINDOW *win)
! 594: {
! 595: char old_score_file[2*LINELEN];
! 596: int status;
! 597:
! 598: if (use_savedir)
! 599: return get_restr(opt, win);
! 600:
! 601: strncpy(old_score_file, opt->str, 2*LINELEN);
! 602: old_score_file[2*LINELEN - 1] = '\0';
! 603: status = get_str(opt, win);
! 604: if (status == NORM && strcmp(old_score_file, opt->str)) {
! 605: fclose(fd_score);
! 606: fd_score = fopen(score_file, "r+");
! 607: if (fd_score == NULL)
! 608: fd_score = fopen(score_file, "a+");
! 609: }
! 610: return status;
! 611: }
CVSweb