1377e2678Sbostic /*-
2*b209e5b3Sbostic * Copyright (c) 1993
3*b209e5b3Sbostic * The Regents of the University of California. All rights reserved.
4377e2678Sbostic *
5377e2678Sbostic * This code is derived from software contributed to Berkeley by
6377e2678Sbostic * Barry Brachman.
7377e2678Sbostic *
8377e2678Sbostic * %sccs.include.redist.c%
9377e2678Sbostic */
10377e2678Sbostic
11377e2678Sbostic #ifndef lint
12*b209e5b3Sbostic static char sccsid[] = "@(#)mach.c 8.1 (Berkeley) 06/11/93";
13377e2678Sbostic #endif /* not lint */
147ecd1e75Sbostic
157ecd1e75Sbostic /*
167ecd1e75Sbostic * Terminal interface
177ecd1e75Sbostic *
187ecd1e75Sbostic * Input is raw and unechoed
197ecd1e75Sbostic */
207ecd1e75Sbostic #include <ctype.h>
21377e2678Sbostic #include <curses.h>
22377e2678Sbostic #include <fcntl.h>
23377e2678Sbostic #include <sgtty.h>
24377e2678Sbostic #include <signal.h>
257ecd1e75Sbostic #include <stdio.h>
26377e2678Sbostic #include <stdlib.h>
27377e2678Sbostic #include <time.h>
287ecd1e75Sbostic
297ecd1e75Sbostic #include "bog.h"
30377e2678Sbostic #include "extern.h"
317ecd1e75Sbostic
327ecd1e75Sbostic static int ccol, crow, maxw;
337ecd1e75Sbostic static int colstarts[MAXCOLS], ncolstarts;
347ecd1e75Sbostic static int lastline;
357ecd1e75Sbostic int ncols, nlines;
367ecd1e75Sbostic
377ecd1e75Sbostic extern char *pword[], *mword[];
38377e2678Sbostic extern int ngames, nmwords, npwords, tnmwords, tnpwords;
39377e2678Sbostic
40377e2678Sbostic static void cont_catcher __P((int));
41377e2678Sbostic static int prwidth __P((char *[], int));
42377e2678Sbostic static void prword __P((char *[], int));
43377e2678Sbostic static void stop_catcher __P((int));
44377e2678Sbostic static void tty_cleanup __P((void));
45377e2678Sbostic static int tty_setup __P((void));
46377e2678Sbostic static void tty_showboard __P((char *));
47377e2678Sbostic static void winch_catcher __P((int));
487ecd1e75Sbostic
497ecd1e75Sbostic /*
507ecd1e75Sbostic * Do system dependent initialization
517ecd1e75Sbostic * This is called once, when the program starts
527ecd1e75Sbostic */
53377e2678Sbostic int
setup(sflag,seed)547ecd1e75Sbostic setup(sflag, seed)
557ecd1e75Sbostic int sflag;
567ecd1e75Sbostic long seed;
577ecd1e75Sbostic {
587ecd1e75Sbostic extern int debug;
597ecd1e75Sbostic
607ecd1e75Sbostic if (tty_setup() < 0)
617ecd1e75Sbostic return(-1);
627ecd1e75Sbostic
637ecd1e75Sbostic if (!sflag)
647ecd1e75Sbostic time(&seed);
657ecd1e75Sbostic srandom(seed);
667ecd1e75Sbostic if (debug)
677ecd1e75Sbostic (void) printf("seed = %ld\n", seed);
687ecd1e75Sbostic return(0);
697ecd1e75Sbostic }
707ecd1e75Sbostic
717ecd1e75Sbostic /*
727ecd1e75Sbostic * Do system dependent clean up
737ecd1e75Sbostic * This is called once, just before the program terminates
747ecd1e75Sbostic */
75377e2678Sbostic void
cleanup()767ecd1e75Sbostic cleanup()
777ecd1e75Sbostic {
787ecd1e75Sbostic tty_cleanup();
797ecd1e75Sbostic }
807ecd1e75Sbostic
817ecd1e75Sbostic /*
827ecd1e75Sbostic * Display the player's word list, the list of words not found, and the running
837ecd1e75Sbostic * stats
847ecd1e75Sbostic */
85377e2678Sbostic void
results()867ecd1e75Sbostic results()
877ecd1e75Sbostic {
887ecd1e75Sbostic int col, row;
897ecd1e75Sbostic int denom1, denom2;
907ecd1e75Sbostic
917ecd1e75Sbostic move(LIST_LINE, LIST_COL);
927ecd1e75Sbostic clrtobot();
937ecd1e75Sbostic printw("Words you found (%d):", npwords);
947ecd1e75Sbostic refresh();
957ecd1e75Sbostic move(LIST_LINE + 1, LIST_COL);
967ecd1e75Sbostic prtable(pword, npwords, 0, ncols, prword, prwidth);
977ecd1e75Sbostic
987ecd1e75Sbostic getyx(stdscr, row, col);
997ecd1e75Sbostic move(row + 1, col);
1007ecd1e75Sbostic printw("Words you missed (%d):", nmwords);
1017ecd1e75Sbostic refresh();
1027ecd1e75Sbostic move(row + 2, col);
1037ecd1e75Sbostic prtable(mword, nmwords, 0, ncols, prword, prwidth);
1047ecd1e75Sbostic
1057ecd1e75Sbostic denom1 = npwords + nmwords;
1067ecd1e75Sbostic denom2 = tnpwords + tnmwords;
1077ecd1e75Sbostic
1087ecd1e75Sbostic move(SCORE_LINE, SCORE_COL);
1097ecd1e75Sbostic printw("Percentage: %0.2f%% (%0.2f%% over %d game%s)\n",
1107ecd1e75Sbostic denom1 ? (100.0 * npwords) / (double) (npwords + nmwords) : 0.0,
1117ecd1e75Sbostic denom2 ? (100.0 * tnpwords) / (double) (tnpwords + tnmwords) : 0.0,
1127ecd1e75Sbostic ngames, ngames > 1 ? "s" : "");
1137ecd1e75Sbostic }
1147ecd1e75Sbostic
115377e2678Sbostic static void
prword(base,indx)116377e2678Sbostic prword(base, indx)
117377e2678Sbostic char *base[];
118377e2678Sbostic int indx;
1197ecd1e75Sbostic {
120377e2678Sbostic printw("%s", base[indx]);
1217ecd1e75Sbostic }
1227ecd1e75Sbostic
123377e2678Sbostic static int
prwidth(base,indx)124377e2678Sbostic prwidth(base, indx)
125377e2678Sbostic char *base[];
126377e2678Sbostic int indx;
1277ecd1e75Sbostic {
128377e2678Sbostic return (strlen(base[indx]));
1297ecd1e75Sbostic }
1307ecd1e75Sbostic
1317ecd1e75Sbostic /*
1327ecd1e75Sbostic * Main input routine
1337ecd1e75Sbostic *
1347ecd1e75Sbostic * - doesn't accept words longer than MAXWORDLEN or containing caps
1357ecd1e75Sbostic */
1367ecd1e75Sbostic char *
getline(q)1377ecd1e75Sbostic getline(q)
1387ecd1e75Sbostic char *q;
1397ecd1e75Sbostic {
1407ecd1e75Sbostic register int ch, done;
1417ecd1e75Sbostic register char *p;
1427ecd1e75Sbostic int row, col;
1437ecd1e75Sbostic
1447ecd1e75Sbostic p = q;
1457ecd1e75Sbostic done = 0;
1467ecd1e75Sbostic while (!done) {
147377e2678Sbostic ch = timerch();
1487ecd1e75Sbostic switch (ch) {
1497ecd1e75Sbostic case '\n':
1507ecd1e75Sbostic case '\r':
1517ecd1e75Sbostic case ' ':
1527ecd1e75Sbostic done = 1;
1537ecd1e75Sbostic break;
1547ecd1e75Sbostic case '\033':
1557ecd1e75Sbostic findword();
1567ecd1e75Sbostic break;
1577ecd1e75Sbostic case '\177': /* <del> */
1587ecd1e75Sbostic case '\010': /* <bs> */
1597ecd1e75Sbostic if (p == q)
1607ecd1e75Sbostic break;
1617ecd1e75Sbostic p--;
1627ecd1e75Sbostic getyx(stdscr, row, col);
1637ecd1e75Sbostic move(row, col - 1);
1647ecd1e75Sbostic clrtoeol();
1657ecd1e75Sbostic refresh();
1667ecd1e75Sbostic break;
1677ecd1e75Sbostic case '\025': /* <^u> */
1687ecd1e75Sbostic case '\027': /* <^w> */
1697ecd1e75Sbostic if (p == q)
1707ecd1e75Sbostic break;
1717ecd1e75Sbostic getyx(stdscr, row, col);
1727ecd1e75Sbostic move(row, col - (int) (p - q));
1737ecd1e75Sbostic p = q;
1747ecd1e75Sbostic clrtoeol();
1757ecd1e75Sbostic refresh();
1767ecd1e75Sbostic break;
1777ecd1e75Sbostic #ifdef SIGTSTP
1787ecd1e75Sbostic case '\032': /* <^z> */
179377e2678Sbostic stop_catcher(0);
1807ecd1e75Sbostic break;
1817ecd1e75Sbostic #endif
1827ecd1e75Sbostic case '\023': /* <^s> */
1837ecd1e75Sbostic stoptime();
1847ecd1e75Sbostic printw("<PAUSE>");
1857ecd1e75Sbostic refresh();
1867ecd1e75Sbostic while ((ch = inputch()) != '\021' && ch != '\023')
1877ecd1e75Sbostic ;
1887ecd1e75Sbostic move(crow, ccol);
1897ecd1e75Sbostic clrtoeol();
1907ecd1e75Sbostic refresh();
1917ecd1e75Sbostic starttime();
1927ecd1e75Sbostic break;
1937ecd1e75Sbostic case '\003': /* <^c> */
1947ecd1e75Sbostic cleanup();
1957ecd1e75Sbostic exit(0);
1967ecd1e75Sbostic /*NOTREACHED*/
1977ecd1e75Sbostic case '\004': /* <^d> */
1987ecd1e75Sbostic done = 1;
1997ecd1e75Sbostic ch = EOF;
2007ecd1e75Sbostic break;
2017ecd1e75Sbostic case '\014': /* <^l> */
2027ecd1e75Sbostic case '\022': /* <^r> */
2037ecd1e75Sbostic redraw();
2047ecd1e75Sbostic break;
2057ecd1e75Sbostic case '?':
2067ecd1e75Sbostic stoptime();
2077ecd1e75Sbostic if (help() < 0)
2087ecd1e75Sbostic showstr("Can't open help file", 1);
2097ecd1e75Sbostic starttime();
2107ecd1e75Sbostic break;
2117ecd1e75Sbostic default:
2127ecd1e75Sbostic if (!islower(ch))
2137ecd1e75Sbostic break;
2147ecd1e75Sbostic if ((int) (p - q) == MAXWORDLEN) {
2157ecd1e75Sbostic p = q;
2167ecd1e75Sbostic badword();
2177ecd1e75Sbostic break;
2187ecd1e75Sbostic }
2197ecd1e75Sbostic *p++ = ch;
2207ecd1e75Sbostic addch(ch);
2217ecd1e75Sbostic refresh();
2227ecd1e75Sbostic break;
2237ecd1e75Sbostic }
2247ecd1e75Sbostic }
2257ecd1e75Sbostic *p = '\0';
2267ecd1e75Sbostic if (ch == EOF)
2277ecd1e75Sbostic return((char *) NULL);
2287ecd1e75Sbostic return(q);
2297ecd1e75Sbostic }
2307ecd1e75Sbostic
231377e2678Sbostic int
inputch()2327ecd1e75Sbostic inputch()
2337ecd1e75Sbostic {
2347ecd1e75Sbostic return (getch() & 0177);
2357ecd1e75Sbostic }
2367ecd1e75Sbostic
237377e2678Sbostic void
redraw()2387ecd1e75Sbostic redraw()
2397ecd1e75Sbostic {
2407ecd1e75Sbostic clearok(stdscr, 1);
2417ecd1e75Sbostic refresh();
2427ecd1e75Sbostic }
2437ecd1e75Sbostic
244377e2678Sbostic void
flushin(fp)2457ecd1e75Sbostic flushin(fp)
2467ecd1e75Sbostic FILE *fp;
2477ecd1e75Sbostic {
2487ecd1e75Sbostic int arg;
2497ecd1e75Sbostic
2507ecd1e75Sbostic arg = FREAD;
2517ecd1e75Sbostic (void)ioctl(fileno(fp), TIOCFLUSH, &arg);
2527ecd1e75Sbostic }
2537ecd1e75Sbostic
2547ecd1e75Sbostic static int gone;
2557ecd1e75Sbostic
2567ecd1e75Sbostic /*
2577ecd1e75Sbostic * Stop the game timer
2587ecd1e75Sbostic */
259377e2678Sbostic void
stoptime()2607ecd1e75Sbostic stoptime()
2617ecd1e75Sbostic {
2627ecd1e75Sbostic extern long start_t;
263377e2678Sbostic long t;
2647ecd1e75Sbostic
265377e2678Sbostic (void)time(&t);
2667ecd1e75Sbostic gone = (int) (t - start_t);
2677ecd1e75Sbostic }
2687ecd1e75Sbostic
2697ecd1e75Sbostic /*
2707ecd1e75Sbostic * Restart the game timer
2717ecd1e75Sbostic */
272377e2678Sbostic void
starttime()2737ecd1e75Sbostic starttime()
2747ecd1e75Sbostic {
2757ecd1e75Sbostic extern long start_t;
276377e2678Sbostic long t;
2777ecd1e75Sbostic
278377e2678Sbostic (void)time(&t);
2797ecd1e75Sbostic start_t = t - (long) gone;
2807ecd1e75Sbostic }
2817ecd1e75Sbostic
2827ecd1e75Sbostic /*
2837ecd1e75Sbostic * Initialize for the display of the player's words as they are typed
2847ecd1e75Sbostic * This display starts at (LIST_LINE, LIST_COL) and goes "down" until the last
2857ecd1e75Sbostic * line. After the last line a new column is started at LIST_LINE
2867ecd1e75Sbostic * Keep track of each column position for showword()
2877ecd1e75Sbostic * There is no check for exceeding COLS
2887ecd1e75Sbostic */
289377e2678Sbostic void
startwords()2907ecd1e75Sbostic startwords()
2917ecd1e75Sbostic {
2927ecd1e75Sbostic crow = LIST_LINE;
2937ecd1e75Sbostic ccol = LIST_COL;
2947ecd1e75Sbostic maxw = 0;
2957ecd1e75Sbostic ncolstarts = 1;
2967ecd1e75Sbostic colstarts[0] = LIST_COL;
2977ecd1e75Sbostic move(LIST_LINE, LIST_COL);
2987ecd1e75Sbostic refresh();
2997ecd1e75Sbostic }
3007ecd1e75Sbostic
3017ecd1e75Sbostic /*
3027ecd1e75Sbostic * Add a word to the list and start a new column if necessary
3037ecd1e75Sbostic * The maximum width of the current column is maintained so we know where
3047ecd1e75Sbostic * to start the next column
3057ecd1e75Sbostic */
306377e2678Sbostic void
addword(w)3077ecd1e75Sbostic addword(w)
3087ecd1e75Sbostic char *w;
3097ecd1e75Sbostic {
3107ecd1e75Sbostic int n;
3117ecd1e75Sbostic
3127ecd1e75Sbostic if (crow == lastline) {
3137ecd1e75Sbostic crow = LIST_LINE;
3147ecd1e75Sbostic ccol += (maxw + 5);
3157ecd1e75Sbostic colstarts[ncolstarts++] = ccol;
3167ecd1e75Sbostic maxw = 0;
3177ecd1e75Sbostic move(crow, ccol);
3187ecd1e75Sbostic }
3197ecd1e75Sbostic else {
3207ecd1e75Sbostic move(++crow, ccol);
3217ecd1e75Sbostic if ((n = strlen(w)) > maxw)
3227ecd1e75Sbostic maxw = n;
3237ecd1e75Sbostic }
3247ecd1e75Sbostic refresh();
3257ecd1e75Sbostic }
3267ecd1e75Sbostic
3277ecd1e75Sbostic /*
3287ecd1e75Sbostic * The current word is unacceptable so erase it
3297ecd1e75Sbostic */
330377e2678Sbostic void
badword()3317ecd1e75Sbostic badword()
3327ecd1e75Sbostic {
3337ecd1e75Sbostic
3347ecd1e75Sbostic move(crow, ccol);
3357ecd1e75Sbostic clrtoeol();
3367ecd1e75Sbostic refresh();
3377ecd1e75Sbostic }
3387ecd1e75Sbostic
3397ecd1e75Sbostic /*
3407ecd1e75Sbostic * Highlight the nth word in the list (starting with word 0)
3417ecd1e75Sbostic * No check for wild arg
3427ecd1e75Sbostic */
343377e2678Sbostic void
showword(n)3447ecd1e75Sbostic showword(n)
3457ecd1e75Sbostic int n;
3467ecd1e75Sbostic {
3477ecd1e75Sbostic int col, row;
3487ecd1e75Sbostic
3497ecd1e75Sbostic row = LIST_LINE + n % (lastline - LIST_LINE + 1);
3507ecd1e75Sbostic col = colstarts[n / (lastline - LIST_LINE + 1)];
3517ecd1e75Sbostic move(row, col);
3527ecd1e75Sbostic standout();
3537ecd1e75Sbostic printw("%s", pword[n]);
3547ecd1e75Sbostic standend();
3557ecd1e75Sbostic move(crow, ccol);
3567ecd1e75Sbostic refresh();
3577ecd1e75Sbostic delay(15);
3587ecd1e75Sbostic move(row, col);
3597ecd1e75Sbostic printw("%s", pword[n]);
3607ecd1e75Sbostic move(crow, ccol);
3617ecd1e75Sbostic refresh();
3627ecd1e75Sbostic }
3637ecd1e75Sbostic
3647ecd1e75Sbostic /*
3657ecd1e75Sbostic * Get a word from the user and check if it is in either of the two
3667ecd1e75Sbostic * word lists
3677ecd1e75Sbostic * If it's found, show the word on the board for a short time and then
3687ecd1e75Sbostic * erase the word
3697ecd1e75Sbostic *
3707ecd1e75Sbostic * Note: this function knows about the format of the board
3717ecd1e75Sbostic */
372377e2678Sbostic void
findword()3737ecd1e75Sbostic findword()
3747ecd1e75Sbostic {
3757ecd1e75Sbostic int c, col, found, i, r, row;
3767ecd1e75Sbostic char buf[MAXWORDLEN + 1];
3777ecd1e75Sbostic extern char board[];
3787ecd1e75Sbostic extern int usedbits, wordpath[];
3797ecd1e75Sbostic extern char *mword[], *pword[];
3807ecd1e75Sbostic extern int nmwords, npwords;
3817ecd1e75Sbostic
3827ecd1e75Sbostic getyx(stdscr, r, c);
3837ecd1e75Sbostic getword(buf);
3847ecd1e75Sbostic found = 0;
3857ecd1e75Sbostic for (i = 0; i < npwords; i++) {
3867ecd1e75Sbostic if (strcmp(buf, pword[i]) == 0) {
3877ecd1e75Sbostic found = 1;
3887ecd1e75Sbostic break;
3897ecd1e75Sbostic }
3907ecd1e75Sbostic }
3917ecd1e75Sbostic if (!found) {
3927ecd1e75Sbostic for (i = 0; i < nmwords; i++) {
3937ecd1e75Sbostic if (strcmp(buf, mword[i]) == 0) {
3947ecd1e75Sbostic found = 1;
3957ecd1e75Sbostic break;
3967ecd1e75Sbostic }
3977ecd1e75Sbostic }
3987ecd1e75Sbostic }
3997ecd1e75Sbostic for (i = 0; i < MAXWORDLEN; i++)
4007ecd1e75Sbostic wordpath[i] = -1;
4017ecd1e75Sbostic usedbits = 0;
4027ecd1e75Sbostic if (!found || checkword(buf, -1, wordpath) == -1) {
4037ecd1e75Sbostic move(r, c);
4047ecd1e75Sbostic clrtoeol();
4057ecd1e75Sbostic addstr("[???]");
4067ecd1e75Sbostic refresh();
4077ecd1e75Sbostic delay(10);
4087ecd1e75Sbostic move(r, c);
4097ecd1e75Sbostic clrtoeol();
4107ecd1e75Sbostic refresh();
4117ecd1e75Sbostic return;
4127ecd1e75Sbostic }
4137ecd1e75Sbostic
4147ecd1e75Sbostic standout();
4157ecd1e75Sbostic for (i = 0; wordpath[i] != -1; i++) {
4167ecd1e75Sbostic row = BOARD_LINE + (wordpath[i] / 4) * 2 + 1;
4177ecd1e75Sbostic col = BOARD_COL + (wordpath[i] % 4) * 4 + 2;
4187ecd1e75Sbostic move(row, col);
4197ecd1e75Sbostic if (board[wordpath[i]] == 'q')
4207ecd1e75Sbostic printw("Qu");
4217ecd1e75Sbostic else
4227ecd1e75Sbostic printw("%c", toupper(board[wordpath[i]]));
4237ecd1e75Sbostic move(r, c);
4247ecd1e75Sbostic refresh();
4257ecd1e75Sbostic delay(5);
4267ecd1e75Sbostic }
4277ecd1e75Sbostic
4287ecd1e75Sbostic standend();
4297ecd1e75Sbostic
4307ecd1e75Sbostic for (i = 0; wordpath[i] != -1; i++) {
4317ecd1e75Sbostic row = BOARD_LINE + (wordpath[i] / 4) * 2 + 1;
4327ecd1e75Sbostic col = BOARD_COL + (wordpath[i] % 4) * 4 + 2;
4337ecd1e75Sbostic move(row, col);
4347ecd1e75Sbostic if (board[wordpath[i]] == 'q')
4357ecd1e75Sbostic printw("Qu");
4367ecd1e75Sbostic else
4377ecd1e75Sbostic printw("%c", toupper(board[wordpath[i]]));
4387ecd1e75Sbostic }
4397ecd1e75Sbostic move(r, c);
4407ecd1e75Sbostic clrtoeol();
4417ecd1e75Sbostic refresh();
4427ecd1e75Sbostic }
4437ecd1e75Sbostic
4447ecd1e75Sbostic /*
4457ecd1e75Sbostic * Display a string at the current cursor position for the given number of secs
4467ecd1e75Sbostic */
447377e2678Sbostic void
showstr(str,delaysecs)4487ecd1e75Sbostic showstr(str, delaysecs)
4497ecd1e75Sbostic char *str;
4507ecd1e75Sbostic int delaysecs;
4517ecd1e75Sbostic {
4527ecd1e75Sbostic addstr(str);
4537ecd1e75Sbostic refresh();
4547ecd1e75Sbostic delay(delaysecs * 10);
4557ecd1e75Sbostic move(crow, ccol);
4567ecd1e75Sbostic clrtoeol();
4577ecd1e75Sbostic refresh();
4587ecd1e75Sbostic }
4597ecd1e75Sbostic
460377e2678Sbostic void
putstr(s)4617ecd1e75Sbostic putstr(s)
4627ecd1e75Sbostic char *s;
4637ecd1e75Sbostic {
4647ecd1e75Sbostic addstr(s);
4657ecd1e75Sbostic }
4667ecd1e75Sbostic
4677ecd1e75Sbostic /*
4687ecd1e75Sbostic * Get a valid word and put it in the buffer
4697ecd1e75Sbostic */
470377e2678Sbostic void
getword(q)4717ecd1e75Sbostic getword(q)
4727ecd1e75Sbostic char *q;
4737ecd1e75Sbostic {
4747ecd1e75Sbostic int ch, col, done, i, row;
4757ecd1e75Sbostic char *p;
4767ecd1e75Sbostic
4777ecd1e75Sbostic done = 0;
4787ecd1e75Sbostic i = 0;
4797ecd1e75Sbostic p = q;
4807ecd1e75Sbostic addch('[');
4817ecd1e75Sbostic refresh();
4827ecd1e75Sbostic while (!done && i < MAXWORDLEN - 1) {
4837ecd1e75Sbostic ch = getch() & 0177;
4847ecd1e75Sbostic switch (ch) {
4857ecd1e75Sbostic case '\177': /* <del> */
4867ecd1e75Sbostic case '\010': /* <bs> */
4877ecd1e75Sbostic if (p == q)
4887ecd1e75Sbostic break;
4897ecd1e75Sbostic p--;
4907ecd1e75Sbostic getyx(stdscr, row, col);
4917ecd1e75Sbostic move(row, col - 1);
4927ecd1e75Sbostic clrtoeol();
4937ecd1e75Sbostic break;
4947ecd1e75Sbostic case '\025': /* <^u> */
4957ecd1e75Sbostic case '\027': /* <^w> */
4967ecd1e75Sbostic if (p == q)
4977ecd1e75Sbostic break;
4987ecd1e75Sbostic getyx(stdscr, row, col);
4997ecd1e75Sbostic move(row, col - (int) (p - q));
5007ecd1e75Sbostic p = q;
5017ecd1e75Sbostic clrtoeol();
5027ecd1e75Sbostic break;
5037ecd1e75Sbostic case ' ':
5047ecd1e75Sbostic case '\n':
5057ecd1e75Sbostic case '\r':
5067ecd1e75Sbostic done = 1;
5077ecd1e75Sbostic break;
5087ecd1e75Sbostic case '\014': /* <^l> */
5097ecd1e75Sbostic case '\022': /* <^r> */
5107ecd1e75Sbostic clearok(stdscr, 1);
5117ecd1e75Sbostic refresh();
5127ecd1e75Sbostic break;
5137ecd1e75Sbostic default:
5147ecd1e75Sbostic if (islower(ch)) {
5157ecd1e75Sbostic *p++ = ch;
5167ecd1e75Sbostic addch(ch);
5177ecd1e75Sbostic i++;
5187ecd1e75Sbostic }
5197ecd1e75Sbostic break;
5207ecd1e75Sbostic }
5217ecd1e75Sbostic refresh();
5227ecd1e75Sbostic }
5237ecd1e75Sbostic *p = '\0';
5247ecd1e75Sbostic addch(']');
5257ecd1e75Sbostic refresh();
5267ecd1e75Sbostic }
5277ecd1e75Sbostic
528377e2678Sbostic void
showboard(b)5297ecd1e75Sbostic showboard(b)
5307ecd1e75Sbostic char *b;
5317ecd1e75Sbostic {
5327ecd1e75Sbostic tty_showboard(b);
5337ecd1e75Sbostic }
5347ecd1e75Sbostic
535377e2678Sbostic void
prompt(mesg)5367ecd1e75Sbostic prompt(mesg)
5377ecd1e75Sbostic char *mesg;
5387ecd1e75Sbostic {
5397ecd1e75Sbostic move(PROMPT_LINE, PROMPT_COL);
5407ecd1e75Sbostic printw("%s", mesg);
5417ecd1e75Sbostic move(PROMPT_LINE + 1, PROMPT_COL);
5427ecd1e75Sbostic refresh();
5437ecd1e75Sbostic }
5447ecd1e75Sbostic
545377e2678Sbostic static int
tty_setup()5467ecd1e75Sbostic tty_setup()
5477ecd1e75Sbostic {
5487ecd1e75Sbostic initscr();
5497ecd1e75Sbostic raw();
5507ecd1e75Sbostic noecho();
5517ecd1e75Sbostic
5527ecd1e75Sbostic /*
5537ecd1e75Sbostic * Does curses look at the winsize structure?
5547ecd1e75Sbostic * Should handle SIGWINCH ...
5557ecd1e75Sbostic */
5567ecd1e75Sbostic nlines = LINES;
5577ecd1e75Sbostic lastline = nlines - 1;
5587ecd1e75Sbostic ncols = COLS;
5597ecd1e75Sbostic
5607ecd1e75Sbostic (void) signal(SIGTSTP, stop_catcher);
5617ecd1e75Sbostic (void) signal(SIGCONT, cont_catcher);
5627ecd1e75Sbostic (void) signal(SIGWINCH, winch_catcher);
5637ecd1e75Sbostic return(0);
5647ecd1e75Sbostic }
5657ecd1e75Sbostic
566377e2678Sbostic static void
stop_catcher(signo)567377e2678Sbostic stop_catcher(signo)
568377e2678Sbostic int signo;
5697ecd1e75Sbostic {
5707ecd1e75Sbostic stoptime();
5717ecd1e75Sbostic noraw();
5727ecd1e75Sbostic echo();
5737ecd1e75Sbostic move(nlines - 1, 0);
5747ecd1e75Sbostic refresh();
5757ecd1e75Sbostic
5767ecd1e75Sbostic (void) signal(SIGTSTP, SIG_DFL);
5777ecd1e75Sbostic (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP-1)));
5787ecd1e75Sbostic (void) kill(0, SIGTSTP);
5797ecd1e75Sbostic (void) signal(SIGTSTP, stop_catcher);
5807ecd1e75Sbostic }
5817ecd1e75Sbostic
582377e2678Sbostic static void
cont_catcher(signo)583377e2678Sbostic cont_catcher(signo)
584377e2678Sbostic int signo;
5857ecd1e75Sbostic {
5867ecd1e75Sbostic (void) signal(SIGCONT, cont_catcher);
5877ecd1e75Sbostic noecho();
5887ecd1e75Sbostic raw();
5897ecd1e75Sbostic clearok(stdscr, 1);
5907ecd1e75Sbostic move(crow, ccol);
5917ecd1e75Sbostic refresh();
5927ecd1e75Sbostic starttime();
5937ecd1e75Sbostic }
5947ecd1e75Sbostic
5957ecd1e75Sbostic /*
5967ecd1e75Sbostic * The signal is caught but nothing is done about it...
5977ecd1e75Sbostic * It would mean reformatting the entire display
5987ecd1e75Sbostic */
599377e2678Sbostic static void
winch_catcher(signo)600377e2678Sbostic winch_catcher(signo)
601377e2678Sbostic int signo;
6027ecd1e75Sbostic {
6037ecd1e75Sbostic struct winsize win;
6047ecd1e75Sbostic
6057ecd1e75Sbostic (void) signal(SIGWINCH, winch_catcher);
6067ecd1e75Sbostic (void) ioctl(fileno(stdout), TIOCGWINSZ, &win);
6077ecd1e75Sbostic /*
6087ecd1e75Sbostic LINES = win.ws_row;
6097ecd1e75Sbostic COLS = win.ws_col;
6107ecd1e75Sbostic */
6117ecd1e75Sbostic }
6127ecd1e75Sbostic
613377e2678Sbostic static void
tty_cleanup()6147ecd1e75Sbostic tty_cleanup()
6157ecd1e75Sbostic {
6167ecd1e75Sbostic move(nlines - 1, 0);
6177ecd1e75Sbostic refresh();
6187ecd1e75Sbostic noraw();
6197ecd1e75Sbostic echo();
6207ecd1e75Sbostic endwin();
6217ecd1e75Sbostic }
6227ecd1e75Sbostic
623377e2678Sbostic static void
tty_showboard(b)6247ecd1e75Sbostic tty_showboard(b)
6257ecd1e75Sbostic char *b;
6267ecd1e75Sbostic {
6277ecd1e75Sbostic register int i;
6287ecd1e75Sbostic int line;
6297ecd1e75Sbostic
6307ecd1e75Sbostic clear();
6317ecd1e75Sbostic move(BOARD_LINE, BOARD_COL);
6327ecd1e75Sbostic line = BOARD_LINE;
6337ecd1e75Sbostic printw("+---+---+---+---+");
6347ecd1e75Sbostic move(++line, BOARD_COL);
6357ecd1e75Sbostic for (i = 0; i < 16; i++) {
6367ecd1e75Sbostic if (b[i] == 'q')
6377ecd1e75Sbostic printw("| Qu");
6387ecd1e75Sbostic else
6397ecd1e75Sbostic printw("| %c ", toupper(b[i]));
6407ecd1e75Sbostic if ((i + 1) % 4 == 0) {
6417ecd1e75Sbostic printw("|");
6427ecd1e75Sbostic move(++line, BOARD_COL);
6437ecd1e75Sbostic printw("+---+---+---+---+");
6447ecd1e75Sbostic move(++line, BOARD_COL);
6457ecd1e75Sbostic }
6467ecd1e75Sbostic }
6477ecd1e75Sbostic move(SCORE_LINE, SCORE_COL);
6487ecd1e75Sbostic printw("Type '?' for help");
6497ecd1e75Sbostic refresh();
6507ecd1e75Sbostic }
651