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