4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / games / cribbage / io.c
index 2a3abed..5887cf8 100644 (file)
-# include      <curses.h>
-# include      <ctype.h>
-# include      <unctrl.h>
-# include      "deck.h"
-# include      "cribbage.h"
+/*-
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)io.c       8.1 (Berkeley) %G%";
+#endif /* not lint */
 
 
-# define       LINESIZE                128
+#include <ctype.h>
+#include <curses.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
 
 
-# define       CTRL(X)                 ('X' - 'A' + 1)
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
 
 
-# ifndef       attron
-#      define  erasechar()     _tty.sg_erase
-#      define  killchar()      _tty.sg_kill
-# endif                attron
+#include "deck.h"
+#include "cribbage.h"
+#include "cribcur.h"
 
 
-char           linebuf[ LINESIZE ];
+#define        LINESIZE                128
 
 
-char           *rankname[ RANKS ]      = { "ACE", "TWO", "THREE", "FOUR",
-                                           "FIVE", "SIX", "SEVEN", "EIGHT",
-                                           "NINE", "TEN", "JACK", "QUEEN",
-                                           "KING" };
+#ifdef CTRL
+#undef CTRL
+#endif
+#define        CTRL(X)                 (X - 'A' + 1)
 
 
-char            *rankchar[ RANKS ]      = { "A", "2", "3", "4", "5", "6", "7",
-                                           "8", "9", "T", "J", "Q", "K" };
+char    linebuf[LINESIZE];
 
 
-char            *suitname[ SUITS ]      = { "SPADES", "HEARTS", "DIAMONDS",
-                                           "CLUBS" };
+char   *rankname[RANKS] = {
+       "ACE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
+       "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"
+};
 
 
-char            *suitchar[ SUITS ]      = { "S", "H", "D", "C" };
+char   *rankchar[RANKS] = {
+       "A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"
+};
 
 
+char   *suitname[SUITS] = {"SPADES", "HEARTS", "DIAMONDS", "CLUBS"};
 
 
+char   *suitchar[SUITS] = {"S", "H", "D", "C"};
 
 /*
  * msgcard:
  *     Call msgcrd in one of two forms
  */
 
 /*
  * msgcard:
  *     Call msgcrd in one of two forms
  */
+int
 msgcard(c, brief)
 msgcard(c, brief)
-CARD           c;
-BOOLEAN                brief;
+       CARD c;
+       BOOLEAN brief;
 {
        if (brief)
 {
        if (brief)
-               return msgcrd(c, TRUE, (char *) NULL, TRUE);
+               return (msgcrd(c, TRUE, NULL, TRUE));
        else
        else
-               return msgcrd(c, FALSE, " of ", FALSE);
+               return (msgcrd(c, FALSE, " of ", FALSE));
 }
 
 }
 
-
-
 /*
  * msgcrd:
  *     Print the value of a card in ascii
  */
 /*
  * msgcrd:
  *     Print the value of a card in ascii
  */
+int
 msgcrd(c, brfrank, mid, brfsuit)
 msgcrd(c, brfrank, mid, brfsuit)
-CARD           c;
-char           *mid;
-BOOLEAN                brfrank,  brfsuit;
+       CARD c;
+       BOOLEAN brfrank, brfsuit;
+       char *mid;
 {
        if (c.rank == EMPTY || c.suit == EMPTY)
 {
        if (c.rank == EMPTY || c.suit == EMPTY)
-           return FALSE;
+               return (FALSE);
        if (brfrank)
        if (brfrank)
-           addmsg("%1.1s", rankchar[c.rank]);
+               addmsg("%1.1s", rankchar[c.rank]);
        else
        else
-           addmsg(rankname[c.rank]);
+               addmsg(rankname[c.rank]);
        if (mid != NULL)
        if (mid != NULL)
-           addmsg(mid);
+               addmsg(mid);
        if (brfsuit)
        if (brfsuit)
-           addmsg("%1.1s", suitchar[c.suit]);
+               addmsg("%1.1s", suitchar[c.suit]);
        else
        else
-           addmsg(suitname[c.suit]);
-       return TRUE;
+               addmsg(suitname[c.suit]);
+       return (TRUE);
 }
 
 /*
  * printcard:
  *     Print out a card.
  */
 }
 
 /*
  * printcard:
  *     Print out a card.
  */
-printcard(win, cardno, c)
-WINDOW         *win;
-int            cardno;
-CARD           c;
+void
+printcard(win, cardno, c, blank)
+       WINDOW *win;
+       int     cardno;
+       CARD    c;
+       BOOLEAN blank;
 {
 {
-       prcard(win, cardno * 2, cardno, c);
+       prcard(win, cardno * 2, cardno, c, blank);
 }
 
 /*
  * prcard:
  *     Print out a card on the window at the specified location
  */
 }
 
 /*
  * prcard:
  *     Print out a card on the window at the specified location
  */
-prcard(win, y, x, c)
-WINDOW         *win;
-int            y, x;
-CARD           c;
+void
+prcard(win, y, x, c, blank)
+       WINDOW *win;
+       int y, x;
+       CARD c;
+       BOOLEAN blank;
 {
        if (c.rank == EMPTY)
 {
        if (c.rank == EMPTY)
-           return;
+               return;
+
        mvwaddstr(win, y + 0, x, "+-----+");
        mvwaddstr(win, y + 1, x, "|     |");
        mvwaddstr(win, y + 2, x, "|     |");
        mvwaddstr(win, y + 3, x, "|     |");
        mvwaddstr(win, y + 4, x, "+-----+");
        mvwaddstr(win, y + 0, x, "+-----+");
        mvwaddstr(win, y + 1, x, "|     |");
        mvwaddstr(win, y + 2, x, "|     |");
        mvwaddstr(win, y + 3, x, "|     |");
        mvwaddstr(win, y + 4, x, "+-----+");
-       mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
-       waddch(win, suitchar[c.suit][0]);
-       mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
-       waddch(win, suitchar[c.suit][0]);
+       if (!blank) {
+               mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
+               waddch(win, suitchar[c.suit][0]);
+               mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
+               waddch(win, suitchar[c.suit][0]);
+       }
 }
 
 /*
  * prhand:
  *     Print a hand of n cards
  */
 }
 
 /*
  * prhand:
  *     Print a hand of n cards
  */
-prhand(h, n, win)
-CARD           h[];
-int            n;
-WINDOW         *win;
+void
+prhand(h, n, win, blank)
+       CARD h[];
+       int n;
+       WINDOW *win;
+       BOOLEAN blank;
 {
 {
-       register int    i;
+       register int i;
 
        werase(win);
        for (i = 0; i < n; i++)
 
        werase(win);
        for (i = 0; i < n; i++)
-           printcard(win, i, h[i]);
+               printcard(win, i, *h++, blank);
        wrefresh(win);
 }
 
        wrefresh(win);
 }
 
-
-
 /*
  * infrom:
  *     reads a card, supposedly in hand, accepting unambigous brief
  *     input, returns the index of the card found...
  */
 /*
  * infrom:
  *     reads a card, supposedly in hand, accepting unambigous brief
  *     input, returns the index of the card found...
  */
+int
 infrom(hand, n, prompt)
 infrom(hand, n, prompt)
-CARD           hand[];
-int            n;
-char           *prompt;
+       CARD hand[];
+       int n;
+       char *prompt;
 {
 {
-       register int           i, j;
-       CARD                    crd;
+       register int i, j;
+       CARD crd;
 
        if (n < 1) {
 
        if (n < 1) {
-           printf("\nINFROM: %d = n < 1!!\n", n);
-           exit(74);
+               printf("\nINFROM: %d = n < 1!!\n", n);
+               exit(74);
        }
        for (;;) {
        }
        for (;;) {
-           if (incard(&crd)) {                 /* if card is full card */
-               if (!isone(crd, hand, n))
-                   msg("That's not in your hand");
-               else {
-                   for (i = 0; i < n; i++)
-                       if (hand[i].rank == crd.rank &&
-                           hand[i].suit == crd.suit)
-                               break;
-                   if (i >= n) {
+               msg(prompt);
+               if (incard(&crd)) {     /* if card is full card */
+                       if (!isone(crd, hand, n))
+                               msg("That's not in your hand");
+                       else {
+                               for (i = 0; i < n; i++)
+                                       if (hand[i].rank == crd.rank &&
+                                           hand[i].suit == crd.suit)
+                                               break;
+                               if (i >= n) {
                        printf("\nINFROM: isone or something messed up\n");
                        printf("\nINFROM: isone or something messed up\n");
-                       exit(77);
-                   }
-                   return i;
-               }
-           }
-           else                                /* if not full card... */
-               if (crd.rank != EMPTY) {
-                   for (i = 0; i < n; i++)
-                       if (hand[i].rank == crd.rank)
-                               break;
-                   if (i >= n)
-                       msg("No such rank in your hand");
-                   else {
-                       for (j = i + 1; j < n; j++)
-                           if (hand[j].rank == crd.rank)
-                               break;
-                       if (j < n)
-                           msg("Ambiguous rank");
-                       else
-                           return i;
-                   }
-               }
-               else
-                   msg("Sorry, I missed that");
-           msg(prompt);
+                                       exit(77);
+                               }
+                               return (i);
+                       }
+               } else                  /* if not full card... */
+                       if (crd.rank != EMPTY) {
+                               for (i = 0; i < n; i++)
+                                       if (hand[i].rank == crd.rank)
+                                               break;
+                               if (i >= n)
+                                       msg("No such rank in your hand");
+                               else {
+                                       for (j = i + 1; j < n; j++)
+                                               if (hand[j].rank == crd.rank)
+                                                       break;
+                                       if (j < n)
+                                               msg("Ambiguous rank");
+                                       else
+                                               return (i);
+                               }
+                       } else
+                               msg("Sorry, I missed that");
        }
        /* NOTREACHED */
 }
 
        }
        /* NOTREACHED */
 }
 
-
-
 /*
  * incard:
  *     Inputs a card in any format.  It reads a line ending with a CR
  *     and then parses it.
  */
 /*
  * incard:
  *     Inputs a card in any format.  It reads a line ending with a CR
  *     and then parses it.
  */
+int
 incard(crd)
 incard(crd)
-CARD           *crd;
+       CARD *crd;
 {
 {
-       char            *getline();
-       register int    i;
-       int             rnk, sut;
-       char            *line, *p, *p1;
-       BOOLEAN         retval;
+       register int i;
+       int rnk, sut;
+       char *line, *p, *p1;
+       BOOLEAN retval;
 
        retval = FALSE;
        rnk = sut = EMPTY;
        if (!(line = getline()))
                goto gotit;
        p = p1 = line;
 
        retval = FALSE;
        rnk = sut = EMPTY;
        if (!(line = getline()))
                goto gotit;
        p = p1 = line;
-       while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
+       while (*p1 != ' ' && *p1 != NULL)
+               ++p1;
        *p1++ = NULL;
        *p1++ = NULL;
-       if(  *p == NULL  )  goto  gotit;
-                       /* IMPORTANT: no real card has 2 char first name */
-       if(  strlen(p) == 2  )  {               /* check for short form */
-           rnk = EMPTY;
-           for( i = 0; i < RANKS; i++ )  {
-               if(  *p == *rankchar[i]  )  {
-                   rnk = i;
-                   break;
+       if (*p == NULL)
+               goto gotit;
+
+       /* IMPORTANT: no real card has 2 char first name */
+       if (strlen(p) == 2) {   /* check for short form */
+               rnk = EMPTY;
+               for (i = 0; i < RANKS; i++) {
+                       if (*p == *rankchar[i]) {
+                               rnk = i;
+                               break;
+                       }
                }
                }
-           }
-           if(  rnk == EMPTY  )  goto  gotit;     /* it's nothing... */
-           ++p;                                /* advance to next char */
-           sut = EMPTY;
-           for( i = 0; i < SUITS; i++ )  {
-               if(  *p == *suitchar[i]  )  {
-                   sut = i;
-                   break;
+               if (rnk == EMPTY)
+                       goto gotit;     /* it's nothing... */
+               ++p;            /* advance to next char */
+               sut = EMPTY;
+               for (i = 0; i < SUITS; i++) {
+                       if (*p == *suitchar[i]) {
+                               sut = i;
+                               break;
+                       }
                }
                }
-           }
-           if(  sut != EMPTY  )  retval = TRUE;
-           goto  gotit;
+               if (sut != EMPTY)
+                       retval = TRUE;
+               goto gotit;
        }
        rnk = EMPTY;
        }
        rnk = EMPTY;
-       for( i = 0; i < RANKS; i++ )  {
-           if(  !strcmp( p, rankname[i] )  ||  !strcmp( p, rankchar[i] )  )  {
-               rnk = i;
-               break;
-           }
+       for (i = 0; i < RANKS; i++) {
+               if (!strcmp(p, rankname[i]) || !strcmp(p, rankchar[i])) {
+                       rnk = i;
+                       break;
+               }
        }
        }
-       if(  rnk == EMPTY  )  goto  gotit;
+       if (rnk == EMPTY)
+               goto gotit;
        p = p1;
        p = p1;
-       while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
+       while (*p1 != ' ' && *p1 != NULL)
+               ++p1;
        *p1++ = NULL;
        *p1++ = NULL;
-       if(  *p == NULL  )  goto  gotit;
-       if(  !strcmp( "OF", p )  )  {
-           p = p1;
-           while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
-           *p1++ = NULL;
-           if(  *p == NULL  )  goto  gotit;
+       if (*p == NULL)
+               goto gotit;
+       if (!strcmp("OF", p)) {
+               p = p1;
+               while (*p1 != ' ' && *p1 != NULL)
+                       ++p1;
+               *p1++ = NULL;
+               if (*p == NULL)
+                       goto gotit;
        }
        sut = EMPTY;
        }
        sut = EMPTY;
-       for( i = 0; i < SUITS; i++ )  {
-           if(  !strcmp( p, suitname[i] )  ||  !strcmp( p, suitchar[i] )  )  {
-               sut = i;
-               break;
-           }
+       for (i = 0; i < SUITS; i++) {
+               if (!strcmp(p, suitname[i]) || !strcmp(p, suitchar[i])) {
+                       sut = i;
+                       break;
+               }
        }
        }
-       if(  sut != EMPTY  )  retval = TRUE;
+       if (sut != EMPTY)
+               retval = TRUE;
 gotit:
        (*crd).rank = rnk;
        (*crd).suit = sut;
 gotit:
        (*crd).rank = rnk;
        (*crd).suit = sut;
-       return( retval );
+       return (retval);
 }
 
 }
 
-
-
 /*
  * getuchar:
  *     Reads and converts to upper case
  */
 /*
  * getuchar:
  *     Reads and converts to upper case
  */
+int
 getuchar()
 {
 getuchar()
 {
-       register int            c;
+       register int c;
 
        c = readchar();
        if (islower(c))
 
        c = readchar();
        if (islower(c))
-           c = toupper(c);
-       addch(c);
-       return c;
+               c = toupper(c);
+       waddch(Msgwin, c);
+       return (c);
 }
 
 /*
 }
 
 /*
@@ -279,175 +312,213 @@ getuchar()
  *     Reads in a decimal number and makes sure it is between "lo" and
  *     "hi" inclusive.
  */
  *     Reads in a decimal number and makes sure it is between "lo" and
  *     "hi" inclusive.
  */
+int
 number(lo, hi, prompt)
 number(lo, hi, prompt)
-int            lo, hi;
-char           *prompt;
+       int lo, hi;
+       char *prompt;
 {
 {
-       char                    *getline();
-       register char           *p;
-       register int            sum;
-
-       sum = 0;
-       for (;;) {
-           msg(prompt);
-           if(!(p = getline()) || *p == NULL) {
-               msg(quiet ? "Not a number" : "That doesn't look like a number");
-               continue;
-           }
-           sum = 0;
-
-           if (!isdigit(*p))
-               sum = lo - 1;
-           else
-               while (isdigit(*p)) {
-                   sum = 10 * sum + (*p - '0');
-                   ++p;
+       register char *p;
+       register int sum;
+
+       for (sum = 0;;) {
+               msg(prompt);
+               if (!(p = getline()) || *p == NULL) {
+                       msg(quiet ? "Not a number" :
+                           "That doesn't look like a number");
+                       continue;
                }
                }
+               sum = 0;
 
 
-           if (*p != ' ' && *p != '\t' && *p != NULL)
-               sum = lo - 1;
-           if (sum >= lo && sum <= hi)
-               return sum;
-           if (sum == lo - 1)
-               msg("that doesn't look like a number, try again --> ");
-           else
+               if (!isdigit(*p))
+                       sum = lo - 1;
+               else
+                       while (isdigit(*p)) {
+                               sum = 10 * sum + (*p - '0');
+                               ++p;
+                       }
+
+               if (*p != ' ' && *p != '\t' && *p != NULL)
+                       sum = lo - 1;
+               if (sum >= lo && sum <= hi)
+                       break;
+               if (sum == lo - 1)
+                       msg("that doesn't look like a number, try again --> ");
+               else
                msg("%d is not between %d and %d inclusive, try again --> ",
                msg("%d is not between %d and %d inclusive, try again --> ",
-                                                               sum, lo, hi);
+                           sum, lo, hi);
        }
        }
+       return (sum);
 }
 
 /*
  * msg:
  *     Display a message at the top of the screen.
  */
 }
 
 /*
  * msg:
  *     Display a message at the top of the screen.
  */
-char           Msgbuf[BUFSIZ] = "";
-
-int            Mpos = 0;
-
-static int     Newpos = 0;
-
-/* VARARGS1 */
-msg(fmt, args)
-char   *fmt;
-int    args;
+char    Msgbuf[BUFSIZ] = {'\0'};
+int     Mpos = 0;
+static int Newpos = 0;
+
+void
+#if __STDC__
+msg(const char *fmt, ...)
+#else
+msg(fmt, va_alist)
+       char *fmt;
+       va_dcl
+#endif
 {
 {
-    /*
-     * if the string is "", just clear the line
-     */
-    if (*fmt == '\0') {
-       move(LINES - 1, 0);
-       clrtoeol();
-       Mpos = 0;
-       Hasread = TRUE;
-       return;
-    }
-    /*
-     * otherwise add to the message and flush it out
-     */
-    doadd(fmt, &args);
-    endmsg();
+       va_list ap;
+
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
+       (void)vsprintf(&Msgbuf[Newpos], fmt, ap);
+       va_end(ap);
+       endmsg();
 }
 
 /*
  * addmsg:
  *     Add things to the current message
  */
 }
 
 /*
  * addmsg:
  *     Add things to the current message
  */
-/* VARARGS1 */
-addmsg(fmt, args)
-char   *fmt;
-int    args;
+void
+#if __STDC__
+addmsg(const char *fmt, ...)
+#else
+addmsg(fmt, va_alist)
+       char *fmt;
+       va_dcl
+#endif
 {
 {
-    doadd(fmt, &args);
+       va_list ap;
+
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
+       (void)vsprintf(&Msgbuf[Newpos], fmt, ap);
+       va_end(ap);
 }
 
 /*
  * endmsg:
 }
 
 /*
  * endmsg:
- *     Display a new msg (giving him a chance to see the previous one
- *     if it is up there with the --More--)
+ *     Display a new msg.
  */
  */
+int     Lineno = 0;
+
+void
 endmsg()
 {
 endmsg()
 {
-    if (!Hasread) {
-       move(LINES - 1, Mpos);
-       addstr("--More--");
+       static int lastline = 0;
+       register int len;
+       register char *mp, *omp;
+
+       /* All messages should start with uppercase */
+       mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
+       if (islower(Msgbuf[0]) && Msgbuf[1] != ')')
+               Msgbuf[0] = toupper(Msgbuf[0]);
+       mp = Msgbuf;
+       len = strlen(mp);
+       if (len / MSG_X + Lineno >= MSG_Y) {
+               while (Lineno < MSG_Y) {
+                       wmove(Msgwin, Lineno++, 0);
+                       wclrtoeol(Msgwin);
+               }
+               Lineno = 0;
+       }
+       mvaddch(Lineno + Y_MSG_START, SCORE_X, '*');
+       lastline = Lineno;
+       do {
+               mvwaddstr(Msgwin, Lineno, 0, mp);
+               if ((len = strlen(mp)) > MSG_X) {
+                       omp = mp;
+                       for (mp = &mp[MSG_X - 1]; *mp != ' '; mp--)
+                               continue;
+                       while (*mp == ' ')
+                               mp--;
+                       mp++;
+                       wmove(Msgwin, Lineno, mp - omp);
+                       wclrtoeol(Msgwin);
+               }
+               if (++Lineno >= MSG_Y)
+                       Lineno = 0;
+       } while (len > MSG_X);
+       wclrtoeol(Msgwin);
+       Mpos = len;
+       Newpos = 0;
+       wrefresh(Msgwin);
        refresh();
        refresh();
-       wait_for(' ');
-    }
-    /*
-     * All messages should start with uppercase, except ones that
-     * start with a pack addressing character
-     */
-    if (islower(Msgbuf[0]) && Msgbuf[1] != ')')
-       Msgbuf[0] = toupper(Msgbuf[0]);
-    mvaddstr(LINES - 1, 0, Msgbuf);
-    clrtoeol();
-    Mpos = Newpos;
-    Newpos = 0;
-    refresh();
-    Hasread = FALSE;
+       wrefresh(Msgwin);
 }
 
 /*
 }
 
 /*
- * doadd:
- *     Perform an add onto the message buffer
+ * do_wait:
+ *     Wait for the user to type ' ' before doing anything else
  */
  */
-doadd(fmt, args)
-char   *fmt;
-int    *args;
+void
+do_wait()
 {
 {
-    static FILE        junk;
-
-    /*
-     * Do the printf into Msgbuf
-     */
-    junk._flag = _IOWRT + _IOSTRG;
-    junk._ptr = &Msgbuf[Newpos];
-    junk._cnt = 32767;
-    _doprnt(fmt, args, &junk);
-    putc('\0', &junk);
-    Newpos = strlen(Msgbuf);
+       static char prompt[] = {'-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0'};
+
+       if (Mpos + sizeof prompt < MSG_X)
+               wmove(Msgwin, Lineno > 0 ? Lineno - 1 : MSG_Y - 1, Mpos);
+       else {
+               mvwaddch(Msgwin, Lineno, 0, ' ');
+               wclrtoeol(Msgwin);
+               if (++Lineno >= MSG_Y)
+                       Lineno = 0;
+       }
+       waddstr(Msgwin, prompt);
+       wrefresh(Msgwin);
+       wait_for(' ');
 }
 
 /*
  * wait_for
  *     Sit around until the guy types the right key
  */
 }
 
 /*
  * wait_for
  *     Sit around until the guy types the right key
  */
+void
 wait_for(ch)
 wait_for(ch)
-register char  ch;
+       register int ch;
 {
 {
-    register char      c;
-
-    if (ch == '\n')
-       while ((c = readchar()) != '\n')
-           continue;
-    else
-       while (readchar() != ch)
-           continue;
+       register char c;
+
+       if (ch == '\n')
+               while ((c = readchar()) != '\n')
+                       continue;
+       else
+               while (readchar() != ch)
+                       continue;
 }
 
 /*
  * readchar:
  *     Reads and returns a character, checking for gross input errors
  */
 }
 
 /*
  * readchar:
  *     Reads and returns a character, checking for gross input errors
  */
+int
 readchar()
 {
 readchar()
 {
-    register int       cnt, y, x;
-    auto char          c;
+       register int cnt;
+       char c;
 
 over:
 
 over:
-    cnt = 0;
-    while (read(0, &c, 1) <= 0)
-       if (cnt++ > 100)        /* if we are getting infinite EOFs */
-           bye();              /* quit the game */
-    if (c == CTRL(L)) {
-       wrefresh(curscr);
-       goto over;
-    }
-    Hasread = TRUE;
-    if (c == '\r')
-       return '\n';
-    else
-       return c;
+       cnt = 0;
+       while (read(STDIN_FILENO, &c, sizeof(char)) <= 0)
+               if (cnt++ > 100) {      /* if we are getting infinite EOFs */
+                       bye();          /* quit the game */
+                       exit(1);
+               }
+       if (c == CTRL('L')) {
+               wrefresh(curscr);
+               goto over;
+       }
+       if (c == '\r')
+               return ('\n');
+       else
+               return (c);
 }
 
 /*
 }
 
 /*
@@ -458,45 +529,70 @@ over:
 char *
 getline()
 {
 char *
 getline()
 {
-    register char      *sp;
-    register int       c, oy, ox;
-
-    getyx(stdscr, oy, ox);
-    refresh();
-    /*
-     * loop reading in the string, and put it in a temporary buffer
-     */
-    for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
-       if (c == -1)
-           continue;
-       else if (c == erasechar()) {    /* process erase character */
-           if (sp > linebuf) {
-               register int i;
-
-               sp--;
-               for (i = strlen(unctrl(*sp)); i; i--)
-                   addch('\b');
-           }
-           continue;
-       }
-       else if (c == killchar()) {     /* process kill character */
-           sp = linebuf;
-           move(oy, ox);
-           continue;
-       }
-       else if (sp == linebuf && c == ' ')
-           continue;
-       if (sp >= &linebuf[LINESIZE-1] || !(isprint(c) || c == ' '))
-           putchar(CTRL(G));
-       else {
-           if (islower(c))
-               c = toupper(c);
-           *sp++ = c;
-           addstr(unctrl(c));
-/*###366 [cc] Mpos undefined %%%*/
-           Mpos++;
+       register char *sp;
+       register int c, oy, ox;
+       register WINDOW *oscr;
+
+       oscr = stdscr;
+       stdscr = Msgwin;
+       getyx(stdscr, oy, ox);
+       refresh();
+       /* loop reading in the string, and put it in a temporary buffer */
+       for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
+               if (c == -1)
+                       continue;
+               else
+                       if (c == erasechar()) { /* process erase character */
+                               if (sp > linebuf) {
+                                       register int i;
+
+                                       sp--;
+                                       for (i = strlen(unctrl(*sp)); i; i--)
+                                               addch('\b');
+                               }
+                               continue;
+                       } else
+                               if (c == killchar()) {  /* process kill
+                                                        * character */
+                                       sp = linebuf;
+                                       move(oy, ox);
+                                       continue;
+                               } else
+                                       if (sp == linebuf && c == ' ')
+                                               continue;
+               if (sp >= &linebuf[LINESIZE - 1] || !(isprint(c) || c == ' '))
+                       putchar(CTRL('G'));
+               else {
+                       if (islower(c))
+                               c = toupper(c);
+                       *sp++ = c;
+                       addstr(unctrl(c));
+                       Mpos++;
+               }
        }
        }
-    }
-    *sp = '\0';
-    return linebuf;
+       *sp = '\0';
+       stdscr = oscr;
+       return (linebuf);
+}
+
+void
+rint(signo)
+       int signo;
+{
+       bye();
+       exit(1);
+}
+
+/*
+ * bye:
+ *     Leave the program, cleaning things up as we go.
+ */
+void
+bye()
+{
+       signal(SIGINT, SIG_IGN);
+       mvcur(0, COLS - 1, LINES - 1, 0);
+       fflush(stdout);
+       endwin();
+       putchar('\n');
 }
 }