File: | src/games/hunt/hunt/playit.c |
Warning: | line 139, column 12 1st function call argument is an uninitialized value |
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); | |||
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 | } |