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) {