comparison arogue5/options.c @ 63:0ed67132cf10

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