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