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 * + Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * + 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 * + 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);