Mercurial > hg > early-roguelike
comparison urogue/options.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Jan 2017 19:56:04 -0500 |
parents | |
children | ac42afd962e4 |
comparison
equal
deleted
inserted
replaced
253:d9badb9c0179 | 256:c495a4f288c6 |
---|---|
1 /* | |
2 options.c - This file has all the code for the option command | |
3 | |
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong | |
6 All rights reserved. | |
7 | |
8 Based on "Advanced Rogue" | |
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka | |
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 #include <string.h> | |
20 #include <ctype.h> | |
21 #include "rogue.h" | |
22 | |
23 #define NUM_OPTS (sizeof optlist / sizeof (OPTION)) | |
24 #define EQSTR(a, b, c) (strncmp(a, b, c) == 0) | |
25 | |
26 /* description of an option and what to do with it */ | |
27 static OPTION optlist[] = | |
28 { | |
29 {"jump","Show position only at end of run (jump): ", &jump,put_bool,get_bool}, | |
30 {"inven","Style of inventories (inven): ", &inv_type, put_inv, get_inv}, | |
31 {"askme","Ask me about unidentified things (askme): ",&askme,put_bool,get_bool}, | |
32 {"doorstop","Stop running when adjacent (doorstop): ",&doorstop,put_bool,get_bool}, | |
33 {"name", "Name (name): ", &whoami, put_str, get_str}, | |
34 {"fruit", "Fruit (fruit): ", &fruit, put_str, get_str}, | |
35 {"file", "Save file (file): ", &file_name, put_str, get_str}, | |
36 {"score", "Score file (score): ", &score_file, put_str, get_str}, | |
37 {"class", "Character class (class): ",&char_type, put_abil, get_abil} | |
38 }; | |
39 | |
40 /* | |
41 option() | |
42 print and then set options from the terminal | |
43 */ | |
44 | |
45 void | |
46 option(void) | |
47 { | |
48 OPTION *op; | |
49 int retval; | |
50 | |
51 wclear(hw); | |
52 touchwin(hw); | |
53 | |
54 /* Display current values of options */ | |
55 | |
56 for (op = optlist; op < &optlist[NUM_OPTS]; op++) | |
57 { | |
58 waddstr(hw, op->o_prompt); | |
59 (*op->o_putfunc)(&op->o_opt, hw); | |
60 waddch(hw, '\n'); | |
61 } | |
62 | |
63 /* Set values */ | |
64 | |
65 wmove(hw, 0, 0); | |
66 | |
67 for (op = optlist; op < &optlist[NUM_OPTS]; op++) | |
68 { | |
69 waddstr(hw, op->o_prompt); | |
70 | |
71 retval = (*op->o_getfunc)(&op->o_opt, hw); | |
72 | |
73 if (retval) | |
74 if (retval == QUIT) | |
75 break; | |
76 else if (op > optlist) /* MINUS */ | |
77 { | |
78 wmove(hw, (int)(op - optlist) - 1, 0); | |
79 op -= 2; | |
80 } | |
81 else /* trying to back up beyond the top */ | |
82 { | |
83 putchar('\007'); | |
84 wmove(hw, 0, 0); | |
85 op--; | |
86 } | |
87 } | |
88 | |
89 /* Switch back to original screen */ | |
90 | |
91 mvwaddstr(hw, LINES - 1, 0, spacemsg); | |
92 wrefresh(hw); | |
93 wait_for(' '); | |
94 clearok(cw, TRUE); | |
95 touchwin(cw); | |
96 } | |
97 | |
98 /* | |
99 put_bool() | |
100 put out a boolean | |
101 */ | |
102 | |
103 void | |
104 put_bool(opt_arg *opt, WINDOW *win) | |
105 { | |
106 waddstr(win, *opt->iarg ? "True" : "False"); | |
107 } | |
108 | |
109 /* | |
110 put_str() | |
111 put out a string | |
112 */ | |
113 | |
114 void | |
115 put_str(opt_arg *opt, WINDOW *win) | |
116 { | |
117 waddstr(win, opt->str); | |
118 } | |
119 | |
120 /* | |
121 put_abil() | |
122 print the character type | |
123 */ | |
124 | |
125 void | |
126 put_abil(opt_arg *opt, WINDOW *win) | |
127 { | |
128 char *abil; | |
129 | |
130 switch(*opt->iarg) | |
131 { | |
132 case C_FIGHTER: | |
133 abil = "Fighter"; | |
134 break; | |
135 case C_MAGICIAN: | |
136 abil = "Magic User"; | |
137 break; | |
138 case C_CLERIC: | |
139 abil = "Cleric"; | |
140 break; | |
141 case C_THIEF: | |
142 abil = "Thief"; | |
143 break; | |
144 case C_PALADIN: | |
145 abil = "Paladin"; | |
146 break; | |
147 case C_RANGER: | |
148 abil = "Ranger"; | |
149 break; | |
150 case C_ILLUSION: | |
151 abil = "Illusionist"; | |
152 break; | |
153 case C_ASSASIN: | |
154 abil = "Assasin"; | |
155 break; | |
156 case C_NINJA: | |
157 abil = "Ninja"; | |
158 break; | |
159 case C_DRUID: | |
160 abil = "Druid"; | |
161 break; | |
162 default: | |
163 abil = "(unknown)"; | |
164 } | |
165 waddstr(win, abil); | |
166 } | |
167 | |
168 | |
169 /* | |
170 get_bool() | |
171 allow changing a boolean option and print it out | |
172 */ | |
173 | |
174 int | |
175 get_bool(opt_arg *opt, WINDOW *win) | |
176 { | |
177 int oy, ox; | |
178 int op_bad; | |
179 | |
180 op_bad = TRUE; | |
181 getyx(win, oy, ox); | |
182 waddstr(win, *opt->iarg ? "True" : "False"); | |
183 | |
184 while(op_bad) | |
185 { | |
186 wmove(win, oy, ox); | |
187 wrefresh(win); | |
188 | |
189 switch (readcharw(win)) | |
190 { | |
191 case 't': | |
192 case 'T': | |
193 *opt->iarg = TRUE; | |
194 op_bad = FALSE; | |
195 break; | |
196 | |
197 case 'f': | |
198 case 'F': | |
199 *opt->iarg = FALSE; | |
200 op_bad = FALSE; | |
201 break; | |
202 | |
203 case '\n': | |
204 case '\r': | |
205 op_bad = FALSE; | |
206 break; | |
207 | |
208 case '\033': | |
209 case '\007': | |
210 return QUIT; | |
211 | |
212 case '-': | |
213 return MINUS; | |
214 | |
215 default: | |
216 mvwaddstr(win, oy, ox + 10, "(T or F)"); | |
217 } | |
218 } | |
219 | |
220 wmove(win, oy, ox); | |
221 wclrtoeol(win); | |
222 waddstr(win, *opt->iarg ? "True" : "False"); | |
223 waddch(win, '\n'); | |
224 | |
225 return(NORM); | |
226 } | |
227 | |
228 /* | |
229 get_str() | |
230 set a string option | |
231 */ | |
232 | |
233 int | |
234 get_str(opt_arg *opt, WINDOW *win) | |
235 { | |
236 return( get_string(opt->str, win) ); | |
237 } | |
238 | |
239 /* | |
240 get_abil() | |
241 The ability field is read-only | |
242 */ | |
243 | |
244 int | |
245 get_abil(opt_arg *opt, WINDOW *win) | |
246 { | |
247 int oy, ox, ny, nx; | |
248 int op_bad; | |
249 | |
250 op_bad = TRUE; | |
251 getyx(win, oy, ox); | |
252 put_abil(opt, win); | |
253 getyx(win, ny, nx); | |
254 | |
255 while(op_bad) | |
256 { | |
257 wmove(win, oy, ox); | |
258 wrefresh(win); | |
259 | |
260 switch(readcharw(win)) | |
261 { | |
262 case '\n': | |
263 case '\r': | |
264 op_bad = FALSE; | |
265 break; | |
266 | |
267 case '\033': | |
268 case '\007': | |
269 return(QUIT); | |
270 | |
271 case '-': | |
272 return(MINUS); | |
273 | |
274 default: | |
275 mvwaddstr(win, ny, nx + 5, "(no change allowed)"); | |
276 } | |
277 } | |
278 | |
279 wmove(win, ny, nx + 5); | |
280 wclrtoeol(win); | |
281 wmove(win, ny, nx); | |
282 waddch(win, '\n'); | |
283 | |
284 return(NORM); | |
285 } | |
286 | |
287 | |
288 /* | |
289 parse_opts() | |
290 parse options from string, usually taken from the environment. the | |
291 string is a series of comma seperated values, with booleans being | |
292 stated as "name" (true) or "noname" (false), and strings being | |
293 "name=....", with the string being defined up to a comma or the | |
294 end of the entire option string. | |
295 */ | |
296 | |
297 void | |
298 parse_opts(char *str) | |
299 { | |
300 char *sp; | |
301 const OPTION *op; | |
302 size_t len; | |
303 | |
304 while (*str) | |
305 { | |
306 for (sp = str; isalpha(*sp); sp++) | |
307 continue; | |
308 | |
309 len = sp - str; | |
310 | |
311 /* Look it up and deal with it */ | |
312 | |
313 for (op = optlist; op < &optlist[NUM_OPTS]; op++) | |
314 if (EQSTR(str, op->o_name, len)) | |
315 { | |
316 if (op->o_putfunc == put_bool) | |
317 *op->o_opt.iarg = TRUE; | |
318 else /* string option */ | |
319 { | |
320 char *start; | |
321 char value[80]; | |
322 | |
323 /* Skip to start of string value */ | |
324 | |
325 for (str = sp + 1; *str == '='; str++) | |
326 continue; | |
327 | |
328 start = (char *) value; | |
329 | |
330 /* Skip to end of string value */ | |
331 | |
332 for (sp = str + 1; *sp && *sp != ','; sp++) | |
333 continue; | |
334 | |
335 strncpy(start, str, sp - str); | |
336 | |
337 /* Put the value into the option field */ | |
338 | |
339 if (op->o_putfunc != put_abil && | |
340 op->o_putfunc != put_inv) | |
341 strcpy(op->o_opt.str, value); | |
342 | |
343 if (op->o_putfunc == put_inv) | |
344 { | |
345 int *opt = op->o_opt.iarg; | |
346 | |
347 len = strlen(value); | |
348 | |
349 if (isupper(value[0])) | |
350 value[0] = (char) tolower(value[0]); | |
351 if (EQSTR(value, "overwrite",len)) | |
352 *opt = INV_OVER; | |
353 if (EQSTR(value, "slow", len)) | |
354 *opt = INV_SLOW; | |
355 if (EQSTR(value, "clear", len)) | |
356 *opt = INV_CLEAR; | |
357 } | |
358 else if (*op->o_opt.iarg == -1) | |
359 { | |
360 int *opt = op->o_opt.iarg; | |
361 | |
362 len = strlen(value); | |
363 | |
364 if (isupper(value[0])) | |
365 value[0] = (char) tolower(value[0]); | |
366 if (EQSTR(value, "fighter", len)) | |
367 *opt = C_FIGHTER; | |
368 else if (EQSTR(value, "magic", min(len, 5))) | |
369 *opt = C_MAGICIAN; | |
370 else if (EQSTR(value, "illus", min(len, 5))) | |
371 *opt = C_ILLUSION; | |
372 else if (EQSTR(value, "cleric", len)) | |
373 *opt = C_CLERIC; | |
374 else if (EQSTR(value, "thief", len)) | |
375 *opt = C_THIEF; | |
376 else if (EQSTR(value, "paladin", len)) | |
377 *opt = C_PALADIN; |