File: | src/games/hunt/hunt/playit.c |
Warning: | line 115, column 4 Value stored to 'ch' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: playit.c,v 1.13 2016/08/27 02:06:40 guenther Exp $ */ |
2 | /* $NetBSD: playit.c,v 1.4 1997/10/20 00:37:15 lukem Exp $ */ |
3 | /* |
4 | * Copyright (c) 1983-2003, Regents of the University of California. |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions are |
9 | * met: |
10 | * |
11 | * + Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * + Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. |
16 | * + Neither the name of the University of California, San Francisco nor |
17 | * the names of its contributors may be used to endorse or promote |
18 | * products derived from this software without specific prior written |
19 | * permission. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ |
33 | |
34 | #include <sys/select.h> |
35 | #include <ctype.h> |
36 | #include <err.h> |
37 | #include <errno(*__errno()).h> |
38 | #include <stdio.h> |
39 | #include <string.h> |
40 | #include <termios.h> |
41 | #include <unistd.h> |
42 | |
43 | #include "display.h" |
44 | #include "hunt.h" |
45 | #include "client.h" |
46 | |
47 | static int nchar_send; |
48 | static FLAG Last_player; |
49 | static int Otto_expect; |
50 | |
51 | # define MAX_SEND5 5 |
52 | |
53 | /* |
54 | * ibuf is the input buffer used for the stream from the driver. |
55 | * It is small because we do not check for user input when there |
56 | * are characters in the input buffer. |
57 | */ |
58 | static int icnt = 0; |
59 | static unsigned char ibuf[256], *iptr = ibuf; |
60 | |
61 | #define GETCHR()(--icnt < 0 ? getchr() : *iptr++) (--icnt < 0 ? getchr() : *iptr++) |
62 | |
63 | static unsigned char getchr(void); |
64 | static void send_stuff(void); |
65 | |
66 | /* |
67 | * playit: |
68 | * Play a given game, handling all the curses commands from |
69 | * the driver. |
70 | */ |
71 | void |
72 | playit(void) |
73 | { |
74 | int ch; |
75 | int y, x; |
76 | u_int32_t version; |
77 | int otto_y, otto_x; |
78 | char otto_face = ' '; |
79 | int chars_processed; |
80 | |
81 | if (read(Socket, &version, sizeof version) != sizeof version) { |
82 | bad_con(); |
83 | } |
84 | if (ntohl(version)(__uint32_t)(__builtin_constant_p(version) ? (__uint32_t)(((__uint32_t )(version) & 0xff) << 24 | ((__uint32_t)(version) & 0xff00) << 8 | ((__uint32_t)(version) & 0xff0000) >> 8 | ((__uint32_t)(version) & 0xff000000) >> 24) : __swap32md (version)) != HUNT_VERSION(-1)) { |
85 | bad_ver(); |
86 | } |
87 | errno(*__errno()) = 0; |
88 | nchar_send = MAX_SEND5; |
89 | Otto_expect = 0; |
90 | while ((ch = GETCHR()(--icnt < 0 ? getchr() : *iptr++)) != EOF(-1)) { |
91 | switch (ch & 0377) { |
92 | case MOVE('m' | 0200): |
93 | y = GETCHR()(--icnt < 0 ? getchr() : *iptr++); |
94 | x = GETCHR()(--icnt < 0 ? getchr() : *iptr++); |
95 | display_move(y, x); |
96 | break; |
97 | |
98 | case CLRTOEOL('c' | 0200): |
99 | display_clear_eol(); |
100 | break; |
101 | case CLEAR('C' | 0200): |
102 | display_clear_the_screen(); |
103 | break; |
104 | case REFRESH('r' | 0200): |
105 | display_refresh(); |
106 | break; |
107 | case REDRAW('R' | 0200): |
108 | display_redraw_screen(); |
109 | display_refresh(); |
110 | break; |
111 | case ENDWIN('e' | 0200): |
112 | display_refresh(); |
113 | if ((ch = GETCHR()(--icnt < 0 ? getchr() : *iptr++)) == LAST_PLAYER('l' | 0200)) |
114 | Last_player = TRUE1; |
115 | ch = EOF(-1); |
Value stored to 'ch' is never read | |
116 | goto out; |
117 | case BELL('b' | 0200): |
118 | display_beep(); |
119 | break; |
120 | case READY('g' | 0200): |
121 | chars_processed = GETCHR()(--icnt < 0 ? getchr() : *iptr++); |
122 | display_refresh(); |
123 | if (nchar_send < 0) |
124 | tcflush(STDIN_FILENO0, TCIFLUSH1); |
125 | nchar_send = MAX_SEND5; |
126 | if (Otto_mode) { |
127 | /* |
128 | * The driver returns the number of keypresses |
129 | * that it has processed. Use this to figure |
130 | * out if otto's commands have completed. |
131 | */ |
132 | Otto_expect -= chars_processed; |
133 | if (Otto_expect == 0) { |
134 | /* not very fair! */ |
135 | static char buf[MAX_SEND5 * 2]; |
136 | int len; |
137 | |
138 | /* Ask otto what it wants to do: */ |
139 | len = otto(otto_y, otto_x, otto_face, |
140 | buf, sizeof buf); |
141 | if (len) { |
142 | /* Pass it on to the driver: */ |
143 | write(Socket, buf, len); |
144 | /* Update expectations: */ |
145 | Otto_expect += len; |
146 | } |
147 | } |
148 | } |
149 | break; |
150 | case ADDCH('a' | 0200): |
151 | ch = GETCHR()(--icnt < 0 ? getchr() : *iptr++); |
152 | /* FALLTHROUGH */ |
153 | default: |
154 | if (!isprint(ch)) |
155 | ch = ' '; |
156 | display_put_ch(ch); |
157 | if (Otto_mode) |
158 | switch (ch) { |
159 | case '<': |
160 | case '>': |
161 | case '^': |
162 | case 'v': |
163 | otto_face = ch; |
164 | display_getyx(&otto_y, &otto_x); |
165 | otto_x--; |
166 | break; |
167 | } |
168 | break; |
169 | } |
170 | } |
171 | out: |
172 | (void) close(Socket); |
173 | } |
174 | |
175 | /* |
176 | * getchr: |
177 | * Grab input and pass it along to the driver |
178 | * Return any characters from the driver |
179 | * When this routine is called by GETCHR, we already know there are |
180 | * no characters in the input buffer. |
181 | */ |
182 | static unsigned char |
183 | getchr(void) |
184 | { |
185 | fd_set readfds, s_readfds; |
186 | int nfds, s_nfds; |
187 | |
188 | FD_ZERO(&s_readfds)do { fd_set *_p = (&s_readfds); __size_t _n = (((1024) + ( (((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof (__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[--_n] = 0; } while (0); |
189 | FD_SET(Socket, &s_readfds)__fd_set((Socket), (&s_readfds)); |
190 | FD_SET(STDIN_FILENO, &s_readfds)__fd_set((0), (&s_readfds)); |
191 | s_nfds = (Socket > STDIN_FILENO0) ? Socket : STDIN_FILENO0; |
192 | s_nfds++; |
193 | |
194 | one_more_time: |
195 | do { |
196 | errno(*__errno()) = 0; |
197 | readfds = s_readfds; |
198 | nfds = s_nfds; |
199 | nfds = select(nfds, &readfds, NULL((void *)0), NULL((void *)0), NULL((void *)0)); |
200 | } while (nfds <= 0 && errno(*__errno()) == EINTR4); |
201 | |
202 | if (FD_ISSET(STDIN_FILENO, &readfds)__fd_isset((0), (&readfds))) |
203 | send_stuff(); |
204 | if (!FD_ISSET(Socket, &readfds)__fd_isset((Socket), (&readfds))) |
205 | goto one_more_time; |
206 | icnt = read(Socket, ibuf, sizeof ibuf); |
207 | if (icnt <= 0) { |
208 | bad_con(); |
209 | } |
210 | iptr = ibuf; |
211 | icnt--; |
212 | return *iptr++; |
213 | } |
214 | |
215 | /* |
216 | * send_stuff: |
217 | * Send standard input characters to the driver |
218 | */ |
219 | static void |
220 | send_stuff(void) |
221 | { |
222 | int count; |
223 | char *sp, *nsp; |
224 | static char inp[BUFSIZ1024]; |
225 | static char Buf[BUFSIZ1024]; |
226 | |
227 | /* Drain the user's keystrokes: */ |
228 | count = read(STDIN_FILENO0, Buf, sizeof Buf); |
229 | if (count < 0) |
230 | err(1, "read"); |
231 | if (count == 0) |
232 | return; |
233 | |
234 | if (nchar_send <= 0 && !no_beep) { |
235 | display_beep(); |
236 | return; |
237 | } |
238 | |
239 | /* |
240 | * look for 'q'uit commands; if we find one, |
241 | * confirm it. If it is not confirmed, strip |
242 | * it out of the input |
243 | */ |
244 | Buf[count] = '\0'; |
245 | for (sp = Buf, nsp = inp; *sp != '\0'; sp++, nsp++) { |
246 | *nsp = map_key[(int)*sp]; |
247 | if (*nsp == 'q') |
248 | intr(0); |
249 | } |
250 | count = nsp - inp; |
251 | if (count) { |
252 | nchar_send -= count; |
253 | if (nchar_send < 0) |
254 | count += nchar_send; |
255 | (void) write(Socket, inp, count); |
256 | if (Otto_mode) { |
257 | /* |
258 | * The user can insert commands over otto. |
259 | * So, otto shouldn't be alarmed when the |
260 | * server processes more than otto asks for. |
261 | */ |
262 | Otto_expect += count; |
263 | } |
264 | } |
265 | } |
266 | |
267 | /* |
268 | * quit: |
269 | * Handle the end of the game when the player dies |
270 | */ |
271 | int |
272 | quit(int old_status) |
273 | { |
274 | int explain, ch; |
275 | |
276 | if (Last_player) |
277 | return Q_QUIT0; |
278 | if (Otto_mode) |
279 | return otto_quit(old_status); |
280 | display_move(HEIGHT23, 0); |
281 | display_put_str("Re-enter game [ynwo]? "); |
282 | display_clear_eol(); |
283 | explain = FALSE0; |
284 | for (;;) { |
285 | display_refresh(); |
286 | if (isupper(ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0]))))) |
287 | ch = tolower(ch); |
288 | if (ch == 'y') |
289 | return old_status; |
290 | else if (ch == 'o') |
291 | break; |
292 | else if (ch == 'n') { |
293 | display_move(HEIGHT23, 0); |
294 | display_put_str("Write a parting message [yn]? "); |
295 | display_clear_eol(); |
296 | display_refresh(); |
297 | for (;;) { |
298 | if (isupper(ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0]))))) |
299 | ch = tolower(ch); |
300 | if (ch == 'y') |
301 | goto get_message; |
302 | if (ch == 'n') |
303 | return Q_QUIT0; |
304 | } |
305 | } |
306 | else if (ch == 'w') { |
307 | static char buf[WIDTH51 + WIDTH51 % 2]; |
308 | char *cp, c; |
309 | |
310 | get_message: |
311 | c = ch; /* save how we got here */ |
312 | display_move(HEIGHT23, 0); |
313 | display_put_str("Message: "); |
314 | display_clear_eol(); |
315 | display_refresh(); |
316 | cp = buf; |
317 | for (;;) { |
318 | display_refresh(); |
319 | if ((ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0])))) == '\n' || ch == '\r') |
320 | break; |
321 | if (display_iserasechar(ch)) |
322 | { |
323 | if (cp > buf) { |
324 | int y, x; |
325 | |
326 | display_getyx(&y, &x); |
327 | display_move(y, x - 1); |
328 | cp -= 1; |
329 | display_clear_eol(); |
330 | } |
331 | continue; |
332 | } |
333 | else if (display_iskillchar(ch)) |
334 | { |
335 | int y, x; |
336 | |
337 | display_getyx(&y, &x); |
338 | display_move(y, x - (cp - buf)); |
339 | cp = buf; |
340 | display_clear_eol(); |
341 | continue; |
342 | } else if (!isprint(ch)) { |
343 | display_beep(); |
344 | continue; |
345 | } |
346 | display_put_ch(ch); |
347 | *cp++ = ch; |
348 | if (cp + 1 >= buf + sizeof buf) |
349 | break; |
350 | } |
351 | *cp = '\0'; |
352 | Send_message = buf; |
353 | return (c == 'w') ? old_status : Q_MESSAGE4; |
354 | } |
355 | display_beep(); |
356 | if (!explain) { |
357 | display_put_str("(Yes, No, Write message, or Options) "); |
358 | explain = TRUE1; |
359 | } |
360 | } |
361 | |
362 | display_move(HEIGHT23, 0); |
363 | display_put_str("Scan, Cloak, Flying, or Quit? "); |
364 | display_clear_eol(); |
365 | display_refresh(); |
366 | explain = FALSE0; |
367 | for (;;) { |
368 | if (isupper(ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0]))))) |
369 | ch = tolower(ch); |
370 | if (ch == 's') |
371 | return Q_SCAN3; |
372 | else if (ch == 'c') |
373 | return Q_CLOAK1; |
374 | else if (ch == 'f') |
375 | return Q_FLY2; |
376 | else if (ch == 'q') |
377 | return Q_QUIT0; |
378 | display_beep(); |
379 | if (!explain) { |
380 | display_put_str("[SCFQ] "); |
381 | explain = TRUE1; |
382 | } |
383 | display_refresh(); |
384 | } |
385 | } |
386 | |
387 | /* |
388 | * do_message: |
389 | * Send a message to the driver and return |
390 | */ |
391 | void |
392 | do_message(void) |
393 | { |
394 | u_int32_t version; |
395 | |
396 | if (read(Socket, &version, sizeof version) != sizeof version) { |
397 | bad_con(); |
398 | } |
399 | if (ntohl(version)(__uint32_t)(__builtin_constant_p(version) ? (__uint32_t)(((__uint32_t )(version) & 0xff) << 24 | ((__uint32_t)(version) & 0xff00) << 8 | ((__uint32_t)(version) & 0xff0000) >> 8 | ((__uint32_t)(version) & 0xff000000) >> 24) : __swap32md (version)) != HUNT_VERSION(-1)) { |
400 | bad_ver(); |
401 | } |
402 | if (write(Socket, Send_message, strlen(Send_message)) < 0) { |
403 | bad_con(); |
404 | } |
405 | (void) close(Socket); |
406 | } |