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