]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - phantasia/io.c
don't use char values for functions that can return -1; chars are not always
[bsdgames-darwin.git] / phantasia / io.c
1 /* $NetBSD: io.c,v 1.12 2009/05/25 23:08:45 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 void
13 getstring(char *cp, 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(int where)
64 {
65 mvaddstr(where, 0, "-- more --");
66 getanswer(" ", FALSE);
67 }
68
69 double
70 infloat(void)
71 {
72 double result; /* return value */
73
74 getstring(Databuf, SZ_DATABUF);
75 if (sscanf(Databuf, "%lf", &result) < 1)
76 /* no valid number entered */
77 result = 0.0;
78
79 return (result);
80 }
81
82 int
83 inputoption(void)
84 {
85 ++Player.p_age; /* increase age */
86
87 if (Player.p_ring.ring_type != R_SPOILED)
88 /* ring ok */
89 return (getanswer("T ", TRUE));
90 else
91 /* bad ring */
92 {
93 getanswer(" ", TRUE);
94 return ((int) ROLL(0.0, 5.0) + '0');
95 }
96 }
97
98 void
99 interrupt(void)
100 {
101 char line[81]; /* a place to store data already on screen */
102 int loop; /* counter */
103 int x, y; /* coordinates on screen */
104 int ch; /* input */
105 unsigned savealarm; /* to save alarm value */
106
107 #ifdef SYS3
108 signal(SIGINT, SIG_IGN);
109 #endif
110 #ifdef SYS5
111 signal(SIGINT, SIG_IGN);
112 #endif
113
114 savealarm = alarm(0); /* turn off any alarms */
115
116 getyx(stdscr, y, x); /* save cursor location */
117
118 for (loop = 0; loop < 80; ++loop) { /* save line on screen */
119 move(4, loop);
120 line[loop] = inch();
121 }
122 line[80] = '\0'; /* nul terminate */
123
124 if (Player.p_status == S_INBATTLE || Player.p_status == S_MONSTER)
125 /* in midst of fighting */
126 {
127 mvaddstr(4, 0, "Quitting now will automatically kill your character. Still want to ? ");
128 ch = getanswer("NY", FALSE);
129 if (ch == 'Y')
130 death("Bailing out");
131 /* NOTREACHED */
132 } else {
133 mvaddstr(4, 0, "Do you really want to quit ? ");
134 ch = getanswer("NY", FALSE);
135 if (ch == 'Y')
136 leavegame();
137 /* NOTREACHED */
138 }
139
140 mvaddstr(4, 0, line); /* restore data on screen */
141 move(y, x); /* restore cursor */
142 refresh();
143
144 #ifdef SYS3
145 signal(SIGINT, interrupt);
146 #endif
147 #ifdef SYS5
148 signal(SIGINT, interrupt);
149 #endif
150
151 alarm(savealarm); /* restore alarm */
152 }
153
154 int
155 getanswer(const char *choices, phbool def)
156 {
157 int ch; /* input */
158 volatile int loop; /* counter */
159 volatile int oldx, oldy; /* original coordinates on screen */
160
161 getyx(stdscr, oldy, oldx);
162 alarm(0); /* make sure alarm is off */
163
164 for (loop = 3; loop; --loop)
165 /* try for 3 times */
166 {
167 if (setjmp(Timeoenv) != 0)
168 /* timed out waiting for response */
169 {
170 if (def || loop <= 1)
171 /* return default answer */
172 break;
173 else
174 /* prompt, and try again */
175 goto YELL;
176 } else
177 /* wait for response */
178 {
179 clrtoeol();
180 refresh();
181 #ifdef BSD41
182 sigset(SIGALRM, catchalarm);
183 #else
184 signal(SIGALRM, catchalarm);
185 #endif
186 /* set timeout */
187 if (Timeout)
188 alarm(7); /* short */
189 else
190 alarm(600); /* long */
191
192 ch = getchar();
193
194 alarm(0); /* turn off timeout */
195
196 if (ch < 0)
197 /* caught some signal */
198 {
199 ++loop;
200 continue;
201 } else
202 if (ch == CH_REDRAW)
203 /* redraw screen */
204 {
205 clearok(stdscr, TRUE); /* force clear screen */
206 ++loop; /* don't count this input */
207 continue;
208 } else
209 if (Echo) {
210 addch(ch); /* echo character */
211 refresh();
212 }
213 if (islower(ch))
214 /* convert to upper case */
215 ch = toupper(ch);
216
217 if (def || strchr(choices, ch) != NULL)
218 /* valid choice */
219 return (ch);
220 else
221 if (!def && loop > 1)
222 /* bad choice; prompt, and try again */
223 {
224 YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices);
225 move(oldy, oldx);
226 clrtoeol();
227 continue;
228 } else
229 /* return default answer */
230 break;
231 }
232 }
233
234 return (*choices);
235 }
236
237 void
238 catchalarm(int dummy __unused)
239 {
240 longjmp(Timeoenv, 1);
241 }