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

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

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

CVSweb