]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - phantasia/io.c
sprinkle static
[bsdgames-darwin.git] / phantasia / io.c
1 /* $NetBSD: io.c,v 1.13 2009/08/12 08:21:41 dholland Exp $ */
2
3 /*
4 * io.c - input/output routines for Phantasia
5 */
6
7 #include "include.h"
8 #undef bool
9 #include <sys/cdefs.h>
10 #include <curses.h>
11
12 static void catchalarm(int) __dead;
13
14 void
15 getstring(char *cp, int mx)
16 {
17 char *inptr; /* pointer into string for next string */
18 int x, y; /* original x, y coordinates on screen */
19 int ch; /* input */
20
21 getyx(stdscr, y, x); /* get coordinates on screen */
22 inptr = cp;
23 *inptr = '\0'; /* clear string to start */
24 --mx; /* reserve room in string for nul terminator */
25
26 do
27 /* get characters and process */
28 {
29 if (Echo)
30 mvaddstr(y, x, cp); /* print string on screen */
31 clrtoeol(); /* clear any data after string */
32 refresh(); /* update screen */
33
34 ch = getchar(); /* get character */
35
36 switch (ch) {
37 case CH_ERASE: /* back up one character */
38 if (inptr > cp)
39 --inptr;
40 break;
41
42 case CH_KILL: /* back up to original location */
43 inptr = cp;
44 break;
45
46 case CH_NEWLINE: /* terminate string */
47 break;
48
49 case CH_REDRAW:/* redraw screen */
50 clearok(stdscr, TRUE);
51 continue;
52
53 default: /* put data in string */
54 if (ch >= ' ' || Wizard)
55 /* printing char; put in string */
56 *inptr++ = ch;
57 }
58
59 *inptr = '\0'; /* terminate string */
60 }
61 while (ch != CH_NEWLINE && inptr < cp + mx);
62 }
63
64 void
65 more(int where)
66 {
67 mvaddstr(where, 0, "-- more --");
68 getanswer(" ", FALSE);
69 }
70
71 double
72 infloat(void)
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(void)
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(void)
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(const char *choices, phbool def)
158 {
159 int ch; /* input */
160 volatile int loop; /* counter */
161 volatile int oldx, oldy; /* original coordinates on screen */
162
163 getyx(stdscr, oldy, oldx);
164 alarm(0); /* make sure alarm is off */
165
166 for (loop = 3; loop; --loop)
167 /* try for 3 times */
168 {
169 if (setjmp(Timeoenv) != 0)
170 /* timed out waiting for response */
171 {
172 if (def || loop <= 1)
173 /* return default answer */
174 break;
175 else
176 /* prompt, and try again */
177 goto YELL;
178 } else
179 /* wait for response */
180 {
181 clrtoeol();
182 refresh();
183 #ifdef BSD41
184 sigset(SIGALRM, catchalarm);
185 #else
186 signal(SIGALRM, catchalarm);
187 #endif
188 /* set timeout */
189 if (Timeout)
190 alarm(7); /* short */
191 else
192 alarm(600); /* long */
193
194 ch = getchar();
195
196 alarm(0); /* turn off timeout */
197
198 if (ch < 0)
199 /* caught some signal */
200 {
201 ++loop;
202 continue;
203 } else
204 if (ch == CH_REDRAW)
205 /* redraw screen */
206 {
207 clearok(stdscr, TRUE); /* force clear screen */
208 ++loop; /* don't count this input */
209 continue;
210 } else
211 if (Echo) {
212 addch(ch); /* echo character */
213 refresh();
214 }
215 if (islower(ch))
216 /* convert to upper case */
217 ch = toupper(ch);
218
219 if (def || strchr(choices, ch) != NULL)
220 /* valid choice */
221 return (ch);
222 else
223 if (!def && loop > 1)
224 /* bad choice; prompt, and try again */
225 {
226 YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
227 move(oldy, oldx);
228 clrtoeol();
229 continue;
230 } else
231 /* return default answer */
232 break;
233 }
234 }
235
236 return (*choices);
237 }
238
239 static void
240 catchalarm(int dummy __unused)
241 {
242 longjmp(Timeoenv, 1);
243 }