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

Annotation of early-roguelike/rogue3/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:  * @(#)options.c       3.3 (Berkeley) 5/25/81
                      7:  *
                      8:  * 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: #include <stdlib.h>
                     16: #include "curses.h"
                     17: #include <ctype.h>
                     18: #include <string.h>
                     19: #include "machdep.h"
                     20: #include "rogue.h"
                     21:
                     22: #define        NUM_OPTS        (sizeof optlist / sizeof (OPTION))
                     23:
                     24: /*
                     25:  * description of an option and what to do with it
                     26:  */
                     27: struct optstruct {
                     28:     char       *o_name;        /* option name */
                     29:     char       *o_prompt;      /* prompt for interactive entry */
                     30:     void       *o_opt;         /* pointer to thing to set */
                     31:     void       (*o_putfunc)(); /* function to print value */
                     32:     int                (*o_getfunc)(); /* function to get value interactively */
                     33: };
                     34:
                     35: typedef struct optstruct       OPTION;
                     36:
                     37: int allowchange(OPTION *opt); /* doesn't need to be externally visible */
                     38:
                     39: OPTION optlist[] = {
                     40:     {"terse",   "Terse output: ",
                     41:                 (int *) &terse,        put_bool,       get_bool        },
                     42:     {"flush",   "Flush typeahead during battle: ",
                     43:                 (int *) &fight_flush,  put_bool,       get_bool        },
                     44:     {"jump",    "Show position only at end of run: ",
                     45:                 (int *) &jump,         put_bool,       get_bool        },
                     46:     {"step",   "Do inventories one line at a time: ",
                     47:                (int *) &slow_invent,   put_bool,       get_bool        },
                     48:     {"askme",  "Ask me about unidentified things: ",
                     49:                (int *) &askme,         put_bool,       get_bool        },
                     50:     {"name",    "Name: ",
                     51:                 (int *) whoami,        put_str,        get_str         },
                     52:     {"fruit",   "Fruit: ",
                     53:                 (int *) fruit,         put_str,        get_str         },
                     54:     {"file",    "Save file: ",
                     55:                 (int *) file_name,     put_str,        get_str         }
                     56: };
                     57:
                     58: /*
                     59:  * print and then set options from the terminal
                     60:  */
                     61: void
                     62: option()
                     63: {
                     64:     OPTION     *op;
                     65:     int        retval;
                     66:
                     67:     wclear(hw);
                     68:     touchwin(hw);
                     69:     /*
                     70:      * Display current values of options
                     71:      */
                     72:     for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
                     73:     {
                     74:         if (allowchange(op))
                     75:         {
                     76:            waddstr(hw, op->o_prompt);
                     77:            (*op->o_putfunc)(op->o_opt);
                     78:            waddch(hw, '\n');
                     79:         }
                     80:     }
                     81:     /*
                     82:      * Set values
                     83:      */
                     84:     wmove(hw, 0, 0);
                     85:     for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
                     86:     {
                     87:         if (!allowchange(op))
                     88:             continue;
                     89:        waddstr(hw, op->o_prompt);
                     90:        if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
                     91:         {
                     92:            if (retval == QUIT)
                     93:                break;
                     94: #if 0
                     95: /* Support for MINUS has been removed because making it work with
                     96:  * hidden unchangable options without underflowing optlist will
                     97:  * require a complete rewrite.  And it should also be rewritten
                     98:  * so option() doesn't count on get_str() to put the cursor in the
                     99:  * right place, because that makes it a pain to understand.
                    100:  */
                    101:            else if (op > optlist) {    /* retval == MINUS */
                    102:                wmove(hw, (int)(op - optlist) - 1, 0);
                    103:                op -= 2;
                    104:            }
                    105:            else        /* trying to back up beyond the top */
                    106:            {
                    107:                beep();
                    108:                wmove(hw, 0, 0);
                    109:                op--;
                    110:            }
                    111: #else
                    112:             break;
                    113: #endif
                    114:         }
                    115:     }
                    116:     /*
                    117:      * Switch back to original screen
                    118:      */
                    119:     mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
                    120:     draw(hw);
                    121:     wait_for(hw,' ');
                    122:     clearok(cw, TRUE);
                    123:     touchwin(cw);
                    124:     after = FALSE;
                    125: }
                    126:
                    127: /*
                    128:  * put out a boolean
                    129:  */
                    130: void
                    131: put_bool(void *b)
                    132: {
                    133:     waddstr(hw, *(int *)b ? "True" : "False");
                    134: }
                    135:
                    136: /*
                    137:  * put out a string
                    138:  */
                    139: void
                    140: put_str(void *str)
                    141: {
                    142:     waddstr(hw, (char *) str);
                    143: }
                    144:
                    145: /*
                    146:  * allow changing a boolean option and print it out
                    147:  */
                    148:
                    149: int
                    150: get_bool(void *vp, WINDOW *win)
                    151: {
                    152:     int *bp = (int *) vp;
                    153:     int oy, ox;
                    154:     int op_bad;
                    155:
                    156:     op_bad = TRUE;
                    157:     getyx(win, oy, ox);
                    158:     waddstr(win, *bp ? "True" : "False");
                    159:     while(op_bad)
                    160:     {
                    161:        wmove(win, oy, ox);
                    162:        draw(win);
                    163:        switch (readchar(win))
                    164:        {
                    165:            case 't':
                    166:            case 'T':
                    167:                *bp = TRUE;
                    168:                op_bad = FALSE;
                    169:                break;
                    170:            case 'f':
                    171:            case 'F':
                    172:                *bp = FALSE;
                    173:                op_bad = FALSE;
                    174:                break;
                    175:            case '\n':
                    176:            case '\r':
                    177:                op_bad = FALSE;
                    178:                break;
                    179:            case '\033':
                    180:            case '\007':
                    181:                return QUIT;
                    182:            case '-':
                    183:                return MINUS;
                    184:            default:
                    185:                mvwaddstr(win, oy, ox + 10, "(T or F)");
                    186:        }
                    187:     }
                    188:     wmove(win, oy, ox);
                    189:     waddstr(win, *bp ? "True" : "False");
                    190:     waddch(win, '\n');
                    191:     return NORM;
                    192: }
                    193:
                    194: /*
                    195:  * set a string option
                    196:  */
                    197: int
                    198: get_str(void *vopt, WINDOW *win)
                    199: {
                    200:     char *opt = (char *) vopt;
                    201:     char *sp;
                    202:     int c, oy, ox;
                    203:     char buf[80];
                    204:
                    205:     draw(win);
                    206:     getyx(win, oy, ox);
                    207:     /*
                    208:      * loop reading in the string, and put it in a temporary buffer
                    209:      */
                    210:     for (sp = buf;
                    211:        (c = readchar(win)) != '\n' && c != '\r' && c != '\033' && c != '\007';
                    212:        wclrtoeol(win), draw(win))
                    213:     {
                    214:        if (c == -1)
                    215:            continue;
                    216:        else if (c == md_erasechar())   /* process erase character */
                    217:        {
                    218:            if (sp > buf)
                    219:            {
                    220:                int i;
                    221:                int myx, myy;
                    222:
                    223:                sp--;
                    224:
                    225:                for (i = (int) strlen(unctrl(*sp)); i; i--)
                    226:                {
                    227:                    getyx(win,myy,myx);
                    228:                    if ((myx == 0)&& (myy > 0))
                    229:                    {
                    230:                        wmove(win,myy-1,getmaxx(win)-1);
                    231:                        waddch(win,' ');
                    232:                        wmove(win,myy-1,getmaxx(win)-1);
                    233:                    }
                    234:                    else
                    235:                        waddch(win, '\b');
                    236:                }
                    237:            }
                    238:            continue;
                    239:        }
                    240:        else if (c == md_killchar())    /* process kill character */
                    241:        {
                    242:            sp = buf;
                    243:            wmove(win, oy, ox);
                    244:            continue;
                    245:        }
                    246:        else if (sp == buf)
                    247:            if (c == '-')
                    248:                break;
                    249:            else if (c == '~')
                    250:            {
                    251:                strcpy(buf, home);
                    252:                waddstr(win, home);
                    253:                sp += strlen(home);
                    254:                continue;
                    255:            }
                    256:
                    257:        if ((sp - buf) < 78) /* Avoid overflow */
                    258:        {
                    259:            *sp++ = c;
                    260:            waddstr(win, unctrl(c));
                    261:        }
                    262:     }
                    263:     *sp = '\0';
                    264:     if (sp > buf)      /* only change option if something has been typed */
                    265:        strucpy(opt, buf, strlen(buf));
                    266:     wmove(win, oy, ox);
                    267:     waddstr(win, opt);
                    268:     waddch(win, '\n');
                    269:     draw(win);
                    270:     if (win == cw)
                    271:        mpos += (int)(sp - buf);
                    272:     if (c == '-')
                    273:        return MINUS;
                    274:     else if (c == '\033' || c == '\007')
                    275:        return QUIT;
                    276:     else
                    277:        return NORM;
                    278: }
                    279:
                    280: /*
                    281:  * parse options from string, usually taken from the environment.
                    282:  * the string is a series of comma seperated values, with booleans
                    283:  * being stated as "name" (true) or "noname" (false), and strings
                    284:  * being "name=....", with the string being defined up to a comma
                    285:  * or the end of the entire option string.
                    286:  */
                    287:
                    288: void
                    289: parse_opts(char *str)
                    290: {
                    291:     char *sp;
                    292:     OPTION *op;
                    293:     int len;
                    294:
                    295:     while (*str)
                    296:     {
                    297:        /*
                    298:         * Get option name
                    299:         */
                    300:        for (sp = str; isalpha(*sp); sp++)
                    301:            continue;
                    302:        len = (int)(sp - str);
                    303:        /*
                    304:         * Look it up and deal with it
                    305:         */
                    306:        for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
                    307:         {
                    308:             /* If using system savefiles, changing your name or the
                    309:                save file is not allowed. */
                    310:             if (!allowchange(op))
                    311:               continue;
                    312:            if (EQSTR(str, op->o_name, len))
                    313:            {
                    314:                if (op->o_putfunc == put_bool)  /* if option is a boolean */
                    315:                    *(int *)op->o_opt = TRUE;
                    316:                else                            /* string option */
                    317:                {
                    318:                    char *start;
                    319:                    /*
                    320:                     * Skip to start of string value
                    321:                     */
                    322:                    for (str = sp + 1; *str == '='; str++)
                    323:                        continue;
                    324:                    if (*str == '~')
                    325:                    {
                    326:                        strcpy((char *) op->o_opt, home);
                    327:                        start = (char *) op->o_opt + strlen(home);
                    328:                        while (*++str == '/')
                    329:                            continue;
                    330:                    }
                    331:                    else
                    332:                        start = (char *) op->o_opt;
                    333:                    /*
                    334:                     * Skip to end of string value
                    335:                     */
                    336:                    for (sp = str + 1; *sp && *sp != ','; sp++)
                    337:                        continue;
                    338:                    strucpy(start, str, sp - str);
                    339:                }
                    340:                break;
                    341:            }
                    342:            /*
                    343:             * check for "noname" for booleans
                    344:             */
                    345:            else if (op->o_putfunc == put_bool
                    346:              && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
                    347:            {
                    348:                *(int *)op->o_opt = FALSE;
                    349:                break;
                    350:            }
                    351:         }
                    352:
                    353:        /*
                    354:         * skip to start of next option name
                    355:         */
                    356:        while (*sp && !isalpha(*sp))
                    357:            sp++;
                    358:        str = sp;
                    359:     }
                    360: }
                    361:
                    362: /*
                    363:  * copy string using unctrl for things
                    364:  */
                    365: void
                    366: strucpy(char *s1, char *s2, size_t len)
                    367: {
                    368:     const char *sp;
                    369:
                    370:     while (len--)
                    371:     {
                    372:        sp = unctrl(*s2);
                    373:        strcpy(s1, sp);
                    374:        s1 += strlen(sp);
                    375:        s2++;
                    376:     }
                    377:     *s1 = '\0';
                    378: }
                    379:
                    380: /* Tells whether the user is allowed to change the option. */
                    381: int allowchange(OPTION *opt)
                    382: {
                    383:   if (!use_savedir)
                    384:     return 1;
                    385:   if (!strcmp(opt->o_name, "name"))
                    386:     return 0;
                    387:   if (!strcmp(opt->o_name, "file"))
                    388:     return 0;
                    389:   return 1;
                    390: }

CVSweb