Mercurial > hg > early-roguelike
comparison rogue5/options.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Mon, 24 May 2010 20:10:59 +0000 |
parents | |
children | 655c317b6237 |
comparison
equal
deleted
inserted
replaced
32:2dcd75e6a736 | 33:f502bf60e6e4 |
---|---|
1 /* | |
2 * This file has all the code for the option command. I would rather | |
3 * this command were not necessary, but it is the only way to keep the | |
4 * wolves off of my back. | |
5 * | |
6 * @(#)options.c 4.24 (Berkeley) 05/10/83 | |
7 * | |
8 * Rogue: Exploring the Dungeons of Doom | |
9 * Copyright (C) 1980-1983, 1985, 1999 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 "rogue.h" | |
20 | |
21 #define EQSTR(a, b, c) (strncmp(a, b, c) == 0) | |
22 | |
23 #define NUM_OPTS (sizeof optlist / sizeof (OPTION)) | |
24 | |
25 /* | |
26 * description of an option and what to do with it | |
27 */ | |
28 struct optstruct { | |
29 char *o_name; /* option name */ | |
30 char *o_prompt; /* prompt for interactive entry */ | |
31 void *o_opt; /* pointer to thing to set */ | |
32 /* function to print value */ | |
33 void (*o_putfunc)(void *opt); | |
34 /* function to get value interactively */ | |
35 int (*o_getfunc)(void *opt, WINDOW *win); | |
36 }; | |
37 | |
38 typedef struct optstruct OPTION; | |
39 | |
40 void pr_optname(const OPTION *op); | |
41 | |
42 static const OPTION optlist[] = { | |
43 {"terse", "Terse output", | |
44 &terse, put_bool, get_bool }, | |
45 {"flush", "Flush typeahead during battle", | |
46 &fight_flush, put_bool, get_bool }, | |
47 {"jump", "Show position only at end of run", | |
48 &jump, put_bool, get_bool }, | |
49 {"seefloor", "Show the lamp-illuminated floor", | |
50 &see_floor, put_bool, get_sf }, | |
51 {"passgo", "Follow turnings in passageways", | |
52 &passgo, put_bool, get_bool }, | |
53 {"tombstone", "Print out tombstone when killed", | |
54 &tombstone, put_bool, get_bool }, | |
55 {"inven", "Inventory style", | |
56 &inv_type, put_inv_t, get_inv_t }, | |
57 {"name", "Name", | |
58 whoami, put_str, get_str }, | |
59 {"fruit", "Fruit", | |
60 fruit, put_str, get_str }, | |
61 {"file", "Save file", | |
62 file_name, put_str, get_str } | |
63 }; | |
64 | |
65 /* | |
66 * option: | |
67 * Print and then set options from the terminal | |
68 */ | |
69 | |
70 void | |
71 option(void) | |
72 { | |
73 const OPTION *op; | |
74 int retval; | |
75 | |
76 wclear(hw); | |
77 /* | |
78 * Display current values of options | |
79 */ | |
80 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++) | |
81 { | |
82 pr_optname(op); | |
83 (*op->o_putfunc)(op->o_opt); | |
84 waddch(hw, '\n'); | |
85 } | |
86 /* | |
87 * Set values | |
88 */ | |
89 wmove(hw, 0, 0); | |
90 for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++) | |
91 { | |
92 pr_optname(op); | |
93 retval = (*op->o_getfunc)(op->o_opt, hw); | |
94 if (retval) | |
95 { | |
96 if (retval == QUIT) | |
97 break; | |
98 else if (op > optlist) { /* MINUS */ | |
99 wmove(hw, (int)(op - optlist) - 1, 0); | |
100 op -= 2; | |
101 } | |
102 else /* trying to back up beyond the top */ | |
103 { | |
104 putchar('\007'); | |
105 wmove(hw, 0, 0); | |
106 op--; | |
107 } | |
108 } | |
109 } | |
110 /* | |
111 * Switch back to original screen | |
112 */ | |
113 wmove(hw, LINES - 1, 0); | |
114 waddstr(hw, "--Press space to continue--"); | |
115 wrefresh(hw); | |
116 wait_for(hw, ' '); | |
117 clearok(curscr, TRUE); | |
118 touchwin(stdscr); | |
119 after = FALSE; | |
120 } | |
121 | |
122 /* | |
123 * pr_optname: | |
124 * Print out the option name prompt | |
125 */ | |
126 | |
127 void | |
128 pr_optname(const OPTION *op) | |
129 { | |
130 wprintw(hw, "%s (\"%s\"): ", op->o_prompt, op->o_name); | |
131 } | |
132 | |
133 /* | |
134 * put_bool | |
135 * Put out a boolean | |
136 */ | |
137 | |
138 void | |
139 put_bool(void *b) | |
140 { | |
141 waddstr(hw, *(int *) b ? "True" : "False"); | |
142 } | |
143 | |
144 /* | |
145 * put_str: | |
146 * Put out a string | |
147 */ | |
148 | |
149 void | |
150 put_str(void *str) | |
151 { | |
152 waddstr(hw, (char *) str); | |
153 } | |
154 | |
155 /* | |
156 * put_inv_t: | |
157 * Put out an inventory type | |
158 */ | |
159 | |
160 void | |
161 put_inv_t(void *ip) | |
162 { | |
163 waddstr(hw, inv_t_name[*(int *) ip]); | |
164 } | |
165 | |
166 /* | |
167 * get_bool: | |
168 * Allow changing a boolean option and print it out | |
169 */ | |
170 int | |
171 get_bool(void *vp, WINDOW *win) | |
172 { | |
173 int *bp = (int *) vp; | |
174 int oy, ox; | |
175 int op_bad; | |
176 | |
177 op_bad = TRUE; | |
178 getyx(win, oy, ox); | |
179 waddstr(win, *bp ? "True" : "False"); | |
180 while (op_bad) | |
181 { | |
182 wmove(win, oy, ox); | |
183 wrefresh(win); | |
184 switch (wreadchar(win)) | |
185 { | |
186 case 't': | |
187 case 'T': | |
188 *bp = TRUE; | |
189 op_bad = FALSE; | |
190 break; | |
191 case 'f': | |
192 case 'F': | |
193 *bp = FALSE; | |
194 op_bad = FALSE; | |
195 break; | |
196 case '\n': | |
197 case '\r': | |
198 op_bad = FALSE; | |
199 break; | |
200 case ESCAPE: | |
201 return QUIT; | |
202 case '-': | |
203 return MINUS; | |
204 default: | |
205 wmove(win, oy, ox + 10); | |
206 waddstr(win, "(T or F)"); | |
207 } | |
208 } | |
209 wmove(win, oy, ox); | |
210 waddstr(win, *bp ? "True" : "False"); | |
211 waddch(win, '\n'); | |
212 return NORM; | |
213 } | |
214 | |
215 /* | |
216 * get_sf: | |
217 * Change value and handle transition problems from see_floor to | |
218 * !see_floor. | |
219 */ | |
220 int | |
221 get_sf(void *vp, WINDOW *win) | |
222 { | |
223 int *bp = (int *) vp; | |
224 int was_sf; | |
225 int retval; | |
226 | |
227 was_sf = see_floor; | |
228 retval = get_bool(bp, win); | |
229 if (retval == QUIT) return(QUIT); | |
230 if (was_sf != see_floor) | |
231 { | |
232 if (!see_floor) { | |
233 see_floor = TRUE; | |
234 erase_lamp(&hero, proom); | |
235 see_floor = FALSE; | |
236 } | |
237 else | |
238 look(FALSE); | |
239 } | |
240 return(NORM); | |
241 } | |
242 | |
243 /* | |
244 * get_str: | |
245 * Set a string option | |
246 */ | |
247 #define MAXINP 50 /* max string to read from terminal or environment */ | |
248 | |
249 int | |
250 get_str(void *vopt, WINDOW *win) | |
251 { | |
252 char *opt = (char *) vopt; | |
253 char *sp; | |
254 int oy, ox; | |
255 size_t i; | |
256 int c; | |
257 static char buf[MAXSTR]; | |
258 | |
259 getyx(win, oy, ox); | |
260 wrefresh(win); | |
261 /* | |
262 * loop reading in the string, and put it in a temporary buffer | |
263 */ | |
264 for (sp = buf; (c = wreadchar(win)) != '\n' && c != '\r' && c != ESCAPE; | |
265 wclrtoeol(win), wrefresh(win)) | |
266 { | |
267 if (c == -1) | |
268 continue; | |
269 else if (c == erasechar()) /* process erase character */ | |
270 { | |
271 if (sp > buf) | |
272 { | |
273 sp--; | |
274 for (i = strlen(unctrl(*sp)); i; i--) | |
275 waddch(win, '\b'); | |
276 } | |
277 continue; | |
278 } | |
279 else if (c == killchar()) /* process kill character */ | |
280 { | |
281 sp = buf; | |
282 wmove(win, oy, ox); | |
283 continue; | |
284 } | |
285 else if (sp == buf) | |
286 { | |
287 if (c == '-' && win != stdscr) | |
288 break; | |
289 else if (c == '~') | |
290 { | |
291 strcpy(buf, home); | |
292 waddstr(win, home); | |
293 sp += strlen(home); | |
294 continue; | |
295 } | |
296 } | |
297 if (sp >= &buf[MAXINP] || !(isprint(c) || c == ' ')) | |
298 putchar(CTRL('G')); | |
299 else | |
300 { | |
301 *sp++ = (char) c; | |
302 waddstr(win, unctrl(c)); | |
303 } | |
304 } | |
305 *sp = '\0'; | |
306 if (sp > buf) /* only change option if something has been typed */ | |
307 strucpy(opt, buf, strlen(buf)); | |
308 mvwprintw(win, oy, ox, "%s\n", opt); | |
309 wrefresh(win); | |
310 if (win == stdscr) | |
311 mpos += (int)(sp - buf); | |
312 if (c == '-') | |
313 return MINUS; | |
314 else if (c == ESCAPE) | |
315 return QUIT; | |
316 else | |
317 return NORM; | |
318 } | |
319 | |
320 /* | |
321 * get_inv_t | |
322 * Get an inventory type name | |
323 */ | |
324 int | |
325 get_inv_t(void *vp, WINDOW *win) | |
326 { | |
327 int *ip = (int *) vp; | |
328 int oy, ox; | |
329 int op_bad; | |
330 | |
331 op_bad = TRUE; | |
332 getyx(win, oy, ox); | |
333 waddstr(win, inv_t_name[*ip]); | |
334 while (op_bad) | |
335 { | |
336 wmove(win, oy, ox); | |
337 wrefresh(win); | |
338 switch (wreadchar(win)) | |
339 { | |
340 case 'o': | |
341 case 'O': | |
342 *ip = INV_OVER; | |
343 op_bad = FALSE; | |
344 break; | |
345 case 's': | |
346 case 'S': | |
347 *ip = INV_SLOW; | |
348 op_bad = FALSE; | |
349 break; | |
350 case 'c': | |
351 case 'C': | |
352 *ip = INV_CLEAR; | |
353 op_bad = FALSE; | |
354 break; | |
355 case '\n': | |
356 case '\r': | |
357 op_bad = FALSE; | |
358 break; | |
359 case ESCAPE: | |
360 return QUIT; | |
361 case '-': | |
362 return MINUS; | |
363 default: | |
364 wmove(win, oy, ox + 15); | |
365 waddstr(win, "(O, S, or C)"); | |
366 } | |
367 } | |
368 mvwprintw(win, oy, ox, "%s\n", inv_t_name[*ip]); | |
369 return NORM; | |
370 } | |
371 | |
372 | |
373 #ifdef MASTER | |
374 /* | |
375 * get_num: | |
376 * Get a numeric option | |
377 */ | |
378 int | |
379 get_num(void *vp, WINDOW *win) | |
380 { | |
381 int *opt = (int *) vp; | |
382 int i; | |
383 static char buf[MAXSTR]; | |
384 | |
385 if ((i = get_str(buf, win)) == NORM) | |
386 *opt = atoi(buf); | |
387 return i; | |
388 } | |
389 #endif | |
390 | |
391 /* | |