Annotation of 43BSDTahoe/games/phantasia/io.c, revision 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.