comparison xrogue/options.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children ce0cf824c192
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 options.c - This file has all the code for the option command
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 /*
20 * I would rather this command were not necessary, but
21 * it is the only way to keep the wolves off of my back.
22 */
23
24 #include <curses.h>
25 #include <ctype.h>
26 #include "rogue.h"
27
28 #define NUM_OPTS (sizeof optlist / sizeof (OPTION))
29
30 /*
31 * description of an option and what to do with it
32 */
33 struct optstruct {
34 char *o_name; /* option name */
35 char *o_prompt; /* prompt for interactive entry */
36 int *o_opt; /* pointer to thing to set */
37 int (*o_putfunc)(); /* function to print value */
38 int (*o_getfunc)(); /* function to get value interactively */
39 };
40
41 typedef struct optstruct OPTION;
42
43 int put_bool(),
44 get_bool(),
45 put_str(),
46 get_str(),
47 put_abil(),
48 get_abil(),
49 get_quest(),
50 put_quest(),
51 get_default();
52
53 OPTION optlist[] = {
54 {"terse", "Terse output: ",
55 (int *) &terse, put_bool, get_bool },
56 {"flush", "Flush typeahead during battle: ",
57 (int *) &fight_flush, put_bool, get_bool },
58 {"jump", "Show position only at end of run: ",
59 (int *) &jump, put_bool, get_bool },
60 {"step", "Do inventories one line at a time: ",
61 (int *) &slow_invent, put_bool, get_bool },
62 {"askme", "Ask me about unidentified things: ",
63 (int *) &askme, put_bool, get_bool },
64 {"pickup", "Pick things up automatically: ",
65 (int *) &auto_pickup, put_bool, get_bool },
66 {"overlay", "Overlay menu: ",
67 (int *) &menu_overlay, put_bool, get_bool },
68 {"name", "Name: ",
69 (int *) whoami, put_str, get_str },
70 {"file", "Save file: ",
71 (int *) file_name, put_str, get_str },
72 {"score", "Score file: ",
73 (int *) score_file, put_str, get_str },
74 {"class", "Character type: ",
75 (int *) &char_type, put_abil, get_abil },
76 {"quest", "Quest item: ",
77 (int *) &quest_item, put_quest, get_quest },
78 {"default", "Default Attributes: ",
79 (int *) &def_attr, put_bool, get_default }
80 };
81
82 /*
83 * The default attribute field is read-only
84 */
85
86 get_default(bp, win)
87 bool *bp;
88 WINDOW *win;
89 {
90 register int oy, ox;
91
92 getyx(win, oy, ox);
93 put_bool(bp, win);
94 get_ro(win, oy, ox);
95 }
96
97 /*
98 * The ability (class) field is read-only
99 */
100
101 get_abil(abil, win)
102 int *abil;
103 WINDOW *win;
104 {
105 register int oy, ox;
106
107 getyx(win, oy, ox);
108 put_abil(abil, win);
109 get_ro(win, oy, ox);
110 }
111
112 /*
113 * The quest field is read-only
114 */
115
116 get_quest(quest, win)
117 int *quest;
118 WINDOW *win;
119 {
120 register int oy, ox;
121
122 getyx(win, oy, ox);
123 waddstr(win, rel_magic[*quest].mi_name);
124 get_ro(win, oy, ox);
125 }
126
127 /*
128 * get_ro:
129 * "Get" a read-only value.
130 */
131
132 get_ro(win, oy, ox)
133 WINDOW *win;
134 register int oy, ox;
135 {
136 register int ny, nx;
137 register bool op_bad;
138
139 op_bad = TRUE;
140 getyx(win, ny, nx);
141 while(op_bad)
142 {
143 wmove(win, oy, ox);
144 draw(win);
145 switch (wgetch(win))
146 {
147 case '\n':
148 case '\r':
149 op_bad = FALSE;
150 break;
151 case '\033':
152 case '\007':
153 return QUIT;
154 case '-':
155 return MINUS;
156 default:
157 mvwaddstr(win, ny, nx + 5, "(no change allowed)");
158 }
159 }
160 wmove(win, ny, nx + 5);
161 wclrtoeol(win);
162 wmove(win, ny, nx);
163 waddch(win, '\n');
164 return NORM;
165 }
166
167 /*
168 * allow changing a boolean option and print it out
169 */
170
171 get_bool(bp, win)
172 bool *bp;
173 WINDOW *win;
174 {
175 register int oy, ox;
176 register bool op_bad;
177
178 op_bad = TRUE;
179 getyx(win, oy, ox);
180 waddstr(win, *bp ? "True" : "False");
181 while(op_bad)
182 {
183 wmove(win, oy, ox);
184 draw(win);
185 switch (wgetch(win))
186 {
187 case 't':
188 case 'T':
189 *bp = TRUE;
190 op_bad = FALSE;
191 break;
192 case 'f':
193 case 'F':
194 *bp = FALSE;
195 op_bad = FALSE;
196 break;
197 case '\n':
198 case '\r':
199 op_bad = FALSE;
200 break;
201 case '\033':
202 case '\007':
203 return QUIT;
204 case '-':
205 return MINUS;
206 default:
207 mvwaddstr(win, oy, ox + 10, "(T or F)");
208 }
209 }
210 wmove(win, oy, ox);
211 wclrtoeol(win);
212 waddstr(win, *bp ? "True" : "False");
213 waddch(win, '\n');
214 return NORM;
215 }
216
217 /*
218 * set a string option
219 */
220
221 get_str(opt, win)
222 register char *opt;
223 WINDOW *win;
224 {
225 register char *sp;
226 register int c, oy, ox;
227 char buf[LINELEN];
228
229 draw(win);
230 getyx(win, oy, ox);
231 /*
232 * loop reading in the string, and put it in a temporary buffer
233 */
234 for (sp = buf;
235 (c = wgetch(win)) != '\n' &&
236 c != '\r' &&
237 c != '\033' &&
238 c != '\007' &&
239 sp < &buf[LINELEN-1];
240 wclrtoeol(win), draw(win))
241 {
242 if (c == -1)
243 continue;
244 else if (c == erasechar()) /* process erase character */
245 {
246 if (sp > buf)
247 {
248 register int i;
249
250 sp--;
251 for (i = strlen(unctrl(*sp)); i; i--)
252 waddch(win, '\b');
253 }
254 continue;
255 }
256 else if (c == killchar()) /* process kill character */
257 {
258 sp = buf;
259 wmove(win, oy, ox);
260 continue;
261 }
262 else if (sp == buf)
263 if (c == '-' && win == hw) /* To move back a line in hw */
264 break;
265 else if (c == '~')
266 {
267 strcpy(buf, home);
268 waddstr(win, home);
269 sp += strlen(home);
270 continue;
271 }
272 *sp++ = c;
273 waddstr(win, unctrl(c));
274 }
275 *sp = '\0';
276 if (sp > buf) /* only change option if something has been typed */
277 strucpy(opt, buf, strlen(buf));
278 wmove(win, oy, ox);
279 waddstr(win, opt);
280 waddch(win, '\n');
281 draw(win);
282 if (win == msgw)
283 mpos += sp - buf;
284 if (c == '-')
285 return MINUS;
286 else if (c == '\033' || c == '\007')
287 return QUIT;
288 else
289 return NORM;
290 }
291
292 /*
293 * print and then set options from the terminal
294 */
295
296 option()
297 {
298 register OPTION *op;
299 register int retval;
300
301 wclear(hw);
302 touchwin(hw);
303 /*
304 * Display current values of options
305 */
306 for (op = optlist; op < &optlist[NUM_OPTS]; op++)
307 {
308 waddstr(hw, op->o_prompt);
309 (*op->o_putfunc)(op->o_opt, hw);
310 waddch(hw, '\n');
311 }
312 /*
313 * Set values
314 */
315 wmove(hw, 0, 0);
316 for (op = optlist; op < &optlist[NUM_OPTS]; op++)
317 {
318 waddstr(hw, op->o_prompt);
319
320 retval = (*op->o_getfunc)(op->o_opt, hw);
321
322 if (retval)
323 if (retval == QUIT)
324 break;
325 else if (op > optlist) { /* MINUS */
326 wmove(hw, (op - optlist) - 1, 0);
327 op -= 2;
328 }
329 else /* trying to back up beyond the top */
330 {
331 putchar('\007');
332 wmove(hw, 0, 0);
333 op--;
334 }
335 }
336 /*
337 * Switch back to original screen
338 */
339 mvwaddstr(hw, lines-1, 0, spacemsg);
340 draw(hw);
341 wait_for(' ');
342 restscr(cw);
343 after = FALSE;
344 }
345
346 /*
347 * parse options from string, usually taken from the environment.
348 * the string is a series of comma seperated values, with booleans
349 * being stated as "name" (true) or "noname" (false), and strings
350 * being "name=....", with the string being defined up to a comma
351 * or the end of the entire option string.
352 */
353
354 parse_opts(str)
355 register char *str;
356 {
357 register char *sp;
358 register OPTION *op;
359 register int len;
360
361 if (*str == '\"')
362 str++;
363
364 while (*str)
365 {
366 /*
367 * Get option name
368 */
369
370 for (sp = str; isalpha(*sp); sp++)
371 continue;
372 len = (char *)sp - str;
373 /*
374 * Look it up and deal with it
375 */
376 for (op = optlist; op < &optlist[NUM_OPTS]; op++)
377 if (EQSTR(str, op->o_name, len))
378 {
379 if (op->o_putfunc == put_bool) /* if option is a boolean */
380 *(bool *)op->o_opt = TRUE;
381 else /* string option */
382 {
383 register char *start;
384 char value[LINELEN];
385
386 /*
387 * Skip to start of string value
388 */
389 for (str = sp + 1; *str == '=' || *str == ':'; str++)
390 continue;
391
392 if (*str == '~')
393 {
394 strcpy((char *) value, home);
395 start = (char *) value + strlen(home);
396 while (*++str == '/')
397 continue;
398 }
399 else
400 start = (char *) value;
401 /*
402 * Skip to end of string value
403 */
404 for (sp = str + 1; *sp && *sp != ',' && *sp != '\"'; sp++)
405 continue;
406 strucpy(start, str, (char *) sp - str);
407
408 /* Put the value into the option field */
409 if (op->o_putfunc != put_abil)
410 strcpy((char *)op->o_opt, value);
411
412 else if (*op->o_opt == -1) { /* Only init ability once */
413 register int len = strlen(value);
414 register int i;
415
416 for (i=0; i<NUM_CHARTYPES-1; i++) {
417 if (EQSTR(value, char_class[i].name, len)) {
418 *op->o_opt = i;
419 break;
420 }
421 }
422 }
423 }
424 break;
425 }
426 /*
427 * check for "noname" for booleans
428 */
429 else if (op->o_putfunc == put_bool
430 && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
431 {
432 *(bool *)op->o_opt = FALSE;
433 break;
434 }
435
436 /*
437 * skip to start of next option name
438 */
439 while (*sp && !isalpha(*sp))
440 sp++;
441 str = sp;
442 }
443 }
444
445
446 /*
447 * print the default attributes
448 */
449
450 /* put_default(b, win)
451 * bool *b;
452 * WINDOW *win;
453 * {
454 * waddstr(win, *b ? "True" : "False");
455 * }
456 */
457
458 /*
459 * print the character type
460 */
461
462 put_abil(ability, win)
463 int *ability;
464 WINDOW *win;
465 {
466 waddstr(win, char_class[*ability].name);
467 }
468
469 /*
470 * print out the quest
471 */
472
473 put_quest(quest, win)
474 int *quest;
475 WINDOW *win;
476 {
477 waddstr(win, rel_magic[*quest].mi_name);
478 }
479
480 /*
481 * put out a boolean
482 */
483
484 put_bool(b, win)
485 bool *b;
486 WINDOW *win;
487 {
488 waddstr(win, *b ? "True" : "False");
489 }
490
491 /*
492 * put out a string
493 */
494
495 put_str(str, win)
496 char *str;
497 WINDOW *win;
498 {
499 waddstr(win, str);
500 }
501