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

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

1.1       rubenllo    1: /*
                      2:  * This file has all the code for the option command.  I would rather
                      3:  * this command were not necessary, but it is the only way to keep the
                      4:  * wolves off of my back.
                      5:  *
                      6:  * @(#)options.c       4.24 (Berkeley) 05/10/83
                      7:  *
                      8:  * Rogue: Exploring the Dungeons of Doom
                      9:  * Copyright (C) 1980-1983, 1985, 1999 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: #include <stdlib.h>
                     16: #include <curses.h>
                     17: #include <ctype.h>
                     18: #include <string.h>
                     19: #include "rogue.h"
                     20:
                     21: #define        EQSTR(a, b, c)  (strncmp(a, b, c) == 0)
                     22:
                     23: #define        NUM_OPTS        (sizeof optlist / sizeof (OPTION))
                     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:                                /* function to print value */
                     33:     void       (*o_putfunc)(void *opt);
                     34:                                /* function to get value interactively */
                     35:     int                (*o_getfunc)(void *opt, WINDOW *win);
                     36: };
                     37:
                     38: typedef struct optstruct       OPTION;
                     39:
                     40: void   pr_optname(const OPTION *op);
                     41: int     allowchange(const OPTION *op);
                     42:
                     43: static const OPTION    optlist[] = {
                     44:     {"terse",   "Terse output",
                     45:                 &terse,        put_bool,       get_bool        },
                     46:     {"flush",   "Flush typeahead during battle",
                     47:                 &fight_flush,  put_bool,       get_bool        },
                     48:     {"jump",    "Show position only at end of run",
                     49:                 &jump,         put_bool,       get_bool        },
                     50:     {"seefloor", "Show the lamp-illuminated floor",
                     51:                 &see_floor,    put_bool,       get_sf          },
                     52:     {"passgo", "Follow turnings in passageways",
                     53:                 &passgo,       put_bool,       get_bool        },
                     54:     {"tombstone", "Print out tombstone when killed",
                     55:                 &tombstone,    put_bool,       get_bool        },
                     56:     {"inven",  "Inventory style",
                     57:                 &inv_type,     put_inv_t,      get_inv_t       },
                     58:     {"name",    "Name",
                     59:                 whoami,        put_str,        get_str         },
                     60:     {"fruit",   "Fruit",
                     61:                 fruit,         put_str,        get_str         },
                     62:     {"file",    "Save file",
                     63:                 file_name,     put_str,        get_str         }
                     64: };
                     65:
                     66: /*
                     67:  * option:
                     68:  *     Print and then set options from the terminal
                     69:  */
                     70:
                     71: void
                     72: option(void)
                     73: {
                     74:     const OPTION *op;
                     75:     int                retval;
                     76:
                     77:     wclear(hw);
                     78:     /*
                     79:      * Display current values of options
                     80:      */
                     81:     for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
                     82:     {
                     83:         if (allowchange(op))
                     84:         {
                     85:            pr_optname(op);
                     86:            (*op->o_putfunc)(op->o_opt);
                     87:            waddch(hw, '\n');
                     88:         }
                     89:     }
                     90:     /*
                     91:      * Set values
                     92:      */
                     93:     wmove(hw, 0, 0);
                     94:     for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
                     95:     {
                     96:         if (!allowchange(op))
                     97:             continue;
                     98:        pr_optname(op);
                     99:        retval = (*op->o_getfunc)(op->o_opt, hw);
                    100:        if (retval)
                    101:        {
                    102:            if (retval == QUIT)
                    103:                break;
                    104: #if 0
                    105: /* Support for MINUS removed until this section is rewritten. */
                    106:            else if (op > optlist) {    /* MINUS */
                    107:                wmove(hw, (int)(op - optlist) - 1, 0);
                    108:                op -= 2;
                    109:            }
                    110:            else        /* trying to back up beyond the top */
                    111:            {
                    112:                putchar('\007');
                    113:                wmove(hw, 0, 0);
                    114:                op--;
                    115:            }
                    116: #else
                    117:             break;
                    118: #endif
                    119:        }
                    120:     }
                    121:     /*
                    122:      * Switch back to original screen
                    123:      */
                    124:     wmove(hw, LINES - 1, 0);
                    125:     waddstr(hw, "--Press space to continue--");
                    126:     wrefresh(hw);
                    127:     wait_for(hw, ' ');
                    128:     clearok(curscr, TRUE);
                    129:     touchwin(stdscr);
                    130:     after = FALSE;
                    131: }
                    132:
                    133: /*
                    134:  * pr_optname:
                    135:  *     Print out the option name prompt
                    136:  */
                    137:
                    138: void
                    139: pr_optname(const OPTION *op)
                    140: {
                    141:     wprintw(hw, "%s (\"%s\"): ", op->o_prompt, op->o_name);
                    142: }
                    143:
                    144: /*
                    145:  * put_bool
                    146:  *     Put out a boolean
                    147:  */
                    148:
                    149: void
                    150: put_bool(void *b)
                    151: {
                    152:     waddstr(hw, *(int *) b ? "True" : "False");
                    153: }
                    154:
                    155: /*
                    156:  * put_str:
                    157:  *     Put out a string
                    158:  */
                    159:
                    160: void
                    161: put_str(void *str)
                    162: {
                    163:     waddstr(hw, (char *) str);
                    164: }
                    165:
                    166: /*
                    167:  * put_inv_t:
                    168:  *     Put out an inventory type
                    169:  */
                    170:
                    171: void
                    172: put_inv_t(void *ip)
                    173: {
                    174:     waddstr(hw, inv_t_name[*(int *) ip]);
                    175: }
                    176:
                    177: /*
                    178:  * get_bool:
                    179:  *     Allow changing a boolean option and print it out
                    180:  */
                    181: int
                    182: get_bool(void *vp, WINDOW *win)
                    183: {
                    184:     int *bp = (int *) vp;
                    185:     int oy, ox;
                    186:     int op_bad;
                    187:
                    188:     op_bad = TRUE;
                    189:     getyx(win, oy, ox);
                    190:     waddstr(win, *bp ? "True" : "False");
                    191:     while (op_bad)
                    192:     {
                    193:        wmove(win, oy, ox);
                    194:        wrefresh(win);
                    195:        switch (wreadchar(win))
                    196:        {
                    197:            case 't':
                    198:            case 'T':
                    199:                *bp = TRUE;
                    200:                op_bad = FALSE;
                    201:                break;
                    202:            case 'f':
                    203:            case 'F':
                    204:                *bp = FALSE;
                    205:                op_bad = FALSE;
                    206:                break;
                    207:            case '\n':
                    208:            case '\r':
                    209:                op_bad = FALSE;
                    210:                break;
                    211:            case ESCAPE:
                    212:                return QUIT;
                    213:            case '-':
                    214:                return MINUS;
                    215:            default:
                    216:                wmove(win, oy, ox + 10);
                    217:                waddstr(win, "(T or F)");
                    218:        }
                    219:     }
                    220:     wmove(win, oy, ox);
                    221:     waddstr(win, *bp ? "True" : "False");
                    222:     waddch(win, '\n');
                    223:     return NORM;
                    224: }
                    225:
                    226: /*
                    227:  * get_sf:
                    228:  *     Change value and handle transition problems from see_floor to
                    229:  *     !see_floor.
                    230:  */
                    231: int
                    232: get_sf(void *vp, WINDOW *win)
                    233: {
                    234:     int        *bp = (int *) vp;
                    235:     int        was_sf;
                    236:     int                retval;
                    237:
                    238:     was_sf = see_floor;
                    239:     retval = get_bool(bp, win);
                    240:     if (retval == QUIT) return(QUIT);
                    241:     if (was_sf != see_floor)
                    242:     {
                    243:        if (!see_floor) {
                    244:            see_floor = TRUE;
                    245:            erase_lamp(&hero, proom);
                    246:            see_floor = FALSE;
                    247:        }
                    248:        else
                    249:            look(FALSE);
                    250:     }
                    251:     return(NORM);
                    252: }
                    253:
                    254: /*
                    255:  * get_str:
                    256:  *     Set a string option
                    257:  */
                    258: #define MAXINP 50      /* max string to read from terminal or environment */
                    259:
                    260: int
                    261: get_str(void *vopt, WINDOW *win)
                    262: {
                    263:     char *opt = (char *) vopt;
                    264:     char *sp;
                    265:     int oy, ox;
                    266:     size_t i;
                    267:     int c;
                    268:     static char buf[MAXSTR];
                    269:
                    270:     getyx(win, oy, ox);
                    271:     wrefresh(win);
                    272:     /*
                    273:      * loop reading in the string, and put it in a temporary buffer
                    274:      */
                    275:     for (sp = buf; (c = wreadchar(win)) != '\n' && c != '\r' && c != ESCAPE;
                    276:        wclrtoeol(win), wrefresh(win))
                    277:     {
                    278:        if (c == -1)
                    279:            continue;
                    280:        else if (c == erasechar())      /* process erase character */
                    281:        {
                    282:            if (sp > buf)
                    283:            {
                    284:                sp--;
                    285:                for (i = strlen(unctrl(*sp)); i; i--)
                    286:                    waddch(win, '\b');
                    287:            }
                    288:            continue;
                    289:        }
                    290:        else if (c == killchar())       /* process kill character */
                    291:        {
                    292:            sp = buf;
                    293:            wmove(win, oy, ox);
                    294:            continue;
                    295:        }
                    296:        else if (sp == buf)
                    297:        {
                    298:            if (c == '-' && win != stdscr)
                    299:                break;
                    300:            else if (c == '~')
                    301:            {
                    302:                strcpy(buf, home);
                    303:                waddstr(win, home);
                    304:                sp += strlen(home);
                    305:                continue;
                    306:            }
                    307:        }
                    308:        if (sp >= &buf[MAXINP] || !(isprint(c) || c == ' '))
                    309:            putchar(CTRL('G'));
                    310:        else
                    311:        {
                    312:            *sp++ = (char) c;
                    313:            waddstr(win, unctrl(c));
                    314:        }
                    315:     }
                    316:     *sp = '\0';
                    317:     if (sp > buf)      /* only change option if something has been typed */
                    318:        strucpy(opt, buf, strlen(buf));
                    319:     mvwprintw(win, oy, ox, "%s\n", opt);
                    320:     wrefresh(win);
                    321:     if (win == stdscr)
                    322:        mpos += (int)(sp - buf);
                    323:     if (c == '-')
                    324:        return MINUS;
                    325:     else if (c == ESCAPE)
                    326:        return QUIT;
                    327:     else
                    328:        return NORM;
                    329: }
                    330:
                    331: /*
                    332:  * get_inv_t
                    333:  *     Get an inventory type name
                    334:  */
                    335: int
                    336: get_inv_t(void *vp, WINDOW *win)
                    337: {
                    338:     int *ip = (int *) vp;
                    339:     int oy, ox;
                    340:     int op_bad;
                    341:
                    342:     op_bad = TRUE;
                    343:     getyx(win, oy, ox);
                    344:     waddstr(win, inv_t_name[*ip]);
                    345:     while (op_bad)
                    346:     {
                    347:        wmove(win, oy, ox);
                    348:        wrefresh(win);
                    349:        switch (wreadchar(win))
                    350:        {
                    351:            case 'o':
                    352:            case 'O':
                    353:                *ip = INV_OVER;
                    354:                op_bad = FALSE;
                    355:                break;
                    356:            case 's':
                    357:            case 'S':
                    358:                *ip = INV_SLOW;
                    359:                op_bad = FALSE;
                    360:                break;
                    361:            case 'c':
                    362:            case 'C':
                    363:                *ip = INV_CLEAR;
                    364:                op_bad = FALSE;
                    365:                break;
                    366:            case '\n':
                    367:            case '\r':
                    368:                op_bad = FALSE;
                    369:                break;
                    370:            case ESCAPE:
                    371:                return QUIT;
                    372:            case '-':
                    373:                return MINUS;
                    374:            default:
                    375:                wmove(win, oy, ox + 15);
                    376:                waddstr(win, "(O, S, or C)");
                    377:        }
                    378:     }
                    379:     mvwprintw(win, oy, ox, "%s\n", inv_t_name[*ip]);
                    380:     return NORM;
                    381: }
                    382:
                    383:
                    384: #ifdef MASTER
                    385: /*
                    386:  * get_num:
                    387:  *     Get a numeric option
                    388:  */
                    389: int
                    390: get_num(void *vp, WINDOW *win)
                    391: {
                    392:     int *opt = (int *) vp;
                    393:     int i;
                    394:     static char buf[MAXSTR];
                    395:
                    396:     if ((i = get_str(buf, win)) == NORM)
                    397:        *opt = atoi(buf);
                    398:     return i;
                    399: }
                    400: #endif
                    401:
                    402: /*
                    403:  * parse_opts:
                    404:  *     Parse options from string, usually taken from the environment.
                    405:  *     The string is a series of comma seperated values, with booleans
                    406:  *     being stated as "name" (true) or "noname" (false), and strings
                    407:  *     being "name=....", with the string being defined up to a comma
                    408:  *     or the end of the entire option string.
                    409:  */
                    410:
                    411: void
                    412: parse_opts(char *str)
                    413: {
                    414:     char *sp;
                    415:     const OPTION *op;
                    416:     int len;
                    417:     const char **i;
                    418:     char *start;
                    419:
                    420:     while (*str)
                    421:     {
                    422:        /*
                    423:         * Get option name
                    424:         */
                    425:        for (sp = str; isalpha((int)*sp); sp++)
                    426:            continue;
                    427:        len = (int)(sp - str);
                    428:        /*
                    429:         * Look it up and deal with it
                    430:         */
                    431:        for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
                    432:         {
                    433:             if (!allowchange(op))
                    434:                 continue;
                    435:            if (EQSTR(str, op->o_name, len))
                    436:            {
                    437:                if (op->o_putfunc == put_bool)  /* if option is a boolean */
                    438:                    *(int *)op->o_opt = TRUE;   /* NOSTRICT */
                    439:                else                            /* string option */
                    440:                {
                    441:                    /*
                    442:                     * Skip to start of string value
                    443:                     */
                    444:                    for (str = sp + 1; *str == '='; str++)
                    445:                        continue;
                    446:                    if (*str == '~')
                    447:                    {
                    448:                        strcpy((char *) op->o_opt, home);         /* NOSTRICT */
                    449:                        start = (char *) op->o_opt + strlen(home);/* NOSTRICT */
                    450:                        while (*++str == '/')
                    451:                            continue;
                    452:                    }
                    453:                    else
                    454:                        start = (char *) op->o_opt;     /* NOSTRICT */
                    455:                    /*
                    456:                     * Skip to end of string value
                    457:                     */
                    458:                    for (sp = str + 1; *sp && *sp != ','; sp++)
                    459:                        continue;
                    460:                    /*
                    461:                     * check for type of inventory
                    462:                     */
                    463:                    if (op->o_putfunc == put_inv_t)
                    464:                    {
                    465:                        if (islower((int)*str))
                    466:                            *str = (char) toupper(*str);
                    467:                        for (i = inv_t_name; i <= &inv_t_name[INV_CLEAR]; i++)
                    468:                            if (strncmp(str, *i, sp - str) == 0)
                    469:                            {
                    470:                                inv_type = (int)(i - inv_t_name);
                    471:                                break;
                    472:                            }
                    473:                    }
                    474:                    else
                    475:                        strucpy(start, str, (size_t)(sp - str));
                    476:                }
                    477:                break;
                    478:            }
                    479:            /*
                    480:             * check for "noname" for booleans
                    481:             */
                    482:            else if (op->o_putfunc == put_bool
                    483:              && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
                    484:            {
                    485:                *(int *)op->o_opt = FALSE;      /* NOSTRICT */
                    486:                break;
                    487:            }
                    488:         }
                    489:
                    490:        /*
                    491:         * skip to start of next option name
                    492:         */
                    493:        while (*sp && !isalpha((int)*sp))
                    494:            sp++;
                    495:        str = sp;
                    496:     }
                    497: }
                    498:
                    499: /*
                    500:  * strucpy:
                    501:  *     Copy string using unctrl for things
                    502:  */
                    503:
                    504: void
                    505: strucpy(char *s1, const char *s2, size_t len)
                    506: {
                    507:     if (len > MAXINP)
                    508:        len = MAXINP;
                    509:     while (len--)
                    510:     {
                    511:        if (isprint((int)*s2) || *s2 == ' ')
                    512:            *s1++ = *s2;
                    513:        s2++;
                    514:     }
                    515:     *s1 = '\0';
                    516: }
                    517:
                    518: /* Tells whether the user is allowed to change the option. */
                    519: int
                    520: allowchange(const OPTION *opt)
                    521: {
                    522:     if (!use_savedir)
                    523:         return TRUE;
                    524:     if (!strcmp(opt->o_name, "name"))
                    525:         return FALSE;
                    526:     if (!strcmp(opt->o_name, "file"))
                    527:         return FALSE;
                    528:     return TRUE;
                    529: }

CVSweb