[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.1.1.1

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

CVSweb <webmaster@jp.NetBSD.org>