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