io.c revision 1.14 1 1.14 dholland /* $NetBSD: io.c,v 1.14 2009/08/31 08:27:16 dholland Exp $ */
2 1.2 cgd
3 1.1 jtc /*
4 1.1 jtc * io.c - input/output routines for Phantasia
5 1.1 jtc */
6 1.1 jtc
7 1.14 dholland #include <sys/cdefs.h>
8 1.14 dholland
9 1.14 dholland #include <ctype.h>
10 1.14 dholland #include <math.h>
11 1.14 dholland #include <setjmp.h>
12 1.14 dholland #include <signal.h>
13 1.14 dholland #include <stdio.h>
14 1.14 dholland #include <string.h>
15 1.14 dholland #include <unistd.h>
16 1.14 dholland
17 1.14 dholland #include "macros.h"
18 1.14 dholland #include "phantdefs.h"
19 1.14 dholland #include "phantstruct.h"
20 1.14 dholland #include "phantglobs.h"
21 1.14 dholland //#include "pathnames.h"
22 1.14 dholland
23 1.8 he #undef bool
24 1.7 ross #include <curses.h>
25 1.1 jtc
26 1.13 dholland static void catchalarm(int) __dead;
27 1.13 dholland
28 1.3 lukem void
29 1.12 dholland getstring(char *cp, int mx)
30 1.1 jtc {
31 1.3 lukem char *inptr; /* pointer into string for next string */
32 1.3 lukem int x, y; /* original x, y coordinates on screen */
33 1.3 lukem int ch; /* input */
34 1.3 lukem
35 1.3 lukem getyx(stdscr, y, x); /* get coordinates on screen */
36 1.3 lukem inptr = cp;
37 1.3 lukem *inptr = '\0'; /* clear string to start */
38 1.3 lukem --mx; /* reserve room in string for nul terminator */
39 1.3 lukem
40 1.3 lukem do
41 1.3 lukem /* get characters and process */
42 1.3 lukem {
43 1.3 lukem if (Echo)
44 1.3 lukem mvaddstr(y, x, cp); /* print string on screen */
45 1.3 lukem clrtoeol(); /* clear any data after string */
46 1.3 lukem refresh(); /* update screen */
47 1.3 lukem
48 1.3 lukem ch = getchar(); /* get character */
49 1.3 lukem
50 1.3 lukem switch (ch) {
51 1.3 lukem case CH_ERASE: /* back up one character */
52 1.3 lukem if (inptr > cp)
53 1.3 lukem --inptr;
54 1.3 lukem break;
55 1.3 lukem
56 1.3 lukem case CH_KILL: /* back up to original location */
57 1.3 lukem inptr = cp;
58 1.3 lukem break;
59 1.3 lukem
60 1.3 lukem case CH_NEWLINE: /* terminate string */
61 1.3 lukem break;
62 1.3 lukem
63 1.3 lukem case CH_REDRAW:/* redraw screen */
64 1.3 lukem clearok(stdscr, TRUE);
65 1.3 lukem continue;
66 1.3 lukem
67 1.3 lukem default: /* put data in string */
68 1.3 lukem if (ch >= ' ' || Wizard)
69 1.3 lukem /* printing char; put in string */
70 1.3 lukem *inptr++ = ch;
71 1.3 lukem }
72 1.1 jtc
73 1.3 lukem *inptr = '\0'; /* terminate string */
74 1.1 jtc }
75 1.3 lukem while (ch != CH_NEWLINE && inptr < cp + mx);
76 1.1 jtc }
77 1.1 jtc
78 1.3 lukem void
79 1.12 dholland more(int where)
80 1.1 jtc {
81 1.3 lukem mvaddstr(where, 0, "-- more --");
82 1.3 lukem getanswer(" ", FALSE);
83 1.1 jtc }
84 1.1 jtc
85 1.1 jtc double
86 1.12 dholland infloat(void)
87 1.1 jtc {
88 1.3 lukem double result; /* return value */
89 1.1 jtc
90 1.3 lukem getstring(Databuf, SZ_DATABUF);
91 1.3 lukem if (sscanf(Databuf, "%lf", &result) < 1)
92 1.3 lukem /* no valid number entered */
93 1.3 lukem result = 0.0;
94 1.1 jtc
95 1.3 lukem return (result);
96 1.1 jtc }
97 1.1 jtc
98 1.3 lukem int
99 1.12 dholland inputoption(void)
100 1.1 jtc {
101 1.3 lukem ++Player.p_age; /* increase age */
102 1.1 jtc
103 1.3 lukem if (Player.p_ring.ring_type != R_SPOILED)
104 1.3 lukem /* ring ok */
105 1.3 lukem return (getanswer("T ", TRUE));
106 1.3 lukem else
107 1.3 lukem /* bad ring */
108 1.1 jtc {
109 1.3 lukem getanswer(" ", TRUE);
110 1.3 lukem return ((int) ROLL(0.0, 5.0) + '0');
111 1.1 jtc }
112 1.1 jtc }
113 1.1 jtc
114 1.3 lukem void
115 1.12 dholland interrupt(void)
116 1.1 jtc {
117 1.3 lukem char line[81]; /* a place to store data already on screen */
118 1.3 lukem int loop; /* counter */
119 1.3 lukem int x, y; /* coordinates on screen */
120 1.3 lukem int ch; /* input */
121 1.3 lukem unsigned savealarm; /* to save alarm value */
122 1.1 jtc
123 1.1 jtc #ifdef SYS3
124 1.3 lukem signal(SIGINT, SIG_IGN);
125 1.1 jtc #endif
126 1.1 jtc #ifdef SYS5
127 1.3 lukem signal(SIGINT, SIG_IGN);
128 1.1 jtc #endif
129 1.1 jtc
130 1.3 lukem savealarm = alarm(0); /* turn off any alarms */
131 1.1 jtc
132 1.3 lukem getyx(stdscr, y, x); /* save cursor location */
133 1.1 jtc
134 1.3 lukem for (loop = 0; loop < 80; ++loop) { /* save line on screen */
135 1.3 lukem move(4, loop);
136 1.3 lukem line[loop] = inch();
137 1.3 lukem }
138 1.3 lukem line[80] = '\0'; /* nul terminate */
139 1.3 lukem
140 1.3 lukem if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER)
141 1.3 lukem /* in midst of fighting */
142 1.3 lukem {
143 1.3 lukem mvaddstr(4, 0, "Quitting now will automatically kill your character. Still want to ? ");
144 1.3 lukem ch = getanswer("NY", FALSE);
145 1.3 lukem if (ch == 'Y')
146 1.3 lukem death("Bailing out");
147 1.3 lukem /* NOTREACHED */
148 1.3 lukem } else {
149 1.3 lukem mvaddstr(4, 0, "Do you really want to quit ? ");
150 1.3 lukem ch = getanswer("NY", FALSE);
151 1.3 lukem if (ch == 'Y')
152 1.3 lukem leavegame();
153 1.3 lukem /* NOTREACHED */
154 1.3 lukem }
155 1.3 lukem
156 1.3 lukem mvaddstr(4, 0, line); /* restore data on screen */
157 1.3 lukem move(y, x); /* restore cursor */
158 1.3 lukem refresh();
159 1.1 jtc
160 1.1 jtc #ifdef SYS3
161 1.3 lukem signal(SIGINT, interrupt);
162 1.1 jtc #endif
163 1.1 jtc #ifdef SYS5
164 1.3 lukem signal(SIGINT, interrupt);
165 1.1 jtc #endif
166 1.1 jtc
167 1.3 lukem alarm(savealarm); /* restore alarm */
168 1.1 jtc }
169 1.1 jtc
170 1.3 lukem int
171 1.12 dholland getanswer(const char *choices, phbool def)
172 1.1 jtc {
173 1.3 lukem int ch; /* input */
174 1.6 jsm volatile int loop; /* counter */
175 1.6 jsm volatile int oldx, oldy; /* original coordinates on screen */
176 1.1 jtc
177 1.3 lukem getyx(stdscr, oldy, oldx);
178 1.3 lukem alarm(0); /* make sure alarm is off */
179 1.1 jtc
180 1.3 lukem for (loop = 3; loop; --loop)
181 1.3 lukem /* try for 3 times */
182 1.1 jtc {
183 1.3 lukem if (setjmp(Timeoenv) != 0)
184 1.3 lukem /* timed out waiting for response */
185 1.3 lukem {
186 1.3 lukem if (def || loop <= 1)
187 1.3 lukem /* return default answer */
188 1.3 lukem break;
189 1.3 lukem else
190 1.3 lukem /* prompt, and try again */
191 1.3 lukem goto YELL;
192 1.3 lukem } else
193 1.3 lukem /* wait for response */
194 1.3 lukem {
195 1.3 lukem clrtoeol();
196 1.3 lukem refresh();
197 1.1 jtc #ifdef BSD41
198 1.3 lukem sigset(SIGALRM, catchalarm);
199 1.1 jtc #else
200 1.3 lukem signal(SIGALRM, catchalarm);
201 1.1 jtc #endif
202 1.3 lukem /* set timeout */
203 1.3 lukem if (Timeout)
204 1.3 lukem alarm(7); /* short */
205 1.3 lukem else
206 1.3 lukem alarm(600); /* long */
207 1.3 lukem
208 1.3 lukem ch = getchar();
209 1.3 lukem
210 1.3 lukem alarm(0); /* turn off timeout */
211 1.3 lukem
212 1.3 lukem if (ch < 0)
213 1.3 lukem /* caught some signal */
214 1.3 lukem {
215 1.3 lukem ++loop;
216 1.3 lukem continue;
217 1.3 lukem } else
218 1.3 lukem if (ch == CH_REDRAW)
219 1.3 lukem /* redraw screen */
220 1.3 lukem {
221 1.3 lukem clearok(stdscr, TRUE); /* force clear screen */
222 1.3 lukem ++loop; /* don't count this input */
223 1.3 lukem continue;
224 1.3 lukem } else
225 1.3 lukem if (Echo) {
226 1.3 lukem addch(ch); /* echo character */
227 1.3 lukem refresh();
228 1.3 lukem }
229 1.3 lukem if (islower(ch))
230 1.3 lukem /* convert to upper case */
231 1.3 lukem ch = toupper(ch);
232 1.3 lukem
233 1.3 lukem if (def || strchr(choices, ch) != NULL)
234 1.3 lukem /* valid choice */
235 1.3 lukem return (ch);
236 1.3 lukem else
237 1.3 lukem if (!def && loop > 1)
238 1.3 lukem /* bad choice; prompt, and try again */
239 1.3 lukem {
240 1.3 lukem YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
241 1.3 lukem move(oldy, oldx);
242 1.3 lukem clrtoeol();
243 1.3 lukem continue;
244 1.3 lukem } else
245 1.3 lukem /* return default answer */
246 1.3 lukem break;
247 1.1 jtc }
248 1.1 jtc }
249 1.1 jtc
250 1.3 lukem return (*choices);
251 1.1 jtc }
252 1.1 jtc
253 1.13 dholland static void
254 1.12 dholland catchalarm(int dummy __unused)
255 1.1 jtc {
256 1.3 lukem longjmp(Timeoenv, 1);
257 1.1 jtc }
258