|
|
1.1 root 1: /*
2: * Hunt
3: * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
4: * San Francisco, California
5: *
6: * Copyright (c) 1985 Regents of the University of California.
7: * All rights reserved. The Berkeley software License Agreement
8: * specifies the terms and conditions for redistribution.
9: */
10:
11: # include <curses.h>
12: # include <ctype.h>
13: # include <signal.h>
14: # include <errno.h>
15: # include "hunt.h"
16: # include <sys/file.h>
17:
18: # undef CTRL
19: # define CTRL(x) ('x' & 037)
20:
21: int input();
22: static int nchar_send;
23: static int in = FREAD;
24: char screen[24][80], blanks[80];
25: int cur_row, cur_col;
26: # ifdef OTTO
27: int Otto_count;
28: int Otto_mode;
29: static int otto_y, otto_x;
30: static char otto_face;
31: # endif OTTO
32:
33: # define MAX_SEND 5
34:
35: /*
36: * ibuf is the input buffer used for the stream from the driver.
37: * It is small because we do not check for user input when there
38: * are characters in the input buffer.
39: */
40: static char ibuf[20];
41:
42: #define GETCHR(fd) (--(fd)->_cnt >= 0 ? *(fd)->_ptr++&0377 : getchr(fd))
43:
44: /*
45: * playit:
46: * Play a given game, handling all the curses commands from
47: * the driver.
48: */
49: playit()
50: {
51: register FILE *inf;
52: register int ch;
53: register unsigned int y, x;
54: extern int Master_pid;
55: extern int errno;
56: extern int _putchar();
57:
58: errno = 0;
59: while ((inf = fdopen(Socket, "r")) == NULL)
60: if (errno == EINTR)
61: errno = 0;
62: else {
63: perror("fdopen of socket");
64: exit(1);
65: }
66: setbuffer(inf, ibuf, sizeof ibuf);
67: Master_pid = getw(inf);
68: if (Master_pid == 0 || Master_pid == EOF) {
69: bad_con();
70: /* NOTREACHED */
71: }
72: # ifdef OTTO
73: Otto_count = 0;
74: # endif OTTO
75: nchar_send = MAX_SEND;
76: while ((ch = GETCHR(inf)) != EOF) {
77: # ifdef DEBUG
78: fputc(ch, stderr);
79: # endif DEBUG
80: switch (ch & 0377) {
81: case MOVE:
82: y = GETCHR(inf);
83: x = GETCHR(inf);
84: mvcur(cur_row, cur_col, y, x);
85: cur_row = y;
86: cur_col = x;
87: break;
88: case ADDCH:
89: ch = GETCHR(inf);
90: # ifdef OTTO
91: switch (ch) {
92:
93: case '<':
94: case '>':
95: case '^':
96: case 'v':
97: otto_face = ch;
98: getyx(stdscr, otto_y, otto_x);
99: break;
100: }
101: # endif OTTO
102: put_ch(ch);
103: break;
104: case CLRTOEOL:
105: clear_eol();
106: break;
107: case CLEAR:
108: clear_screen();
109: break;
110: case REFRESH:
111: fflush(stdout);
112: break;
113: case REDRAW:
114: redraw_screen();
115: fflush(stdout);
116: break;
117: case ENDWIN:
118: fflush(stdout);
119: if ((ch = GETCHR(inf)) == LAST_PLAYER)
120: Last_player = TRUE;
121: ch = EOF;
122: goto out;
123: case BELL:
124: putchar(CTRL(G));
125: break;
126: case READY:
127: (void) fflush(stdout);
128: if (nchar_send < 0)
129: (void) ioctl(fileno(stdin), TIOCFLUSH, &in);
130: nchar_send = MAX_SEND;
131: # ifndef OTTO
132: (void) GETCHR(inf);
133: # else OTTO
134: Otto_count -= (GETCHR(inf) & 255);
135: if (!Am_monitor) {
136: # ifdef DEBUG
137: fputc('0' + Otto_count, stderr);
138: # endif DEBUG
139: if (Otto_count == 0 && Otto_mode)
140: otto(otto_y, otto_x, otto_face);
141: }
142: # endif OTTO
143: break;
144: default:
145: # ifdef OTTO
146: switch (ch) {
147:
148: case '<':
149: case '>':
150: case '^':
151: case 'v':
152: otto_face = ch;
153: getyx(stdscr, otto_y, otto_x);
154: break;
155: }
156: # endif OTTO
157: put_ch(ch);
158: break;
159: }
160: }
161: out:
162: (void) fclose(inf);
163: }
164:
165: /*
166: * getchr:
167: * Grab input and pass it along to the driver
168: * Return any characters from the driver
169: * When this routine is called by GETCHR, we already know there are
170: * no characters in the input buffer.
171: */
172: getchr(fd)
173: register FILE *fd;
174: {
175: long nchar;
176: long readfds, s_readfds;
177: int driver_mask, stdin_mask;
178: int nfds, s_nfds;
179:
180: driver_mask = 1L << fileno(fd);
181: stdin_mask = 1L << fileno(stdin);
182: s_readfds = driver_mask | stdin_mask;
183: s_nfds = (driver_mask > stdin_mask) ? driver_mask : stdin_mask;
184: s_nfds++;
185:
186: one_more_time:
187: do {
188: errno = 0;
189: readfds = s_readfds;
190: nfds = s_nfds;
191: # ifndef OLDIPC
192: nfds = select(nfds, &readfds, NULL, NULL, NULL);
193: # else OLDIPC
194: nfds = select(nfds, &readfds, (int *) NULL, 32767);
195: # endif OLDIPC
196: } while (nfds <= 0 && errno == EINTR);
197:
198: if (readfds & stdin_mask)
199: send_stuff();
200: if ((readfds & driver_mask) == 0)
201: goto one_more_time;
202: return _filbuf(fd);
203: }
204:
205: /*
206: * send_stuff:
207: * Send standard input characters to the driver
208: */
209: send_stuff()
210: {
211: register int count;
212: register char *sp, *nsp;
213: static char inp[sizeof Buf];
214: extern char map_key[256];
215:
216: count = read(fileno(stdin), Buf, sizeof Buf);
217: if (count <= 0)
218: return;
219: if (nchar_send <= 0) {
220: (void) write(1, "\7", 1);
221: return;
222: }
223:
224: /*
225: * look for 'q'uit commands; if we find one,
226: * confirm it. If it is not confirmed, strip
227: * it out of the input
228: */
229: Buf[count] = '\0';
230: nsp = inp;
231: for (sp = Buf; *sp != '\0'; sp++)
232: if ((*nsp = map_key[*sp]) == 'q')
233: intr();
234: # ifdef OTTO
235: else if (*nsp == CTRL(O))
236: Otto_mode = !Otto_mode;
237: # endif OTTO
238: else
239: nsp++;
240: count = nsp - inp;
241: if (count) {
242: # ifdef OTTO
243: Otto_count += count;
244: # endif OTTO
245: nchar_send -= count;
246: if (nchar_send < 0)
247: count += nchar_send;
248: (void) write(Socket, inp, count);
249: }
250: }
251:
252: /*
253: * quit:
254: * Handle the end of the game when the player dies
255: */
256: quit()
257: {
258: register int explain, ch;
259:
260: if (Last_player)
261: return TRUE;
262: # ifdef OTTO
263: if (Otto_mode)
264: return FALSE;
265: # endif OTTO
266: mvcur(cur_row, cur_col, HEIGHT, 0);
267: cur_row = HEIGHT;
268: cur_col = 0;
269: put_str("Re-enter game? ");
270: clear_eol();
271: fflush(stdout);
272: explain = FALSE;
273: for (;;) {
274: if (isupper(ch = getchar()))
275: ch = tolower(ch);
276: if (ch == 'y') {
277: sleep(2);
278: return FALSE;
279: }
280: else if (ch == 'n')
281: return TRUE;
282: (void) putchar(CTRL(G));
283: if (!explain) {
284: put_str("(Y or N) ");
285: explain = TRUE;
286: }
287: fflush(stdout);
288: }
289: }
290:
291: put_ch(ch)
292: char ch;
293: {
294: if (!isprint(ch)) {
295: fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch);
296: return;
297: }
298: screen[cur_row][cur_col] = ch;
299: putchar(ch);
300: if (++cur_col >= COLS) {
301: if (!AM || XN)
302: putchar('\n');
303: cur_col = 0;
304: if (++cur_row >= LINES)
305: cur_row = LINES;
306: }
307: }
308:
309: put_str(s)
310: char *s;
311: {
312: while (*s)
313: put_ch(*s++);
314: }
315:
316: clear_screen()
317: {
318: register int i;
319:
320: if (blanks[0] == '\0')
321: for (i = 0; i < 80; i++)
322: blanks[i] = ' ';
323:
324: if (CL != NULL) {
325: tputs(CL, LINES, _putchar);
326: for (i = 0; i < 24; i++)
327: bcopy(blanks, screen[i], 80);
328: } else {
329: for (i = 0; i < 24; i++) {
330: mvcur(cur_row, cur_col, i, 0);
331: cur_row = i;
332: cur_col = 0;
333: clear_eol();
334: }
335: mvcur(cur_row, cur_col, 0, 0);
336: }
337: cur_row = cur_col = 0;
338: }
339:
340: clear_eol()
341: {
342: if (CE != NULL)
343: tputs(CE, 1, _putchar);
344: else {
345: fwrite(blanks, sizeof (char), 80 - cur_col, stdout);
346: if (COLS != 80)
347: mvcur(cur_row, 80, cur_row, cur_col);
348: else if (AM)
349: mvcur(cur_row + 1, 0, cur_row, cur_col);
350: else
351: mvcur(cur_row, 79, cur_row, cur_col);
352: }
353: bcopy(blanks, &screen[cur_row][cur_col], 80 - cur_col);
354: }
355:
356: redraw_screen()
357: {
358: register int i;
359: static int first = 1;
360:
361: if (first) {
362: if ((curscr = newwin(24, 80, 0, 0)) == NULL) {
363: fprintf(stderr, "Can't create curscr\n");
364: exit(1);
365: }
366: for (i = 0; i < 24; i++)
367: curscr->_y[i] = screen[i];
368: first = 0;
369: }
370: curscr->_cury = cur_row;
371: curscr->_curx = cur_col;
372: wrefresh(curscr);
373: #ifdef NOCURSES
374: mvcur(cur_row, cur_col, 0, 0);
375: for (i = 0; i < 23; i++) {
376: fwrite(screen[i], sizeof (char), 80, stdout);
377: if (COLS > 80 || (COLS == 80 && !AM))
378: putchar('\n');
379: }
380: fwrite(screen[23], sizeof (char), 79, stdout);
381: mvcur(23, 79, cur_row, cur_col);
382: #endif
383: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.