1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)io.c	5.1 (Berkeley) 5/30/85";
   9: #endif not lint
  10: 
  11: # include   <curses.h>
  12: # include   <ctype.h>
  13: # include   <signal.h>
  14: # include   "deck.h"
  15: # include   "cribbage.h"
  16: # include   "cribcur.h"
  17: 
  18: # define    LINESIZE        128
  19: 
  20: # ifdef CTRL
  21: # undef CTRL
  22: # endif
  23: # define    CTRL(X)         ('X' - 'A' + 1)
  24: 
  25: # ifndef    erasechar()
  26: #	define    erasechar() _tty.sg_erase
  27: # endif		erasechar()
  28: 
  29: # ifndef    killchar()
  30: #	define    killchar()  _tty.sg_kill
  31: # endif		killchar()
  32: 
  33: char        linebuf[ LINESIZE ];
  34: 
  35: char        *rankname[ RANKS ]  = { "ACE", "TWO", "THREE", "FOUR",
  36:                         "FIVE", "SIX", "SEVEN", "EIGHT",
  37:                         "NINE", "TEN", "JACK", "QUEEN",
  38:                         "KING" };
  39: 
  40: char            *rankchar[ RANKS ]      = { "A", "2", "3", "4", "5", "6", "7",
  41:                         "8", "9", "T", "J", "Q", "K" };
  42: 
  43: char            *suitname[ SUITS ]      = { "SPADES", "HEARTS", "DIAMONDS",
  44:                         "CLUBS" };
  45: 
  46: char            *suitchar[ SUITS ]      = { "S", "H", "D", "C" };
  47: 
  48: 
  49: 
  50: /*
  51:  * msgcard:
  52:  *	Call msgcrd in one of two forms
  53:  */
  54: msgcard(c, brief)
  55: CARD        c;
  56: BOOLEAN     brief;
  57: {
  58:     if (brief)
  59:         return msgcrd(c, TRUE, (char *) NULL, TRUE);
  60:     else
  61:         return msgcrd(c, FALSE, " of ", FALSE);
  62: }
  63: 
  64: 
  65: 
  66: /*
  67:  * msgcrd:
  68:  *	Print the value of a card in ascii
  69:  */
  70: msgcrd(c, brfrank, mid, brfsuit)
  71: CARD        c;
  72: char        *mid;
  73: BOOLEAN     brfrank,  brfsuit;
  74: {
  75:     if (c.rank == EMPTY || c.suit == EMPTY)
  76:         return FALSE;
  77:     if (brfrank)
  78:         addmsg("%1.1s", rankchar[c.rank]);
  79:     else
  80:         addmsg(rankname[c.rank]);
  81:     if (mid != NULL)
  82:         addmsg(mid);
  83:     if (brfsuit)
  84:         addmsg("%1.1s", suitchar[c.suit]);
  85:     else
  86:         addmsg(suitname[c.suit]);
  87:     return TRUE;
  88: }
  89: 
  90: /*
  91:  * printcard:
  92:  *	Print out a card.
  93:  */
  94: printcard(win, cardno, c, blank)
  95: WINDOW      *win;
  96: int     cardno;
  97: CARD        c;
  98: BOOLEAN     blank;
  99: {
 100:     prcard(win, cardno * 2, cardno, c, blank);
 101: }
 102: 
 103: /*
 104:  * prcard:
 105:  *	Print out a card on the window at the specified location
 106:  */
 107: prcard(win, y, x, c, blank)
 108: WINDOW      *win;
 109: int     y, x;
 110: CARD        c;
 111: BOOLEAN     blank;
 112: {
 113:     if (c.rank == EMPTY)
 114:         return;
 115:     mvwaddstr(win, y + 0, x, "+-----+");
 116:     mvwaddstr(win, y + 1, x, "|     |");
 117:     mvwaddstr(win, y + 2, x, "|     |");
 118:     mvwaddstr(win, y + 3, x, "|     |");
 119:     mvwaddstr(win, y + 4, x, "+-----+");
 120:     if (!blank) {
 121:         mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
 122:         waddch(win, suitchar[c.suit][0]);
 123:         mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
 124:         waddch(win, suitchar[c.suit][0]);
 125:     }
 126: }
 127: 
 128: /*
 129:  * prhand:
 130:  *	Print a hand of n cards
 131:  */
 132: prhand(h, n, win, blank)
 133: CARD        h[];
 134: int     n;
 135: WINDOW      *win;
 136: BOOLEAN     blank;
 137: {
 138:     register int    i;
 139: 
 140:     werase(win);
 141:     for (i = 0; i < n; i++)
 142:         printcard(win, i, *h++, blank);
 143:     wrefresh(win);
 144: }
 145: 
 146: 
 147: 
 148: /*
 149:  * infrom:
 150:  *	reads a card, supposedly in hand, accepting unambigous brief
 151:  *	input, returns the index of the card found...
 152:  */
 153: infrom(hand, n, prompt)
 154: CARD        hand[];
 155: int     n;
 156: char        *prompt;
 157: {
 158:     register int           i, j;
 159:     CARD                    crd;
 160: 
 161:     if (n < 1) {
 162:         printf("\nINFROM: %d = n < 1!!\n", n);
 163:         exit(74);
 164:     }
 165:     for (;;) {
 166:         msg(prompt);
 167:         if (incard(&crd)) {         /* if card is full card */
 168:         if (!isone(crd, hand, n))
 169:             msg("That's not in your hand");
 170:         else {
 171:             for (i = 0; i < n; i++)
 172:             if (hand[i].rank == crd.rank &&
 173:                 hand[i].suit == crd.suit)
 174:                 break;
 175:             if (i >= n) {
 176:             printf("\nINFROM: isone or something messed up\n");
 177:             exit(77);
 178:             }
 179:             return i;
 180:         }
 181:         }
 182:         else                /* if not full card... */
 183:         if (crd.rank != EMPTY) {
 184:             for (i = 0; i < n; i++)
 185:             if (hand[i].rank == crd.rank)
 186:                 break;
 187:             if (i >= n)
 188:             msg("No such rank in your hand");
 189:             else {
 190:             for (j = i + 1; j < n; j++)
 191:                 if (hand[j].rank == crd.rank)
 192:                 break;
 193:             if (j < n)
 194:                 msg("Ambiguous rank");
 195:             else
 196:                 return i;
 197:             }
 198:         }
 199:         else
 200:             msg("Sorry, I missed that");
 201:     }
 202:     /* NOTREACHED */
 203: }
 204: 
 205: 
 206: 
 207: /*
 208:  * incard:
 209:  *	Inputs a card in any format.  It reads a line ending with a CR
 210:  *	and then parses it.
 211:  */
 212: incard(crd)
 213: CARD        *crd;
 214: {
 215:     char        *getline();
 216:     register int    i;
 217:     int     rnk, sut;
 218:     char        *line, *p, *p1;
 219:     BOOLEAN     retval;
 220: 
 221:     retval = FALSE;
 222:     rnk = sut = EMPTY;
 223:     if (!(line = getline()))
 224:         goto gotit;
 225:     p = p1 = line;
 226:     while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
 227:     *p1++ = NULL;
 228:     if(  *p == NULL  )  goto  gotit;
 229:             /* IMPORTANT: no real card has 2 char first name */
 230:     if(  strlen(p) == 2  )  {               /* check for short form */
 231:         rnk = EMPTY;
 232:         for( i = 0; i < RANKS; i++ )  {
 233:         if(  *p == *rankchar[i]  )  {
 234:             rnk = i;
 235:             break;
 236:         }
 237:         }
 238:         if(  rnk == EMPTY  )  goto  gotit;     /* it's nothing... */
 239:         ++p;                                /* advance to next char */
 240:         sut = EMPTY;
 241:         for( i = 0; i < SUITS; i++ )  {
 242:         if(  *p == *suitchar[i]  )  {
 243:             sut = i;
 244:             break;
 245:         }
 246:         }
 247:         if(  sut != EMPTY  )  retval = TRUE;
 248:         goto  gotit;
 249:     }
 250:     rnk = EMPTY;
 251:     for( i = 0; i < RANKS; i++ )  {
 252:         if(  !strcmp( p, rankname[i] )  ||  !strcmp( p, rankchar[i] )  )  {
 253:         rnk = i;
 254:         break;
 255:         }
 256:     }
 257:     if(  rnk == EMPTY  )  goto  gotit;
 258:     p = p1;
 259:     while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
 260:     *p1++ = NULL;
 261:     if(  *p == NULL  )  goto  gotit;
 262:     if(  !strcmp( "OF", p )  )  {
 263:         p = p1;
 264:         while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
 265:         *p1++ = NULL;
 266:         if(  *p == NULL  )  goto  gotit;
 267:     }
 268:     sut = EMPTY;
 269:     for( i = 0; i < SUITS; i++ )  {
 270:         if(  !strcmp( p, suitname[i] )  ||  !strcmp( p, suitchar[i] )  )  {
 271:         sut = i;
 272:         break;
 273:         }
 274:     }
 275:     if(  sut != EMPTY  )  retval = TRUE;
 276: gotit:
 277:     (*crd).rank = rnk;
 278:     (*crd).suit = sut;
 279:     return( retval );
 280: }
 281: 
 282: 
 283: 
 284: /*
 285:  * getuchar:
 286:  *	Reads and converts to upper case
 287:  */
 288: getuchar()
 289: {
 290:     register int        c;
 291: 
 292:     c = readchar();
 293:     if (islower(c))
 294:         c = toupper(c);
 295:     waddch(Msgwin, c);
 296:     return c;
 297: }
 298: 
 299: /*
 300:  * number:
 301:  *	Reads in a decimal number and makes sure it is between "lo" and
 302:  *	"hi" inclusive.
 303:  */
 304: number(lo, hi, prompt)
 305: int     lo, hi;
 306: char        *prompt;
 307: {
 308:     char            *getline();
 309:     register char       *p;
 310:     register int        sum;
 311: 
 312:     sum = 0;
 313:     for (;;) {
 314:         msg(prompt);
 315:         if(!(p = getline()) || *p == NULL) {
 316:         msg(quiet ? "Not a number" : "That doesn't look like a number");
 317:         continue;
 318:         }
 319:         sum = 0;
 320: 
 321:         if (!isdigit(*p))
 322:         sum = lo - 1;
 323:         else
 324:         while (isdigit(*p)) {
 325:             sum = 10 * sum + (*p - '0');
 326:             ++p;
 327:         }
 328: 
 329:         if (*p != ' ' && *p != '\t' && *p != NULL)
 330:         sum = lo - 1;
 331:         if (sum >= lo && sum <= hi)
 332:         return sum;
 333:         if (sum == lo - 1)
 334:         msg("that doesn't look like a number, try again --> ");
 335:         else
 336:         msg("%d is not between %d and %d inclusive, try again --> ",
 337:                                 sum, lo, hi);
 338:     }
 339: }
 340: 
 341: /*
 342:  * msg:
 343:  *	Display a message at the top of the screen.
 344:  */
 345: char        Msgbuf[BUFSIZ] = { '\0' };
 346: 
 347: int     Mpos = 0;
 348: 
 349: static int  Newpos = 0;
 350: 
 351: /* VARARGS1 */
 352: msg(fmt, args)
 353: char    *fmt;
 354: int args;
 355: {
 356:     doadd(fmt, &args);
 357:     endmsg();
 358: }
 359: 
 360: /*
 361:  * addmsg:
 362:  *	Add things to the current message
 363:  */
 364: /* VARARGS1 */
 365: addmsg(fmt, args)
 366: char    *fmt;
 367: int args;
 368: {
 369:     doadd(fmt, &args);
 370: }
 371: 
 372: /*
 373:  * endmsg:
 374:  *	Display a new msg.
 375:  */
 376: 
 377: int Lineno = 0;
 378: 
 379: endmsg()
 380: {
 381:     register int    len;
 382:     register char   *mp, *omp;
 383:     static int      lastline = 0;
 384: 
 385:     /*
 386:      * All messages should start with uppercase
 387:      */
 388:     mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
 389:     if (islower(Msgbuf[0]) && Msgbuf[1] != ')')
 390:     Msgbuf[0] = toupper(Msgbuf[0]);
 391:     mp = Msgbuf;
 392:     len = strlen(mp);
 393:     if (len / MSG_X + Lineno >= MSG_Y) {
 394:     while (Lineno < MSG_Y) {
 395:         wmove(Msgwin, Lineno++, 0);
 396:         wclrtoeol(Msgwin);
 397:     }
 398:     Lineno = 0;
 399:     }
 400:     mvaddch(Lineno + Y_MSG_START, SCORE_X, '*');
 401:     lastline = Lineno;
 402:     do {
 403:     mvwaddstr(Msgwin, Lineno, 0, mp);
 404:     if ((len = strlen(mp)) > MSG_X) {
 405:         omp = mp;
 406:         for (mp = &mp[MSG_X-1]; *mp != ' '; mp--)
 407:             continue;
 408:         while (*mp == ' ')
 409:         mp--;
 410:         mp++;
 411:         wmove(Msgwin, Lineno, mp - omp);
 412:         wclrtoeol(Msgwin);
 413:     }
 414:     if (++Lineno >= MSG_Y)
 415:         Lineno = 0;
 416:     } while (len > MSG_X);
 417:     wclrtoeol(Msgwin);
 418:     Mpos = len;
 419:     Newpos = 0;
 420:     wrefresh(Msgwin);
 421:     refresh();
 422:     wrefresh(Msgwin);
 423: }
 424: 
 425: /*
 426:  * doadd:
 427:  *	Perform an add onto the message buffer
 428:  */
 429: doadd(fmt, args)
 430: char    *fmt;
 431: int *args;
 432: {
 433:     static FILE junk;
 434: 
 435:     /*
 436:      * Do the printf into Msgbuf
 437:      */
 438:     junk._flag = _IOWRT + _IOSTRG;
 439:     junk._ptr = &Msgbuf[Newpos];
 440:     junk._cnt = 32767;
 441:     _doprnt(fmt, args, &junk);
 442:     putc('\0', &junk);
 443:     Newpos = strlen(Msgbuf);
 444: }
 445: 
 446: /*
 447:  * do_wait:
 448:  *	Wait for the user to type ' ' before doing anything else
 449:  */
 450: do_wait()
 451: {
 452:     register int line;
 453:     static char prompt[] = { '-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0' };
 454: 
 455:     if (Mpos + sizeof prompt < MSG_X)
 456:     wmove(Msgwin, Lineno > 0 ? Lineno - 1 : MSG_Y - 1, Mpos);
 457:     else {
 458:     mvwaddch(Msgwin, Lineno, 0, ' ');
 459:     wclrtoeol(Msgwin);
 460:     if (++Lineno >= MSG_Y)
 461:         Lineno = 0;
 462:     }
 463:     waddstr(Msgwin, prompt);
 464:     wrefresh(Msgwin);
 465:     wait_for(' ');
 466: }
 467: 
 468: /*
 469:  * wait_for
 470:  *	Sit around until the guy types the right key
 471:  */
 472: wait_for(ch)
 473: register char   ch;
 474: {
 475:     register char   c;
 476: 
 477:     if (ch == '\n')
 478:     while ((c = readchar()) != '\n')
 479:         continue;
 480:     else
 481:     while (readchar() != ch)
 482:         continue;
 483: }
 484: 
 485: /*
 486:  * readchar:
 487:  *	Reads and returns a character, checking for gross input errors
 488:  */
 489: readchar()
 490: {
 491:     register int    cnt, y, x;
 492:     auto char       c;
 493: 
 494: over:
 495:     cnt = 0;
 496:     while (read(0, &c, 1) <= 0)
 497:     if (cnt++ > 100)    /* if we are getting infinite EOFs */
 498:         bye();      /* quit the game */
 499:     if (c == CTRL(L)) {
 500:     wrefresh(curscr);
 501:     goto over;
 502:     }
 503:     if (c == '\r')
 504:     return '\n';
 505:     else
 506:     return c;
 507: }
 508: 
 509: /*
 510:  * getline:
 511:  *      Reads the next line up to '\n' or EOF.  Multiple spaces are
 512:  *	compressed to one space; a space is inserted before a ','
 513:  */
 514: char *
 515: getline()
 516: {
 517:     register char   *sp;
 518:     register int    c, oy, ox;
 519:     register WINDOW *oscr;
 520: 
 521:     oscr = stdscr;
 522:     stdscr = Msgwin;
 523:     getyx(stdscr, oy, ox);
 524:     refresh();
 525:     /*
 526:      * loop reading in the string, and put it in a temporary buffer
 527:      */
 528:     for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
 529:     if (c == -1)
 530:         continue;
 531:     else if (c == erasechar()) {    /* process erase character */
 532:         if (sp > linebuf) {
 533:         register int i;
 534: 
 535:         sp--;
 536:         for (i = strlen(unctrl(*sp)); i; i--)
 537:             addch('\b');
 538:         }
 539:         continue;
 540:     }
 541:     else if (c == killchar()) { /* process kill character */
 542:         sp = linebuf;
 543:         move(oy, ox);
 544:         continue;
 545:     }
 546:     else if (sp == linebuf && c == ' ')
 547:         continue;
 548:     if (sp >= &linebuf[LINESIZE-1] || !(isprint(c) || c == ' '))
 549:         putchar(CTRL(G));
 550:     else {
 551:         if (islower(c))
 552:         c = toupper(c);
 553:         *sp++ = c;
 554:         addstr(unctrl(c));
 555:         Mpos++;
 556:     }
 557:     }
 558:     *sp = '\0';
 559:     stdscr = oscr;
 560:     return linebuf;
 561: }
 562: 
 563: /*
 564:  * bye:
 565:  *	Leave the program, cleaning things up as we go.
 566:  */
 567: bye()
 568: {
 569:     signal(SIGINT, SIG_IGN);
 570:     mvcur(0, COLS - 1, LINES - 1, 0);
 571:     fflush(stdout);
 572:     endwin();
 573:     putchar('\n');
 574:     exit(1);
 575: }

Defined functions

addmsg defined in line 365; used 10 times
bye defined in line 567; used 4 times
doadd defined in line 429; used 2 times
endmsg defined in line 379; used 6 times
getline defined in line 514; used 7 times
getuchar defined in line 288; used 4 times
incard defined in line 212; used 1 times
infrom defined in line 153; used 3 times
msg defined in line 352; used 38 times
msgcard defined in line 54; used 5 times
msgcrd defined in line 70; used 2 times
number defined in line 304; used 1 times
prcard defined in line 107; used 2 times
prhand defined in line 132; used 11 times
printcard defined in line 94; used 1 times
readchar defined in line 489; used 4 times
wait_for defined in line 472; used 1 times

Defined variables

Lineno defined in line 377; used 15 times
Mpos defined in line 347; used 4 times
Msgbuf defined in line 345; used 7 times
Newpos defined in line 349; used 3 times
linebuf defined in line 33; used 6 times
rankchar defined in line 40; used 5 times
rankname defined in line 35; used 2 times
sccsid defined in line 8; never used
suitchar defined in line 46; used 5 times
suitname defined in line 43; used 2 times

Defined macros

CTRL defined in line 23; used 4 times
LINESIZE defined in line 18; used 2 times
erasechar defined in line 26; used 2 times
killchar defined in line 30; used 2 times
Last modified: 1993-01-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5083
Valid CSS Valid XHTML 1.0 Strict