2012-10-14 00:36:06 +04:00
|
|
|
/* $NetBSD: io.c,v 1.27 2012/10/13 20:36:06 dholland Exp $ */
|
1995-03-21 18:03:38 +03:00
|
|
|
|
|
|
|
/*-
|
|
|
|
* Copyright (c) 1980, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
1993-03-21 12:45:37 +03:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2003-08-07 13:36:50 +04:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1993-03-21 12:45:37 +03:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
1997-10-10 16:26:34 +04:00
|
|
|
#include <sys/cdefs.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#ifndef lint
|
1995-03-21 18:03:38 +03:00
|
|
|
#if 0
|
|
|
|
static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 5/31/93";
|
|
|
|
#else
|
2012-10-14 00:36:06 +04:00
|
|
|
__RCSID("$NetBSD: io.c,v 1.27 2012/10/13 20:36:06 dholland Exp $");
|
1995-03-21 18:03:38 +03:00
|
|
|
#endif
|
1993-03-21 12:45:37 +03:00
|
|
|
#endif /* not lint */
|
|
|
|
|
1995-03-21 18:03:38 +03:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <curses.h>
|
|
|
|
#include <signal.h>
|
2002-05-26 04:12:11 +04:00
|
|
|
#include <stdarg.h>
|
1995-03-21 18:03:38 +03:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <termios.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "deck.h"
|
|
|
|
#include "cribbage.h"
|
|
|
|
#include "cribcur.h"
|
1993-12-08 10:50:47 +03:00
|
|
|
|
1995-03-21 18:03:38 +03:00
|
|
|
#define LINESIZE 128
|
1993-12-08 10:50:47 +03:00
|
|
|
|
1995-03-21 18:03:38 +03:00
|
|
|
#ifdef CTRL
|
|
|
|
#undef CTRL
|
|
|
|
#endif
|
|
|
|
#define CTRL(X) (X - 'A' + 1)
|
1993-12-08 10:50:47 +03:00
|
|
|
|
2009-08-12 09:48:04 +04:00
|
|
|
static int msgcrd(CARD, BOOLEAN, const char *, BOOLEAN);
|
2012-10-14 00:36:06 +04:00
|
|
|
static void printcard(WINDOW *, unsigned, CARD, BOOLEAN);
|
2009-08-12 09:48:04 +04:00
|
|
|
static int incard(CARD *);
|
|
|
|
static void wait_for(int);
|
|
|
|
static int readchar(void);
|
1993-12-08 10:50:47 +03:00
|
|
|
|
2009-08-12 09:48:04 +04:00
|
|
|
static char linebuf[LINESIZE];
|
|
|
|
|
|
|
|
static const char *const rankname[RANKS] = {
|
1995-03-21 18:03:38 +03:00
|
|
|
"ACE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
|
|
|
|
"EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"
|
|
|
|
};
|
1993-12-08 10:50:47 +03:00
|
|
|
|
2009-08-12 09:48:04 +04:00
|
|
|
static const char *const rankchar[RANKS] = {
|
1995-03-21 18:03:38 +03:00
|
|
|
"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"
|
|
|
|
};
|
1993-12-08 10:50:47 +03:00
|
|
|
|
2009-08-12 09:48:04 +04:00
|
|
|
static const char *const suitname[SUITS] = {
|
|
|
|
"SPADES", "HEARTS", "DIAMONDS", "CLUBS"
|
|
|
|
};
|
1993-12-08 10:50:47 +03:00
|
|
|
|
2009-08-12 09:48:04 +04:00
|
|
|
static const char *const suitchar[SUITS] = {"S", "H", "D", "C"};
|
1993-12-08 10:50:47 +03:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
/*
|
|
|
|
* msgcard:
|
|
|
|
* Call msgcrd in one of two forms
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
int
|
2011-05-24 02:47:22 +04:00
|
|
|
msgcard(CARD c, BOOLEAN brief)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
if (brief)
|
1995-03-21 18:03:38 +03:00
|
|
|
return (msgcrd(c, TRUE, NULL, TRUE));
|
1993-03-21 12:45:37 +03:00
|
|
|
else
|
1995-03-21 18:03:38 +03:00
|
|
|
return (msgcrd(c, FALSE, " of ", FALSE));
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* msgcrd:
|
|
|
|
* Print the value of a card in ascii
|
|
|
|
*/
|
2009-08-12 09:48:04 +04:00
|
|
|
static int
|
2005-07-02 12:32:32 +04:00
|
|
|
msgcrd(CARD c, BOOLEAN brfrank, const char *mid, BOOLEAN brfsuit)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
if (c.rank == EMPTY || c.suit == EMPTY)
|
1995-03-21 18:03:38 +03:00
|
|
|
return (FALSE);
|
1993-03-21 12:45:37 +03:00
|
|
|
if (brfrank)
|
1995-03-21 18:03:38 +03:00
|
|
|
addmsg("%1.1s", rankchar[c.rank]);
|
1993-03-21 12:45:37 +03:00
|
|
|
else
|
2011-05-24 02:48:52 +04:00
|
|
|
addmsg("%s", rankname[c.rank]);
|
1993-03-21 12:45:37 +03:00
|
|
|
if (mid != NULL)
|
2011-05-24 02:48:52 +04:00
|
|
|
addmsg("%s", mid);
|
1993-03-21 12:45:37 +03:00
|
|
|
if (brfsuit)
|
1995-03-21 18:03:38 +03:00
|
|
|
addmsg("%1.1s", suitchar[c.suit]);
|
1993-03-21 12:45:37 +03:00
|
|
|
else
|
2011-05-24 02:48:52 +04:00
|
|
|
addmsg("%s", suitname[c.suit]);
|
1995-03-21 18:03:38 +03:00
|
|
|
return (TRUE);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* printcard:
|
|
|
|
* Print out a card.
|
|
|
|
*/
|
2009-08-12 09:48:04 +04:00
|
|
|
static void
|
2012-10-14 00:36:06 +04:00
|
|
|
printcard(WINDOW *win, unsigned cardno, CARD c, BOOLEAN blank)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
prcard(win, cardno * 2, cardno, c, blank);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* prcard:
|
|
|
|
* Print out a card on the window at the specified location
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
void
|
2005-07-02 12:32:32 +04:00
|
|
|
prcard(WINDOW *win, int y, int x, CARD c, BOOLEAN blank)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
if (c.rank == EMPTY)
|
1995-03-21 18:03:38 +03:00
|
|
|
return;
|
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
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, "+-----+");
|
|
|
|
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
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
void
|
2012-10-14 00:36:06 +04:00
|
|
|
prhand(const CARD h[], unsigned n, WINDOW *win, BOOLEAN blank)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2012-10-14 00:36:06 +04:00
|
|
|
unsigned i;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
werase(win);
|
|
|
|
for (i = 0; i < n; i++)
|
1995-03-21 18:03:38 +03:00
|
|
|
printcard(win, i, *h++, blank);
|
1993-03-21 12:45:37 +03:00
|
|
|
wrefresh(win);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* infrom:
|
|
|
|
* reads a card, supposedly in hand, accepting unambigous brief
|
|
|
|
* input, returns the index of the card found...
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
int
|
2005-07-02 12:32:32 +04:00
|
|
|
infrom(const CARD hand[], int n, const char *prompt)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1997-10-10 16:26:34 +04:00
|
|
|
int i, j;
|
1995-03-21 18:03:38 +03:00
|
|
|
CARD crd;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
if (n < 1) {
|
1995-03-21 18:03:38 +03:00
|
|
|
printf("\nINFROM: %d = n < 1!!\n", n);
|
|
|
|
exit(74);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
for (;;) {
|
2011-05-24 02:48:52 +04:00
|
|
|
msg("%s", prompt);
|
1995-03-21 18:03:38 +03:00
|
|
|
if (incard(&crd)) { /* if card is full card */
|
1999-09-30 22:01:31 +04:00
|
|
|
if (!is_one(crd, hand, n))
|
1995-03-21 18:03:38 +03:00
|
|
|
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) {
|
1999-09-30 22:01:31 +04:00
|
|
|
printf("\nINFROM: is_one or something messed up\n");
|
1995-03-21 18:03:38 +03:00
|
|
|
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");
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
/* NOTREACHED */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* incard:
|
|
|
|
* Inputs a card in any format. It reads a line ending with a CR
|
|
|
|
* and then parses it.
|
|
|
|
*/
|
2009-08-12 09:48:04 +04:00
|
|
|
static int
|
2005-07-02 12:32:32 +04:00
|
|
|
incard(CARD *crd)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1997-10-10 16:26:34 +04:00
|
|
|
int i;
|
1995-03-21 18:03:38 +03:00
|
|
|
int rnk, sut;
|
|
|
|
char *line, *p, *p1;
|
|
|
|
BOOLEAN retval;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
retval = FALSE;
|
|
|
|
rnk = sut = EMPTY;
|
2009-07-13 23:05:39 +04:00
|
|
|
if (!(line = get_line()))
|
1993-03-21 12:45:37 +03:00
|
|
|
goto gotit;
|
|
|
|
p = p1 = line;
|
1997-05-17 23:24:44 +04:00
|
|
|
while (*p1 != ' ' && *p1 != '\0')
|
1995-03-21 18:03:38 +03:00
|
|
|
++p1;
|
1997-05-17 23:24:44 +04:00
|
|
|
*p1++ = '\0';
|
|
|
|
if (*p == '\0')
|
1995-03-21 18:03:38 +03:00
|
|
|
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;
|
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
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;
|
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
if (sut != EMPTY)
|
|
|
|
retval = TRUE;
|
|
|
|
goto gotit;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
rnk = EMPTY;
|
1995-03-21 18:03:38 +03:00
|
|
|
for (i = 0; i < RANKS; i++) {
|
|
|
|
if (!strcmp(p, rankname[i]) || !strcmp(p, rankchar[i])) {
|
|
|
|
rnk = i;
|
|
|
|
break;
|
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
if (rnk == EMPTY)
|
|
|
|
goto gotit;
|
1993-03-21 12:45:37 +03:00
|
|
|
p = p1;
|
1997-05-17 23:24:44 +04:00
|
|
|
while (*p1 != ' ' && *p1 != '\0')
|
1995-03-21 18:03:38 +03:00
|
|
|
++p1;
|
1997-05-17 23:24:44 +04:00
|
|
|
*p1++ = '\0';
|
|
|
|
if (*p == '\0')
|
1995-03-21 18:03:38 +03:00
|
|
|
goto gotit;
|
|
|
|
if (!strcmp("OF", p)) {
|
|
|
|
p = p1;
|
1997-05-17 23:24:44 +04:00
|
|
|
while (*p1 != ' ' && *p1 != '\0')
|
1995-03-21 18:03:38 +03:00
|
|
|
++p1;
|
1997-05-17 23:24:44 +04:00
|
|
|
*p1++ = '\0';
|
|
|
|
if (*p == '\0')
|
1995-03-21 18:03:38 +03:00
|
|
|
goto gotit;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
sut = EMPTY;
|
1995-03-21 18:03:38 +03:00
|
|
|
for (i = 0; i < SUITS; i++) {
|
|
|
|
if (!strcmp(p, suitname[i]) || !strcmp(p, suitchar[i])) {
|
|
|
|
sut = i;
|
|
|
|
break;
|
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
if (sut != EMPTY)
|
|
|
|
retval = TRUE;
|
1993-03-21 12:45:37 +03:00
|
|
|
gotit:
|
|
|
|
(*crd).rank = rnk;
|
|
|
|
(*crd).suit = sut;
|
1995-03-21 18:03:38 +03:00
|
|
|
return (retval);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* getuchar:
|
|
|
|
* Reads and converts to upper case
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
int
|
2005-07-02 12:32:32 +04:00
|
|
|
getuchar(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1997-10-10 16:26:34 +04:00
|
|
|
int c;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
c = readchar();
|
|
|
|
if (islower(c))
|
1995-03-21 18:03:38 +03:00
|
|
|
c = toupper(c);
|
1993-03-21 12:45:37 +03:00
|
|
|
waddch(Msgwin, c);
|
1995-03-21 18:03:38 +03:00
|
|
|
return (c);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* number:
|
|
|
|
* Reads in a decimal number and makes sure it is between "lo" and
|
|
|
|
* "hi" inclusive.
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
int
|
2005-07-02 12:32:32 +04:00
|
|
|
number(int lo, int hi, const char *prompt)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1997-10-10 16:26:34 +04:00
|
|
|
char *p;
|
|
|
|
int sum;
|
1995-03-21 18:03:38 +03:00
|
|
|
|
|
|
|
for (sum = 0;;) {
|
2011-05-24 02:48:52 +04:00
|
|
|
msg("%s", prompt);
|
2009-07-13 23:05:39 +04:00
|
|
|
if (!(p = get_line()) || *p == '\0') {
|
1995-03-21 18:03:38 +03:00
|
|
|
msg(quiet ? "Not a number" :
|
|
|
|
"That doesn't look like a number");
|
|
|
|
continue;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
sum = 0;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2004-11-06 00:30:31 +03:00
|
|
|
if (!isdigit((unsigned char)*p))
|
1995-03-21 18:03:38 +03:00
|
|
|
sum = lo - 1;
|
|
|
|
else
|
2004-11-06 00:30:31 +03:00
|
|
|
while (isdigit((unsigned char)*p)) {
|
1995-03-21 18:03:38 +03:00
|
|
|
sum = 10 * sum + (*p - '0');
|
|
|
|
++p;
|
|
|
|
}
|
|
|
|
|
1997-05-17 23:24:44 +04:00
|
|
|
if (*p != ' ' && *p != '\t' && *p != '\0')
|
1995-03-21 18:03:38 +03:00
|
|
|
sum = lo - 1;
|
|
|
|
if (sum >= lo && sum <= hi)
|
|
|
|
break;
|
|
|
|
if (sum == lo - 1)
|
|
|
|
msg("that doesn't look like a number, try again --> ");
|
|
|
|
else
|
1993-03-21 12:45:37 +03:00
|
|
|
msg("%d is not between %d and %d inclusive, try again --> ",
|
1995-03-21 18:03:38 +03:00
|
|
|
sum, lo, hi);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
return (sum);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
1995-03-21 18:03:38 +03:00
|
|
|
* msg:
|
|
|
|
* Display a message at the top of the screen.
|
1993-03-21 12:45:37 +03:00
|
|
|
*/
|
2009-08-12 09:48:04 +04:00
|
|
|
static char Msgbuf[BUFSIZ] = {'\0'};
|
|
|
|
static int Mpos = 0;
|
1995-03-21 18:03:38 +03:00
|
|
|
static int Newpos = 0;
|
|
|
|
|
|
|
|
void
|
|
|
|
msg(const char *fmt, ...)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1995-03-21 18:03:38 +03:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
2009-06-04 08:48:04 +04:00
|
|
|
(void)vsnprintf(&Msgbuf[Newpos], sizeof(Msgbuf)-Newpos, fmt, ap);
|
1997-07-09 10:25:45 +04:00
|
|
|
Newpos = strlen(Msgbuf);
|
1995-03-21 18:03:38 +03:00
|
|
|
va_end(ap);
|
|
|
|
endmsg();
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* addmsg:
|
|
|
|
* Add things to the current message
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
addmsg(const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
2009-06-04 08:48:04 +04:00
|
|
|
(void)vsnprintf(&Msgbuf[Newpos], sizeof(Msgbuf)-Newpos, fmt, ap);
|
1997-07-09 10:25:45 +04:00
|
|
|
Newpos = strlen(Msgbuf);
|
1995-03-21 18:03:38 +03:00
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* endmsg:
|
|
|
|
* Display a new msg.
|
|
|
|
*/
|
2009-08-12 09:48:04 +04:00
|
|
|
static int Lineno = 0;
|
1995-03-21 18:03:38 +03:00
|
|
|
|
|
|
|
void
|
2005-07-02 12:32:32 +04:00
|
|
|
endmsg(void)
|
1995-03-21 18:03:38 +03:00
|
|
|
{
|
|
|
|
static int lastline = 0;
|
1997-10-10 16:26:34 +04:00
|
|
|
int len;
|
|
|
|
char *mp, *omp;
|
1995-03-21 18:03:38 +03:00
|
|
|
|
|
|
|
/* All messages should start with uppercase */
|
|
|
|
mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
|
2004-11-06 00:30:31 +03:00
|
|
|
if (islower((unsigned char)Msgbuf[0]) && Msgbuf[1] != ')')
|
|
|
|
Msgbuf[0] = toupper((unsigned char)Msgbuf[0]);
|
1995-03-21 18:03:38 +03:00
|
|
|
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();
|
|
|
|
wrefresh(Msgwin);
|
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* do_wait:
|
|
|
|
* Wait for the user to type ' ' before doing anything else
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
void
|
2005-07-02 12:32:32 +04:00
|
|
|
do_wait(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
Add use of `const' where appropriate to the games.
This merges in all such remaining changes from the Linux port of the
NetBSD games, except in hunt (where substantial changes from OpenBSD
need to be looked at).
Some such changes were previously covered in PRs bin/6041, bin/6146,
bin/6148, bin/6150, bin/6151, bin/6580, bin/6660, bin/7993, bin/7994,
bin/8039, bin/8057 and bin/8093.
1999-09-09 01:17:44 +04:00
|
|
|
static const char prompt[] = {'-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0'};
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1999-09-18 23:38:46 +04:00
|
|
|
if ((int)(Mpos + sizeof prompt) < MSG_X)
|
1995-03-21 18:03:38 +03:00
|
|
|
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(' ');
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* wait_for
|
|
|
|
* Sit around until the guy types the right key
|
|
|
|
*/
|
2009-08-12 09:48:04 +04:00
|
|
|
static void
|
2005-07-02 12:32:32 +04:00
|
|
|
wait_for(int ch)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2005-04-20 00:12:07 +04:00
|
|
|
int c;
|
1995-03-21 18:03:38 +03:00
|
|
|
|
|
|
|
if (ch == '\n')
|
|
|
|
while ((c = readchar()) != '\n')
|
|
|
|
continue;
|
|
|
|
else
|
|
|
|
while (readchar() != ch)
|
|
|
|
continue;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* readchar:
|
|
|
|
* Reads and returns a character, checking for gross input errors
|
|
|
|
*/
|
2009-08-12 09:48:04 +04:00
|
|
|
static int
|
2005-07-02 12:32:32 +04:00
|
|
|
readchar(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1997-10-10 16:26:34 +04:00
|
|
|
int cnt;
|
2005-04-20 00:12:07 +04:00
|
|
|
unsigned char c;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
over:
|
1995-03-21 18:03:38 +03:00
|
|
|
cnt = 0;
|
2005-04-20 00:12:07 +04:00
|
|
|
while (read(STDIN_FILENO, &c, sizeof(unsigned char)) <= 0)
|
1995-03-21 18:03:38 +03:00
|
|
|
if (cnt++ > 100) { /* if we are getting infinite EOFs */
|
|
|
|
bye(); /* quit the game */
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (c == CTRL('L')) {
|
|
|
|
wrefresh(curscr);
|
|
|
|
goto over;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
1995-03-21 18:03:38 +03:00
|
|
|
if (c == '\r')
|
|
|
|
return ('\n');
|
|
|
|
else
|
|
|
|
return (c);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-07-13 23:05:39 +04:00
|
|
|
* get_line:
|
1993-03-21 12:45:37 +03:00
|
|
|
* Reads the next line up to '\n' or EOF. Multiple spaces are
|
|
|
|
* compressed to one space; a space is inserted before a ','
|
|
|
|
*/
|
|
|
|
char *
|
2009-07-13 23:05:39 +04:00
|
|
|
get_line(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2012-10-14 00:36:06 +04:00
|
|
|
size_t pos;
|
1997-10-10 16:26:34 +04:00
|
|
|
int c, oy, ox;
|
|
|
|
WINDOW *oscr;
|
1995-03-21 18:03:38 +03:00
|
|
|
|
|
|
|
oscr = stdscr;
|
|
|
|
stdscr = Msgwin;
|
|
|
|
getyx(stdscr, oy, ox);
|
|
|
|
refresh();
|
|
|
|
/* loop reading in the string, and put it in a temporary buffer */
|
2012-10-14 00:36:06 +04:00
|
|
|
for (pos = 0; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
|
1995-03-21 18:03:38 +03:00
|
|
|
if (c == erasechar()) { /* process erase character */
|
2012-10-14 00:36:06 +04:00
|
|
|
if (pos > 0) {
|
1997-10-10 16:26:34 +04:00
|
|
|
int i;
|
1995-03-21 18:03:38 +03:00
|
|
|
|
2012-10-14 00:36:06 +04:00
|
|
|
pos--;
|
|
|
|
for (i = strlen(unctrl(linebuf[pos])); i; i--)
|
1995-03-21 18:03:38 +03:00
|
|
|
addch('\b');
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
} else
|
|
|
|
if (c == killchar()) { /* process kill
|
|
|
|
* character */
|
2012-10-14 00:36:06 +04:00
|
|
|
pos = 0;
|
1995-03-21 18:03:38 +03:00
|
|
|
move(oy, ox);
|
|
|
|
continue;
|
|
|
|
} else
|
2012-10-14 00:36:06 +04:00
|
|
|
if (pos == 0 && c == ' ')
|
1995-03-21 18:03:38 +03:00
|
|
|
continue;
|
2012-10-14 00:36:06 +04:00
|
|
|
if (pos >= LINESIZE - 1 || !(isprint(c) || c == ' '))
|
1995-03-21 18:03:38 +03:00
|
|
|
putchar(CTRL('G'));
|
|
|
|
else {
|
|
|
|
if (islower(c))
|
|
|
|
c = toupper(c);
|
2012-10-14 00:36:06 +04:00
|
|
|
linebuf[pos++] = c;
|
1995-03-21 18:03:38 +03:00
|
|
|
addstr(unctrl(c));
|
|
|
|
Mpos++;
|
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
2012-10-14 00:36:06 +04:00
|
|
|
linebuf[pos] = '\0';
|
1995-03-21 18:03:38 +03:00
|
|
|
stdscr = oscr;
|
|
|
|
return (linebuf);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
1995-03-21 18:03:38 +03:00
|
|
|
void
|
2007-12-15 22:44:37 +03:00
|
|
|
receive_intr(int signo __unused)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
bye();
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bye:
|
|
|
|
* Leave the program, cleaning things up as we go.
|
|
|
|
*/
|
1995-03-21 18:03:38 +03:00
|
|
|
void
|
2005-07-02 12:32:32 +04:00
|
|
|
bye(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
signal(SIGINT, SIG_IGN);
|
|
|
|
mvcur(0, COLS - 1, LINES - 1, 0);
|
|
|
|
fflush(stdout);
|
|
|
|
endwin();
|
|
|
|
putchar('\n');
|
|
|
|
}
|