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 $
33 * $DragonFly: src/games/hunt/hunt/playit.c,v 1.2 2008/09/04 16:12:51 swildner Exp $
36 #include <sys/types.h>
38 #include <arpa/inet.h>
52 static int nchar_send
;
53 static FLAG Last_player
;
54 static int Otto_expect
;
59 * ibuf is the input buffer used for the stream from the driver.
60 * It is small because we do not check for user input when there
61 * are characters in the input buffer.
64 static unsigned char ibuf
[256], *iptr
= ibuf
;
66 #define GETCHR() (--icnt < 0 ? getchr() : *iptr++)
68 static unsigned char getchr(void);
69 static void send_stuff(void);
73 * Play a given game, handling all the curses commands from
86 if (read(Socket
, &version
, sizeof version
) != sizeof version
) {
90 if (ntohl(version
) != (unsigned int)HUNT_VERSION
) {
95 nchar_send
= MAX_SEND
;
97 while ((ch
= GETCHR()) != EOF
) {
109 display_clear_the_screen();
115 display_redraw_screen();
120 if ((ch
= GETCHR()) == LAST_PLAYER
)
128 chars_processed
= GETCHR();
131 tcflush(STDIN_FILENO
, TCIFLUSH
);
132 nchar_send
= MAX_SEND
;
135 * The driver returns the number of keypresses
136 * that it has processed. Use this to figure
137 * out if otto's commands have completed.
139 Otto_expect
-= chars_processed
;
140 if (Otto_expect
== 0) {
142 static char buf
[MAX_SEND
* 2];
145 /* Ask otto what it wants to do: */
146 len
= otto(otto_y
, otto_x
, otto_face
,
149 /* Pass it on to the driver: */
150 write(Socket
, buf
, len
);
151 /* Update expectations: */
171 display_getyx(&otto_y
, &otto_x
);
179 (void) close(Socket
);
184 * Grab input and pass it along to the driver
185 * Return any characters from the driver
186 * When this routine is called by GETCHR, we already know there are
187 * no characters in the input buffer.
192 fd_set readfds
, s_readfds
;
196 FD_SET(Socket
, &s_readfds
);
197 FD_SET(STDIN_FILENO
, &s_readfds
);
198 s_nfds
= (Socket
> STDIN_FILENO
) ? Socket
: STDIN_FILENO
;
206 nfds
= select(nfds
, &readfds
, NULL
, NULL
, NULL
);
207 } while (nfds
<= 0 && errno
== EINTR
);
209 if (FD_ISSET(STDIN_FILENO
, &readfds
))
211 if (!FD_ISSET(Socket
, &readfds
))
213 icnt
= read(Socket
, ibuf
, sizeof ibuf
);
225 * Send standard input characters to the driver
232 static char inp
[BUFSIZ
];
233 static char Buf
[BUFSIZ
];
235 /* Drain the user's keystrokes: */
236 count
= read(STDIN_FILENO
, Buf
, sizeof Buf
);
242 if (nchar_send
<= 0 && !no_beep
) {
248 * look for 'q'uit commands; if we find one,
249 * confirm it. If it is not confirmed, strip
250 * it out of the input
253 for (sp
= Buf
, nsp
= inp
; *sp
!= '\0'; sp
++, nsp
++) {
254 *nsp
= map_key
[(int)*sp
];
263 (void) write(Socket
, inp
, count
);
266 * The user can insert commands over otto.
267 * So, otto shouldn't be alarmed when the
268 * server processes more than otto asks for.
270 Otto_expect
+= count
;
277 * Handle the end of the game when the player dies
287 return otto_quit(old_status
);
288 display_move(HEIGHT
, 0);
289 display_put_str("Re-enter game [ynwo]? ");
294 if (isupper(ch
= getchar()))
300 else if (ch
== 'n') {
301 display_move(HEIGHT
, 0);
302 display_put_str("Write a parting message [yn]? ");
306 if (isupper(ch
= getchar()))
314 else if (ch
== 'w') {
315 static char buf
[WIDTH
+ WIDTH
% 2];
319 c
= ch
; /* save how we got here */
320 display_move(HEIGHT
, 0);
321 display_put_str("Message: ");
327 if ((ch
= getchar()) == '\n' || ch
== '\r')
329 if (display_iserasechar(ch
))
334 display_getyx(&y
, &x
);
335 display_move(y
, x
- 1);
341 else if (display_iskillchar(ch
))
345 display_getyx(&y
, &x
);
346 display_move(y
, x
- (cp
- buf
));
350 } else if (!isprint(ch
)) {
356 if (cp
+ 1 >= buf
+ sizeof buf
)
361 return (c
== 'w') ? old_status
: Q_MESSAGE
;
365 display_put_str("(Yes, No, Write message, or Options) ");
370 display_move(HEIGHT
, 0);
371 display_put_str("Scan, Cloak, Flying, or Quit? ");
376 if (isupper(ch
= getchar()))
388 display_put_str("[SCFQ] ");
397 * Send a message to the driver and return
404 if (read(Socket
, &version
, sizeof version
) != sizeof version
) {
408 if (ntohl(version
) != (unsigned int)HUNT_VERSION
) {
412 if (write(Socket
, Send_message
, strlen(Send_message
)) < 0) {
416 (void) close(Socket
);