Ignore object files and resulting binary.
[rogue-pphs.git] / options.c
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 "curses.h"
16 #include <ctype.h>
17 #include <string.h>
18 #include "rogue.h"
19
20 #define NUM_OPTS (sizeof optlist / sizeof (OPTION))
21
22 /*
23 * description of an option and what to do with it
24 */
25 struct optstruct {
26 char *o_name; /* option name */
27 char *o_prompt; /* prompt for interactive entry */
28 int *o_opt; /* pointer to thing to set */
29 int (*o_putfunc)(); /* function to print value */
30 int (*o_getfunc)(); /* function to get value interactively */
31 };
32
33 typedef struct optstruct OPTION;
34
35 int put_bool(), get_bool(), put_str(), get_str();
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 option()
60 {
61 register OPTION *op;
62 register int retval;
63
64 wclear(hw);
65 touchwin(hw);
66 /*
67 * Display current values of options
68 */
69 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
70 {
71 waddstr(hw, op->o_prompt);
72 (*op->o_putfunc)(op->o_opt);
73 waddch(hw, '\n');
74 }
75 /*
76 * Set values
77 */
78 wmove(hw, 0, 0);
79 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
80 {
81 waddstr(hw, op->o_prompt);
82 if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
83 if (retval == QUIT)
84 break;
85 else if (op > optlist) { /* MINUS */
86 wmove(hw, (op - optlist) - 1, 0);
87 op -= 2;
88 }
89 else /* trying to back up beyond the top */
90 {
91 beep();
92 wmove(hw, 0, 0);
93 op--;
94 }
95 }
96 /*
97 * Switch back to original screen
98 */
99 mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
100 draw(hw);
101 wait_for(hw,' ');
102 clearok(cw, TRUE);
103 touchwin(cw);
104 after = FALSE;
105 }
106
107 /*
108 * put out a boolean
109 */
110 put_bool(b)
111 bool *b;
112 {
113 waddstr(hw, *b ? "True" : "False");
114 }
115
116 /*
117 * put out a string
118 */
119 put_str(str)
120 char *str;
121 {
122 waddstr(hw, str);
123 }
124
125 /*
126 * allow changing a boolean option and print it out
127 */
128
129 get_bool(bp, win)
130 bool *bp;
131 WINDOW *win;
132 {
133 register int oy, ox;
134 register bool op_bad;
135
136 op_bad = TRUE;
137 getyx(win, oy, ox);
138 waddstr(win, *bp ? "True" : "False");
139 while(op_bad)
140 {
141 wmove(win, oy, ox);
142 draw(win);
143 switch (readchar(win))
144 {
145 case 't':
146 case 'T':
147 *bp = TRUE;
148 op_bad = FALSE;
149 break;
150 case 'f':
151 case 'F':
152 *bp = FALSE;
153 op_bad = FALSE;
154 break;
155 case '\n':
156 case '\r':
157 op_bad = FALSE;
158 break;
159 case '\033':
160 case '\007':
161 return QUIT;
162 case '-':
163 return MINUS;
164 default:
165 mvwaddstr(win, oy, ox + 10, "(T or F)");
166 }
167 }
168 wmove(win, oy, ox);
169 waddstr(win, *bp ? "True" : "False");
170 waddch(win, '\n');
171 return NORM;
172 }
173
174 /*
175 * set a string option
176 */
177 get_str(opt, win)
178 register char *opt;
179 WINDOW *win;
180 {
181 register char *sp;
182 register int c, oy, ox;
183 char buf[80];
184
185 draw(win);
186 getyx(win, oy, ox);
187 /*
188 * loop reading in the string, and put it in a temporary buffer
189 */
190 for (sp = buf;
191 (c = readchar(win)) != '\n' && c != '\r' && c != '\033' && c != '\007';
192 wclrtoeol(win), draw(win))
193 {
194 if (c == -1)
195 continue;
196 else if (c == md_erasechar()) /* process erase character */
197 {
198 if (sp > buf)
199 {
200 register int i;
201 int myx, myy;
202
203 sp--;
204
205 for (i = (int) strlen(unctrl(*sp)); i; i--)
206 {
207 getyx(win,myy,myx);
208 if ((myx == 0)&& (myy > 0))
209 {
210 wmove(win,myy-1,getmaxx(win)-1);
211 waddch(win,' ');
212 wmove(win,myy-1,getmaxx(win)-1);
213 }
214 else
215 waddch(win, '\b');
216 }
217 }
218 continue;
219 }
220 else if (c == md_killchar()) /* process kill character */
221 {
222 sp = buf;
223 wmove(win, oy, ox);
224 continue;
225 }
226 else if (sp == buf)
227 if (c == '-')
228 break;
229 else if (c == '~')
230 {
231 strcpy(buf, home);
232 waddstr(win, home);
233 sp += strlen(home);
234 continue;
235 }
236
237 if ((sp - buf) < 78) /* Avoid overflow */
238 {
239 *sp++ = c;
240 waddstr(win, unctrl(c));
241 }
242 }
243 *sp = '\0';
244 if (sp > buf) /* only change option if something has been typed */
245 strucpy(opt, buf, strlen(buf));
246 wmove(win, oy, ox);
247 waddstr(win, opt);
248 waddch(win, '\n');
249 draw(win);
250 if (win == cw)
251 mpos += sp - buf;
252 if (c == '-')
253 return MINUS;
254 else if (c == '\033' || c == '\007')
255 return QUIT;
256 else
257 return NORM;
258 }
259
260 /*
261 * parse options from string, usually taken from the environment.
262 * the string is a series of comma seperated values, with booleans
263 * being stated as "name" (true) or "noname" (false), and strings
264 * being "name=....", with the string being defined up to a comma
265 * or the end of the entire option string.
266 */
267
268 parse_opts(str)
269 register char *str;
270 {
271 register char *sp;
272 register OPTION *op;
273 register int len;
274
275 while (*str)
276 {
277 /*
278 * Get option name
279 */
280 for (sp = str; isalpha(*sp); sp++)
281 continue;
282 len = sp - str;
283 /*
284 * Look it up and deal with it
285 */
286 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
287 if (EQSTR(str, op->o_name, len))
288 {
289 if (op->o_putfunc == put_bool) /* if option is a boolean */
290 *(bool *)op->o_opt = TRUE;
291 else /* string option */
292 {
293 register char *start;
294 /*
295 * Skip to start of string value
296 */
297 for (str = sp + 1; *str == '='; str++)
298 continue;
299 if (*str == '~')
300 {
301 strcpy((char *) op->o_opt, home);
302 start = (char *) op->o_opt + strlen(home);
303 while (*++str == '/')
304 continue;
305 }
306 else
307 start = (char *) op->o_opt;
308 /*
309 * Skip to end of string value
310 */
311 for (sp = str + 1; *sp && *sp != ','; sp++)
312 continue;
313 strucpy(start, str, sp - str);
314 }
315 break;
316 }
317 /*
318 * check for "noname" for booleans
319 */
320 else if (op->o_putfunc == put_bool
321 && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
322 {
323 *(bool *)op->o_opt = FALSE;
324 break;
325 }
326
327 /*
328 * skip to start of next option name
329 */
330 while (*sp && !isalpha(*sp))
331 sp++;
332 str = sp;
333 }
334 }
335
336 /*
337 * copy string using unctrl for things
338 */
339 strucpy(s1, s2, len)
340 register char *s1, *s2;
341 register int len;
342 {
343 register char *sp;
344
345 while (len--)
346 {
347 strcpy(s1, (sp = unctrl(*s2)));
348 s1 += strlen(sp);
349 s2++;
350 }
351 *s1 = '\0';
352 }