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