comparison rogue3/options.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children e676d52b5d09
comparison
equal deleted inserted replaced
-1:000000000000 0:527e2150eaf0
1 /*
2 * This file has all the code for the option command.
3 * I would rather this command were not necessary, but
4 * it is the only way to keep the wolves off of my back.
5 *
6 * @(#)options.c 3.3 (Berkeley) 5/25/81
7 *
8 * Rogue: Exploring the Dungeons of Doom
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10 * All rights reserved.
11 *
12 * See the file LICENSE.TXT for full copyright and licensing information.
13 */
14
15 #include <stdlib.h>
16 #include "curses.h"
17 #include <ctype.h>
18 #include <string.h>
19 #include "machdep.h"
20 #include "rogue.h"
21
22 #define NUM_OPTS (sizeof optlist / sizeof (OPTION))
23
24 /*
25 * description of an option and what to do with it
26 */
27 struct optstruct {
28 char *o_name; /* option name */
29 char *o_prompt; /* prompt for interactive entry */
30 void *o_opt; /* pointer to thing to set */
31 void (*o_putfunc)(); /* function to print value */
32 int (*o_getfunc)(); /* function to get value interactively */
33 };
34
35 typedef struct optstruct OPTION;
36
37 OPTION optlist[] = {
38 {"terse", "Terse output: ",
39 (int *) &terse, put_bool, get_bool },
40 {"flush", "Flush typeahead during battle: ",
41 (int *) &fight_flush, put_bool, get_bool },
42 {"jump", "Show position only at end of run: ",
43 (int *) &jump, put_bool, get_bool },
44 {"step", "Do inventories one line at a time: ",
45 (int *) &slow_invent, put_bool, get_bool },
46 {"askme", "Ask me about unidentified things: ",
47 (int *) &askme, put_bool, get_bool },
48 {"name", "Name: ",
49 (int *) whoami, put_str, get_str },
50 {"fruit", "Fruit: ",
51 (int *) fruit, put_str, get_str },
52 {"file", "Save file: ",
53 (int *) file_name, put_str, get_str }
54 };
55
56 /*
57 * print and then set options from the terminal
58 */
59 void
60 option()
61 {
62 OPTION *op;
63 int retval;
64
65 wclear(hw);
66 touchwin(hw);
67 /*
68 * Display current values of options
69 */
70 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
71 {
72 waddstr(hw, op->o_prompt);
73 (*op->o_putfunc)(op->o_opt);
74 waddch(hw, '\n');
75 }
76 /*
77 * Set values
78 */
79 wmove(hw, 0, 0);
80 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
81 {
82 waddstr(hw, op->o_prompt);
83 if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
84 if (retval == QUIT)
85 break;
86 else if (op > optlist) { /* MINUS */
87 wmove(hw, (int)(op - optlist) - 1, 0);
88 op -= 2;
89 }
90 else /* trying to back up beyond the top */
91 {
92 beep();
93 wmove(hw, 0, 0);
94 op--;
95 }
96 }
97 /*
98 * Switch back to original screen
99 */
100 mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
101 draw(hw);
102 wait_for(hw,' ');
103 clearok(cw, TRUE);
104 touchwin(cw);
105 after = FALSE;
106 }
107
108 /*
109 * put out a boolean
110 */
111 void
112 put_bool(void *b)
113 {
114 waddstr(hw, *(int *)b ? "True" : "False");
115 }
116
117 /*
118 * put out a string
119 */
120 void
121 put_str(void *str)
122 {
123 waddstr(hw, (char *) str);
124 }
125
126 /*
127 * allow changing a boolean option and print it out
128 */
129
130 int
131 get_bool(void *vp, WINDOW *win)
132 {
133 int *bp = (int *) vp;
134 int oy, ox;
135 int op_bad;
136
137 op_bad = TRUE;
138 getyx(win, oy, ox);
139 waddstr(win, *bp ? "True" : "False");
140 while(op_bad)
141 {
142 wmove(win, oy, ox);
143 draw(win);
144 switch (readchar(win))
145 {
146 case 't':
147 case 'T':
148 *bp = TRUE;
149 op_bad = FALSE;
150 break;
151 case 'f':
152 case 'F':
153 *bp = FALSE;
154 op_bad = FALSE;
155 break;
156 case '\n':
157 case '\r':
158 op_bad = FALSE;
159 break;
160 case '\033':
161 case '\007':
162 return QUIT;
163 case '-':
164 return MINUS;
165 default:
166 mvwaddstr(win, oy, ox + 10, "(T or F)");
167 }
168 }
169 wmove(win, oy, ox);
170 waddstr(win, *bp ? "True" : "False");
171 waddch(win, '\n');
172 return NORM;
173 }
174
175 /*
176 * set a string option
177 */
178 int
179 get_str(void *vopt, WINDOW *win)
180 {
181 char *opt = (char *) vopt;
182 char *sp;
183 int c, oy, ox;
184 char buf[80];
185
186 draw(win);
187 getyx(win, oy, ox);
188 /*
189 * loop reading in the string, and put it in a temporary buffer
190 */
191 for (sp = buf;
192 (c = readchar(win)) != '\n' && c != '\r' && c != '\033' && c != '\007';
193 wclrtoeol(win), draw(win))
194 {
195 if (c == -1)
196 continue;
197 else if (c == md_erasechar()) /* process erase character */
198 {
199 if (sp > buf)
200 {
201 int i;
202 int myx, myy;
203
204 sp--;
205
206 for (i = (int) strlen(unctrl(*sp)); i; i--)
207 {
208 getyx(win,myy,myx);
209 if ((myx == 0)&& (myy > 0))
210 {
211 wmove(win,myy-1,getmaxx(win)-1);
212 waddch(win,' ');
213 wmove(win,myy-1,getmaxx(win)-1);
214 }
215 else
216 waddch(win, '\b');
217 }
218 }
219 continue;
220 }
221 else if (c == md_killchar()) /* process kill character */
222 {
223 sp = buf;
224 wmove(win, oy, ox);
225 continue;
226 }
227 else if (sp == buf)
228 if (c == '-')
229 break;
230 else if (c == '~')
231 {
232 strcpy(buf, home);
233 waddstr(win, home);
234 sp += strlen(home);
235 continue;
236 }
237
238 if ((sp - buf) < 78) /* Avoid overflow */
239 {
240 *sp++ = c;
241 waddstr(win, unctrl(c));
242 }
243 }
244 *sp = '\0';
245 if (sp > buf) /* only change option if something has been typed */
246 strucpy(opt, buf, strlen(buf));
247 wmove(win, oy, ox);
248 waddstr(win, opt);
249 waddch(win, '\n');
250 draw(win);
251 if (win == cw)
252 mpos += (int)(sp - buf);
253 if (c == '-')
254 return MINUS;
255 else if (c == '\033' || c == '\007')
256 return QUIT;
257 else
258 return NORM;
259 }
260
261 /*
262 * parse options from string, usually taken from the environment.
263 * the string is a series of comma seperated values, with booleans
264 * being stated as "name" (true) or "noname" (false), and strings
265 * being "name=....", with the string being defined up to a comma
266 * or the end of the entire option string.
267 */
268
269 void
270 parse_opts(char *str)
271 {
272 char *sp;
273 OPTION *op;
274 int len;
275
276 while (*str)
277 {
278 /*
279 * Get option name
280 */
281 for (sp = str; isalpha(*sp); sp++)
282 continue;
283 len = (int)(sp - str);
284 /*
285 * Look it up and deal with it
286 */
287 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
288 if (EQSTR(str, op->o_name, len))
289 {
290 if (op->o_putfunc == put_bool) /* if option is a boolean */
291 *(int *)op->o_opt = TRUE;
292 else /* string option */
293 {
294 char *start;
295 /*
296 * Skip to start of string value
297 */
298 for (str = sp + 1; *str == '='; str++)
299 continue;
300 if (*str == '~')
301 {
302 strcpy((char *) op->o_opt, home);
303 start = (char *) op->o_opt + strlen(home);
304 while (*++str == '/')
305 continue;
306 }
307 else
308 start = (char *) op->o_opt;
309 /*
310 * Skip to end of string value
311 */
312 for (sp = str + 1; *sp && *sp != ','; sp++)
313 continue;
314 strucpy(start, str, sp - str);
315 }
316 break;
317 }
318 /*
319 * check for "noname" for booleans
320 */
321 else if (op->o_putfunc == put_bool
322 && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
323 {
324 *(int *)op->o_opt = FALSE;
325 break;
326 }
327
328 /*
329 * skip to start of next option name
330 */
331 while (*sp && !isalpha(*sp))
332 sp++;
333 str = sp;
334 }
335 }
336
337 /*
338 * copy string using unctrl for things
339 */
340 void
341 strucpy(char *s1, char *s2, size_t len)
342 {
343 const char *sp;
344
345 while (len--)
346 {
347 sp = unctrl(*s2);
348 strcpy(s1, sp);
349 s1 += strlen(sp);
350 s2++;
351 }
352 *s1 = '\0';
353 }