Commit | Line | Data |
---|---|---|
db16ccc5 C |
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 | } |