[BACK]Return to io.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / games / phantasia

Annotation of src/games/phantasia/io.c, Revision 1.2

1.2     ! cgd         1: /*     $NetBSD$        */
        !             2:
1.1       jtc         3: /*
                      4:  * io.c - input/output routines for Phantasia
                      5:  */
                      6:
                      7: #include "include.h"
                      8:
                      9: /************************************************************************
                     10: /
                     11: / FUNCTION NAME: getstring()
                     12: /
                     13: / FUNCTION: read a string from operator
                     14: /
                     15: / AUTHOR: E. A. Estes, 12/4/85
                     16: /
                     17: / ARGUMENTS:
                     18: /      char *cp - pointer to buffer area to fill
                     19: /      int mx - maximum number of characters to put in buffer
                     20: /
                     21: / RETURN VALUE: none
                     22: /
                     23: / MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
                     24: /      wclrtoeol()
                     25: /
                     26: / GLOBAL INPUTS: Echo, _iob[], Wizard, *stdscr
                     27: /
                     28: / GLOBAL OUTPUTS: _iob[]
                     29: /
                     30: / DESCRIPTION:
                     31: /      Read a string from the keyboard.
                     32: /      This routine is specially designed to:
                     33: /
                     34: /          - strip non-printing characters (unless Wizard)
                     35: /          - echo, if desired
                     36: /          - redraw the screen if CH_REDRAW is entered
                     37: /          - read in only 'mx - 1' characters or less characters
                     38: /          - nul-terminate string, and throw away newline
                     39: /
                     40: /      'mx' is assumed to be at least 2.
                     41: /
                     42: /************************************************************************/
                     43:
                     44: getstring(cp, mx)
                     45: register char  *cp;
                     46: register int   mx;
                     47: {
                     48: register char  *inptr;         /* pointer into string for next string */
                     49: int    x, y;                   /* original x, y coordinates on screen */
                     50: int    ch;                     /* input */
                     51:
                     52:     getyx(stdscr, y, x);       /* get coordinates on screen */
                     53:     inptr = cp;
                     54:     *inptr = '\0';             /* clear string to start */
                     55:     --mx;                      /* reserve room in string for nul terminator */
                     56:
                     57:     do
                     58:        /* get characters and process */
                     59:        {
                     60:        if (Echo)
                     61:            mvaddstr(y, x, cp); /* print string on screen */
                     62:        clrtoeol();             /* clear any data after string */
                     63:        refresh();              /* update screen */
                     64:
                     65:        ch = getchar();         /* get character */
                     66:
                     67:        switch (ch)
                     68:            {
                     69:            case CH_ERASE:      /* back up one character */
                     70:                if (inptr > cp)
                     71:                    --inptr;
                     72:                break;
                     73:
                     74:            case CH_KILL:       /* back up to original location */
                     75:                inptr = cp;
                     76:                break;
                     77:
                     78:            case CH_NEWLINE:    /* terminate string */
                     79:                break;
                     80:
                     81:            case CH_REDRAW:     /* redraw screen */
                     82:                clearok(stdscr, TRUE);
                     83:                continue;
                     84:
                     85:            default:            /* put data in string */
                     86:                if (ch >= ' ' || Wizard)
                     87:                    /* printing char; put in string */
                     88:                    *inptr++ = ch;
                     89:            }
                     90:
                     91:        *inptr = '\0';          /* terminate string */
                     92:        }
                     93:     while (ch != CH_NEWLINE && inptr < cp + mx);
                     94: }
                     95: /**/
                     96: /************************************************************************
                     97: /
                     98: / FUNCTION NAME: more()
                     99: /
                    100: / FUNCTION: pause and prompt player
                    101: /
                    102: / AUTHOR: E. A. Estes, 12/4/85
                    103: /
                    104: / ARGUMENTS:
                    105: /      int where - line on screen on which to pause
                    106: /
                    107: / RETURN VALUE: none
                    108: /
                    109: / MODULES CALLED: wmove(), waddstr(), getanswer()
                    110: /
                    111: / GLOBAL INPUTS: *stdscr
                    112: /
                    113: / GLOBAL OUTPUTS: none
                    114: /
                    115: / DESCRIPTION:
                    116: /      Print a message, and wait for a space character.
                    117: /
                    118: /************************************************************************/
                    119:
                    120: more(where)
                    121: int    where;
                    122: {
                    123:     mvaddstr(where, 0, "-- more --");
                    124:     getanswer(" ", FALSE);
                    125: }
                    126: /**/
                    127: /************************************************************************
                    128: /
                    129: / FUNCTION NAME: infloat()
                    130: /
                    131: / FUNCTION: input a floating point number from operator
                    132: /
                    133: / AUTHOR: E. A. Estes, 12/4/85
                    134: /
                    135: / ARGUMENTS: none
                    136: /
                    137: / RETURN VALUE: floating point number from operator
                    138: /
                    139: / MODULES CALLED: sscanf(), getstring()
                    140: /
                    141: / GLOBAL INPUTS: Databuf[]
                    142: /
                    143: / GLOBAL OUTPUTS: none
                    144: /
                    145: / DESCRIPTION:
                    146: /      Read a string from player, and scan for a floating point
                    147: /      number.
                    148: /      If no valid number is found, return 0.0.
                    149: /
                    150: /************************************************************************/
                    151:
                    152: double
                    153: infloat()
                    154: {
                    155: double result;         /* return value */
                    156:
                    157:     getstring(Databuf, SZ_DATABUF);
                    158:     if (sscanf(Databuf, "%lf", &result) < 1)
                    159:        /* no valid number entered */
                    160:        result = 0.0;
                    161:
                    162:     return(result);
                    163: }
                    164: /**/
                    165: /************************************************************************
                    166: /
                    167: / FUNCTION NAME: inputoption()
                    168: /
                    169: / FUNCTION: input an option value from player
                    170: /
                    171: / AUTHOR: E. A. Estes, 12/4/85
                    172: /
                    173: / ARGUMENTS: none
                    174: /
                    175: / RETURN VALUE: none
                    176: /
                    177: / MODULES CALLED: floor(), drandom(), getanswer()
                    178: /
                    179: / GLOBAL INPUTS: Player
                    180: /
                    181: / GLOBAL OUTPUTS: Player
                    182: /
                    183: / DESCRIPTION:
                    184: /      Age increases with every move.
                    185: /      Refresh screen, and get a single character option from player.
                    186: /      Return a random value if player's ring has gone bad.
                    187: /
                    188: /************************************************************************/
                    189:
                    190: inputoption()
                    191: {
                    192:     ++Player.p_age;            /* increase age */
                    193:
                    194:     if (Player.p_ring.ring_type != R_SPOILED)
                    195:        /* ring ok */
                    196:        return(getanswer("T ", TRUE));
                    197:     else
                    198:        /* bad ring */
                    199:        {
                    200:        getanswer(" ", TRUE);
                    201:        return((int) ROLL(0.0, 5.0) + '0');
                    202:        }
                    203: }
                    204: /**/
                    205: /************************************************************************
                    206: /
                    207: / FUNCTION NAME: interrupt()
                    208: /
                    209: / FUNCTION: handle interrupt from operator
                    210: /
                    211: / AUTHOR: E. A. Estes, 12/4/85
                    212: /
                    213: / ARGUMENTS: none
                    214: /
                    215: / RETURN VALUE: none
                    216: /
                    217: / MODULES CALLED: fork(), exit(), wait(), death(), alarm(), execl(), wmove(),
                    218: /      getgid(), signal(), getenv(), wclear(), setuid(), getuid(), setgid(),
                    219: /      crmode(), clearok(), waddstr(), cleanup(), wrefresh(), leavegame(),
                    220: /      getanswer()
                    221: /
                    222: / GLOBAL INPUTS: Player, *stdscr
                    223: /
                    224: / GLOBAL OUTPUTS: none
                    225: /
                    226: / DESCRIPTION:
                    227: /      Allow player to quit upon hitting the interrupt key.
                    228: /      If the player wants to quit while in battle, he/she automatically
                    229: /      dies.
                    230: /
                    231: /************************************************************************/
                    232:
                    233: interrupt()
                    234: {
                    235: char   line[81];               /* a place to store data already on screen */
                    236: register int   loop;           /* counter */
                    237: int    x, y;                   /* coordinates on screen */
                    238: int    ch;                     /* input */
                    239: unsigned       savealarm;      /* to save alarm value */
                    240:
                    241: #ifdef SYS3
                    242:     signal(SIGINT, SIG_IGN);
                    243: #endif
                    244: #ifdef SYS5
                    245:     signal(SIGINT, SIG_IGN);
                    246: #endif
                    247:
                    248:     savealarm = alarm(0);              /* turn off any alarms */
                    249:
                    250:     getyx(stdscr, y, x);               /* save cursor location */
                    251:
                    252:     for (loop = 0; loop < 80; ++loop)  /* save line on screen */
                    253:        {
                    254:        move(4, loop);
                    255:        line[loop] = inch();
                    256:        }
                    257:     line[80] = '\0';                   /* nul terminate */
                    258:
                    259:     if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER)
                    260:        /* in midst of fighting */
                    261:        {
                    262:        mvaddstr(4, 0, "Quitting now will automatically kill your character.  Still want to ? ");
                    263:        ch = getanswer("NY", FALSE);
                    264:        if (ch == 'Y')
                    265:            death("Bailing out");
                    266:            /*NOTREACHED*/
                    267:        }
                    268:     else
                    269:        {
                    270:        mvaddstr(4, 0, "Do you really want to quit ? ");
                    271:        ch = getanswer("NY", FALSE);
                    272:        if (ch == 'Y')
                    273:            leavegame();
                    274:            /*NOTREACHED*/
                    275:        }
                    276:
                    277:     mvaddstr(4, 0, line);              /* restore data on screen */
                    278:     move(y, x);                                /* restore cursor */
                    279:     refresh();
                    280:
                    281: #ifdef SYS3
                    282:     signal(SIGINT, interrupt);
                    283: #endif
                    284: #ifdef SYS5
                    285:     signal(SIGINT, interrupt);
                    286: #endif
                    287:
                    288:     alarm(savealarm);                  /* restore alarm */
                    289: }
                    290: /**/
                    291: /************************************************************************
                    292: /
                    293: / FUNCTION NAME: getanswer()
                    294: /
                    295: / FUNCTION: get an answer from operator
                    296: /
                    297: / AUTHOR: E. A. Estes, 12/4/85
                    298: /
                    299: / ARGUMENTS:
                    300: /      char *choices - string of (upper case) valid choices
                    301: /      bool def - set if default answer
                    302: /
                    303: / RETURN VALUE: none
                    304: /
                    305: / MODULES CALLED: alarm(), wmove(), waddch(), signal(), setjmp(), strchr(),
                    306: /      _filbuf(), clearok(), toupper(), wrefresh(), mvprintw(), wclrtoeol()
                    307: /
                    308: / GLOBAL INPUTS: catchalarm(), Echo, _iob[], _ctype[], *stdscr, Timeout,
                    309: /      Timeoenv[]
                    310: /
                    311: / GLOBAL OUTPUTS: _iob[]
                    312: /
                    313: / DESCRIPTION:
                    314: /      Get a single character answer from operator.
                    315: /      Timeout waiting for response.  If we timeout, or the
                    316: /      answer in not in the list of valid choices, print choices,
                    317: /      and wait again, otherwise return the first character in ths
                    318: /      list of choices.
                    319: /      Give up after 3 tries.
                    320: /
                    321: /************************************************************************/
                    322:
                    323: getanswer(choices, def)
                    324: char   *choices;
                    325: bool   def;
                    326: {
                    327: int    ch;                     /* input */
                    328: int    loop;                   /* counter */
                    329: int    oldx, oldy;             /* original coordinates on screen */
                    330:
                    331:     getyx(stdscr, oldy, oldx);
                    332:     alarm(0);                          /* make sure alarm is off */
                    333:
                    334:     for (loop = 3; loop; --loop)
                    335:        /* try for 3 times */
                    336:        {
                    337:        if (setjmp(Timeoenv) != 0)
                    338:            /* timed out waiting for response */
                    339:            {
                    340:            if (def || loop <= 1)
                    341:                /* return default answer */
                    342:                break;
                    343:            else
                    344:                /* prompt, and try again */
                    345:                goto YELL;
                    346:            }
                    347:        else
                    348:            /* wait for response */
                    349:            {
                    350:            clrtoeol();
                    351:            refresh();
                    352: #ifdef BSD41
                    353:            sigset(SIGALRM, catchalarm);
                    354: #else
                    355:            signal(SIGALRM, catchalarm);
                    356: #endif
                    357:            /* set timeout */
                    358:            if (Timeout)
                    359:                alarm(7);               /* short */
                    360:            else
                    361:                alarm(600);             /* long */
                    362:
                    363:            ch = getchar();
                    364:
                    365:            alarm(0);                   /* turn off timeout */
                    366:
                    367:            if (ch < 0)
                    368:                /* caught some signal */
                    369:                {
                    370:                ++loop;
                    371:                continue;
                    372:                }
                    373:            else if (ch == CH_REDRAW)
                    374:                /* redraw screen */
                    375:                {
                    376:                clearok(stdscr, TRUE);  /* force clear screen */
                    377:                ++loop;                 /* don't count this input */
                    378:                continue;
                    379:                }
                    380:            else if (Echo)
                    381:                {
                    382:                addch(ch);              /* echo character */
                    383:                refresh();
                    384:                }
                    385:
                    386:            if (islower(ch))
                    387:                /* convert to upper case */
                    388:                ch = toupper(ch);
                    389:
                    390:            if (def || strchr(choices, ch) != NULL)
                    391:                /* valid choice */
                    392:                return(ch);
                    393:            else if (!def && loop > 1)
                    394:                /* bad choice; prompt, and try again */
                    395:                {
                    396: YELL:          mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
                    397:                move(oldy, oldx);
                    398:                clrtoeol();
                    399:                continue;
                    400:                }
                    401:            else
                    402:                /* return default answer */
                    403:                break;
                    404:            }
                    405:        }
                    406:
                    407:     return(*choices);
                    408: }
                    409: /**/
                    410: /************************************************************************
                    411: /
                    412: / FUNCTION NAME: catchalarm()
                    413: /
                    414: / FUNCTION: catch timer when waiting for input
                    415: /
                    416: / AUTHOR: E. A. Estes, 12/4/85
                    417: /
                    418: / ARGUMENTS: none
                    419: /
                    420: / RETURN VALUE: none
                    421: /
                    422: / MODULES CALLED: longjmp()
                    423: /
                    424: / GLOBAL INPUTS: Timeoenv[]
                    425: /
                    426: / GLOBAL OUTPUTS: none
                    427: /
                    428: / DESCRIPTION:
                    429: /      Come here when the alarm expires while waiting for input.
                    430: /      Simply longjmp() into getanswer().
                    431: /
                    432: /************************************************************************/
                    433:
                    434: void
                    435: catchalarm()
                    436: {
                    437:     longjmp(Timeoenv, 1);
                    438: }

CVSweb <webmaster@jp.NetBSD.org>