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