2 * Copyright (c) 1983-2003, Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University of California, San Francisco nor
15 * the names of its contributors may be used to endorse or promote
16 * products derived from this software without specific prior written
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * $OpenBSD: playit.c,v 1.8 2003/06/11 08:45:25 pjanzen Exp $
32 * $NetBSD: playit.c,v 1.4 1997/10/20 00:37:15 lukem Exp $
35 #include <sys/types.h>
37 #include <arpa/inet.h>
51 static int nchar_send;
52 static FLAG Last_player;
53 static int Otto_expect;
58 * ibuf is the input buffer used for the stream from the driver.
59 * It is small because we do not check for user input when there
60 * are characters in the input buffer.
63 static unsigned char ibuf[256], *iptr = ibuf;
65 #define GETCHR() (--icnt < 0 ? getchr() : *iptr++)
67 static unsigned char getchr(void);
68 static void send_stuff(void);
72 * Play a given game, handling all the curses commands from
85 if (read(Socket, &version, sizeof version) != sizeof version) {
89 if (ntohl(version) != (unsigned int)HUNT_VERSION) {
94 nchar_send = MAX_SEND;
96 while ((ch = GETCHR()) != EOF) {
108 display_clear_the_screen();
114 display_redraw_screen();
119 if ((ch = GETCHR()) == LAST_PLAYER)
127 chars_processed = GETCHR();
130 tcflush(STDIN_FILENO, TCIFLUSH);
131 nchar_send = MAX_SEND;
134 * The driver returns the number of keypresses
135 * that it has processed. Use this to figure
136 * out if otto's commands have completed.
138 Otto_expect -= chars_processed;
139 if (Otto_expect == 0) {
141 static char buf[MAX_SEND * 2];
144 /* Ask otto what it wants to do: */
145 len = otto(otto_y, otto_x, otto_face,
148 /* Pass it on to the driver: */
149 write(Socket, buf, len);
150 /* Update expectations: */
170 display_getyx(&otto_y, &otto_x);
183 * Grab input and pass it along to the driver
184 * Return any characters from the driver
185 * When this routine is called by GETCHR, we already know there are
186 * no characters in the input buffer.
191 fd_set readfds, s_readfds;
195 FD_SET(Socket, &s_readfds);
196 FD_SET(STDIN_FILENO, &s_readfds);
197 s_nfds = (Socket > STDIN_FILENO) ? Socket : STDIN_FILENO;
205 nfds = select(nfds, &readfds, NULL, NULL, NULL);
206 } while (nfds <= 0 && errno == EINTR);
208 if (FD_ISSET(STDIN_FILENO, &readfds))
210 if (!FD_ISSET(Socket, &readfds))
212 icnt = read(Socket, ibuf, sizeof ibuf);
224 * Send standard input characters to the driver
231 static char inp[BUFSIZ];
232 static char Buf[BUFSIZ];
234 /* Drain the user's keystrokes: */
235 count = read(STDIN_FILENO, Buf, sizeof Buf);
241 if (nchar_send <= 0 && !no_beep) {
247 * look for 'q'uit commands; if we find one,
248 * confirm it. If it is not confirmed, strip
249 * it out of the input
252 for (sp = Buf, nsp = inp; *sp != '\0'; sp++, nsp++) {
253 *nsp = map_key[(int)*sp];
262 write(Socket, inp, count);
265 * The user can insert commands over otto.
266 * So, otto shouldn't be alarmed when the
267 * server processes more than otto asks for.
269 Otto_expect += count;
276 * Handle the end of the game when the player dies
286 return otto_quit(old_status);
287 display_move(HEIGHT, 0);
288 display_put_str("Re-enter game [ynwo]? ");
293 if (isupper(ch = getchar()))
299 else if (ch == 'n') {
300 display_move(HEIGHT, 0);
301 display_put_str("Write a parting message [yn]? ");
305 if (isupper(ch = getchar()))
313 else if (ch == 'w') {
314 static char buf[WIDTH + WIDTH % 2];
318 c = ch; /* save how we got here */
319 display_move(HEIGHT, 0);
320 display_put_str("Message: ");
326 if ((ch = getchar()) == '\n' || ch == '\r')
328 if (display_iserasechar(ch))
333 display_getyx(&y, &x);
334 display_move(y, x - 1);
340 else if (display_iskillchar(ch))
344 display_getyx(&y, &x);
345 display_move(y, x - (cp - buf));
349 } else if (!isprint(ch)) {
355 if (cp + 1 >= buf + sizeof buf)
360 return (c == 'w') ? old_status : Q_MESSAGE;
364 display_put_str("(Yes, No, Write message, or Options) ");
369 display_move(HEIGHT, 0);
370 display_put_str("Scan, Cloak, Flying, or Quit? ");
375 if (isupper(ch = getchar()))
387 display_put_str("[SCFQ] ");
396 * Send a message to the driver and return
403 if (read(Socket, &version, sizeof version) != sizeof version) {
407 if (ntohl(version) != (unsigned int)HUNT_VERSION) {
411 if (write(Socket, Send_message, strlen(Send_message)) < 0) {