comparison arogue7/options.c @ 125:adfa37e67084

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