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