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