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