1 #include "angband.h"
2
3 /* Hack - main-gcu.c wants to set this to TRUE */
4 bool multi_key_macros = FALSE;
5
6 static bool flush_later = FALSE;
7
move_cursor(int row,int col)8 void move_cursor(int row, int col)
9 {
10 Term_gotoxy(col, row);
11 }
12
flush(void)13 void flush(void)
14 {
15 flush_later = TRUE;
16 }
17
18
19 /*
20 * XXX -- Temporary version of "inkey" with no macros
21 */
inkey(void)22 char inkey(void)
23 {
24 char ch;
25
26 /* Refresh screen */
27 Term_fresh();
28
29 /* Check for flush */
30 if (flush_later)
31 {
32 /* Flush input */
33 Term_flush();
34
35 /* Clear the flag */
36 flush_later = FALSE;
37 }
38
39 (void)(Term_inkey(&ch, TRUE, TRUE));
40
41 return ch;
42 }
43
44
45 /*
46 * Flush the screen, make a noise
47 */
bell(void)48 void bell(void)
49 {
50 /* Mega-Hack -- Flush the output */
51 Term_fresh();
52
53 /* Make a bell noise (if allowed) */
54 /*if (ring_bell)*/ Term_xtra(TERM_XTRA_NOISE, 0);
55
56 /* Flush the input (later!) */
57 flush();
58 }
59
60 /*
61 * Display a string on the screen using an attribute, and clear
62 * to the end of the line.
63 */
c_prt(byte attr,cptr str,int row,int col)64 void c_prt(byte attr, cptr str, int row, int col)
65 {
66 /* Hack -- fake monochrome */
67 /* if (!use_color) attr = TERM_WHITE; */
68
69 /* Clear line, position cursor */
70 Term_erase(col, row, 255);
71
72 /* Dump the attr/text */
73 Term_addstr(-1, attr, str);
74 }
75
76 /*
77 * As above, but in "white"
78 */
prt(cptr str,int row,int col)79 void prt(cptr str, int row, int col)
80 {
81 /* Spawn */
82 c_prt(TERM_WHITE, str, row, col);
83 }
84
85 /*
86 * Get some input at the cursor location.
87 * Assume the buffer is initialized to a default string.
88 * Note that this string is often "empty" (see below).
89 * The default buffer is displayed in yellow until cleared.
90 * Pressing RETURN right away accepts the default entry.
91 * Normal chars clear the default and append the char.
92 * Backspace clears the default or deletes the final char.
93 * ESCAPE clears the buffer and the window and returns FALSE.
94 * RETURN accepts the current buffer contents and returns TRUE.
95 */
96
97 /* APD -- added private so passwords will not be displayed. */
askfor_aux(char * buf,int len,char private)98 bool askfor_aux(char *buf, int len, char private)
99 {
100 int y, x;
101
102 int i = 0;
103
104 int k = 0;
105
106 bool done = FALSE;
107
108
109 /* Locate the cursor */
110 Term_locate(&x, &y);
111
112 /* Paranoia -- check len */
113 if (len < 1) len = 1;
114
115 /* Paranoia -- check column */
116 if ((x < 0) || (x >= 80)) x = 0;
117
118 /* Restrict the length */
119 if (x + len > 80) len = 80 - x;
120
121
122 /* Paranoia -- Clip the default entry */
123 buf[len] = '\0';
124
125
126 /* Display the default answer */
127 Term_erase(x, y, len);
128 Term_putstr(x, y, -1, TERM_YELLOW, buf);
129
130
131 /* Process input */
132 while (!done)
133 {
134 /* Place cursor */
135 Term_gotoxy(x + k, y);
136
137 /* Get a key */
138 i = inkey();
139
140 /* Analyze the key */
141 switch (i)
142 {
143 case ESCAPE:
144 k = 0;
145 done = TRUE;
146 break;
147
148 case '\n':
149 case '\r':
150 k = strlen(buf);
151 done = TRUE;
152 break;
153
154 case 0x7F:
155 case '\010':
156 if (k > 0) k--;
157 break;
158
159 default:
160 if ((k < len) && (isprint(i)))
161 {
162 buf[k++] = i;
163 }
164 else
165 {
166 bell();
167 }
168 break;
169 }
170
171 /* Terminate */
172 buf[k] = '\0';
173
174 /* Update the entry */
175 if (!private)
176 {
177 Term_erase(x, y, len);
178 Term_putstr(x, y, -1, TERM_WHITE, buf);
179 }
180 else
181 {
182 Term_erase(x+k, y, len-k);
183 if(k) Term_putch(x+k-1, y, TERM_WHITE, 'x');
184 }
185 }
186
187 /* Aborted */
188 if (i == ESCAPE) return (FALSE);
189
190 /* Success */
191 return (TRUE);
192 }
193
194
195
196 /*
197 * Get a string from the user
198 *
199 * The "prompt" should take the form "Prompt: "
200 *
201 * Note that the initial contents of the string is used as
202 * the default response, so be sure to "clear" it if needed.
203 *
204 * We clear the input, and return FALSE, on "ESCAPE".
205 */
get_string(cptr prompt,char * buf,int len)206 bool get_string(cptr prompt, char *buf, int len)
207 {
208 bool res;
209
210 /* Display prompt */
211 prt(prompt, 0, 0);
212
213 /* Ask the user for a string */
214 res = askfor_aux(buf, len, 0);
215
216 /* Clear prompt */
217 prt("", 0, 0);
218
219 /* Result */
220 return (res);
221 }
222
223 /*
224 * Prompts for a keypress
225 *
226 * The "prompt" should take the form "Command: "
227 *
228 * Returns TRUE unless the character is "Escape"
229 */
get_com(cptr prompt,char * command)230 bool get_com(cptr prompt, char *command)
231 {
232 /* Display a prompt */
233 prt(prompt, 0, 0);
234
235 /* Get a key */
236 *command = inkey();
237
238 /* Clear the prompt */
239 prt("", 0, 0);
240
241 /* Handle "cancel" */
242 if (*command == ESCAPE) return (FALSE);
243
244 /* Success */
245 return (TRUE);
246 }
247
248
249 /*
250 * Request a command from the user.
251 *
252 * Sets command_cmd, command_dir, command_rep, command_arg.
253 *
254 * Note that "caret" ("^") is treated special, and is used to
255 * allow manual input of control characters. This can be used
256 * on many machines to request repeated tunneling (Ctrl-H) and
257 * on the Macintosh to request "Control-Caret".
258 *
259 * Note that this command is used both in the dungeon and in
260 * stores, and must be careful to work in both situations.
261 */
request_command(bool shopping)262 void request_command(bool shopping)
263 {
264 char cmd;
265
266
267 /* Flush the input */
268 /* flush(); */
269
270 /* Get a command */
271 cmd = inkey();
272
273 /* Return if no key was pressed */
274 if (!cmd) return;
275
276 /* Clear top line */
277 prt("", 0, 0);
278
279 /* Bypass "keymap" */
280 if (cmd == '\\')
281 {
282 /* Get a char to use without casting */
283 (void)(get_com("Command: ", &cmd));
284
285 /* Hack -- allow "control chars" to be entered */
286 if (cmd == '^')
287 {
288 /* Get a char to "cast" into a control char */
289 (void)(get_com("Command: Control: ", &cmd));
290
291 /* Convert */
292 cmd = KTRL(cmd);
293 }
294
295 /* Use the key directly */
296 command_cmd = cmd;
297 }
298
299 else
300 {
301 /* Hack -- allow "control chars" to be entered */
302 if (cmd == '^')
303 {
304 /* Get a char to "cast" into a control char */
305 (void)(get_com("Control: ", &cmd));
306
307 /* Convert */
308 cmd = KTRL(cmd);
309 }
310
311 /* Use the key directly */
312 command_cmd = cmd;
313 }
314
315 /* Paranoia */
316 if (!command_cmd) command_cmd = ESCAPE;
317
318 /* Hack -- erase the message line. */
319 prt("", 0, 0);
320 }
321
322 /*
323 * Display a string on the screen using an attribute.
324 *
325 * At the given location, using the given attribute, if allowed,
326 * add the given string. Do not clear the line.
327 */
c_put_str(byte attr,cptr str,int row,int col)328 void c_put_str(byte attr, cptr str, int row, int col)
329 {
330 /* Position cursor, Dump the attr/text */
331 Term_putstr(col, row, -1, attr, str);
332 }
333
334
335 /*
336 * As above, but in "white"
337 */
put_str(cptr str,int row,int col)338 void put_str(cptr str, int row, int col)
339 {
340 /* Spawn */
341 Term_putstr(col, row, -1, TERM_WHITE, str);
342 }
343
344 /*
345 * Verify something with the user
346 *
347 * The "prompt" should take the form "Query? "
348 *
349 * Note that "[y/n]" is appended to the prompt.
350 */
get_check(cptr prompt)351 bool get_check(cptr prompt)
352 {
353 int i;
354
355 char buf[80];
356
357 /* Hack -- Build a "useful" prompt */
358 strnfmt(buf, 78, "%.70s[y/n] ", prompt);
359
360 /* Prompt for it */
361 prt(buf, 0, 0);
362
363 /* Get an acceptable answer */
364 while (TRUE)
365 {
366 i = inkey();
367 if (i == ESCAPE) break;
368 if (strchr("YyNn", i)) break;
369 bell();
370 }
371
372 /* Erase the prompt */
373 prt("", 0, 0);
374
375 /* Normal negation */
376 if ((i != 'Y') && (i != 'y')) return (FALSE);
377
378 /* Success */
379 return (TRUE);
380 }
381
382
383 /*
384 * Request a "quantity" from the user
385 *
386 * Hack -- allow "command_arg" to specify a quantity
387 */
c_get_quantity(cptr prompt,int max)388 s16b c_get_quantity(cptr prompt, int max)
389 {
390 int amt;
391
392 char tmp[80];
393
394 char buf[80];
395
396
397 /* Build a prompt if needed */
398 if (!prompt)
399 {
400 /* Build a prompt */
401 sprintf(tmp, "Quantity (1-%d): ", max);
402
403 /* Use that prompt */
404 prompt = tmp;
405 }
406
407
408 /* Default to one */
409 amt = 1;
410
411 /* Build the default */
412 sprintf(buf, "%d", amt);
413
414 /* Ask for a quantity */
415 if (!get_string(prompt, buf, 6)) return (0);
416
417 /* Extract a number */
418 amt = atoi(buf);
419
420 /* A letter means "all" */
421 if (isalpha(buf[0])) amt = max;
422
423 /* Enforce the maximum */
424 if (amt > max) amt = max;
425
426 /* Enforce the minimum */
427 if (amt < 0) amt = 0;
428
429 /* Return the result */
430 return (amt);
431 }
432
clear_from(int row)433 void clear_from(int row)
434 {
435 int y;
436
437 /* Erase requested rows */
438 for (y = row; y < Term->hgt; y++)
439 {
440 /* Erase part of the screen */
441 Term_erase(0, y, 255);
442 }
443 }
444
prt_num(cptr header,int num,int row,int col,byte color)445 void prt_num(cptr header, int num, int row, int col, byte color)
446 {
447 int len = strlen(header);
448 char out_val[32];
449 put_str(header, row, col);
450 put_str(" ", row, col + len);
451 (void)sprintf(out_val, "%6d", num);
452 c_put_str(color, out_val, row, col + len + 3);
453 }
454
prt_lnum(cptr header,s32b num,int row,int col,byte color)455 void prt_lnum(cptr header, s32b num, int row, int col, byte color)
456 {
457 int len = strlen(header);
458 char out_val[32];
459 put_str(header, row, col);
460 (void)sprintf(out_val, "%9d", num);
461 c_put_str(color, out_val, row, col + len);
462 }
463
464
465 #ifdef SET_UID
466
467 # ifndef HAS_USLEEP
468
469 /*
470 * For those systems that don't have "usleep()" but need it.
471 *
472 * Fake "usleep()" function grabbed from the inl netrek server -cba
473 */
usleep(huge microSeconds)474 int usleep(huge microSeconds)
475 {
476 struct timeval Timer;
477
478 int nfds = 0;
479
480 #ifdef FD_SET
481 fd_set *no_fds = NULL;
482 #else
483 int *no_fds = NULL;
484 #endif
485
486 /* Was: int readfds, writefds, exceptfds; */
487 /* Was: readfds = writefds = exceptfds = 0; */
488
489
490 /* Paranoia -- No excessive sleeping */
491 if (microSeconds > 4000000L) core("Illegal usleep() call");
492
493
494 /* Wait for it */
495 Timer.tv_sec = (microSeconds / 1000000L);
496 Timer.tv_usec = (microSeconds % 1000000L);
497
498 /* Wait for it */
499 if (select(nfds, no_fds, no_fds, no_fds, &Timer) < 0)
500 {
501 /* Hack -- ignore interrupts */
502 if (errno != EINTR) return -1;
503 }
504
505 /* Success */
506 return 0;
507 }
508
509 # endif /* HAS_USLEEP */
510
511 #endif /* SET_UID */
512
513 #ifdef WIN32
usleep(long microSeconds)514 int usleep(long microSeconds)
515 {
516 Sleep(microSeconds/10); /* meassured in milliseconds not microseconds*/
517 }
518 #endif /* WIN32 */
519