[BACK]Return to options.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / xrogue

Annotation of early-roguelike/xrogue/options.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:     options.c - This file has all the code for the option command
                      3:
                      4:     XRogue: Expeditions into the Dungeons of Doom
                      5:     Copyright (C) 1991 Robert Pietkivitch
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
                     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:  /*
                     20:  * I would rather this command were not necessary, but
                     21:  * it is the only way to keep the wolves off of my back.
                     22:  */
                     23:
                     24: #include <curses.h>
                     25: #include <ctype.h>
                     26: #include <string.h>
                     27: #include "rogue.h"
                     28:
                     29: #define NUM_OPTS        (sizeof optlist / sizeof (OPTION))
                     30:
                     31: /*
                     32:  * description of an option and what to do with it
                     33:  */
                     34: struct optstruct {
                     35:     char        *o_name;        /* option name */
                     36:     char        *o_prompt;      /* prompt for interactive entry */
                     37:     void        *o_opt;         /* pointer to thing to set */
                     38:     void        (*o_putfunc)(); /* function to print value */
                     39:     int         (*o_getfunc)(); /* function to get value interactively */
                     40: };
                     41:
                     42: typedef struct optstruct        OPTION;
                     43:
                     44: int get_ro(WINDOW *win, int oy, int ox);
                     45: void put_bool(bool *b, WINDOW *win);
                     46: int get_bool(bool *bp, WINDOW *win);
                     47: void put_str(char *str, WINDOW *win);
                     48: int get_str(char *opt, WINDOW *win);
                     49: void put_abil(int *ability, WINDOW *win);
                     50: int get_abil(int *abil, WINDOW *win);
                     51: void put_quest(int *quest, WINDOW *win);
                     52: int get_quest(int *quest, WINDOW *win);
                     53: int get_default(bool *bp, WINDOW *win);
                     54: int get_str_prot(char *opt, WINDOW *win);
                     55: int get_score(char *opt, WINDOW *win);
                     56: bool allowchange(OPTION *op);
                     57:
                     58: OPTION  optlist[] = {
                     59:     {"terse",   "Terse output: ",
                     60:                 (void *) &terse,         put_bool,       get_bool        },
                     61:     {"flush",   "Flush typeahead during battle: ",
                     62:                 (void *) &fight_flush,   put_bool,       get_bool        },
                     63:     {"jump",    "Show position only at end of run: ",
                     64:                 (void *) &jump,          put_bool,       get_bool        },
                     65:     {"step",    "Do inventories one line at a time: ",
                     66:                 (void *) &slow_invent,   put_bool,       get_bool        },
                     67:     {"askme",   "Ask me about unidentified things: ",
                     68:                 (void *) &askme,         put_bool,       get_bool        },
                     69:     {"pickup",  "Pick things up automatically: ",
                     70:                 (void *) &auto_pickup,   put_bool,       get_bool        },
                     71:     {"overlay", "Overlay menu: ",
                     72:                 (void *) &menu_overlay,  put_bool,       get_bool        },
                     73:     {"name",    "Name: ",
                     74:                 (void *) whoami,         put_str,        get_str_prot    },
                     75:     {"file",    "Save file: ",
                     76:                 (void *) file_name,      put_str,        get_str_prot    },
                     77:     {"score",   "Score file: ",
                     78:                 (void *) score_file,     put_str,        get_score       },
                     79:     {"class",   "Character type: ",
                     80:                 (void *) &char_type,     put_abil,       get_abil        },
                     81:     {"quest",   "Quest item: ",
                     82:                 (void *) &quest_item,    put_quest,      get_quest       },
                     83:     {"default", "Default Attributes: ",
                     84:                 (void *) &def_attr,      put_bool,    get_default     }
                     85: };
                     86:
                     87: /*
                     88:  * The default attribute field is read-only
                     89:  */
                     90:
                     91: int
                     92: get_default(bool *bp, WINDOW *win)
                     93: {
                     94:     register int oy, ox;
                     95:
                     96:     getyx(win, oy, ox);
                     97:     put_bool(bp, win);
                     98:     return get_ro(win, oy, ox);
                     99: }
                    100:
                    101: /*
                    102:  * The ability (class) field is read-only
                    103:  */
                    104:
                    105: int
                    106: get_abil(int *abil, WINDOW *win)
                    107: {
                    108:     register int oy, ox;
                    109:
                    110:     getyx(win, oy, ox);
                    111:     put_abil(abil, win);
                    112:     return get_ro(win, oy, ox);
                    113: }
                    114:
                    115: /*
                    116:  * The quest field is read-only
                    117:  */
                    118:
                    119: int
                    120: get_quest(int *quest, WINDOW *win)
                    121: {
                    122:     register int oy, ox;
                    123:
                    124:     getyx(win, oy, ox);
                    125:     waddstr(win, rel_magic[*quest].mi_name);
                    126:     return get_ro(win, oy, ox);
                    127: }
                    128:
                    129: /*
                    130:  * get_ro:
                    131:  *      "Get" a read-only value.
                    132:  */
                    133:
                    134: int
                    135: get_ro(WINDOW *win, int oy, int ox)
                    136: {
                    137:     register int ny, nx;
                    138:     register bool op_bad;
                    139:
                    140:     op_bad = TRUE;
                    141:     getyx(win, ny, nx);
                    142:     while(op_bad)
                    143:     {
                    144:         wmove(win, oy, ox);
                    145:         draw(win);
                    146:         switch (wgetch(win))
                    147:         {
                    148:             case '\n':
                    149:             case '\r':
                    150:                 op_bad = FALSE;
                    151:                 break;
                    152:             case '\033':
                    153:             case '\007':
                    154:                 return QUIT;
                    155:             case '-':
                    156:                 return MINUS;
                    157:             default:
                    158:                 mvwaddstr(win, ny, nx + 5, "(no change allowed)");
                    159:         }
                    160:     }
                    161:     wmove(win, ny, nx + 5);
                    162:     wclrtoeol(win);
                    163:     wmove(win, ny, nx);
                    164:     waddch(win, '\n');
                    165:     return NORM;
                    166: }
                    167:
                    168: /*
                    169:  * allow changing a boolean option and print it out
                    170:  */
                    171:
                    172: int
                    173: get_bool(bool *bp, WINDOW *win)
                    174: {
                    175:     register int oy, ox;
                    176:     register bool op_bad;
                    177:
                    178:     op_bad = TRUE;
                    179:     getyx(win, oy, ox);
                    180:     waddstr(win, *bp ? "True" : "False");
                    181:     while(op_bad)
                    182:     {
                    183:         wmove(win, oy, ox);
                    184:         draw(win);
                    185:         switch (wgetch(win))
                    186:         {
                    187:             case 't':
                    188:             case 'T':
                    189:                 *bp = TRUE;
                    190:                 op_bad = FALSE;
                    191:                 break;
                    192:             case 'f':
                    193:             case 'F':
                    194:                 *bp = FALSE;
                    195:                 op_bad = FALSE;
                    196:                 break;
                    197:             case '\n':
                    198:             case '\r':
                    199:                 op_bad = FALSE;
                    200:                 break;
                    201:             case '\033':
                    202:             case '\007':
                    203:                 return QUIT;
                    204:             case '-':
                    205:                 return MINUS;
                    206:             default:
                    207:                 mvwaddstr(win, oy, ox + 10, "(T or F)");
                    208:         }
                    209:     }
                    210:     wmove(win, oy, ox);
                    211:     wclrtoeol(win);
                    212:     waddstr(win, *bp ? "True" : "False");
                    213:     waddch(win, '\n');
                    214:     return NORM;
                    215: }
                    216:
                    217: /*
                    218:  * set a string option
                    219:  */
                    220:
                    221: int
                    222: get_str(char *opt, WINDOW *win)
                    223: {
                    224:     register char *sp;
                    225:     register int c, oy, ox;
                    226:     char buf[LINELEN];
                    227:
                    228:     draw(win);
                    229:     getyx(win, oy, ox);
                    230:     /*
                    231:      * loop reading in the string, and put it in a temporary buffer
                    232:      */
                    233:     for (sp = buf;
                    234:         (c = wgetch(win)) != '\n'       &&
                    235:         c != '\r'                       &&
                    236:         c != '\033'                     &&
                    237:         c != '\007'                     &&
                    238:         sp < &buf[LINELEN-1];
                    239:         wclrtoeol(win), draw(win))
                    240:     {
                    241:         if (c == -1)
                    242:             continue;
                    243:         else if (c == erasechar()) /* process erase character */
                    244:         {
                    245:             if (sp > buf)
                    246:             {
                    247:                 register int i;
                    248:
                    249:                 sp--;
                    250:                 for (i = strlen(unctrl(*sp)); i; i--)
                    251:                     waddch(win, '\b');
                    252:             }
                    253:             continue;
                    254:         }
                    255:         else if (c == killchar()) /* process kill character */
                    256:         {
                    257:             sp = buf;
                    258:             wmove(win, oy, ox);
                    259:             continue;
                    260:         }
                    261:         else if (sp == buf)
                    262:             if (c == '-' && win == hw)  /* To move back a line in hw */
                    263:                 break;
                    264:             else if (c == '~')
                    265:             {
                    266:                 strcpy(buf, home);
                    267:                 waddstr(win, home);
                    268:                 sp += strlen(home);
                    269:                 continue;
                    270:             }
                    271:         *sp++ = c;
                    272:         waddstr(win, unctrl(c));
                    273:     }
                    274:     *sp = '\0';
                    275:     if (sp > buf)       /* only change option if something has been typed */
                    276:         strucpy(opt, buf, strlen(buf));
                    277:     wmove(win, oy, ox);
                    278:     waddstr(win, opt);
                    279:     waddch(win, '\n');
                    280:     draw(win);
                    281:     if (win == msgw)
                    282:         mpos += sp - buf;
                    283:     if (c == '-')
                    284:         return MINUS;
                    285:     else if (c == '\033' || c == '\007')
                    286:         return QUIT;
                    287:     else
                    288:         return NORM;
                    289: }
                    290:
                    291: /*
                    292:  * print and then set options from the terminal
                    293:  */
                    294:
                    295: void
                    296: option(void)
                    297: {
                    298:     register OPTION     *op;
                    299:     register int        retval;
                    300:
                    301:     wclear(hw);
                    302:     touchwin(hw);
                    303:     /*
                    304:      * Display current values of options
                    305:      */
                    306:     for (op = optlist; op < &optlist[NUM_OPTS]; op++)
                    307:     {
                    308:         waddstr(hw, op->o_prompt);
                    309:         (*op->o_putfunc)(op->o_opt, hw);
                    310:         waddch(hw, '\n');
                    311:     }
                    312:     /*
                    313:      * Set values
                    314:      */
                    315:     wmove(hw, 0, 0);
                    316:     for (op = optlist; op < &optlist[NUM_OPTS]; op++)
                    317:     {
                    318:         waddstr(hw, op->o_prompt);
                    319:
                    320:                retval = (*op->o_getfunc)(op->o_opt, hw);
                    321:
                    322:         if (retval)
                    323:             if (retval == QUIT)
                    324:                 break;
                    325:             else if (op > optlist) {    /* MINUS */
                    326:                 wmove(hw, (op - optlist) - 1, 0);
                    327:                 op -= 2;
                    328:             }
                    329:             else        /* trying to back up beyond the top */
                    330:             {
                    331:                 putchar('\007');
                    332:                 wmove(hw, 0, 0);
                    333:                 op--;
                    334:             }
                    335:     }
                    336:     /*
                    337:      * Switch back to original screen
                    338:      */
                    339:     mvwaddstr(hw, lines-1, 0, spacemsg);
                    340:     draw(hw);
                    341:     wait_for(' ');
                    342:     restscr(cw);
                    343:     after = FALSE;
                    344: }
                    345:
                    346: /*
                    347:  * parse options from string, usually taken from the environment.
                    348:  * the string is a series of comma seperated values, with booleans
                    349:  * being stated as "name" (true) or "noname" (false), and strings
                    350:  * being "name=....", with the string being defined up to a comma
                    351:  * or the end of the entire option string.
                    352:  */
                    353:
                    354: void
                    355: parse_opts(char *str)
                    356: {
                    357:     register char *sp;
                    358:     register OPTION *op;
                    359:     register int len;
                    360:
                    361:     if (*str == '\"')
                    362:        str++;
                    363:
                    364:     while (*str)
                    365:     {
                    366:         /*
                    367:          * Get option name
                    368:          */
                    369:
                    370:         for (sp = str; isalpha(*sp); sp++)
                    371:             continue;
                    372:         len = (char *)sp - str;
                    373:         /*
                    374:          * Look it up and deal with it
                    375:          */
                    376:         for (op = optlist; op < &optlist[NUM_OPTS]; op++)
                    377:        {
                    378:             if (EQSTR(str, op->o_name, len))
                    379:             {
                    380:                 if (op->o_putfunc == put_bool)  /* if option is a boolean */
                    381:                     *(bool *)op->o_opt = TRUE;
                    382:                 else                            /* string option */
                    383:                 {
                    384:                     register char *start;
                    385:                     char value[LINELEN];
                    386:
                    387:                     /*
                    388:                      * Skip to start of string value
                    389:                      */
                    390:                     for (str = sp + 1; *str == '=' || *str == ':'; str++)
                    391:                         continue;
                    392:
                    393:                     if (*str == '~')
                    394:                     {
                    395:                         strcpy((char *) value, home);
                    396:                         start = (char *) value + strlen(home);
                    397:                         while (*++str == '/')
                    398:                             continue;
                    399:                     }
                    400:                     else
                    401:                         start = (char *) value;
                    402:                     /*
                    403:                      * Skip to end of string value
                    404:                      */
                    405:                     for (sp = str + 1; *sp && *sp != ',' && *sp != '\"'; sp++)
                    406:                         continue;
                    407:                     strucpy(start, str, (char *) sp - str);
                    408:
                    409:                     /* Put the value into the option field */
                    410:                     if (op->o_putfunc != put_abil) {
                    411:                         if (allowchange(op))
                    412:                             strcpy((char *)op->o_opt, value);
                    413:                     }
                    414:
                    415:                     else if (*(int *)op->o_opt == -1) {
                    416:                         /* Only init ability once */
                    417:                         register int len = strlen(value);
                    418:                         register int i;
                    419:
                    420:                         for (i=0; i<NUM_CHARTYPES-1; i++) {
                    421:                             if (EQSTR(value, char_class[i].name, len)) {
                    422:                                 *(int *)op->o_opt = i;
                    423:                                 break;
                    424:                             }
                    425:                         }
                    426:                     }
                    427:                 }
                    428:                 break;
                    429:             }
                    430:             /*
                    431:              * check for "noname" for booleans
                    432:              */
                    433:             else if (op->o_putfunc == put_bool
                    434:               && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
                    435:             {
                    436:                 *(bool *)op->o_opt = FALSE;
                    437:                 break;
                    438:             }
                    439:        }
                    440:
                    441:         /*
                    442:          * skip to start of next option name
                    443:          */
                    444:         while (*sp && !isalpha(*sp))
                    445:             sp++;
                    446:         str = sp;
                    447:     }
                    448: }
                    449:
                    450:
                    451: /*
                    452:  * print the default attributes
                    453:  */
                    454:
                    455: /* put_default(b, win)
                    456:  * bool *b;
                    457:  * WINDOW *win;
                    458:  * {
                    459:  *     waddstr(win, *b ? "True" : "False");
                    460:  * }
                    461:  */
                    462:
                    463: /*
                    464:  * print the character type
                    465:  */
                    466:
                    467: void
                    468: put_abil(int *ability, WINDOW *win)
                    469: {
                    470:     waddstr(win, char_class[*ability].name);
                    471: }
                    472:
                    473: /*
                    474:  * print out the quest
                    475:  */
                    476:
                    477: void
                    478: put_quest(int *quest, WINDOW *win)
                    479: {
                    480:     waddstr(win, rel_magic[*quest].mi_name);
                    481: }
                    482:
                    483: /*
                    484:  * put out a boolean
                    485:  */
                    486:
                    487: void
                    488: put_bool(bool *b, WINDOW *win)
                    489: {
                    490:     waddstr(win, *b ? "True" : "False");
                    491: }
                    492:
                    493: /*
                    494:  * put out a string
                    495:  */
                    496:
                    497: void
                    498: put_str(char *str, WINDOW *win)
                    499: {
                    500:     waddstr(win, str);
                    501: }
                    502:
                    503: /* Like get_str, but disallows changes when use_savedir is set. */
                    504: int
                    505: get_str_prot(char *opt, WINDOW *win)
                    506: {
                    507:     int oy, ox;
                    508:
                    509:     if (use_savedir) {
                    510:         getyx(win, oy, ox);
                    511:         waddstr(win, opt);
                    512:         return get_ro(win, oy, ox);
                    513:     }
                    514:     else {
                    515:         return get_str(opt, win);
                    516:     }
                    517: }
                    518:
                    519: /* When getting the scorefile, the new file must be opened. */
                    520: int
                    521: get_score(char *optstr, WINDOW *win)
                    522: {
                    523:     char old_score_file[LINELEN];
                    524:     int status;
                    525:
                    526:     if (use_savedir)
                    527:         return get_str_prot(optstr, win);
                    528:
                    529:     strcpy(old_score_file, optstr);
                    530:     status = get_str(optstr, win);
                    531:     if (status == NORM && strcmp(old_score_file, optstr))
                    532:     {
                    533:         if (scorefi != NULL)
                    534:             fclose(scorefi);
                    535:         scorefi = fopen(score_file, "rb+");
                    536:         if (scorefi == NULL)
                    537:             scorefi = fopen(score_file, "wb+");
                    538:     }
                    539:     return status;
                    540: }
                    541:
                    542: bool
                    543: allowchange(OPTION *op)
                    544: {
                    545:     if (!use_savedir)
                    546:         return TRUE;
                    547:     if (!strcmp(op->o_name, "name"))
                    548:         return FALSE;
                    549:     if (!strcmp(op->o_name, "file"))
                    550:         return FALSE;
                    551:     if (!strcmp(op->o_name, "score"))
                    552:         return FALSE;
                    553:     return TRUE;
                    554: }

CVSweb