1 /* $OpenBSD: mach.c,v 1.22 2016/09/11 14:21:17 tb Exp $ */
2 /* $NetBSD: mach.c,v 1.5 1995/04/28 22:28:48 mycroft Exp $ */
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * Input is raw and unechoed
41 #include <sys/ioctl.h>
57 static int ccol, crow, maxw;
58 static int colstarts[MAXCOLS], ncolstarts;
59 static char *separator;
60 int ncols, nlines, lastline;
63 * The following determine the screen layout
80 static void cont_catcher(int);
81 static int prwidth(char **, int);
82 static void prword(char **, int);
83 static void stop_catcher(int);
84 static void tty_cleanup(void);
85 static int tty_setup(void);
86 static void tty_showboard(char *);
87 static void winch_catcher(int);
90 * Do system dependent initialization
91 * This is called once, when the program starts
101 separator = malloc(4 * grid + 2);
102 if (separator == NULL)
105 ep = separator + 4 * grid;
106 for (cp = separator; cp < ep;) {
115 SCORE_COL += (grid - 4) * 4;
116 TIMER_COL += (grid - 4) * 4;
117 PROMPT_COL += (grid - 4) * 4;
118 LIST_LINE += (grid - 4) * 2;
124 * Do system dependent clean up
125 * This is called once, just before the program terminates
134 * Display the player's word list, the list of words not found, and the running
143 move(LIST_LINE, LIST_COL);
145 printw("Words you found (%d):", npwords);
147 move(LIST_LINE + 1, LIST_COL);
148 prtable(pword, npwords, 0, ncols, prword, prwidth);
150 getyx(stdscr, row, col);
152 printw("Words you missed (%d):", nmwords);
155 prtable(mword, nmwords, 0, ncols, prword, prwidth);
157 denom1 = npwords + nmwords;
158 denom2 = tnpwords + tnmwords;
160 move(SCORE_LINE, SCORE_COL);
161 printw("Score: %d out of %d\n", npwords, denom1);
162 move(SCORE_LINE + 1, SCORE_COL);
163 printw("Percentage: %0.2f%% (%0.2f%% over %d game%s)\n",
164 denom1 ? (100.0 * npwords) / (double) denom1 : 0.0,
165 denom2 ? (100.0 * tnpwords) / (double) denom2 : 0.0,
166 ngames, ngames > 1 ? "s" : "");
167 move(TIMER_LINE, TIMER_COL);
172 prword(char **base, int indx)
174 printw("%s", base[indx]);
178 prwidth(char **base, int indx)
180 return (strlen(base[indx]));
186 * - doesn't accept words longer than MAXWORDLEN or containing caps
208 case '\177': /* <del> */
209 case '\010': /* <bs> */
213 getyx(stdscr, row, col);
218 case '\025': /* <^u> */
219 case '\027': /* <^w> */
222 getyx(stdscr, row, col);
223 move(row, col - (int) (p - q));
229 case '\032': /* <^z> */
233 case '\023': /* <^s> */
237 while ((ch = inputch()) != '\021' && ch != '\023')
244 case '\003': /* <^c> */
247 case '\004': /* <^d> */
251 case '\014': /* <^l> */
252 case '\022': /* <^r> */
258 showstr("Can't open help file", 1);
264 if ((int) (p - q) == MAXWORDLEN) {
286 if ((ch = getch()) == ERR)
287 err(1, "cannot read input");
301 tcflush(fileno(fp), TCIFLUSH);
305 * Stop the game timer
313 gone = (int) (t - start_t);
317 * Restart the game timer
325 start_t = t - (long) gone;
329 * Initialize for the display of the player's words as they are typed
330 * This display starts at (LIST_LINE, LIST_COL) and goes "down" until the last
331 * line. After the last line a new column is started at LIST_LINE
332 * Keep track of each column position for showword()
333 * There is no check for exceeding COLS
342 colstarts[0] = LIST_COL;
343 move(LIST_LINE, LIST_COL);
348 * Add a word to the list and start a new column if necessary
349 * The maximum width of the current column is maintained so we know where
350 * to start the next column
357 if (crow == lastline) {
360 colstarts[ncolstarts++] = ccol;
366 if ((n = strlen(w)) > maxw)
373 * The current word is unacceptable so erase it
384 * Highlight the nth word in the list (starting with word 0)
385 * No check for wild arg
392 row = LIST_LINE + n % (lastline - LIST_LINE + 1);
393 col = colstarts[n / (lastline - LIST_LINE + 1)];
396 printw("%s", pword[n]);
402 printw("%s", pword[n]);
408 * Walk the path of a word, refreshing the letters,
409 * optionally pausing after each
412 doword(int pause, int r, int c)
417 for (i = 0; wordpath[i] != -1; i++) {
418 row = BOARD_LINE + (wordpath[i] / 4) * 2 + 1;
419 col = BOARD_COL + (wordpath[i] % 4) * 4 + 2;
421 ch = board[wordpath[i]];
424 if (SEVENBIT(ch) == 'q')
427 printw("%c", toupper(SEVENBIT(ch)));
439 * Get a word from the user and check if it is in either of the two
441 * If it's found, show the word on the board for a short time and then
444 * Note: this function knows about the format of the board
450 char buf[MAXWORDLEN + 1];
455 for (i = 0; i < npwords; i++) {
456 if (strcmp(buf, pword[i]) == 0) {
462 for (i = 0; i < nmwords; i++) {
463 if (strcmp(buf, mword[i]) == 0) {
469 for (i = 0; i < MAXWORDLEN; i++)
472 if (!found || checkword(buf, -1, wordpath) == -1) {
495 * Display a string at the current cursor position for the given number of secs
498 showstr(const char *str, int delaysecs)
502 delay(delaysecs * 10);
515 * Get a valid word and put it in the buffer
520 int ch, col, done, i, row;
528 while (!done && i < MAXWORDLEN - 1) {
531 case '\177': /* <del> */
532 case '\010': /* <bs> */
536 getyx(stdscr, row, col);
540 case '\025': /* <^u> */
541 case '\027': /* <^w> */
544 getyx(stdscr, row, col);
545 move(row, col - (int) (p - q));
554 case '\014': /* <^l> */
555 case '\022': /* <^r> */
581 prompt(const char *mesg)
583 move(PROMPT_LINE, PROMPT_COL);
585 move(PROMPT_LINE + 1, PROMPT_COL);
597 * Does curses look at the winsize structure?
598 * Should handle SIGWINCH ...
601 lastline = nlines - 1;
604 signal(SIGTSTP, stop_catcher);
605 signal(SIGCONT, cont_catcher);
606 signal(SIGWINCH, winch_catcher);
611 stop_catcher(int signo __unused)
613 sigset_t sigset, osigset;
621 signal(SIGTSTP, SIG_DFL);
622 sigemptyset(&sigset);
623 sigaddset(&sigset, SIGTSTP);
624 sigprocmask(SIG_UNBLOCK, &sigset, &osigset);
626 sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0);
627 signal(SIGTSTP, stop_catcher);
631 cont_catcher(int signo __unused)
642 * The signal is caught but nothing is done about it...
643 * It would mean reformatting the entire display
646 winch_catcher(int signo __unused)
650 signal(SIGWINCH, winch_catcher);
651 ioctl(fileno(stdout), TIOCGWINSZ, &win);
669 tty_showboard(char *b)
676 move(BOARD_LINE, BOARD_COL);
679 move(++line, BOARD_COL);
680 for (i = 0; i < ncubes; i++) {
688 printw("%c ", toupper((unsigned char)ch));
691 if ((i + 1) % grid == 0) {
693 move(++line, BOARD_COL);
695 move(++line, BOARD_COL);
698 move(SCORE_LINE, SCORE_COL);
699 printw("Type '?' for help");