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