[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     ! 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