comparison rogue4/options.c @ 12:9535a08ddc39

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