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