1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33: #include <sys/cdefs.h>
34: #ifndef lint
35: __RCSID("$NetBSD: playit.c,v 1.8 2004/01/27 20:30:29 jsm Exp $");
36: #endif
37:
38: # include <sys/file.h>
39: # include <sys/poll.h>
40: # include <err.h>
41: # include <errno.h>
42: # include <curses.h>
43: # include <ctype.h>
44: # include <signal.h>
45: # include <sys/time.h>
46: # if defined(HPUX) || (defined(BSD_RELEASE) && BSD_RELEASE >= 44)
47: # include <termios.h>
48: # include <unistd.h>
49: # endif
50: # include "hunt.h"
51:
52: # ifndef FREAD
53: # define FREAD 1
54: # endif
55:
56: # if !defined(USE_CURSES) || !defined(TERMINFO)
57: # define beep() (void) putchar(CTRL('G'))
58: # endif
59: # if !defined(USE_CURSES)
60: # undef refresh
61: # define refresh() (void) fflush(stdout);
62: # endif
63: # ifdef USE_CURSES
64: # define clear_eol() clrtoeol()
65: # define put_ch addch
66: # define put_str addstr
67: # endif
68:
69: static int nchar_send;
70: # ifndef USE_CURSES
71: char screen[SCREEN_HEIGHT][SCREEN_WIDTH2], blanks[SCREEN_WIDTH];
72: int cur_row, cur_col;
73: # endif
74: # ifdef OTTO
75: int Otto_count;
76: int Otto_mode;
77: static int otto_y, otto_x;
78: static char otto_face;
79: # endif
80:
81: # define MAX_SEND 5
82: # define STDIN 0
83:
84:
85:
86:
87:
88:
89: static int icnt = 0;
90: static unsigned char ibuf[256], *iptr = ibuf;
91:
92: #define GETCHR() (--icnt < 0 ? getchr() : *iptr++)
93:
94: #if !defined(BSD_RELEASE) || BSD_RELEASE < 44
95: extern int _putchar();
96: #endif
97:
98: static unsigned char getchr(void);
99: static void send_stuff(void);
100:
101:
102:
103:
104:
105:
106: void
107: playit()
108: {
109: int ch;
110: int y, x;
111: u_int32_t version;
112:
113: if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) {
114: bad_con();
115:
116: }
117: if (ntohl(version) != (unsigned long)HUNT_VERSION) {
118: bad_ver();
119:
120: }
121: errno = 0;
122: # ifdef OTTO
123: Otto_count = 0;
124: # endif
125: nchar_send = MAX_SEND;
126: while ((ch = GETCHR()) != EOF) {
127: # ifdef DEBUG
128: fputc(ch, stderr);
129: # endif
130: switch (ch & 0377) {
131: case MOVE:
132: y = GETCHR();
133: x = GETCHR();
134: # ifdef USE_CURSES
135: move(y, x);
136: # else
137: mvcur(cur_row, cur_col, y, x);
138: cur_row = y;
139: cur_col = x;
140: # endif
141: break;
142: case ADDCH:
143: ch = GETCHR();
144: # ifdef OTTO
145: switch (ch) {
146:
147: case '<':
148: case '>':
149: case '^':
150: case 'v':
151: otto_face = ch;
152: # ifdef USE_CURSES
153: getyx(stdscr, otto_y, otto_x);
154: # else
155: otto_y = cur_row;
156: otto_x = cur_col;
157: # endif
158: break;
159: }
160: # endif
161: put_ch(ch);
162: break;
163: case CLRTOEOL:
164: clear_eol();
165: break;
166: case CLEAR:
167: clear_the_screen();
168: break;
169: case REFRESH:
170: refresh();
171: break;
172: case REDRAW:
173: redraw_screen();
174: refresh();
175: break;
176: case ENDWIN:
177: refresh();
178: if ((ch = GETCHR()) == LAST_PLAYER)
179: Last_player = TRUE;
180: ch = EOF;
181: goto out;
182: case BELL:
183: beep();
184: break;
185: case READY:
186: refresh();
187: if (nchar_send < 0)
188: # if defined(HPUX) || (defined(BSD_RELEASE) && BSD_RELEASE >= 44)
189: tcflush(STDIN, TCIFLUSH);
190: # else
191: # ifndef TCFLSH
192: (void) ioctl(STDIN, TIOCFLUSH, &in);
193: # else
194: (void) ioctl(STDIN, TCFLSH, 0);
195: # endif
196: # endif
197: nchar_send = MAX_SEND;
198: # ifndef OTTO
199: (void) GETCHR();
200: # else
201: Otto_count -= (GETCHR() & 0xff);
202: if (!Am_monitor) {
203: # ifdef DEBUG
204: fputc('0' + Otto_count, stderr);
205: # endif
206: if (Otto_count == 0 && Otto_mode)
207: otto(otto_y, otto_x, otto_face);
208: }
209: # endif
210: break;
211: default:
212: # ifdef OTTO
213: switch (ch) {
214:
215: case '<':
216: case '>':
217: case '^':
218: case 'v':
219: otto_face = ch;
220: # ifdef USE_CURSES
221: getyx(stdscr, otto_y, otto_x);
222: # else
223: otto_y = cur_row;
224: otto_x = cur_col;
225: # endif
226: break;
227: }
228: # endif
229: put_ch(ch);
230: break;
231: }
232: }
233: out:
234: (void) close(Socket);
235: }
236:
237:
238:
239:
240:
241:
242:
243:
244: static unsigned char
245: getchr()
246: {
247: struct pollfd set[2];
248: int nfds;
249:
250: set[0].fd = Socket;
251: set[0].events = POLLIN;
252: set[1].fd = STDIN;
253: set[1].events = POLLIN;
254:
255: one_more_time:
256: do {
257: errno = 0;
258: nfds = poll(set, 2, INFTIM);
259: } while (nfds <= 0 && errno == EINTR);
260:
261: if (set[1].revents && POLLIN)
262: send_stuff();
263: if (! (set[0].revents & POLLIN))
264: goto one_more_time;
265: icnt = read(Socket, ibuf, sizeof ibuf);
266: if (icnt < 0) {
267: bad_con();
268:
269: }
270: if (icnt == 0)
271: goto one_more_time;
272: iptr = ibuf;
273: icnt--;
274: return *iptr++;
275: }
276:
277:
278:
279:
280:
281: static void
282: send_stuff()
283: {
284: int count;
285: char *sp, *nsp;
286: static char inp[sizeof Buf];
287:
288: count = read(STDIN, Buf, sizeof Buf);
289: if (count <= 0)
290: return;
291: if (nchar_send <= 0 && !no_beep) {
292: (void) write(1, "\7", 1);
293: return;
294: }
295:
296:
297:
298:
299:
300:
301: Buf[count] = '\0';
302: nsp = inp;
303: for (sp = Buf; *sp != '\0'; sp++)
304: if ((*nsp = map_key[(int)*sp]) == 'q')
305: intr(0);
306: else
307: nsp++;
308: count = nsp - inp;
309: if (count) {
310: # ifdef OTTO
311: Otto_count += count;
312: # endif
313: nchar_send -= count;
314: if (nchar_send < 0)
315: count += nchar_send;
316: (void) write(Socket, inp, count);
317: }
318: }
319:
320:
321:
322:
323:
324: int
325: quit(old_status)
326: int old_status;
327: {
328: int explain, ch;
329:
330: if (Last_player)
331: return Q_QUIT;
332: # ifdef OTTO
333: if (Otto_mode)
334: return Q_CLOAK;
335: # endif
336: # ifdef USE_CURSES
337: move(HEIGHT, 0);
338: # else
339: mvcur(cur_row, cur_col, HEIGHT, 0);
340: cur_row = HEIGHT;
341: cur_col = 0;
342: # endif
343: put_str("Re-enter game [ynwo]? ");
344: clear_eol();
345: explain = FALSE;
346: for (;;) {
347: refresh();
348: if (isupper(ch = getchar()))
349: ch = tolower(ch);
350: if (ch == 'y')
351: return old_status;
352: else if (ch == 'o')
353: break;
354: else if (ch == 'n') {
355: # ifndef INTERNET
356: return Q_QUIT;
357: # else
358: # ifdef USE_CURSES
359: move(HEIGHT, 0);
360: # else
361: mvcur(cur_row, cur_col, HEIGHT, 0);
362: cur_row = HEIGHT;
363: cur_col = 0;
364: # endif
365: put_str("Write a parting message [yn]? ");
366: clear_eol();
367: refresh();
368: for (;;) {
369: if (isupper(ch = getchar()))
370: ch = tolower(ch);
371: if (ch == 'y')
372: goto get_message;
373: if (ch == 'n')
374: return Q_QUIT;
375: }
376: # endif
377: }
378: # ifdef INTERNET
379: else if (ch == 'w') {
380: static char buf[WIDTH + WIDTH % 2];
381: char *cp, c;
382:
383: get_message:
384: c = ch;
385: # ifdef USE_CURSES
386: move(HEIGHT, 0);
387: # else
388: mvcur(cur_row, cur_col, HEIGHT, 0);
389: cur_row = HEIGHT;
390: cur_col = 0;
391: # endif
392: put_str("Message: ");
393: clear_eol();
394: refresh();
395: cp = buf;
396: for (;;) {
397: refresh();
398: if ((ch = getchar()) == '\n' || ch == '\r')
399: break;
400: # if defined(TERMINFO) || BSD_RELEASE >= 44
401: if (ch == erasechar())
402: # else
403: if (ch == _tty.sg_erase)
404: # endif
405: {
406: if (cp > buf) {
407: # ifdef USE_CURSES
408: int y, x;
409: getyx(stdscr, y, x);
410: move(y, x - 1);
411: # else
412: mvcur(cur_row, cur_col, cur_row,
413: cur_col - 1);
414: cur_col -= 1;
415: # endif
416: cp -= 1;
417: clear_eol();
418: }
419: continue;
420: }
421: # if defined(TERMINFO) || BSD_RELEASE >= 44
422: else if (ch == killchar())
423: # else
424: else if (ch == _tty.sg_kill)
425: # endif
426: {
427: # ifdef USE_CURSES
428: int y, x;
429: getyx(stdscr, y, x);
430: move(y, x - (cp - buf));
431: # else
432: mvcur(cur_row, cur_col, cur_row,
433: cur_col - (cp - buf));
434: cur_col -= cp - buf;
435: # endif
436: cp = buf;
437: clear_eol();
438: continue;
439: } else if (!isprint(ch)) {
440: beep();
441: continue;
442: }
443: put_ch(ch);
444: *cp++ = ch;
445: if (cp + 1 >= buf + sizeof buf)
446: break;
447: }
448: *cp = '\0';
449: Send_message = buf;
450: return (c == 'w') ? old_status : Q_MESSAGE;
451: }
452: # endif
453: beep();
454: if (!explain) {
455: put_str("(Yes, No, Write message, or Options) ");
456: explain = TRUE;
457: }
458: }
459:
460: # ifdef USE_CURSES
461: move(HEIGHT, 0);
462: # else
463: mvcur(cur_row, cur_col, HEIGHT, 0);
464: cur_row = HEIGHT;
465: cur_col = 0;
466: # endif
467: # ifdef FLY
468: put_str("Scan, Cloak, Flying, or Quit? ");
469: # else
470: put_str("Scan, Cloak, or Quit? ");
471: # endif
472: clear_eol();
473: refresh();
474: explain = FALSE;
475: for (;;) {
476: if (isupper(ch = getchar()))
477: ch = tolower(ch);
478: if (ch == 's')
479: return Q_SCAN;
480: else if (ch == 'c')
481: return Q_CLOAK;
482: # ifdef FLY
483: else if (ch == 'f')
484: return Q_FLY;
485: # endif
486: else if (ch == 'q')
487: return Q_QUIT;
488: beep();
489: if (!explain) {
490: # ifdef FLY
491: put_str("[SCFQ] ");
492: # else
493: put_str("[SCQ] ");
494: # endif
495: explain = TRUE;
496: }
497: refresh();
498: }
499: }
500:
501: # ifndef USE_CURSES
502: void
503: put_ch(ch)
504: char ch;
505: {
506: if (!isprint(ch)) {
507: fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch);
508: return;
509: }
510: screen[cur_row][cur_col] = ch;
511: putchar(ch);
512: if (++cur_col >= COLS) {
513: if (!AM || XN)
514: putchar('\n');
515: cur_col = 0;
516: if (++cur_row >= LINES)
517: cur_row = LINES;
518: }
519: }
520:
521: void
522: put_str(s)
523: const char *s;
524: {
525: while (*s)
526: put_ch(*s++);
527: }
528: # endif
529:
530: void
531: clear_the_screen()
532: {
533: # ifdef USE_CURSES
534: clear();
535: move(0, 0);
536: refresh();
537: # else
538: int i;
539:
540: if (blanks[0] == '\0')
541: for (i = 0; i < SCREEN_WIDTH; i++)
542: blanks[i] = ' ';
543:
544: if (CL != NULL) {
545: #if !defined(BSD_RELEASE) || BSD_RELEASE < 44
546: tputs(CL, LINES, _putchar);