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