]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - phantasia/io.c
don't xref obsolete regcmp(3)
[bsdgames-darwin.git] / phantasia / io.c
1 /* $NetBSD: io.c,v 1.2 1995/03/24 03:58:50 cgd Exp $ */
2
3 /*
4 * io.c - input/output routines for Phantasia
5 */
6
7 #include "include.h"
8
9 /************************************************************************
10 /
11 / FUNCTION NAME: getstring()
12 /
13 / FUNCTION: read a string from operator
14 /
15 / AUTHOR: E. A. Estes, 12/4/85
16 /
17 / ARGUMENTS:
18 / char *cp - pointer to buffer area to fill
19 / int mx - maximum number of characters to put in buffer
20 /
21 / RETURN VALUE: none
22 /
23 / MODULES CALLED: wmove(), _filbuf(), clearok(), waddstr(), wrefresh(),
24 / wclrtoeol()
25 /
26 / GLOBAL INPUTS: Echo, _iob[], Wizard, *stdscr
27 /
28 / GLOBAL OUTPUTS: _iob[]
29 /
30 / DESCRIPTION:
31 / Read a string from the keyboard.
32 / This routine is specially designed to:
33 /
34 / - strip non-printing characters (unless Wizard)
35 / - echo, if desired
36 / - redraw the screen if CH_REDRAW is entered
37 / - read in only 'mx - 1' characters or less characters
38 / - nul-terminate string, and throw away newline
39 /
40 / 'mx' is assumed to be at least 2.
41 /
42 /************************************************************************/
43
44 getstring(cp, mx)
45 register char *cp;
46 register int mx;
47 {
48 register char *inptr; /* pointer into string for next string */
49 int x, y; /* original x, y coordinates on screen */
50 int ch; /* input */
51
52 getyx(stdscr, y, x); /* get coordinates on screen */
53 inptr = cp;
54 *inptr = '\0'; /* clear string to start */
55 --mx; /* reserve room in string for nul terminator */
56
57 do
58 /* get characters and process */
59 {
60 if (Echo)
61 mvaddstr(y, x, cp); /* print string on screen */
62 clrtoeol(); /* clear any data after string */
63 refresh(); /* update screen */
64
65 ch = getchar(); /* get character */
66
67 switch (ch)
68 {
69 case CH_ERASE: /* back up one character */
70 if (inptr > cp)
71 --inptr;
72 break;
73
74 case CH_KILL: /* back up to original location */
75 inptr = cp;
76 break;
77
78 case CH_NEWLINE: /* terminate string */
79 break;
80
81 case CH_REDRAW: /* redraw screen */
82 clearok(stdscr, TRUE);
83 continue;
84
85 default: /* put data in string */
86 if (ch >= ' ' || Wizard)
87 /* printing char; put in string */
88 *inptr++ = ch;
89 }
90
91 *inptr = '\0'; /* terminate string */
92 }
93 while (ch != CH_NEWLINE && inptr < cp + mx);
94 }
95 /*\f*/
96 /************************************************************************
97 /
98 / FUNCTION NAME: more()
99 /
100 / FUNCTION: pause and prompt player
101 /
102 / AUTHOR: E. A. Estes, 12/4/85
103 /
104 / ARGUMENTS:
105 / int where - line on screen on which to pause
106 /
107 / RETURN VALUE: none
108 /
109 / MODULES CALLED: wmove(), waddstr(), getanswer()
110 /
111 / GLOBAL INPUTS: *stdscr
112 /
113 / GLOBAL OUTPUTS: none
114 /
115 / DESCRIPTION:
116 / Print a message, and wait for a space character.
117 /
118 /************************************************************************/
119
120 more(where)
121 int where;
122 {
123 mvaddstr(where, 0, "-- more --");
124 getanswer(" ", FALSE);
125 }
126 /*\f*/
127 /************************************************************************
128 /
129 / FUNCTION NAME: infloat()
130 /
131 / FUNCTION: input a floating point number from operator
132 /
133 / AUTHOR: E. A. Estes, 12/4/85
134 /
135 / ARGUMENTS: none
136 /
137 / RETURN VALUE: floating point number from operator
138 /
139 / MODULES CALLED: sscanf(), getstring()
140 /
141 / GLOBAL INPUTS: Databuf[]
142 /
143 / GLOBAL OUTPUTS: none
144 /
145 / DESCRIPTION:
146 / Read a string from player, and scan for a floating point
147 / number.
148 / If no valid number is found, return 0.0.
149 /
150 /************************************************************************/
151
152 double
153 infloat()
154 {
155 double result; /* return value */
156
157 getstring(Databuf, SZ_DATABUF);
158 if (sscanf(Databuf, "%lf", &result) < 1)
159 /* no valid number entered */
160 result = 0.0;
161
162 return(result);
163 }
164 /*\f*/
165 /************************************************************************
166 /
167 / FUNCTION NAME: inputoption()
168 /
169 / FUNCTION: input an option value from player
170 /
171 / AUTHOR: E. A. Estes, 12/4/85
172 /
173 / ARGUMENTS: none
174 /
175 / RETURN VALUE: none
176 /
177 / MODULES CALLED: floor(), drandom(), getanswer()
178 /
179 / GLOBAL INPUTS: Player
180 /
181 / GLOBAL OUTPUTS: Player
182 /
183 / DESCRIPTION:
184 / Age increases with every move.
185 / Refresh screen, and get a single character option from player.
186 / Return a random value if player's ring has gone bad.
187 /
188 /************************************************************************/
189
190 inputoption()
191 {
192 ++Player.p_age; /* increase age */
193
194 if (Player.p_ring.ring_type != R_SPOILED)
195 /* ring ok */
196 return(getanswer("T ", TRUE));
197 else
198 /* bad ring */
199 {
200 getanswer(" ", TRUE);
201 return((int) ROLL(0.0, 5.0) + '0');
202 }
203 }
204 /*\f*/
205 /************************************************************************
206 /
207 / FUNCTION NAME: interrupt()
208 /
209 / FUNCTION: handle interrupt from operator
210 /
211 / AUTHOR: E. A. Estes, 12/4/85
212 /
213 / ARGUMENTS: none
214 /
215 / RETURN VALUE: none
216 /
217 / MODULES CALLED: fork(), exit(), wait(), death(), alarm(), execl(), wmove(),
218 / getgid(), signal(), getenv(), wclear(), setuid(), getuid(), setgid(),
219 / crmode(), clearok(), waddstr(), cleanup(), wrefresh(), leavegame(),
220 / getanswer()
221 /
222 / GLOBAL INPUTS: Player, *stdscr
223 /
224 / GLOBAL OUTPUTS: none
225 /
226 / DESCRIPTION:
227 / Allow player to quit upon hitting the interrupt key.
228 / If the player wants to quit while in battle, he/she automatically
229 / dies.
230 /
231 /************************************************************************/
232
233 interrupt()
234 {
235 char line[81]; /* a place to store data already on screen */
236 register int loop; /* counter */
237 int x, y; /* coordinates on screen */
238 int ch; /* input */
239 unsigned savealarm; /* to save alarm value */
240
241 #ifdef SYS3
242 signal(SIGINT, SIG_IGN);
243 #endif
244 #ifdef SYS5
245 signal(SIGINT, SIG_IGN);
246 #endif
247
248 savealarm = alarm(0); /* turn off any alarms */
249
250 getyx(stdscr, y, x); /* save cursor location */
251
252 for (loop = 0; loop < 80; ++loop) /* save line on screen */
253 {
254 move(4, loop);
255 line[loop] = inch();
256 }
257 line[80] = '\0'; /* nul terminate */
258
259 if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER)
260 /* in midst of fighting */
261 {
262 mvaddstr(4, 0, "Quitting now will automatically kill your character. Still want to ? ");
263 ch = getanswer("NY", FALSE);
264 if (ch == 'Y')
265 death("Bailing out");
266 /*NOTREACHED*/
267 }
268 else
269 {
270 mvaddstr(4, 0, "Do you really want to quit ? ");
271 ch = getanswer("NY", FALSE);
272 if (ch == 'Y')
273 leavegame();
274 /*NOTREACHED*/
275 }
276
277 mvaddstr(4, 0, line); /* restore data on screen */
278 move(y, x); /* restore cursor */
279 refresh();
280
281 #ifdef SYS3
282 signal(SIGINT, interrupt);
283 #endif
284 #ifdef SYS5
285 signal(SIGINT, interrupt);
286 #endif
287
288 alarm(savealarm); /* restore alarm */
289 }
290 /*\f*/
291 /************************************************************************
292 /
293 / FUNCTION NAME: getanswer()
294 /
295 / FUNCTION: get an answer from operator
296 /
297 / AUTHOR: E. A. Estes, 12/4/85
298 /
299 / ARGUMENTS:
300 / char *choices - string of (upper case) valid choices
301 / bool def - set if default answer
302 /
303 / RETURN VALUE: none
304 /
305 / MODULES CALLED: alarm(), wmove(), waddch(), signal(), setjmp(), strchr(),
306 / _filbuf(), clearok(), toupper(), wrefresh(), mvprintw(), wclrtoeol()
307 /
308 / GLOBAL INPUTS: catchalarm(), Echo, _iob[], _ctype[], *stdscr, Timeout,
309 / Timeoenv[]
310 /
311 / GLOBAL OUTPUTS: _iob[]
312 /
313 / DESCRIPTION:
314 / Get a single character answer from operator.
315 / Timeout waiting for response. If we timeout, or the
316 / answer in not in the list of valid choices, print choices,
317 / and wait again, otherwise return the first character in ths
318 / list of choices.
319 / Give up after 3 tries.
320 /
321 /************************************************************************/
322
323 getanswer(choices, def)
324 char *choices;
325 bool def;
326 {
327 int ch; /* input */
328 int loop; /* counter */
329 int oldx, oldy; /* original coordinates on screen */
330
331 getyx(stdscr, oldy, oldx);
332 alarm(0); /* make sure alarm is off */
333
334 for (loop = 3; loop; --loop)
335 /* try for 3 times */
336 {
337 if (setjmp(Timeoenv) != 0)
338 /* timed out waiting for response */
339 {
340 if (def || loop <= 1)
341 /* return default answer */
342 break;
343 else
344 /* prompt, and try again */
345 goto YELL;
346 }
347 else
348 /* wait for response */
349 {
350 clrtoeol();
351 refresh();
352 #ifdef BSD41
353 sigset(SIGALRM, catchalarm);
354 #else
355 signal(SIGALRM, catchalarm);
356 #endif
357 /* set timeout */
358 if (Timeout)
359 alarm(7); /* short */
360 else
361 alarm(600); /* long */
362
363 ch = getchar();
364
365 alarm(0); /* turn off timeout */
366
367 if (ch < 0)
368 /* caught some signal */
369 {
370 ++loop;
371 continue;
372 }
373 else if (ch == CH_REDRAW)
374 /* redraw screen */
375 {
376 clearok(stdscr, TRUE); /* force clear screen */
377 ++loop; /* don't count this input */
378 continue;
379 }
380 else if (Echo)
381 {
382 addch(ch); /* echo character */
383 refresh();
384 }
385
386 if (islower(ch))
387 /* convert to upper case */
388 ch = toupper(ch);
389
390 if (def || strchr(choices, ch) != NULL)
391 /* valid choice */
392 return(ch);
393 else if (!def && loop > 1)
394 /* bad choice; prompt, and try again */
395 {
396 YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
397 move(oldy, oldx);
398 clrtoeol();
399 continue;
400 }
401 else
402 /* return default answer */
403 break;
404 }
405 }
406
407 return(*choices);
408 }
409 /*\f*/
410 /************************************************************************
411 /
412 / FUNCTION NAME: catchalarm()
413 /
414 / FUNCTION: catch timer when waiting for input
415 /
416 / AUTHOR: E. A. Estes, 12/4/85
417 /
418 / ARGUMENTS: none
419 /
420 / RETURN VALUE: none
421 /
422 / MODULES CALLED: longjmp()
423 /
424 / GLOBAL INPUTS: Timeoenv[]
425 /
426 / GLOBAL OUTPUTS: none
427 /
428 / DESCRIPTION:
429 / Come here when the alarm expires while waiting for input.
430 / Simply longjmp() into getanswer().
431 /
432 /************************************************************************/
433
434 void
435 catchalarm()
436 {
437 longjmp(Timeoenv, 1);
438 }