Annotation of 43BSDTahoe/games/phantasia/io.c, revision 1.1.1.1

1.1       root        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: /      If SHELL is defined, spawn a shell if the if the question is
                    229: /      answered with a '!'.
                    230: /      We are careful to save the state of the screen, and return it
                    231: /      to its original condition.
                    232: /
                    233: /************************************************************************/
                    234: 
                    235: interrupt()
                    236: {
                    237: char   line[81];               /* a place to store data already on screen */
                    238: register int   loop;           /* counter */
                    239: int    x, y;                   /* coordinates on screen */
                    240: int    ch;                     /* input */
                    241: unsigned       savealarm;      /* to save alarm value */
                    242: #ifdef SHELL
                    243: register char  *shell;         /* pointer to shell to spawn */
                    244: int    childpid;               /* pid of spawned process */
                    245: #endif
                    246: 
                    247: #ifdef SYS3
                    248:     signal(SIGINT, SIG_IGN);
                    249: #endif
                    250: #ifdef SYS5
                    251:     signal(SIGINT, SIG_IGN);
                    252: #endif
                    253: 
                    254:     savealarm = alarm(0);              /* turn off any alarms */
                    255: 
                    256:     getyx(stdscr, y, x);               /* save cursor location */
                    257: 
                    258:     for (loop = 0; loop < 80; ++loop)  /* save line on screen */
                    259:        {
                    260:        move(4, loop);
                    261:        line[loop] = inch();
                    262:        }
                    263:     line[80] = '\0';                   /* nul terminate */
                    264: 
                    265:     if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER)
                    266:        /* in midst of fighting */
                    267:        {
                    268:        mvaddstr(4, 0, "Quitting now will automatically kill your character.  Still want to ? ");
                    269: #ifdef SHELL
                    270:        ch = getanswer("NY!", FALSE);
                    271: #else
                    272:        ch = getanswer("NY", FALSE);
                    273: #endif
                    274:        if (ch == 'Y')
                    275:            death("Bailing out");
                    276:            /*NOTREACHED*/
                    277:        }
                    278:     else
                    279:        {
                    280: #ifdef SHELL
                    281:        mvaddstr(4, 0, "Do you really want to quit [! = Shell] ? ");
                    282:        ch = getanswer("NY!", FALSE);
                    283: #else
                    284:        mvaddstr(4, 0, "Do you really want to quit ? ");
                    285:        ch = getanswer("NY", FALSE);
                    286: #endif
                    287:        if (ch == 'Y')
                    288:            leavegame();
                    289:            /*NOTREACHED*/
                    290:        }
                    291: 
                    292: #ifdef SHELL
                    293:     if (ch == '!')
                    294:        /* shell escape */
                    295:        {
                    296:        if ((shell = getenv("SHELL")) == NULL)
                    297:            /* use default */
                    298:            shell = SHELL;
                    299: 
                    300:        if ((childpid = fork()) == 0)
                    301:            /* in child */
                    302:            {
                    303:            clear();
                    304:            refresh();
                    305:            cleanup(FALSE);             /* out of curses, close files */
                    306: 
                    307:            setuid(getuid());           /* make sure we are running with real uid */
                    308:            setgid(getgid());           /* make sure we are running with real gid */
                    309:            execl(shell, shell, "-i", 0);
                    310:            execl(SHELL, SHELL, "-i", 0);       /* last resort */
                    311: 
                    312:            exit(0);
                    313:            /*NOTREACHED*/
                    314:            }
                    315:        else
                    316:            /* in parent */
                    317:            {
                    318:            while (wait((int *) NULL) != childpid);     /* wait until done */
                    319:            crmode();                   /* restore keyboard */
                    320:            clearok(stdscr, TRUE);      /* force redraw of screen */
                    321:            }
                    322:        }
                    323: #endif
                    324: 
                    325:     mvaddstr(4, 0, line);              /* restore data on screen */
                    326:     move(y, x);                                /* restore cursor */
                    327:     refresh();
                    328: 
                    329: #ifdef SYS3
                    330:     signal(SIGINT, interrupt);
                    331: #endif
                    332: #ifdef SYS5
                    333:     signal(SIGINT, interrupt);
                    334: #endif
                    335: 
                    336:     alarm(savealarm);                  /* restore alarm */
                    337: }
                    338: /**/
                    339: /************************************************************************
                    340: /
                    341: / FUNCTION NAME: getanswer()
                    342: /
                    343: / FUNCTION: get an answer from operator
                    344: /
                    345: / AUTHOR: E. A. Estes, 12/4/85
                    346: /
                    347: / ARGUMENTS:
                    348: /      char *choices - string of (upper case) valid choices
                    349: /      bool def - set if default answer
                    350: /
                    351: / RETURN VALUE: none
                    352: /
                    353: / MODULES CALLED: alarm(), wmove(), waddch(), signal(), setjmp(), strchr(), 
                    354: /      _filbuf(), clearok(), toupper(), wrefresh(), mvprintw(), wclrtoeol()
                    355: /
                    356: / GLOBAL INPUTS: catchalarm(), Echo, _iob[], _ctype[], *stdscr, Timeout, 
                    357: /      Timeoenv[]
                    358: /
                    359: / GLOBAL OUTPUTS: _iob[]
                    360: /
                    361: / DESCRIPTION:
                    362: /      Get a single character answer from operator.
                    363: /      Timeout waiting for response.  If we timeout, or the
                    364: /      answer in not in the list of valid choices, print choices,
                    365: /      and wait again, otherwise return the first character in ths
                    366: /      list of choices.
                    367: /      Give up after 3 tries.
                    368: /
                    369: /************************************************************************/
                    370: 
                    371: getanswer(choices, def)
                    372: char   *choices;
                    373: bool   def;
                    374: {
                    375: int    ch;                     /* input */
                    376: int    loop;                   /* counter */
                    377: int    oldx, oldy;             /* original coordinates on screen */
                    378: 
                    379:     getyx(stdscr, oldy, oldx);
                    380:     alarm(0);                          /* make sure alarm is off */
                    381: 
                    382:     for (loop = 3; loop; --loop)
                    383:        /* try for 3 times */
                    384:        {
                    385:        if (setjmp(Timeoenv) != 0)
                    386:            /* timed out waiting for response */
                    387:            {
                    388:            if (def || loop <= 1)
                    389:                /* return default answer */
                    390:                break;
                    391:            else
                    392:                /* prompt, and try again */
                    393:                goto YELL;
                    394:            }
                    395:        else
                    396:            /* wait for response */
                    397:            {
                    398:            clrtoeol();
                    399:            refresh();
                    400: #ifdef BSD41
                    401:            sigset(SIGALRM, catchalarm);
                    402: #else
                    403:            signal(SIGALRM, catchalarm);
                    404: #endif
                    405:            /* set timeout */
                    406:            if (Timeout)
                    407:                alarm(7);               /* short */
                    408:            else
                    409:                alarm(600);             /* long */
                    410: 
                    411:            ch = getchar();
                    412: 
                    413:            alarm(0);                   /* turn off timeout */
                    414: 
                    415:            if (ch < 0)
                    416:                /* caught some signal */
                    417:                {
                    418:                ++loop;
                    419:                continue;
                    420:                }
                    421:            else if (ch == CH_REDRAW)
                    422:                /* redraw screen */
                    423:                {
                    424:                clearok(stdscr, TRUE);  /* force clear screen */
                    425:                ++loop;                 /* don't count this input */
                    426:                continue;
                    427:                }
                    428:            else if (Echo)
                    429:                {
                    430:                addch(ch);              /* echo character */
                    431:                refresh();
                    432:                }
                    433: 
                    434:            if (islower(ch))
                    435:                /* convert to upper case */
                    436:                ch = toupper(ch);
                    437: 
                    438:            if (def || strchr(choices, ch) != NULL)
                    439:                /* valid choice */
                    440:                return(ch);
                    441:            else if (!def && loop > 1)
                    442:                /* bad choice; prompt, and try again */
                    443:                {
                    444: YELL:          mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
                    445:                move(oldy, oldx);
                    446:                clrtoeol();
                    447:                continue;
                    448:                }
                    449:            else
                    450:                /* return default answer */
                    451:                break;
                    452:            }
                    453:        }
                    454: 
                    455:     return(*choices);
                    456: }
                    457: /**/
                    458: /************************************************************************
                    459: /
                    460: / FUNCTION NAME: catchalarm()
                    461: /
                    462: / FUNCTION: catch timer when waiting for input
                    463: /
                    464: / AUTHOR: E. A. Estes, 12/4/85
                    465: /
                    466: / ARGUMENTS: none
                    467: /
                    468: / RETURN VALUE: none
                    469: /
                    470: / MODULES CALLED: longjmp()
                    471: /
                    472: / GLOBAL INPUTS: Timeoenv[]
                    473: /
                    474: / GLOBAL OUTPUTS: none
                    475: /
                    476: / DESCRIPTION:
                    477: /      Come here when the alarm expires while waiting for input.
                    478: /      Simply longjmp() into getanswer().
                    479: /
                    480: /************************************************************************/
                    481: 
                    482: catchalarm()
                    483: {
                    484:     longjmp(Timeoenv, 1);
                    485: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.