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