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

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

CVSweb