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

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

1.1       rubenllo    1: /*
                      2:     options.c - This file has all the code for the option command
                      3:
                      4:     UltraRogue: The Ultimate Adventure in the Dungeons of Doom
                      5:     Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
                     10:     All rights reserved.
                     11:
                     12:     Based on "Rogue: Exploring the Dungeons of Doom"
                     13:     Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     14:     All rights reserved.
                     15:
                     16:     See the file LICENSE.TXT for full copyright and licensing information.
                     17: */
                     18:
                     19: #include <string.h>
                     20: #include <ctype.h>
                     21: #include "rogue.h"
                     22:
                     23: #define NUM_OPTS    (sizeof optlist / sizeof (OPTION))
                     24: #define EQSTR(a, b, c)  (strncmp(a, b, c) == 0)
                     25:
                     26: int get_restr(opt_arg *opt, WINDOW *win);
                     27: int get_score(opt_arg *opt, WINDOW *win);
                     28:
                     29: /* description of an option and what to do with it */
                     30: static OPTION optlist[] =
                     31: {
                     32:     {"jump","Show position only at end of run (jump): ", { &jump },
                     33:       put_bool, get_bool},
                     34:     {"inven","Style of inventories (inven): ", { &inv_type },
                     35:       put_inv, get_inv},
                     36:     {"askme","Ask me about unidentified things (askme): ", { &askme},
                     37:       put_bool, get_bool},
                     38:     {"doorstop","Stop running when adjacent (doorstop): ", { &doorstop },
                     39:       put_bool, get_bool},
                     40:     {"name", "Name (name): ",              { &whoami }, put_str, get_restr},
                     41:     {"fruit", "Fruit (fruit): ",           { &fruit }, put_str, get_str},
                     42:     {"file", "Save file (file): ",         { &file_name }, put_str, get_restr},
                     43:     {"score", "Score file (score): ",      { &score_file }, put_str, get_score},
                     44:     {"class", "Character class (class): ", { &char_type }, put_abil, get_abil}
                     45: };
                     46:
                     47: /*
                     48:     option()
                     49:         print and then set options from the terminal
                     50: */
                     51:
                     52: void
                     53: option(void)
                     54: {
                     55:     OPTION  *op;
                     56:     int retval;
                     57:
                     58:     wclear(hw);
                     59:     touchwin(hw);
                     60:
                     61:     /* Display current values of options */
                     62:
                     63:     for (op = optlist; op < &optlist[NUM_OPTS]; op++)
                     64:     {
                     65:         waddstr(hw, op->o_prompt);
                     66:         (*op->o_putfunc)(&op->o_opt, hw);
                     67:         waddch(hw, '\n');
                     68:     }
                     69:
                     70:     /* Set values */
                     71:
                     72:     wmove(hw, 0, 0);
                     73:
                     74:     for (op = optlist; op < &optlist[NUM_OPTS]; op++)
                     75:     {
                     76:         waddstr(hw, op->o_prompt);
                     77:
                     78:        retval = (*op->o_getfunc)(&op->o_opt, hw);
                     79:
                     80:         if (retval)
                     81:             if (retval == QUIT)
                     82:                 break;
                     83:             else if (op > optlist)      /* MINUS */
                     84:             {
                     85:                 wmove(hw, (int)(op - optlist) - 1, 0);
                     86:                 op -= 2;
                     87:             }
                     88:             else    /* trying to back up beyond the top */
                     89:             {
                     90:                 putchar('\007');
                     91:                 wmove(hw, 0, 0);
                     92:                 op--;
                     93:             }
                     94:     }
                     95:
                     96:     /* Switch back to original screen */
                     97:
                     98:     mvwaddstr(hw, LINES - 1, 0, spacemsg);
                     99:     wrefresh(hw);
                    100:     wait_for(' ');
                    101:     clearok(cw, TRUE);
                    102:     touchwin(cw);
                    103: }
                    104:
                    105: /*
                    106:     put_bool()
                    107:         put out a boolean
                    108: */
                    109:
                    110: void
                    111: put_bool(opt_arg *opt, WINDOW *win)
                    112: {
                    113:     waddstr(win, *opt->iarg ? "True" : "False");
                    114: }
                    115:
                    116: /*
                    117:     put_str()
                    118:         put out a string
                    119: */
                    120:
                    121: void
                    122: put_str(opt_arg *opt, WINDOW *win)
                    123: {
                    124:     waddstr(win, opt->str);
                    125: }
                    126:
                    127: /*
                    128:     put_abil()
                    129:         print the character type
                    130: */
                    131:
                    132: void
                    133: put_abil(opt_arg *opt, WINDOW *win)
                    134: {
                    135:     char    *abil;
                    136:
                    137:     switch(*opt->iarg)
                    138:     {
                    139:         case C_FIGHTER:
                    140:             abil = "Fighter";
                    141:             break;
                    142:         case C_MAGICIAN:
                    143:             abil = "Magic User";
                    144:             break;
                    145:         case C_CLERIC:
                    146:             abil = "Cleric";
                    147:             break;
                    148:         case C_THIEF:
                    149:             abil = "Thief";
                    150:             break;
                    151:         case C_PALADIN:
                    152:             abil = "Paladin";
                    153:             break;
                    154:         case C_RANGER:
                    155:             abil = "Ranger";
                    156:             break;
                    157:         case C_ILLUSION:
                    158:             abil = "Illusionist";
                    159:             break;
                    160:         case C_ASSASIN:
                    161:             abil = "Assasin";
                    162:             break;
                    163:         case C_NINJA:
                    164:             abil = "Ninja";
                    165:             break;
                    166:         case C_DRUID:
                    167:             abil = "Druid";
                    168:             break;
                    169:         default:
                    170:             abil = "(unknown)";
                    171:     }
                    172:     waddstr(win, abil);
                    173: }
                    174:
                    175:
                    176: /*
                    177:     get_bool()
                    178:         allow changing a boolean option and print it out
                    179: */
                    180:
                    181: int
                    182: get_bool(opt_arg *opt, WINDOW *win)
                    183: {
                    184:     int oy, ox;
                    185:     int op_bad;
                    186:
                    187:     op_bad = TRUE;
                    188:     getyx(win, oy, ox);
                    189:     waddstr(win, *opt->iarg ? "True" : "False");
                    190:
                    191:     while(op_bad)
                    192:     {
                    193:         wmove(win, oy, ox);
                    194:         wrefresh(win);
                    195:
                    196:         switch (readcharw(win))
                    197:         {
                    198:             case 't':
                    199:             case 'T':
                    200:                 *opt->iarg = TRUE;
                    201:                 op_bad = FALSE;
                    202:                 break;
                    203:
                    204:             case 'f':
                    205:             case 'F':
                    206:                 *opt->iarg = FALSE;
                    207:                 op_bad = FALSE;
                    208:                 break;
                    209:
                    210:             case '\n':
                    211:             case '\r':
                    212:                 op_bad = FALSE;
                    213:                 break;
                    214:
                    215:             case '\033':
                    216:             case '\007':
                    217:                 return QUIT;
                    218:
                    219:             case '-':
                    220:                 return MINUS;
                    221:
                    222:             default:
                    223:                 mvwaddstr(win, oy, ox + 10, "(T or F)");
                    224:         }
                    225:     }
                    226:
                    227:     wmove(win, oy, ox);
                    228:     wclrtoeol(win);
                    229:     waddstr(win, *opt->iarg ? "True" : "False");
                    230:     waddch(win, '\n');
                    231:
                    232:     return(NORM);
                    233: }
                    234:
                    235: /*
                    236:     get_str()
                    237:         set a string option
                    238: */
                    239:
                    240: int
                    241: get_str(opt_arg *opt, WINDOW *win)
                    242: {
                    243:     return( get_string(opt->str, win) );
                    244: }
                    245:
                    246: /*
                    247:     get_abil()
                    248:         The ability field is read-only
                    249: */
                    250:
                    251: int
                    252: get_abil(opt_arg *opt, WINDOW *win)
                    253: {
                    254:     int oy, ox, ny, nx;
                    255:     int op_bad;
                    256:
                    257:     op_bad = TRUE;
                    258:     getyx(win, oy, ox);
                    259:     put_abil(opt, win);
                    260:     getyx(win, ny, nx);
                    261:
                    262:     while(op_bad)
                    263:     {
                    264:         wmove(win, oy, ox);
                    265:         wrefresh(win);
                    266:
                    267:         switch(readcharw(win))
                    268:         {
                    269:             case '\n':
                    270:             case '\r':
                    271:                 op_bad = FALSE;
                    272:                 break;
                    273:
                    274:             case '\033':
                    275:             case '\007':
                    276:                 return(QUIT);
                    277:
                    278:             case '-':
                    279:                 return(MINUS);
                    280:
                    281:             default:
                    282:                 mvwaddstr(win, ny, nx + 5, "(no change allowed)");
                    283:         }
                    284:     }
                    285:
                    286:     wmove(win, ny, nx + 5);
                    287:     wclrtoeol(win);
                    288:     wmove(win, ny, nx);
                    289:     waddch(win, '\n');
                    290:
                    291:     return(NORM);
                    292: }
                    293:
                    294:
                    295: /*
                    296:     parse_opts()
                    297:         parse options from string, usually taken from the environment. the
                    298:         string is a series of comma seperated values, with booleans being
                    299:         stated as "name" (true) or "noname" (false), and strings being
                    300:         "name=....", with the string being defined up to a comma or the
                    301:         end of the entire option string.
                    302:  */
                    303:
                    304: void
                    305: parse_opts(char *str)
                    306: {
                    307:     char    *sp;
                    308:     const OPTION  *op;
                    309:     size_t len;
                    310:
                    311:     while (*str)
                    312:     {
                    313:         for (sp = str; isalpha(*sp); sp++)
                    314:             continue;
                    315:
                    316:         len = sp - str;
                    317:
                    318:         /* Look it up and deal with it */
                    319:
                    320:         for (op = optlist; op < &optlist[NUM_OPTS]; op++)
                    321:        {
                    322:             if (EQSTR(str, op->o_name, len))
                    323:             {
                    324:                 if (op->o_putfunc == put_bool)
                    325:                     *op->o_opt.iarg = TRUE;
                    326:                 else    /* string option */
                    327:                 {
                    328:                     char    *start;
                    329:                     char    value[80];
                    330:
                    331:                     /* Skip to start of string value */
                    332:
                    333:                     for (str = sp + 1; *str == '='; str++)
                    334:                         continue;
                    335:
                    336:                     start = (char *) value;
                    337:
                    338:                     /* Skip to end of string value */
                    339:
                    340:                     for (sp = str + 1; *sp && *sp != ','; sp++)
                    341:                         continue;
                    342:
                    343:                     strncpy(start, str, sp - str);
                    344:
                    345:                    /* Some options can't be changed. */
                    346:                    if (use_savedir &&
                    347:                                    (op->o_opt.str == whoami ||
                    348:                                     op->o_opt.str == file_name ||
                    349:                                     op->o_opt.str == score_file))
                    350:                        break;
                    351:
                    352:                     /* Put the value into the option field */
                    353:
                    354:                     if (op->o_putfunc != put_abil &&
                    355:                         op->o_putfunc != put_inv)
                    356:                         strcpy(op->o_opt.str, value);
                    357:
                    358:                     if (op->o_putfunc == put_inv)
                    359:                     {
                    360:                         int *opt = op->o_opt.iarg;
                    361:
                    362:                         len = strlen(value);
                    363:
                    364:                         if (isupper(value[0]))
                    365:                             value[0] = (char) tolower(value[0]);
                    366:                         if (EQSTR(value, "overwrite",len))
                    367:                             *opt = INV_OVER;
                    368:                         if (EQSTR(value, "slow", len))
                    369:                             *opt = INV_SLOW;
                    370:                         if (EQSTR(value, "clear", len))
                    371:                             *opt = INV_CLEAR;
                    372:                     }
                    373:                     else if (*op->o_opt.iarg == -1)
                    374:                     {
                    375:                         int *opt = op->o_opt.iarg;
                    376:
                    377:                         len = strlen(value);
                    378:
                    379:                         if (isupper(value[0]))
                    380:                             value[0] = (char) tolower(value[0]);
                    381:                         if (EQSTR(value, "fighter", len))
                    382:                             *opt = C_FIGHTER;
                    383:                         else if (EQSTR(value, "magic", min(len, 5)))
                    384:                             *opt = C_MAGICIAN;
                    385:                         else if (EQSTR(value, "illus", min(len, 5)))
                    386:                             *opt = C_ILLUSION;
                    387:                         else if (EQSTR(value, "cleric", len))
                    388:                             *opt = C_CLERIC;
                    389:                         else if (EQSTR(value, "thief",  len))
                    390:                             *opt = C_THIEF;
                    391:                         else if (EQSTR(value, "paladin", len))
                    392:                             *opt = C_PALADIN;
                    393:                         else if (EQSTR(value, "ranger",  len))
                    394:                             *opt = C_RANGER;
                    395:                         else if (EQSTR(value, "assasin", len))
                    396:                             *opt = C_ASSASIN;
                    397:                         else if (EQSTR(value, "druid",   len))
                    398:                             *opt = C_DRUID;
                    399:                         else if (EQSTR(value, "ninja",   len))
                    400:                             *opt = C_NINJA;
                    401:                     }
                    402:                 }
                    403:                 break;
                    404:             }
                    405:             else if (op->o_putfunc == put_bool
                    406:                  && EQSTR(str, "no", 2) &&
                    407:                 EQSTR(str + 2, op->o_name, len - 2))
                    408:             {
                    409:                 *op->o_opt.iarg = FALSE;
                    410:                 break;
                    411:             }
                    412:        }
                    413:
                    414:         /* skip to start of next option name  */
                    415:
                    416:         while (*sp && !isalpha(*sp))
                    417:             sp++;
                    418:
                    419:         str = sp;
                    420:     }
                    421: }
                    422:
                    423: /*
                    424:     put_inv()
                    425:         print the inventory type
                    426: */
                    427:
                    428: void
                    429: put_inv(opt_arg *opt, WINDOW *win)
                    430: {
                    431:     char    *style;
                    432:
                    433:     switch(*opt->iarg)
                    434:     {
                    435:         case INV_OVER:
                    436:             style = "Overwrite";
                    437:             break;
                    438:
                    439:         case INV_SLOW:
                    440:             style = "Slow";
                    441:             break;
                    442:
                    443:         case INV_CLEAR:
                    444:             style = "Clear Screen";
                    445:             break;
                    446:
                    447:         default:
                    448:             style = "(unknown)";
                    449:     }
                    450:
                    451:     waddstr(win, style);
                    452: }
                    453:
                    454: /*
                    455:     get_inv()
                    456:         The inventory field.
                    457: */
                    458:
                    459: int
                    460: get_inv(opt_arg *opt, WINDOW *win)
                    461: {
                    462:     int oy, ox, ny, nx;
                    463:     int op_bad;
                    464:
                    465:     op_bad = TRUE;
                    466:     getyx(win, oy, ox);
                    467:     put_inv(opt, win);
                    468:     getyx(win, ny, nx);
                    469:
                    470:     while(op_bad)
                    471:     {
                    472:         wmove(win, oy, ox);
                    473:         wrefresh(win);
                    474:
                    475:         switch(readcharw(win))
                    476:         {
                    477:             case '\n':
                    478:             case '\r':
                    479:                 op_bad = FALSE;
                    480:                 break;
                    481:
                    482:             case '\033':
                    483:             case '\007':
                    484:                 return(QUIT);
                    485:
                    486:             case '-':
                    487:                 return(MINUS);
                    488:
                    489:             case 'O':
                    490:             case 'o':
                    491:                 *opt->iarg = INV_OVER;
                    492:                 op_bad = FALSE;
                    493:                 break;
                    494:
                    495:             case 'S':
                    496:             case 's':
                    497:                 *opt->iarg = INV_SLOW;
                    498:                 op_bad = FALSE;
                    499:                 break;
                    500:
                    501:             case 'C':
                    502:             case 'c':
                    503:                 *opt->iarg = INV_CLEAR;
                    504:                 op_bad = FALSE;
                    505:                 break;
                    506:
                    507:             default:
                    508:                 mvwaddstr(win, ny, nx + 5, "(Use: o, s, or c)");
                    509:         }
                    510:     }
                    511:
                    512:     wmove(win, oy, ox);
                    513:     wclrtoeol(win);
                    514:
                    515:     switch(*opt->iarg)
                    516:     {
                    517:         case INV_SLOW:
                    518:             waddstr(win, "Slow\n");
                    519:             break;
                    520:
                    521:         case INV_CLEAR:
                    522:             waddstr(win, "Clear Screen\n");
                    523:             break;
                    524:
                    525:         case INV_OVER:
                    526:             waddstr(win, "Overwrite\n");
                    527:             break;
                    528:
                    529:         default:
                    530:             waddstr(win, "Unknown\n");
                    531:             break;
                    532:     }
                    533:
                    534:     return(NORM);
                    535: }
                    536:
                    537: /*
                    538:  * get_restr()
                    539:  *
                    540:  * Gets strings that cannot be changed when use_savedir is set.
                    541:  * get_abil() can't be repurposed to do this without ugliness.
                    542:  *
                    543:  */
                    544: int
                    545: get_restr(opt_arg *opt, WINDOW *win)
                    546: {
                    547:     int oy, ox, ny, nx;
                    548:     int keep_up;
                    549:
                    550:     keep_up = TRUE;
                    551:     getyx(win, oy, ox);
                    552:     put_str(opt, win);
                    553:
                    554:     if (!use_savedir) {
                    555:         wmove(win, oy, ox);
                    556:         return get_str(opt, win);
                    557:     }
                    558:
                    559:     getyx(win, ny, nx);
                    560:     while(keep_up)
                    561:     {
                    562:         wmove(win, oy, ox);
                    563:         wrefresh(win);
                    564:
                    565:         switch(readcharw(win))
                    566:         {
                    567:             case '\n':
                    568:             case '\r':
                    569:                 keep_up = FALSE;
                    570:                 break;
                    571:
                    572:             case '\033':
                    573:             case '\007':
                    574:                 return(QUIT);
                    575:
                    576:             case '-':
                    577:                 return(MINUS);
                    578:
                    579:             default:
                    580:                 mvwaddstr(win, ny, nx + 5, "(no change allowed)");
                    581:         }
                    582:     }
                    583:
                    584:     wmove(win, ny, nx + 5);
                    585:     wclrtoeol(win);
                    586:     wmove(win, ny, nx);
                    587:     waddch(win, '\n');
                    588:
                    589:     return(NORM);
                    590: }
                    591:
                    592: int
                    593: get_score(opt_arg *opt, WINDOW *win)
                    594: {
                    595:     char old_score_file[2*LINELEN];
                    596:     int status;
                    597:
                    598:     if (use_savedir)
                    599:         return get_restr(opt, win);
                    600:
                    601:     strncpy(old_score_file, opt->str, 2*LINELEN);
                    602:     old_score_file[2*LINELEN - 1] = '\0';
                    603:     status = get_str(opt, win);
                    604:     if (status == NORM && strcmp(old_score_file, opt->str)) {
                    605:         fclose(fd_score);
                    606:         fd_score = fopen(score_file, "r+");
                    607:         if (fd_score == NULL)
                    608:             fd_score = fopen(score_file, "a+");
                    609:     }
                    610:     return status;
                    611: }

CVSweb