OSDN Git Service

c8ec313f1839183625ca69c5027ad876fb93f3fc
[hengband/hengband.git] / src / util.c
1 /* File: util.c */
2
3 /* Purpose: Angband utilities -BEN- */
4
5
6 #include "angband.h"
7
8
9
10
11 static int num_more = 0;
12
13 #ifndef HAS_MEMSET
14
15 /*
16  * For those systems that don't have "memset()"
17  *
18  * Set the value of each of 'n' bytes starting at 's' to 'c', return 's'
19  * If 'n' is negative, you will erase a whole lot of memory.
20  */
21 char *memset(char *s, int c, huge n)
22 {
23         char *t;
24         for (t = s; len--; ) *t++ = c;
25         return (s);
26 }
27
28 #endif
29
30
31 #if 0
32 #ifndef HAS_STRICMP
33
34 /*
35  * For those systems that don't have "stricmp()"
36  *
37  * Compare the two strings "a" and "b" ala "strcmp()" ignoring case.
38  */
39 int stricmp(cptr a, cptr b)
40 {
41         cptr s1, s2;
42         char z1, z2;
43
44         /* Scan the strings */
45         for (s1 = a, s2 = b; TRUE; s1++, s2++)
46         {
47                 z1 = FORCEUPPER(*s1);
48                 z2 = FORCEUPPER(*s2);
49                 if (z1 < z2) return (-1);
50                 if (z1 > z2) return (1);
51                 if (!z1) return (0);
52         }
53 }
54
55 #endif /* HAS_STRICMP */
56 #endif /* 0 */
57
58 #ifdef SET_UID
59
60 # ifndef HAS_USLEEP
61
62 /*
63  * For those systems that don't have "usleep()" but need it.
64  *
65  * Fake "usleep()" function grabbed from the inl netrek server -cba
66  */
67 int usleep(huge usecs)
68 {
69         struct timeval      Timer;
70
71         int                 nfds = 0;
72
73 #ifdef FD_SET
74         fd_set          *no_fds = NULL;
75 #else
76         int                     *no_fds = NULL;
77 #endif
78
79
80         /* Was: int readfds, writefds, exceptfds; */
81         /* Was: readfds = writefds = exceptfds = 0; */
82
83
84         /* Paranoia -- No excessive sleeping */
85 #ifdef JP
86         if (usecs > 4000000L) core("ÉÔÅö¤Ê usleep() ¸Æ¤Ó½Ð¤·");
87 #else
88         if (usecs > 4000000L) core("Illegal usleep() call");
89 #endif
90
91
92
93         /* Wait for it */
94         Timer.tv_sec = (usecs / 1000000L);
95         Timer.tv_usec = (usecs % 1000000L);
96
97         /* Wait for it */
98         if (select(nfds, no_fds, no_fds, no_fds, &Timer) < 0)
99         {
100                 /* Hack -- ignore interrupts */
101                 if (errno != EINTR) return -1;
102         }
103
104         /* Success */
105         return 0;
106 }
107
108 # endif
109
110
111 /*
112 * Hack -- External functions
113 */
114 extern struct passwd *getpwuid();
115 extern struct passwd *getpwnam();
116
117
118 /*
119  * Find a default user name from the system.
120  */
121 void user_name(char *buf, int id)
122 {
123 #ifdef SET_UID
124         struct passwd *pw;
125
126         /* Look up the user name */
127         if ((pw = getpwuid(id)))
128         {
129                 (void)strcpy(buf, pw->pw_name);
130                 buf[16] = '\0';
131
132 #ifdef CAPITALIZE_USER_NAME
133                 /* Hack -- capitalize the user name */
134 #ifdef JP
135                 if (!iskanji(buf[0]))
136 #endif
137                         if (islower(buf[0]))
138                                 buf[0] = toupper(buf[0]);
139 #endif /* CAPITALIZE_USER_NAME */
140
141                 return;
142         }
143 #endif /* SET_UID */
144
145         /* Oops.  Hack -- default to "PLAYER" */
146         strcpy(buf, "PLAYER");
147 }
148
149 #endif /* SET_UID */
150
151
152
153
154 /*
155  * The concept of the "file" routines below (and elsewhere) is that all
156  * file handling should be done using as few routines as possible, since
157  * every machine is slightly different, but these routines always have the
158  * same semantics.
159  *
160  * In fact, perhaps we should use the "path_parse()" routine below to convert
161  * from "canonical" filenames (optional leading tilde's, internal wildcards,
162  * slash as the path seperator, etc) to "system" filenames (no special symbols,
163  * system-specific path seperator, etc).  This would allow the program itself
164  * to assume that all filenames are "Unix" filenames, and explicitly "extract"
165  * such filenames if needed (by "path_parse()", or perhaps "path_canon()").
166  *
167  * Note that "path_temp" should probably return a "canonical" filename.
168  *
169  * Note that "my_fopen()" and "my_open()" and "my_make()" and "my_kill()"
170  * and "my_move()" and "my_copy()" should all take "canonical" filenames.
171  *
172  * Note that "canonical" filenames use a leading "slash" to indicate an absolute
173  * path, and a leading "tilde" to indicate a special directory, and default to a
174  * relative path, but MSDOS uses a leading "drivename plus colon" to indicate the
175  * use of a "special drive", and then the rest of the path is parsed "normally",
176  * and MACINTOSH uses a leading colon to indicate a relative path, and an embedded
177  * colon to indicate a "drive plus absolute path", and finally defaults to a file
178  * in the current working directory, which may or may not be defined.
179  *
180  * We should probably parse a leading "~~/" as referring to "ANGBAND_DIR". (?)
181  */
182
183
184 #ifdef ACORN
185
186
187 /*
188  * Most of the "file" routines for "ACORN" should be in "main-acn.c"
189  */
190
191
192 #else /* ACORN */
193
194
195 #ifdef SET_UID
196
197 /*
198  * Extract a "parsed" path from an initial filename
199  * Normally, we simply copy the filename into the buffer
200  * But leading tilde symbols must be handled in a special way
201  * Replace "~user/" by the home directory of the user named "user"
202  * Replace "~/" by the home directory of the current user
203  */
204 errr path_parse(char *buf, int max, cptr file)
205 {
206         cptr            u, s;
207         struct passwd   *pw;
208         char            user[128];
209
210
211         /* Assume no result */
212         buf[0] = '\0';
213
214         /* No file? */
215         if (!file) return (-1);
216
217         /* File needs no parsing */
218         if (file[0] != '~')
219         {
220                 strcpy(buf, file);
221                 return (0);
222         }
223
224         /* Point at the user */
225         u = file+1;
226
227         /* Look for non-user portion of the file */
228         s = strstr(u, PATH_SEP);
229
230         /* Hack -- no long user names */
231         if (s && (s >= u + sizeof(user))) return (1);
232
233         /* Extract a user name */
234         if (s)
235         {
236                 int i;
237                 for (i = 0; u < s; ++i) user[i] = *u++;
238                 user[i] = '\0';
239                 u = user;
240         }
241
242         /* Look up the "current" user */
243         if (u[0] == '\0') u = getlogin();
244
245         /* Look up a user (or "current" user) */
246         if (u) pw = getpwnam(u);
247         else pw = getpwuid(getuid());
248
249         /* Nothing found? */
250         if (!pw) return (1);
251
252         /* Make use of the info */
253         (void)strcpy(buf, pw->pw_dir);
254
255         /* Append the rest of the filename, if any */
256         if (s) (void)strcat(buf, s);
257
258         /* Success */
259         return (0);
260 }
261
262
263 #else /* SET_UID */
264
265
266 /*
267  * Extract a "parsed" path from an initial filename
268  *
269  * This requires no special processing on simple machines,
270  * except for verifying the size of the filename.
271  */
272 errr path_parse(char *buf, int max, cptr file)
273 {
274         /* Accept the filename */
275         (void)strnfmt(buf, max, "%s", file);
276
277         /* Success */
278         return (0);
279 }
280
281
282 #endif /* SET_UID */
283
284
285 #ifndef HAVE_MKSTEMP
286
287 /*
288  * Hack -- acquire a "temporary" file name if possible
289  *
290  * This filename is always in "system-specific" form.
291  */
292 static errr path_temp(char *buf, int max)
293 {
294         cptr s;
295
296         /* Temp file */
297         s = tmpnam(NULL);
298
299         /* Oops */
300         if (!s) return (-1);
301
302         /* Format to length */
303         (void)strnfmt(buf, max, "%s", s);
304
305         /* Success */
306         return (0);
307 }
308
309 #endif
310
311 /*
312  * Create a new path by appending a file (or directory) to a path.
313  *
314  * This requires no special processing on simple machines, except
315  * for verifying the size of the filename, but note the ability to
316  * bypass the given "path" with certain special file-names.
317  *
318  * Note that the "file" may actually be a "sub-path", including
319  * a path and a file.
320  *
321  * Note that this function yields a path which must be "parsed"
322  * using the "parse" function above.
323  */
324 errr path_build(char *buf, int max, cptr path, cptr file)
325 {
326         /* Special file */
327         if (file[0] == '~')
328         {
329                 /* Use the file itself */
330                 (void)strnfmt(buf, max, "%s", file);
331         }
332
333         /* Absolute file, on "normal" systems */
334         else if (prefix(file, PATH_SEP) && !streq(PATH_SEP, ""))
335         {
336                 /* Use the file itself */
337                 (void)strnfmt(buf, max, "%s", file);
338         }
339
340         /* No path given */
341         else if (!path[0])
342         {
343                 /* Use the file itself */
344                 (void)strnfmt(buf, max, "%s", file);
345         }
346
347         /* Path and File */
348         else
349         {
350                 /* Build the new path */
351                 (void)strnfmt(buf, max, "%s%s%s", path, PATH_SEP, file);
352         }
353
354         /* Success */
355         return (0);
356 }
357
358
359 /*
360  * Hack -- replacement for "fopen()"
361  */
362 FILE *my_fopen(cptr file, cptr mode)
363 {
364         char buf[1024];
365
366         /* Hack -- Try to parse the path */
367         if (path_parse(buf, 1024, file)) return (NULL);
368
369         /* Attempt to fopen the file anyway */
370         return (fopen(buf, mode));
371 }
372
373
374 /*
375  * Hack -- replacement for "fclose()"
376  */
377 errr my_fclose(FILE *fff)
378 {
379         /* Require a file */
380         if (!fff) return (-1);
381
382         /* Close, check for error */
383         if (fclose(fff) == EOF) return (1);
384
385         /* Success */
386         return (0);
387 }
388
389
390 #endif /* ACORN */
391
392
393 #ifdef HAVE_MKSTEMP
394
395 FILE *my_fopen_temp(char *buf, int max)
396 {
397         int fd;
398
399         /* Prepare the buffer for mkstemp */
400         strncpy(buf, "/tmp/anXXXXXX", max);
401
402         /* Secure creation of a temporary file */
403         fd = mkstemp(buf);
404
405         /* Check the file-descriptor */
406         if (fd < 0) return (NULL);
407
408         /* Return a file stream */
409         return (fdopen(fd, "w"));
410 }
411
412 #else /* HAVE_MKSTEMP */
413
414 FILE *my_fopen_temp(char *buf, int max)
415 {
416         /* Generate a temporary filename */
417         if (path_temp(buf, max)) return (NULL);
418
419         /* Open the file */
420         return (my_fopen(buf, "w"));
421 }
422
423 #endif /* HAVE_MKSTEMP */
424
425
426 /*
427  * Hack -- replacement for "fgets()"
428  *
429  * Read a string, without a newline, to a file
430  *
431  * Process tabs, strip internal non-printables
432  */
433 errr my_fgets(FILE *fff, char *buf, huge n)
434 {
435         huge i = 0;
436
437         char *s;
438
439         char tmp[1024];
440
441         /* Read a line */
442         if (fgets(tmp, 1024, fff))
443         {
444                 /* Convert weirdness */
445                 for (s = tmp; *s; s++)
446                 {
447                         /* Handle newline */
448                         if (*s == '\n')
449                         {
450                                 /* Terminate */
451                                 buf[i] = '\0';
452
453                                 /* Success */
454                                 return (0);
455                         }
456
457                         /* Handle tabs */
458                         else if (*s == '\t')
459                         {
460                                 /* Hack -- require room */
461                                 if (i + 8 >= n) break;
462
463                                 /* Append a space */
464                                 buf[i++] = ' ';
465
466                                 /* Append some more spaces */
467                                 while (!(i % 8)) buf[i++] = ' ';
468                         }
469
470 #ifdef JP
471                         else if (iskanji(*s))
472                         {
473                                 if (!s[1]) break;
474                                 buf[i++] = *s++;
475                                 buf[i++] = *s;
476                         }
477 # ifndef EUC
478         /* È¾³Ñ¤«¤Ê¤ËÂбþ */
479                         else if ((((int)*s & 0xff) > 0xa1) && (((int)*s & 0xff ) < 0xdf))
480                         {
481                                 buf[i++] = *s;
482                                 if (i >= n) break;
483                         }
484 # endif
485 #endif
486                         /* Handle printables */
487                         else if (isprint(*s))
488                         {
489                                 /* Copy */
490                                 buf[i++] = *s;
491
492                                 /* Check length */
493                                 if (i >= n) break;
494                         }
495                 }
496                 /* No newline character, but terminate */
497                 buf[i] = '\0';
498
499                 /* Success */
500                 return (0);
501         }
502
503         /* Nothing */
504         buf[0] = '\0';
505
506         /* Failure */
507         return (1);
508 }
509
510
511 /*
512  * Hack -- replacement for "fputs()"
513  *
514  * Dump a string, plus a newline, to a file
515  *
516  * XXX XXX XXX Process internal weirdness?
517  */
518 errr my_fputs(FILE *fff, cptr buf, huge n)
519 {
520         /* XXX XXX */
521         n = n ? n : 0;
522
523         /* Dump, ignore errors */
524         (void)fprintf(fff, "%s\n", buf);
525
526         /* Success */
527         return (0);
528 }
529
530
531 #ifdef ACORN
532
533
534 /*
535  * Most of the "file" routines for "ACORN" should be in "main-acn.c"
536  *
537  * Many of them can be rewritten now that only "fd_open()" and "fd_make()"
538  * and "my_fopen()" should ever create files.
539  */
540
541
542 #else /* ACORN */
543
544
545 /*
546  * Code Warrior is a little weird about some functions
547  */
548 #ifdef BEN_HACK
549 extern int open(const char *, int, ...);
550 extern int close(int);
551 extern int read(int, void *, unsigned int);
552 extern int write(int, const void *, unsigned int);
553 extern long lseek(int, long, int);
554 #endif /* BEN_HACK */
555
556
557 /*
558  * The Macintosh is a little bit brain-dead sometimes
559  */
560 #ifdef MACINTOSH
561 # define open(N,F,M) \
562 ((M), open((char*)(N),F))
563 # define write(F,B,S) \
564 write(F,(char*)(B),S)
565 #endif /* MACINTOSH */
566
567
568 /*
569  * Several systems have no "O_BINARY" flag
570  */
571 #ifndef O_BINARY
572 # define O_BINARY 0
573 #endif /* O_BINARY */
574
575
576 /*
577  * Hack -- attempt to delete a file
578  */
579 errr fd_kill(cptr file)
580 {
581         char buf[1024];
582
583         /* Hack -- Try to parse the path */
584         if (path_parse(buf, 1024, file)) return (-1);
585
586         /* Remove */
587         (void)remove(buf);
588
589         /* XXX XXX XXX */
590         return (0);
591 }
592
593
594 /*
595  * Hack -- attempt to move a file
596  */
597 errr fd_move(cptr file, cptr what)
598 {
599         char buf[1024];
600         char aux[1024];
601
602         /* Hack -- Try to parse the path */
603         if (path_parse(buf, 1024, file)) return (-1);
604
605         /* Hack -- Try to parse the path */
606         if (path_parse(aux, 1024, what)) return (-1);
607
608         /* Rename */
609         (void)rename(buf, aux);
610
611         /* XXX XXX XXX */
612         return (0);
613 }
614
615
616 /*
617  * Hack -- attempt to copy a file
618  */
619 errr fd_copy(cptr file, cptr what)
620 {
621         char buf[1024];
622         char aux[1024];
623         int read_num;
624         int src_fd, dst_fd;
625
626         /* Hack -- Try to parse the path */
627         if (path_parse(buf, 1024, file)) return (-1);
628
629         /* Hack -- Try to parse the path */
630         if (path_parse(aux, 1024, what)) return (-1);
631
632         /* Open source file */
633         src_fd = fd_open(buf, O_RDONLY);
634         if (src_fd < 0) return (-1);
635
636         /* Open destination file */
637         dst_fd = fd_open(aux, O_WRONLY|O_TRUNC|O_CREAT);
638         if (dst_fd < 0) return (-1);
639
640         /* Copy */
641         while ((read_num = read(src_fd, buf, 1024)) > 0)
642         {
643                 write(dst_fd, buf, read_num);
644         }
645
646         /* Close files */
647         fd_close(src_fd);
648         fd_close(dst_fd);
649
650         /* XXX XXX XXX */
651         return (0);
652 }
653
654
655 /*
656  * Hack -- attempt to open a file descriptor (create file)
657  *
658  * This function should fail if the file already exists
659  *
660  * Note that we assume that the file should be "binary"
661  *
662  * XXX XXX XXX The horrible "BEN_HACK" code is for compiling under
663  * the CodeWarrior compiler, in which case, for some reason, none
664  * of the "O_*" flags are defined, and we must fake the definition
665  * of "O_RDONLY", "O_WRONLY", and "O_RDWR" in "A-win-h", and then
666  * we must simulate the effect of the proper "open()" call below.
667  */
668 int fd_make(cptr file, int mode)
669 {
670         char buf[1024];
671
672         /* Hack -- Try to parse the path */
673         if (path_parse(buf, 1024, file)) return (-1);
674
675 #ifdef BEN_HACK
676
677         /* Check for existance */
678         /* if (fd_close(fd_open(file, O_RDONLY | O_BINARY))) return (1); */
679
680         /* Mega-Hack -- Create the file */
681         (void)my_fclose(my_fopen(file, "wb"));
682
683         /* Re-open the file for writing */
684         return (open(buf, O_WRONLY | O_BINARY, mode));
685
686 #else /* BEN_HACK */
687
688         /* Create the file, fail if exists, write-only, binary */
689         return (open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode));
690
691 #endif /* BEN_HACK */
692
693 }
694
695
696 /*
697  * Hack -- attempt to open a file descriptor (existing file)
698  *
699  * Note that we assume that the file should be "binary"
700  */
701 int fd_open(cptr file, int flags)
702 {
703         char buf[1024];
704
705         /* Hack -- Try to parse the path */
706         if (path_parse(buf, 1024, file)) return (-1);
707
708         /* Attempt to open the file */
709         return (open(buf, flags | O_BINARY, 0));
710 }
711
712
713 /*
714  * Hack -- attempt to lock a file descriptor
715  *
716  * Legal lock types -- F_UNLCK, F_RDLCK, F_WRLCK
717  */
718 errr fd_lock(int fd, int what)
719 {
720         /* XXX XXX */
721         what = what ? what : 0;
722
723         /* Verify the fd */
724         if (fd < 0) return (-1);
725
726 #ifdef SET_UID
727
728 # ifdef USG
729
730 #  if defined(F_ULOCK) && defined(F_LOCK)
731
732         /* Un-Lock */
733         if (what == F_UNLCK)
734         {
735                 /* Unlock it, Ignore errors */
736                 lockf(fd, F_ULOCK, 0);
737         }
738
739         /* Lock */
740         else
741         {
742                 /* Lock the score file */
743                 if (lockf(fd, F_LOCK, 0) != 0) return (1);
744         }
745
746 #  endif
747
748 # else
749
750 #  if defined(LOCK_UN) && defined(LOCK_EX)
751
752         /* Un-Lock */
753         if (what == F_UNLCK)
754         {
755                 /* Unlock it, Ignore errors */
756                 (void)flock(fd, LOCK_UN);
757         }
758
759         /* Lock */
760         else
761         {
762                 /* Lock the score file */
763                 if (flock(fd, LOCK_EX) != 0) return (1);
764         }
765
766 #  endif
767
768 # endif
769
770 #endif
771
772         /* Success */
773         return (0);
774 }
775
776
777 /*
778  * Hack -- attempt to seek on a file descriptor
779  */
780 errr fd_seek(int fd, huge n)
781 {
782         huge p;
783
784         /* Verify fd */
785         if (fd < 0) return (-1);
786
787         /* Seek to the given position */
788         p = lseek(fd, n, SEEK_SET);
789
790         /* Failure */
791         if (p < 0) return (1);
792
793         /* Failure */
794         if (p != n) return (1);
795
796         /* Success */
797         return (0);
798 }
799
800
801 /*
802  * Hack -- attempt to truncate a file descriptor
803  */
804 errr fd_chop(int fd, huge n)
805 {
806         /* XXX XXX */
807         n = n ? n : 0;
808
809         /* Verify the fd */
810         if (fd < 0) return (-1);
811
812 #if defined(SUNOS) || defined(ULTRIX) || defined(NeXT)
813         /* Truncate */
814         ftruncate(fd, n);
815 #endif
816
817         /* Success */
818         return (0);
819 }
820
821
822 /*
823  * Hack -- attempt to read data from a file descriptor
824  */
825 errr fd_read(int fd, char *buf, huge n)
826 {
827         /* Verify the fd */
828         if (fd < 0) return (-1);
829
830 #ifndef SET_UID
831
832         /* Read pieces */
833         while (n >= 16384)
834         {
835                 /* Read a piece */
836                 if (read(fd, buf, 16384) != 16384) return (1);
837
838                 /* Shorten the task */
839                 buf += 16384;
840
841                 /* Shorten the task */
842                 n -= 16384;
843         }
844
845 #endif
846
847         /* Read the final piece */
848         if (read(fd, buf, n) != (int)n) return (1);
849
850         /* Success */
851         return (0);
852 }
853
854
855 /*
856  * Hack -- Attempt to write data to a file descriptor
857  */
858 errr fd_write(int fd, cptr buf, huge n)
859 {
860         /* Verify the fd */
861         if (fd < 0) return (-1);
862
863 #ifndef SET_UID
864
865         /* Write pieces */
866         while (n >= 16384)
867         {
868                 /* Write a piece */
869                 if (write(fd, buf, 16384) != 16384) return (1);
870
871                 /* Shorten the task */
872                 buf += 16384;
873
874                 /* Shorten the task */
875                 n -= 16384;
876         }
877
878 #endif
879
880         /* Write the final piece */
881         if (write(fd, buf, n) != (int)n) return (1);
882
883         /* Success */
884         return (0);
885 }
886
887
888 /*
889  * Hack -- attempt to close a file descriptor
890  */
891 errr fd_close(int fd)
892 {
893         /* Verify the fd */
894         if (fd < 0) return (-1);
895
896         /* Close */
897         (void)close(fd);
898
899         /* XXX XXX XXX */
900         return (0);
901 }
902
903
904 #endif /* ACORN */
905
906
907
908
909 /*
910  * XXX XXX XXX Important note about "colors" XXX XXX XXX
911  *
912  * The "TERM_*" color definitions list the "composition" of each
913  * "Angband color" in terms of "quarters" of each of the three color
914  * components (Red, Green, Blue), for example, TERM_UMBER is defined
915  * as 2/4 Red, 1/4 Green, 0/4 Blue.
916  *
917  * The following info is from "Torbjorn Lindgren" (see "main-xaw.c").
918  *
919  * These values are NOT gamma-corrected.  On most machines (with the
920  * Macintosh being an important exception), you must "gamma-correct"
921  * the given values, that is, "correct for the intrinsic non-linearity
922  * of the phosphor", by converting the given intensity levels based
923  * on the "gamma" of the target screen, which is usually 1.7 (or 1.5).
924  *
925  * The actual formula for conversion is unknown to me at this time,
926  * but you can use the table below for the most common gamma values.
927  *
928  * So, on most machines, simply convert the values based on the "gamma"
929  * of the target screen, which is usually in the range 1.5 to 1.7, and
930  * usually is closest to 1.7.  The converted value for each of the five
931  * different "quarter" values is given below:
932  *
933  *  Given     Gamma 1.0       Gamma 1.5       Gamma 1.7     Hex 1.7
934  *  -----       ----            ----            ----          ---
935  *   0/4        0.00            0.00            0.00          #00
936  *   1/4        0.25            0.27            0.28          #47
937  *   2/4        0.50            0.55            0.56          #8f
938  *   3/4        0.75            0.82            0.84          #d7
939  *   4/4        1.00            1.00            1.00          #ff
940  *
941  * Note that some machines (i.e. most IBM machines) are limited to a
942  * hard-coded set of colors, and so the information above is useless.
943  *
944  * Also, some machines are limited to a pre-determined set of colors,
945  * for example, the IBM can only display 16 colors, and only 14 of
946  * those colors resemble colors used by Angband, and then only when
947  * you ignore the fact that "Slate" and "cyan" are not really matches,
948  * so on the IBM, we use "orange" for both "Umber", and "Light Umber"
949  * in addition to the obvious "Orange", since by combining all of the
950  * "indeterminate" colors into a single color, the rest of the colors
951  * are left with "meaningful" values.
952  */
953
954
955 /*
956  * Move the cursor
957  */
958 void move_cursor(int row, int col)
959 {
960         Term_gotoxy(col, row);
961 }
962
963
964
965 /*
966  * Convert a decimal to a single digit octal number
967  */
968 static char octify(uint i)
969 {
970         return (hexsym[i%8]);
971 }
972
973 /*
974  * Convert a decimal to a single digit hex number
975  */
976 static char hexify(uint i)
977 {
978         return (hexsym[i%16]);
979 }
980
981
982 /*
983  * Convert a octal-digit into a decimal
984  */
985 static int deoct(char c)
986 {
987         if (isdigit(c)) return (D2I(c));
988         return (0);
989 }
990
991 /*
992  * Convert a hexidecimal-digit into a decimal
993  */
994 static int dehex(char c)
995 {
996         if (isdigit(c)) return (D2I(c));
997         if (islower(c)) return (A2I(c) + 10);
998         if (isupper(c)) return (A2I(tolower(c)) + 10);
999         return (0);
1000 }
1001
1002
1003 static int my_stricmp(cptr a, cptr b)
1004 {
1005         cptr s1, s2;
1006         char z1, z2;
1007
1008         /* Scan the strings */
1009         for (s1 = a, s2 = b; TRUE; s1++, s2++)
1010         {
1011                 z1 = FORCEUPPER(*s1);
1012                 z2 = FORCEUPPER(*s2);
1013                 if (z1 < z2) return (-1);
1014                 if (z1 > z2) return (1);
1015                 if (!z1) return (0);
1016         }
1017 }
1018
1019 static int my_strnicmp(cptr a, cptr b, int n)
1020 {
1021         cptr s1, s2;
1022         char z1, z2;
1023
1024         /* Scan the strings */
1025         for (s1 = a, s2 = b; n > 0; s1++, s2++, n--)
1026         {
1027                 z1 = FORCEUPPER(*s1);
1028                 z2 = FORCEUPPER(*s2);
1029                 if (z1 < z2) return (-1);
1030                 if (z1 > z2) return (1);
1031                 if (!z1) return (0);
1032         }
1033         return 0;
1034 }
1035
1036
1037 static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
1038 {
1039         char *s = *bufptr;
1040         cptr str = *strptr;
1041         bool mod_status[MAX_MACRO_MOD];
1042
1043         int i, len = 0;
1044         int shiftstatus = 0;
1045         cptr key_code;
1046
1047         if (macro_template == NULL)
1048                 return;
1049         
1050         for (i = 0; macro_modifier_chr[i]; i++)
1051                 mod_status[i] = FALSE;
1052         str++;
1053
1054         /* Examine modifier keys */
1055         while (1)
1056         {
1057                 for (i=0; macro_modifier_chr[i]; i++)
1058                 {
1059                         len = strlen(macro_modifier_name[i]);
1060                         
1061                         if(!my_strnicmp(str, macro_modifier_name[i], len))
1062                                 break;
1063                 }
1064                 if (!macro_modifier_chr[i]) break;
1065                 str += len;
1066                 mod_status[i] = TRUE;
1067                 if ('S' == macro_modifier_chr[i])
1068                         shiftstatus = 1;
1069         }
1070         for (i = 0; i < max_macrotrigger; i++)
1071         {
1072                 len = strlen(macro_trigger_name[i]);
1073                 if (!my_strnicmp(str, macro_trigger_name[i], len) && ']' == str[len])
1074                 {
1075                         /* a trigger name found */
1076                         break;
1077                 }
1078         }
1079         if (i == max_macrotrigger)
1080                 return;
1081         key_code = macro_trigger_keycode[shiftstatus][i];
1082         str += len;
1083
1084         *s++ = (char)31;
1085         for (i = 0; macro_template[i]; i++)
1086         {
1087                 char ch = macro_template[i];
1088                 int j;
1089
1090                 switch(ch)
1091                 {
1092                 case '&':
1093                         for (j = 0; macro_modifier_chr[j]; j++) {
1094                                 if (mod_status[j])
1095                                         *s++ = macro_modifier_chr[j];
1096                         }
1097                         break;
1098                 case '#':
1099                         strcpy(s, key_code);
1100                         s += strlen(key_code);
1101                         break;
1102                 default:
1103                         *s++ = ch;
1104                         break;
1105                 }
1106         }
1107         *s++ = (char)13;
1108
1109         *bufptr = s;
1110         *strptr = str; /* where **strptr == ']' */
1111         return;
1112 }
1113
1114
1115 /*
1116  * Hack -- convert a printable string into real ascii
1117  *
1118  * I have no clue if this function correctly handles, for example,
1119  * parsing "\xFF" into a (signed) char.  Whoever thought of making
1120  * the "sign" of a "char" undefined is a complete moron.  Oh well.
1121  */
1122 void text_to_ascii(char *buf, cptr str)
1123 {
1124         char *s = buf;
1125
1126         /* Analyze the "ascii" string */
1127         while (*str)
1128         {
1129                 /* Backslash codes */
1130                 if (*str == '\\')
1131                 {
1132                         /* Skip the backslash */
1133                         str++;
1134
1135                         /* Macro Trigger */
1136                         if (*str == '[')
1137                         {
1138                                 trigger_text_to_ascii(&s, &str);
1139                         }
1140                         else
1141
1142                         /* Hex-mode XXX */
1143                         if (*str == 'x')
1144                         {
1145                                 *s = 16 * dehex(*++str);
1146                                 *s++ += dehex(*++str);
1147                         }
1148
1149                         /* Hack -- simple way to specify "backslash" */
1150                         else if (*str == '\\')
1151                         {
1152                                 *s++ = '\\';
1153                         }
1154
1155                         /* Hack -- simple way to specify "caret" */
1156                         else if (*str == '^')
1157                         {
1158                                 *s++ = '^';
1159                         }
1160
1161                         /* Hack -- simple way to specify "space" */
1162                         else if (*str == 's')
1163                         {
1164                                 *s++ = ' ';
1165                         }
1166
1167                         /* Hack -- simple way to specify Escape */
1168                         else if (*str == 'e')
1169                         {
1170                                 *s++ = ESCAPE;
1171                         }
1172
1173                         /* Backspace */
1174                         else if (*str == 'b')
1175                         {
1176                                 *s++ = '\b';
1177                         }
1178
1179                         /* Newline */
1180                         else if (*str == 'n')
1181                         {
1182                                 *s++ = '\n';
1183                         }
1184
1185                         /* Return */
1186                         else if (*str == 'r')
1187                         {
1188                                 *s++ = '\r';
1189                         }
1190
1191                         /* Tab */
1192                         else if (*str == 't')
1193                         {
1194                                 *s++ = '\t';
1195                         }
1196
1197                         /* Octal-mode */
1198                         else if (*str == '0')
1199                         {
1200                                 *s = 8 * deoct(*++str);
1201                                 *s++ += deoct(*++str);
1202                         }
1203
1204                         /* Octal-mode */
1205                         else if (*str == '1')
1206                         {
1207                                 *s = 64 + 8 * deoct(*++str);
1208                                 *s++ += deoct(*++str);
1209                         }
1210
1211                         /* Octal-mode */
1212                         else if (*str == '2')
1213                         {
1214                                 *s = 64 * 2 + 8 * deoct(*++str);
1215                                 *s++ += deoct(*++str);
1216                         }
1217
1218                         /* Octal-mode */
1219                         else if (*str == '3')
1220                         {
1221                                 *s = 64 * 3 + 8 * deoct(*++str);
1222                                 *s++ += deoct(*++str);
1223                         }
1224
1225                         /* Skip the final char */
1226                         str++;
1227                 }
1228
1229                 /* Normal Control codes */
1230                 else if (*str == '^')
1231                 {
1232                         str++;
1233                         *s++ = (*str++ & 037);
1234                 }
1235
1236                 /* Normal chars */
1237                 else
1238                 {
1239                         *s++ = *str++;
1240                 }
1241         }
1242
1243         /* Terminate */
1244         *s = '\0';
1245 }
1246
1247
1248 bool trigger_ascii_to_text(char **bufptr, cptr *strptr)
1249 {
1250         char *s = *bufptr;
1251         cptr str = *strptr;
1252         char key_code[100];
1253         int i;
1254         cptr tmp;
1255
1256         if (macro_template == NULL)
1257                 return FALSE;
1258
1259         *s++ = '\\';
1260         *s++ = '[';
1261
1262         for (i = 0; macro_template[i]; i++)
1263         {
1264                 int j;
1265                 char ch = macro_template[i];
1266
1267                 switch(ch)
1268                 {
1269                 case '&':
1270                         while ((tmp = strchr(macro_modifier_chr, *str)))
1271                         {
1272                                 j = (int)(tmp - macro_modifier_chr);
1273                                 tmp = macro_modifier_name[j];
1274                                 while(*tmp) *s++ = *tmp++;
1275                                 str++;
1276                         }
1277                         break;
1278                 case '#':
1279                         for (j = 0; *str && *str != (char)13; j++)
1280                                 key_code[j] = *str++;
1281                         key_code[j] = '\0';
1282                         break;
1283                 default:
1284                         if (ch != *str) return FALSE;
1285                         str++;
1286                 }
1287         }
1288         if (*str++ != (char)13) return FALSE;
1289
1290         for (i = 0; i < max_macrotrigger; i++)
1291         {
1292                 if (!my_stricmp(key_code, macro_trigger_keycode[0][i])
1293                     || !my_stricmp(key_code, macro_trigger_keycode[1][i]))
1294                         break;
1295         }
1296         if (i == max_macrotrigger)
1297                 return FALSE;
1298
1299         tmp = macro_trigger_name[i];
1300         while (*tmp) *s++ = *tmp++;
1301
1302         *s++ = ']';
1303         
1304         *bufptr = s;
1305         *strptr = str;
1306         return TRUE;
1307 }
1308
1309
1310 /*
1311  * Hack -- convert a string into a printable form
1312  */
1313 void ascii_to_text(char *buf, cptr str)
1314 {
1315         char *s = buf;
1316
1317         /* Analyze the "ascii" string */
1318         while (*str)
1319         {
1320                 byte i = (byte)(*str++);
1321
1322                 /* Macro Trigger */
1323                 if (i == 31)
1324                 {
1325                         if(!trigger_ascii_to_text(&s, &str))
1326                         {
1327                                 *s++ = '^';
1328                                 *s++ = '_';
1329                         }
1330                 }
1331                 else
1332
1333                 if (i == ESCAPE)
1334                 {
1335                         *s++ = '\\';
1336                         *s++ = 'e';
1337                 }
1338                 else if (i == ' ')
1339                 {
1340                         *s++ = '\\';
1341                         *s++ = 's';
1342                 }
1343                 else if (i == '\b')
1344                 {
1345                         *s++ = '\\';
1346                         *s++ = 'b';
1347                 }
1348                 else if (i == '\t')
1349                 {
1350                         *s++ = '\\';
1351                         *s++ = 't';
1352                 }
1353                 else if (i == '\n')
1354                 {
1355                         *s++ = '\\';
1356                         *s++ = 'n';
1357                 }
1358                 else if (i == '\r')
1359                 {
1360                         *s++ = '\\';
1361                         *s++ = 'r';
1362                 }
1363                 else if (i == '^')
1364                 {
1365                         *s++ = '\\';
1366                         *s++ = '^';
1367                 }
1368                 else if (i == '\\')
1369                 {
1370                         *s++ = '\\';
1371                         *s++ = '\\';
1372                 }
1373                 else if (i < 32)
1374                 {
1375                         *s++ = '^';
1376                         *s++ = i + 64;
1377                 }
1378                 else if (i < 127)
1379                 {
1380                         *s++ = i;
1381                 }
1382                 else if (i < 64)
1383                 {
1384                         *s++ = '\\';
1385                         *s++ = '0';
1386                         *s++ = octify(i / 8);
1387                         *s++ = octify(i % 8);
1388                 }
1389                 else
1390                 {
1391                         *s++ = '\\';
1392                         *s++ = 'x';
1393                         *s++ = hexify(i / 16);
1394                         *s++ = hexify(i % 16);
1395                 }
1396         }
1397
1398         /* Terminate */
1399         *s = '\0';
1400 }
1401
1402
1403
1404 /*
1405  * The "macro" package
1406  *
1407  * Functions are provided to manipulate a collection of macros, each
1408  * of which has a trigger pattern string and a resulting action string
1409  * and a small set of flags.
1410  */
1411
1412
1413
1414 /*
1415  * Determine if any macros have ever started with a given character.
1416  */
1417 static bool macro__use[256];
1418
1419
1420 /*
1421  * Find the macro (if any) which exactly matches the given pattern
1422  */
1423 sint macro_find_exact(cptr pat)
1424 {
1425         int i;
1426
1427         /* Nothing possible */
1428         if (!macro__use[(byte)(pat[0])])
1429         {
1430                 return (-1);
1431         }
1432
1433         /* Scan the macros */
1434         for (i = 0; i < macro__num; ++i)
1435         {
1436                 /* Skip macros which do not match the pattern */
1437                 if (!streq(macro__pat[i], pat)) continue;
1438
1439                 /* Found one */
1440                 return (i);
1441         }
1442
1443         /* No matches */
1444         return (-1);
1445 }
1446
1447
1448 /*
1449  * Find the first macro (if any) which contains the given pattern
1450  */
1451 static sint macro_find_check(cptr pat)
1452 {
1453         int i;
1454
1455         /* Nothing possible */
1456         if (!macro__use[(byte)(pat[0])])
1457         {
1458                 return (-1);
1459         }
1460
1461         /* Scan the macros */
1462         for (i = 0; i < macro__num; ++i)
1463         {
1464                 /* Skip macros which do not contain the pattern */
1465                 if (!prefix(macro__pat[i], pat)) continue;
1466
1467                 /* Found one */
1468                 return (i);
1469         }
1470
1471         /* Nothing */
1472         return (-1);
1473 }
1474
1475
1476 /*
1477  * Find the first macro (if any) which contains the given pattern and more
1478  */
1479 static sint macro_find_maybe(cptr pat)
1480 {
1481         int i;
1482
1483         /* Nothing possible */
1484         if (!macro__use[(byte)(pat[0])])
1485         {
1486                 return (-1);
1487         }
1488
1489         /* Scan the macros */
1490         for (i = 0; i < macro__num; ++i)
1491         {
1492                 /* Skip macros which do not contain the pattern */
1493                 if (!prefix(macro__pat[i], pat)) continue;
1494
1495                 /* Skip macros which exactly match the pattern XXX XXX */
1496                 if (streq(macro__pat[i], pat)) continue;
1497
1498                 /* Found one */
1499                 return (i);
1500         }
1501
1502         /* Nothing */
1503         return (-1);
1504 }
1505
1506
1507 /*
1508  * Find the longest macro (if any) which starts with the given pattern
1509  */
1510 static sint macro_find_ready(cptr pat)
1511 {
1512         int i, t, n = -1, s = -1;
1513
1514         /* Nothing possible */
1515         if (!macro__use[(byte)(pat[0])])
1516         {
1517                 return (-1);
1518         }
1519
1520         /* Scan the macros */
1521         for (i = 0; i < macro__num; ++i)
1522         {
1523                 /* Skip macros which are not contained by the pattern */
1524                 if (!prefix(pat, macro__pat[i])) continue;
1525
1526                 /* Obtain the length of this macro */
1527                 t = strlen(macro__pat[i]);
1528
1529                 /* Only track the "longest" pattern */
1530                 if ((n >= 0) && (s > t)) continue;
1531
1532                 /* Track the entry */
1533                 n = i;
1534                 s = t;
1535         }
1536
1537         /* Result */
1538         return (n);
1539 }
1540
1541
1542 /*
1543  * Add a macro definition (or redefinition).
1544  *
1545  * We should use "act == NULL" to "remove" a macro, but this might make it
1546  * impossible to save the "removal" of a macro definition.  XXX XXX XXX
1547  *
1548  * We should consider refusing to allow macros which contain existing macros,
1549  * or which are contained in existing macros, because this would simplify the
1550  * macro analysis code.  XXX XXX XXX
1551  *
1552  * We should consider removing the "command macro" crap, and replacing it
1553  * with some kind of "powerful keymap" ability, but this might make it hard
1554  * to change the "roguelike" option from inside the game.  XXX XXX XXX
1555  */
1556 errr macro_add(cptr pat, cptr act)
1557 {
1558         int n;
1559
1560
1561         /* Paranoia -- require data */
1562         if (!pat || !act) return (-1);
1563
1564
1565         /* Look for any existing macro */
1566         n = macro_find_exact(pat);
1567
1568         /* Replace existing macro */
1569         if (n >= 0)
1570         {
1571                 /* Free the old macro action */
1572                 string_free(macro__act[n]);
1573         }
1574
1575         /* Create a new macro */
1576         else
1577         {
1578                 /* Acquire a new index */
1579                 n = macro__num++;
1580
1581                 /* Save the pattern */
1582                 macro__pat[n] = string_make(pat);
1583         }
1584
1585         /* Save the action */
1586         macro__act[n] = string_make(act);
1587
1588         /* Efficiency */
1589         macro__use[(byte)(pat[0])] = TRUE;
1590
1591         /* Success */
1592         return (0);
1593 }
1594
1595
1596
1597 /*
1598  * Initialize the "macro" package
1599  */
1600 errr macro_init(void)
1601 {
1602         /* Macro patterns */
1603         C_MAKE(macro__pat, MACRO_MAX, cptr);
1604
1605         /* Macro actions */
1606         C_MAKE(macro__act, MACRO_MAX, cptr);
1607
1608         /* Success */
1609         return (0);
1610 }
1611
1612 /*
1613  * Local variable -- we are inside a "macro action"
1614  *
1615  * Do not match any macros until "ascii 30" is found.
1616  */
1617 static bool parse_macro = FALSE;
1618
1619 /*
1620  * Local variable -- we are inside a "macro trigger"
1621  *
1622  * Strip all keypresses until a low ascii value is found.
1623  */
1624 static bool parse_under = FALSE;
1625
1626
1627 /*
1628  * Flush all input chars.  Actually, remember the flush,
1629  * and do a "special flush" before the next "inkey()".
1630  *
1631  * This is not only more efficient, but also necessary to make sure
1632  * that various "inkey()" codes are not "lost" along the way.
1633  */
1634 void flush(void)
1635 {
1636         /* Do it later */
1637         inkey_xtra = TRUE;
1638 }
1639
1640
1641 /*
1642  * Flush the screen, make a noise
1643  */
1644 void bell(void)
1645 {
1646         /* Mega-Hack -- Flush the output */
1647         Term_fresh();
1648
1649         /* Make a bell noise (if allowed) */
1650         if (ring_bell) Term_xtra(TERM_XTRA_NOISE, 0);
1651
1652         /* Flush the input (later!) */
1653         flush();
1654 }
1655
1656
1657 /*
1658  * Hack -- Make a (relevant?) sound
1659  */
1660 void sound(int val)
1661 {
1662         /* No sound */
1663         if (!use_sound) return;
1664
1665         /* Make a sound (if allowed) */
1666         Term_xtra(TERM_XTRA_SOUND, val);
1667 }
1668
1669
1670
1671 /*
1672  * Helper function called only from "inkey()"
1673  *
1674  * This function does almost all of the "macro" processing.
1675  *
1676  * We use the "Term_key_push()" function to handle "failed" macros, as well
1677  * as "extra" keys read in while choosing the proper macro, and also to hold
1678  * the action for the macro, plus a special "ascii 30" character indicating
1679  * that any macro action in progress is complete.  Embedded macros are thus
1680  * illegal, unless a macro action includes an explicit "ascii 30" character,
1681  * which would probably be a massive hack, and might break things.
1682  *
1683  * Only 500 (0+1+2+...+29+30) milliseconds may elapse between each key in
1684  * the macro trigger sequence.  If a key sequence forms the "prefix" of a
1685  * macro trigger, 500 milliseconds must pass before the key sequence is
1686  * known not to be that macro trigger.  XXX XXX XXX
1687  */
1688 static char inkey_aux(void)
1689 {
1690         int k = 0, n, p = 0, w = 0;
1691
1692         char ch;
1693
1694         cptr pat, act;
1695
1696         char buf[1024];
1697
1698         /* Hack : ¥­¡¼ÆþÎÏÂÔ¤Á¤Ç»ß¤Þ¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢Î®¤ì¤¿¹Ô¤Îµ­²±¤ÏÉÔÍס£ */
1699         num_more = 0;
1700
1701         /* Wait for a keypress */
1702         (void)(Term_inkey(&ch, TRUE, TRUE));
1703
1704
1705         /* End "macro action" */
1706         if (ch == 30) parse_macro = FALSE;
1707
1708         /* Inside "macro action" */
1709         if (ch == 30) return (ch);
1710
1711         /* Inside "macro action" */
1712         if (parse_macro) return (ch);
1713
1714         /* Inside "macro trigger" */
1715         if (parse_under) return (ch);
1716
1717
1718         /* Save the first key, advance */
1719         buf[p++] = ch;
1720         buf[p] = '\0';
1721
1722
1723         /* Check for possible macro */
1724         k = macro_find_check(buf);
1725
1726         /* No macro pending */
1727         if (k < 0) return (ch);
1728
1729
1730         /* Wait for a macro, or a timeout */
1731         while (TRUE)
1732         {
1733                 /* Check for pending macro */
1734                 k = macro_find_maybe(buf);
1735
1736                 /* No macro pending */
1737                 if (k < 0) break;
1738
1739                 /* Check for (and remove) a pending key */
1740                 if (0 == Term_inkey(&ch, FALSE, TRUE))
1741                 {
1742                         /* Append the key */
1743                         buf[p++] = ch;
1744                         buf[p] = '\0';
1745
1746                         /* Restart wait */
1747                         w = 0;
1748                 }
1749
1750                 /* No key ready */
1751                 else
1752                 {
1753                         /* Increase "wait" */
1754                         w += 10;
1755
1756                         /* Excessive delay */
1757                         if (w >= 100) break;
1758
1759                         /* Delay */
1760                         Term_xtra(TERM_XTRA_DELAY, w);
1761                 }
1762         }
1763
1764
1765         /* Check for available macro */
1766         k = macro_find_ready(buf);
1767
1768         /* No macro available */
1769         if (k < 0)
1770         {
1771                 /* Push all the keys back on the queue */
1772                 while (p > 0)
1773                 {
1774                         /* Push the key, notice over-flow */
1775                         if (Term_key_push(buf[--p])) return (0);
1776                 }
1777
1778                 /* Wait for (and remove) a pending key */
1779                 (void)Term_inkey(&ch, TRUE, TRUE);
1780
1781                 /* Return the key */
1782                 return (ch);
1783         }
1784
1785
1786         /* Get the pattern */
1787         pat = macro__pat[k];
1788
1789         /* Get the length of the pattern */
1790         n = strlen(pat);
1791
1792         /* Push the "extra" keys back on the queue */
1793         while (p > n)
1794         {
1795                 /* Push the key, notice over-flow */
1796                 if (Term_key_push(buf[--p])) return (0);
1797         }
1798
1799
1800         /* Begin "macro action" */
1801         parse_macro = TRUE;
1802
1803         /* Push the "end of macro action" key */
1804         if (Term_key_push(30)) return (0);
1805
1806
1807         /* Access the macro action */
1808         act = macro__act[k];
1809
1810         /* Get the length of the action */
1811         n = strlen(act);
1812
1813         /* Push the macro "action" onto the key queue */
1814         while (n > 0)
1815         {
1816                 /* Push the key, notice over-flow */
1817                 if (Term_key_push(act[--n])) return (0);
1818         }
1819
1820
1821         /* Hack -- Force "inkey()" to call us again */
1822         return (0);
1823 }
1824
1825
1826 /*
1827  * Mega-Hack -- special "inkey_next" pointer.  XXX XXX XXX
1828  *
1829  * This special pointer allows a sequence of keys to be "inserted" into
1830  * the stream of keys returned by "inkey()".  This key sequence will not
1831  * trigger any macros, and cannot be bypassed by the Borg.  It is used
1832  * in Angband to handle "keymaps".
1833  */
1834 static cptr inkey_next = NULL;
1835
1836
1837 #ifdef ALLOW_BORG
1838
1839 /*
1840  * Mega-Hack -- special "inkey_hack" hook.  XXX XXX XXX
1841  *
1842  * This special function hook allows the "Borg" (see elsewhere) to take
1843  * control of the "inkey()" function, and substitute in fake keypresses.
1844  */
1845 char (*inkey_hack)(int flush_first) = NULL;
1846
1847 #endif /* ALLOW_BORG */
1848
1849
1850
1851 /*
1852  * Get a keypress from the user.
1853  *
1854  * This function recognizes a few "global parameters".  These are variables
1855  * which, if set to TRUE before calling this function, will have an effect
1856  * on this function, and which are always reset to FALSE by this function
1857  * before this function returns.  Thus they function just like normal
1858  * parameters, except that most calls to this function can ignore them.
1859  *
1860  * If "inkey_xtra" is TRUE, then all pending keypresses will be flushed,
1861  * and any macro processing in progress will be aborted.  This flag is
1862  * set by the "flush()" function, which does not actually flush anything
1863  * itself, but rather, triggers delayed input flushing via "inkey_xtra".
1864  *
1865  * If "inkey_scan" is TRUE, then we will immediately return "zero" if no
1866  * keypress is available, instead of waiting for a keypress.
1867  *
1868  * If "inkey_base" is TRUE, then all macro processing will be bypassed.
1869  * If "inkey_base" and "inkey_scan" are both TRUE, then this function will
1870  * not return immediately, but will wait for a keypress for as long as the
1871  * normal macro matching code would, allowing the direct entry of macro
1872  * triggers.  The "inkey_base" flag is extremely dangerous!
1873  *
1874  * If "inkey_flag" is TRUE, then we will assume that we are waiting for a
1875  * normal command, and we will only show the cursor if "hilite_player" is
1876  * TRUE (or if the player is in a store), instead of always showing the
1877  * cursor.  The various "main-xxx.c" files should avoid saving the game
1878  * in response to a "menu item" request unless "inkey_flag" is TRUE, to
1879  * prevent savefile corruption.
1880  *
1881  * If we are waiting for a keypress, and no keypress is ready, then we will
1882  * refresh (once) the window which was active when this function was called.
1883  *
1884  * Note that "back-quote" is automatically converted into "escape" for
1885  * convenience on machines with no "escape" key.  This is done after the
1886  * macro matching, so the user can still make a macro for "backquote".
1887  *
1888  * Note the special handling of "ascii 30" (ctrl-caret, aka ctrl-shift-six)
1889  * and "ascii 31" (ctrl-underscore, aka ctrl-shift-minus), which are used to
1890  * provide support for simple keyboard "macros".  These keys are so strange
1891  * that their loss as normal keys will probably be noticed by nobody.  The
1892  * "ascii 30" key is used to indicate the "end" of a macro action, which
1893  * allows recursive macros to be avoided.  The "ascii 31" key is used by
1894  * some of the "main-xxx.c" files to introduce macro trigger sequences.
1895  *
1896  * Hack -- we use "ascii 29" (ctrl-right-bracket) as a special "magic" key,
1897  * which can be used to give a variety of "sub-commands" which can be used
1898  * any time.  These sub-commands could include commands to take a picture of
1899  * the current screen, to start/stop recording a macro action, etc.
1900  *
1901  * If "angband_term[0]" is not active, we will make it active during this
1902  * function, so that the various "main-xxx.c" files can assume that input
1903  * is only requested (via "Term_inkey()") when "angband_term[0]" is active.
1904  *
1905  * Mega-Hack -- This function is used as the entry point for clearing the
1906  * "signal_count" variable, and of the "character_saved" variable.
1907  *
1908  * Hack -- Note the use of "inkey_next" to allow "keymaps" to be processed.
1909  *
1910  * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal
1911  * control of the keyboard from the user.
1912  */
1913 char inkey(void)
1914 {
1915         int v;
1916         char kk;
1917         char ch = 0;
1918         bool done = FALSE;
1919         term *old = Term;
1920
1921 #ifdef USE_SCRIPT
1922         char result;
1923 #endif /* USE_SCRIPT */
1924
1925         /* Hack -- Use the "inkey_next" pointer */
1926         if (inkey_next && *inkey_next && !inkey_xtra)
1927         {
1928                 /* Get next character, and advance */
1929                 ch = *inkey_next++;
1930
1931                 /* Cancel the various "global parameters" */
1932                 inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
1933
1934                 /* Accept result */
1935                 return (ch);
1936         }
1937
1938         /* Forget pointer */
1939         inkey_next = NULL;
1940
1941
1942 #ifdef ALLOW_BORG
1943
1944         /* Mega-Hack -- Use the special hook */
1945         if (inkey_hack && ((ch = (*inkey_hack)(inkey_xtra)) != 0))
1946         {
1947                 /* Cancel the various "global parameters" */
1948                 inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
1949
1950                 /* Accept result */
1951                 return (ch);
1952         }
1953
1954 #endif /* ALLOW_BORG */
1955
1956 #ifdef USE_SCRIPT
1957
1958         if ((result = inkey_borg_callback(inkey_base, inkey_xtra, inkey_flag, inkey_scan)))
1959         {
1960                 /* Cancel the various "global parameters" */
1961                 inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
1962
1963                 return (result);
1964         }
1965
1966 #endif /* USE_SCRIPT */
1967
1968
1969         /* Hack -- handle delayed "flush()" */
1970         if (inkey_xtra)
1971         {
1972                 /* End "macro action" */
1973                 parse_macro = FALSE;
1974
1975                 /* End "macro trigger" */
1976                 parse_under = FALSE;
1977
1978                 /* Forget old keypresses */
1979                 Term_flush();
1980         }
1981
1982
1983         /* Access cursor state */
1984         (void)Term_get_cursor(&v);
1985
1986         /* Show the cursor if waiting, except sometimes in "command" mode */
1987         if (!inkey_scan && (!inkey_flag || hilite_player || character_icky))
1988         {
1989                 /* Show the cursor */
1990                 (void)Term_set_cursor(1);
1991         }
1992
1993
1994         /* Hack -- Activate main screen */
1995         Term_activate(angband_term[0]);
1996
1997
1998         /* Get a key */
1999         while (!ch)
2000         {
2001                 /* Hack -- Handle "inkey_scan" */
2002                 if (!inkey_base && inkey_scan &&
2003                         (0 != Term_inkey(&kk, FALSE, FALSE)))
2004                 {
2005                         break;
2006                 }
2007
2008
2009                 /* Hack -- Flush output once when no key ready */
2010                 if (!done && (0 != Term_inkey(&kk, FALSE, FALSE)))
2011                 {
2012                         /* Hack -- activate proper term */
2013                         Term_activate(old);
2014
2015                         /* Flush output */
2016                         Term_fresh();
2017
2018                         /* Hack -- activate main screen */
2019                         Term_activate(angband_term[0]);
2020
2021                         /* Mega-Hack -- reset saved flag */
2022                         character_saved = FALSE;
2023
2024                         /* Mega-Hack -- reset signal counter */
2025                         signal_count = 0;
2026
2027                         /* Only once */
2028                         done = TRUE;
2029                 }
2030
2031
2032                 /* Hack -- Handle "inkey_base" */
2033                 if (inkey_base)
2034                 {
2035                         int w = 0;
2036
2037                         /* Wait forever */
2038                         if (!inkey_scan)
2039                         {
2040                                 /* Wait for (and remove) a pending key */
2041                                 if (0 == Term_inkey(&ch, TRUE, TRUE))
2042                                 {
2043                                         /* Done */
2044                                         break;
2045                                 }
2046
2047                                 /* Oops */
2048                                 break;
2049                         }
2050
2051                         /* Wait */
2052                         while (TRUE)
2053                         {
2054                                 /* Check for (and remove) a pending key */
2055                                 if (0 == Term_inkey(&ch, FALSE, TRUE))
2056                                 {
2057                                         /* Done */
2058                                         break;
2059                                 }
2060
2061                                 /* No key ready */
2062                                 else
2063                                 {
2064                                         /* Increase "wait" */
2065                                         w += 10;
2066
2067                                         /* Excessive delay */
2068                                         if (w >= 100) break;
2069
2070                                         /* Delay */
2071                                         Term_xtra(TERM_XTRA_DELAY, w);
2072                                 }
2073                         }
2074
2075                         /* Done */
2076                         break;
2077                 }
2078
2079
2080                 /* Get a key (see above) */
2081                 ch = inkey_aux();
2082
2083
2084                 /* Handle "control-right-bracket" */
2085                 if (ch == 29)
2086                 {
2087                         /* Strip this key */
2088                         ch = 0;
2089
2090                         /* Continue */
2091                         continue;
2092                 }
2093
2094
2095                 /* Treat back-quote as escape */
2096 /*              if (ch == '`') ch = ESCAPE; */
2097
2098
2099                 /* End "macro trigger" */
2100                 if (parse_under && (ch <= 32))
2101                 {
2102                         /* Strip this key */
2103                         ch = 0;
2104
2105                         /* End "macro trigger" */
2106                         parse_under = FALSE;
2107                 }
2108
2109
2110                 /* Handle "control-caret" */
2111                 if (ch == 30)
2112                 {
2113                         /* Strip this key */
2114                         ch = 0;
2115                 }
2116
2117                 /* Handle "control-underscore" */
2118                 else if (ch == 31)
2119                 {
2120                         /* Strip this key */
2121                         ch = 0;
2122
2123                         /* Begin "macro trigger" */
2124                         parse_under = TRUE;
2125                 }
2126
2127                 /* Inside "macro trigger" */
2128                 else if (parse_under)
2129                 {
2130                         /* Strip this key */
2131                         ch = 0;
2132                 }
2133         }
2134
2135
2136         /* Hack -- restore the term */
2137         Term_activate(old);
2138
2139
2140         /* Restore the cursor */
2141         Term_set_cursor(v);
2142
2143
2144         /* Cancel the various "global parameters" */
2145         inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
2146
2147 #ifdef USE_SCRIPT
2148
2149         if ((result = inkey_callback(ch))) return result;
2150
2151 #endif /* USE_SCRIPT */
2152
2153         /* Return the keypress */
2154         return (ch);
2155 }
2156
2157
2158
2159
2160 /*
2161  * We use a global array for all inscriptions to reduce the memory
2162  * spent maintaining inscriptions.  Of course, it is still possible
2163  * to run out of inscription memory, especially if too many different
2164  * inscriptions are used, but hopefully this will be rare.
2165  *
2166  * We use dynamic string allocation because otherwise it is necessary
2167  * to pre-guess the amount of quark activity.  We limit the total
2168  * number of quarks, but this is much easier to "expand" as needed.
2169  *
2170  * Any two items with the same inscription will have the same "quark"
2171  * index, which should greatly reduce the need for inscription space.
2172  *
2173  * Note that "quark zero" is NULL and should not be "dereferenced".
2174  */
2175
2176 /*
2177  * Add a new "quark" to the set of quarks.
2178  */
2179 s16b quark_add(cptr str)
2180 {
2181         int i;
2182
2183         /* Look for an existing quark */
2184         for (i = 1; i < quark__num; i++)
2185         {
2186                 /* Check for equality */
2187                 if (streq(quark__str[i], str)) return (i);
2188         }
2189
2190         /* Paranoia -- Require room */
2191         if (quark__num == QUARK_MAX) return (0);
2192
2193         /* New maximal quark */
2194         quark__num = i + 1;
2195
2196         /* Add a new quark */
2197         quark__str[i] = string_make(str);
2198
2199         /* Return the index */
2200         return (i);
2201 }
2202
2203
2204 /*
2205  * This function looks up a quark
2206  */
2207 cptr quark_str(s16b i)
2208 {
2209         cptr q;
2210
2211         /* Verify */
2212         if ((i < 0) || (i >= quark__num)) i = 0;
2213
2214         /* Access the quark */
2215         q = quark__str[i];
2216
2217         /* Return the quark */
2218         return (q);
2219 }
2220
2221
2222
2223
2224 /*
2225  * Second try for the "message" handling routines.
2226  *
2227  * Each call to "message_add(s)" will add a new "most recent" message
2228  * to the "message recall list", using the contents of the string "s".
2229  *
2230  * The messages will be stored in such a way as to maximize "efficiency",
2231  * that is, we attempt to maximize the number of sequential messages that
2232  * can be retrieved, given a limited amount of storage space.
2233  *
2234  * We keep a buffer of chars to hold the "text" of the messages, not
2235  * necessarily in "order", and an array of offsets into that buffer,
2236  * representing the actual messages.  This is made more complicated
2237  * by the fact that both the array of indexes, and the buffer itself,
2238  * are both treated as "circular arrays" for efficiency purposes, but
2239  * the strings may not be "broken" across the ends of the array.
2240  *
2241  * The "message_add()" function is rather "complex", because it must be
2242  * extremely efficient, both in space and time, for use with the Borg.
2243  */
2244
2245
2246
2247 /*
2248  * How many messages are "available"?
2249  */
2250 s16b message_num(void)
2251 {
2252         int last, next, n;
2253
2254         /* Extract the indexes */
2255         last = message__last;
2256         next = message__next;
2257
2258         /* Handle "wrap" */
2259         if (next < last) next += MESSAGE_MAX;
2260
2261         /* Extract the space */
2262         n = (next - last);
2263
2264         /* Return the result */
2265         return (n);
2266 }
2267
2268
2269
2270 /*
2271  * Recall the "text" of a saved message
2272  */
2273 cptr message_str(int age)
2274 {
2275         s16b x;
2276         s16b o;
2277         cptr s;
2278
2279         /* Forgotten messages have no text */
2280         if ((age < 0) || (age >= message_num())) return ("");
2281
2282         /* Acquire the "logical" index */
2283         x = (message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX;
2284
2285         /* Get the "offset" for the message */
2286         o = message__ptr[x];
2287
2288         /* Access the message text */
2289         s = &message__buf[o];
2290
2291         /* Return the message text */
2292         return (s);
2293 }
2294
2295
2296
2297 /*
2298  * Add a new message, with great efficiency
2299  */
2300 void message_add(cptr str)
2301 {
2302         int i, k, x, m, n;
2303
2304         char u[1024];
2305         char splitted1[81];
2306         cptr splitted2;
2307
2308         /*** Step 1 -- Analyze the message ***/
2309
2310         /* Hack -- Ignore "non-messages" */
2311         if (!str) return;
2312
2313         /* Message length */
2314         n = strlen(str);
2315
2316         /* Important Hack -- Ignore "long" messages */
2317         if (n >= MESSAGE_BUF / 4) return;
2318
2319         /* extra step -- split the message if n>80.   (added by Mogami) */
2320         if (n > 80) {
2321 #ifdef JP
2322           cptr t = str;
2323
2324           for (n = 0; n < 80; n++, t++)
2325             if(iskanji(*t)) {
2326               t++;
2327               n++;
2328             }
2329           if (n == 81) n = 79; /* ºÇ¸å¤Îʸ»ú¤¬´Á»úȾʬ */
2330 #else
2331           for (n = 80; n > 60; n--)
2332                   if (str[n] == ' ') break;
2333           if (n == 60)
2334                   n = 80;
2335 #endif
2336           splitted2 = str + n;
2337           strncpy(splitted1, str ,n);
2338           splitted1[n] = '\0';
2339           str = splitted1;
2340         } else {
2341           splitted2 = NULL;
2342         }
2343
2344         /*** Step 2 -- Attempt to optimize ***/
2345
2346         /* Limit number of messages to check */
2347         m = message_num();
2348
2349         k = m / 4;
2350
2351         /* Limit number of messages to check */
2352         if (k > MESSAGE_MAX / 32) k = MESSAGE_MAX / 32;
2353
2354         /* Check previous message */
2355         for (i = message__next; m; m--)
2356         {
2357                 int j = 1;
2358
2359                 char buf[1024];
2360                 char *t;
2361
2362                 cptr old;
2363
2364                 /* Back up and wrap if needed */
2365                 if (i-- == 0) i = MESSAGE_MAX - 1;
2366
2367                 /* Access the old string */
2368                 old = &message__buf[message__ptr[i]];
2369
2370                 /* Skip small messages */
2371                 if (!old) continue;
2372
2373                 strcpy(buf, old);
2374
2375                 /* Find multiple */
2376 #ifdef JP
2377  for (t = buf; *t && (*t != '<' || (*(t+1) != 'x' )); t++) 
2378      if( iskanji(*t))t++;
2379 #else
2380                 for (t = buf; *t && (*t != '<'); t++);
2381 #endif
2382
2383                 if (*t)
2384                 {
2385                         /* Message is too small */
2386                         if (strlen(buf) < 6) break;
2387
2388                         /* Drop the space */
2389                         *(t - 1) = '\0';
2390
2391                         /* Get multiplier */
2392                         j = atoi(t+2);
2393                 }
2394
2395                 /* Limit the multiplier to 1000 */
2396                 if (buf && streq(buf, str) && (j < 1000))
2397                 {
2398                         j++;
2399
2400                         /* Overwrite */
2401                         message__next = i;
2402
2403                         str = u;
2404
2405                         /* Write it out */
2406                         sprintf(u, "%s <x%d>", buf, j);
2407
2408                         /* Message length */
2409                         n = strlen(str);
2410
2411                         if (!now_message) now_message++;
2412                 }
2413                 else
2414                 {
2415                         num_more++;/*ή¤ì¤¿¹Ô¤Î¿ô¤ò¿ô¤¨¤Æ¤ª¤¯ */
2416                         now_message++;
2417                 }
2418
2419                 /* Done */
2420                 break;
2421         }
2422
2423         /* Check the last few messages (if any to count) */
2424         for (i = message__next; k; k--)
2425         {
2426                 u16b q;
2427
2428                 cptr old;
2429
2430                 /* Back up and wrap if needed */
2431                 if (i-- == 0) i = MESSAGE_MAX - 1;
2432
2433                 /* Stop before oldest message */
2434                 if (i == message__last) break;
2435
2436                 /* Extract "distance" from "head" */
2437                 q = (message__head + MESSAGE_BUF - message__ptr[i]) % MESSAGE_BUF;
2438
2439                 /* Do not optimize over large distance */
2440                 if (q > MESSAGE_BUF / 2) continue;
2441
2442                 /* Access the old string */
2443                 old = &message__buf[message__ptr[i]];
2444
2445                 /* Compare */
2446                 if (!streq(old, str)) continue;
2447
2448                 /* Get the next message index, advance */
2449                 x = message__next++;
2450
2451                 /* Handle wrap */
2452                 if (message__next == MESSAGE_MAX) message__next = 0;
2453
2454                 /* Kill last message if needed */
2455                 if (message__next == message__last) message__last++;
2456
2457                 /* Handle wrap */
2458                 if (message__last == MESSAGE_MAX) message__last = 0;
2459
2460                 /* Assign the starting address */
2461                 message__ptr[x] = message__ptr[i];
2462
2463                 /* Success */
2464                 /* return; */
2465                 goto end_of_message_add;
2466
2467         }
2468
2469
2470         /*** Step 3 -- Ensure space before end of buffer ***/
2471
2472         /* Kill messages and Wrap if needed */
2473         if (message__head + n + 1 >= MESSAGE_BUF)
2474         {
2475                 /* Kill all "dead" messages */
2476                 for (i = message__last; TRUE; i++)
2477                 {
2478                         /* Wrap if needed */
2479                         if (i == MESSAGE_MAX) i = 0;
2480
2481                         /* Stop before the new message */
2482                         if (i == message__next) break;
2483
2484                         /* Kill "dead" messages */
2485                         if (message__ptr[i] >= message__head)
2486                         {
2487                                 /* Track oldest message */
2488                                 message__last = i + 1;
2489                         }
2490                 }
2491
2492                 /* Wrap "tail" if needed */
2493                 if (message__tail >= message__head) message__tail = 0;
2494
2495                 /* Start over */
2496                 message__head = 0;
2497         }
2498
2499
2500         /*** Step 4 -- Ensure space before next message ***/
2501
2502         /* Kill messages if needed */
2503         if (message__head + n + 1 > message__tail)
2504         {
2505                 /* Grab new "tail" */
2506                 message__tail = message__head + n + 1;
2507
2508                 /* Advance tail while possible past first "nul" */
2509                 while (message__buf[message__tail-1]) message__tail++;
2510
2511                 /* Kill all "dead" messages */
2512                 for (i = message__last; TRUE; i++)
2513                 {
2514                         /* Wrap if needed */
2515                         if (i == MESSAGE_MAX) i = 0;
2516
2517                         /* Stop before the new message */
2518                         if (i == message__next) break;
2519
2520                         /* Kill "dead" messages */
2521                         if ((message__ptr[i] >= message__head) &&
2522                                 (message__ptr[i] < message__tail))
2523                         {
2524                                 /* Track oldest message */
2525                                 message__last = i + 1;
2526                         }
2527                 }
2528         }
2529
2530
2531         /*** Step 5 -- Grab a new message index ***/
2532
2533         /* Get the next message index, advance */
2534         x = message__next++;
2535
2536         /* Handle wrap */
2537         if (message__next == MESSAGE_MAX) message__next = 0;
2538
2539         /* Kill last message if needed */
2540         if (message__next == message__last) message__last++;
2541
2542         /* Handle wrap */
2543         if (message__last == MESSAGE_MAX) message__last = 0;
2544
2545
2546
2547         /*** Step 6 -- Insert the message text ***/
2548
2549         /* Assign the starting address */
2550         message__ptr[x] = message__head;
2551
2552         /* Append the new part of the message */
2553         for (i = 0; i < n; i++)
2554         {
2555                 /* Copy the message */
2556                 message__buf[message__head + i] = str[i];
2557         }
2558
2559         /* Terminate */
2560         message__buf[message__head + i] = '\0';
2561
2562         /* Advance the "head" pointer */
2563         message__head += n + 1;
2564
2565         /* recursively add splitted message (added by Mogami) */
2566  end_of_message_add:
2567         if (splitted2 != NULL)
2568           message_add(splitted2);
2569 }
2570
2571
2572
2573 /*
2574  * Hack -- flush
2575  */
2576 static void msg_flush(int x)
2577 {
2578         byte a = TERM_L_BLUE;
2579         bool nagasu = FALSE;
2580
2581         if ((auto_more && !now_damaged) || num_more < 0){
2582                 int i;
2583                 for (i = 0; i < 8; i++)
2584                 {
2585                         if (angband_term[i] && (window_flag[i] & PW_MESSAGE)) break;
2586                 }
2587                 if (i < 8)
2588                 {
2589                         if (num_more < angband_term[i]->hgt) nagasu = TRUE;
2590                 }
2591                 else
2592                 {
2593                         nagasu = TRUE;
2594                 }
2595         }
2596         now_damaged = FALSE;
2597
2598         if (!alive || !nagasu)
2599         {
2600                 /* Pause for response */
2601 #ifdef JP
2602                 Term_putstr(x, 0, -1, a, "-³¤¯-");
2603 #else
2604                 Term_putstr(x, 0, -1, a, "-more-");
2605 #endif
2606
2607
2608                 /* Get an acceptable keypress */
2609                 while (1)
2610                 {
2611                         int cmd = inkey();
2612                         if (cmd == ESCAPE) {
2613                             num_more = -9999; /*auto_more¤Î¤È¤­¡¢Á´¤Æή¤¹¡£ */
2614                             break;
2615                         } else if (cmd == ' ') {
2616                             num_more = 0; /*£±²èÌ̤À¤±Î®¤¹¡£ */
2617                             break;
2618                         } else if ((cmd == '\n') || (cmd == '\r')) {
2619                             num_more--; /*£±¹Ô¤À¤±Î®¤¹¡£ */
2620                             break;
2621                         }
2622                         if (quick_messages) break;
2623                         bell();
2624                 }
2625         }
2626
2627         /* Clear the line */
2628         Term_erase(0, 0, 255);
2629 }
2630
2631
2632 /*
2633  * Output a message to the top line of the screen.
2634  *
2635  * Break long messages into multiple pieces (40-72 chars).
2636  *
2637  * Allow multiple short messages to "share" the top line.
2638  *
2639  * Prompt the user to make sure he has a chance to read them.
2640  *
2641  * These messages are memorized for later reference (see above).
2642  *
2643  * We could do "Term_fresh()" to provide "flicker" if needed.
2644  *
2645  * The global "msg_flag" variable can be cleared to tell us to
2646  * "erase" any "pending" messages still on the screen.
2647  *
2648  * XXX XXX XXX Note that we must be very careful about using the
2649  * "msg_print()" functions without explicitly calling the special
2650  * "msg_print(NULL)" function, since this may result in the loss
2651  * of information if the screen is cleared, or if anything is
2652  * displayed on the top line.
2653  *
2654  * XXX XXX XXX Note that "msg_print(NULL)" will clear the top line
2655  * even if no messages are pending.  This is probably a hack.
2656  */
2657 void msg_print(cptr msg)
2658 {
2659         static int p = 0;
2660
2661         int n;
2662
2663         char *t;
2664
2665         char buf[1024];
2666
2667         if (world_monster) return;
2668
2669         /* Hack -- Reset */
2670         if (!msg_flag) {
2671                 /* Clear the line */
2672                 Term_erase(0, 0, 255);
2673                 p = 0;
2674         }
2675
2676         /* Message Length */
2677         n = (msg ? strlen(msg) : 0);
2678
2679         /* Hack -- flush when requested or needed */
2680         if (p && (!msg || ((p + n) > 72)))
2681         {
2682                 /* Flush */
2683                 msg_flush(p);
2684
2685                 /* Forget it */
2686                 msg_flag = FALSE;
2687
2688                 /* Reset */
2689                 p = 0;
2690         }
2691
2692
2693         /* No message */
2694         if (!msg) return;
2695
2696         /* Paranoia */
2697         if (n > 1000) return;
2698
2699
2700         /* Memorize the message */
2701         if (character_generated) message_add(msg);
2702
2703
2704         /* Copy it */
2705         strcpy(buf, msg);
2706
2707         /* Analyze the buffer */
2708         t = buf;
2709
2710         /* Split message */
2711         while (n > 72)
2712         {
2713                 char oops;
2714                 int check, split = 72;
2715
2716 #ifdef JP
2717                 bool k_flag = FALSE;
2718                 int wordlen = 0;
2719
2720                 /* Find the "best" split point */
2721                 for (check = 0; check < 72; check++)
2722                 {
2723                         if (k_flag)
2724                         {
2725                                 k_flag = FALSE;
2726                                 continue;
2727                         }
2728
2729                         /* Found a valid split point */
2730                         if (iskanji(t[check]))
2731                         {
2732                                 k_flag = TRUE;
2733                                 split = check;
2734                         }
2735                         else if (t[check] == ' ')
2736                         {
2737                                 split = check;
2738                                 wordlen = 0;
2739                         }
2740                         else
2741                         {
2742                                 wordlen++;
2743                                 if (wordlen > 20)
2744                                         split = check;
2745                         }
2746                 }
2747 #else
2748                 /* Find the "best" split point */
2749                 for (check = 40; check < 72; check++)
2750                 {
2751                         /* Found a valid split point */
2752                         if (t[check] == ' ') split = check;
2753                 }
2754 #endif
2755
2756                 /* Save the split character */
2757                 oops = t[split];
2758
2759                 /* Split the message */
2760                 t[split] = '\0';
2761
2762                 /* Display part of the message */
2763                 Term_putstr(0, 0, split, TERM_WHITE, t);
2764
2765                 /* Flush it */
2766                 msg_flush(split + 1);
2767
2768                 /* Memorize the piece */
2769                 /* if (character_generated) message_add(t); */
2770
2771                 /* Restore the split character */
2772                 t[split] = oops;
2773
2774                 /* Insert a space */
2775                 t[--split] = ' ';
2776
2777                 /* Prepare to recurse on the rest of "buf" */
2778                 t += split; n -= split;
2779         }
2780
2781
2782         /* Display the tail of the message */
2783         Term_putstr(p, 0, n, TERM_WHITE, t);
2784
2785         /* Memorize the tail */
2786         /* if (character_generated) message_add(t); */
2787
2788         /* Window stuff */
2789         p_ptr->window |= (PW_MESSAGE);
2790         window_stuff();
2791
2792         /* Remember the message */
2793         msg_flag = TRUE;
2794
2795         /* Remember the position */
2796 #ifdef JP
2797         p += n;
2798 #else
2799         p += n + 1;
2800 #endif
2801
2802
2803         /* Optional refresh */
2804         if (fresh_message) Term_fresh();
2805 }
2806
2807
2808 /*
2809  * Hack -- prevent "accidents" in "screen_save()" or "screen_load()"
2810  */
2811 static int screen_depth = 0;
2812
2813
2814 /*
2815  * Save the screen, and increase the "icky" depth.
2816  *
2817  * This function must match exactly one call to "screen_load()".
2818  */
2819 void screen_save(void)
2820 {
2821         /* Hack -- Flush messages */
2822         msg_print(NULL);
2823
2824         /* Save the screen (if legal) */
2825         if (screen_depth++ == 0) Term_save();
2826
2827         /* Increase "icky" depth */
2828         character_icky++;
2829 }
2830
2831
2832 /*
2833  * Load the screen, and decrease the "icky" depth.
2834  *
2835  * This function must match exactly one call to "screen_save()".
2836  */
2837 void screen_load(void)
2838 {
2839         /* Hack -- Flush messages */
2840         msg_print(NULL);
2841
2842         /* Load the screen (if legal) */
2843         if (--screen_depth == 0) Term_load();
2844
2845         /* Decrease "icky" depth */
2846         character_icky--;
2847 }
2848
2849
2850 /*
2851  * Display a formatted message, using "vstrnfmt()" and "msg_print()".
2852  */
2853 void msg_format(cptr fmt, ...)
2854 {
2855         va_list vp;
2856
2857         char buf[1024];
2858
2859         /* Begin the Varargs Stuff */
2860         va_start(vp, fmt);
2861
2862         /* Format the args, save the length */
2863         (void)vstrnfmt(buf, 1024, fmt, vp);
2864
2865         /* End the Varargs Stuff */
2866         va_end(vp);
2867
2868         /* Display */
2869         msg_print(buf);
2870 }
2871
2872
2873
2874 /*
2875  * Display a string on the screen using an attribute.
2876  *
2877  * At the given location, using the given attribute, if allowed,
2878  * add the given string.  Do not clear the line.
2879  */
2880 void c_put_str(byte attr, cptr str, int row, int col)
2881 {
2882         /* Position cursor, Dump the attr/text */
2883         Term_putstr(col, row, -1, attr, str);
2884 }
2885
2886 /*
2887  * As above, but in "white"
2888  */
2889 void put_str(cptr str, int row, int col)
2890 {
2891         /* Spawn */
2892         Term_putstr(col, row, -1, TERM_WHITE, str);
2893 }
2894
2895
2896
2897 /*
2898  * Display a string on the screen using an attribute, and clear
2899  * to the end of the line.
2900  */
2901 void c_prt(byte attr, cptr str, int row, int col)
2902 {
2903         /* Clear line, position cursor */
2904         Term_erase(col, row, 255);
2905
2906         /* Dump the attr/text */
2907         Term_addstr(-1, attr, str);
2908 }
2909
2910 /*
2911  * As above, but in "white"
2912  */
2913 void prt(cptr str, int row, int col)
2914 {
2915         /* Spawn */
2916         c_prt(TERM_WHITE, str, row, col);
2917 }
2918
2919
2920
2921
2922 /*
2923  * Print some (colored) text to the screen at the current cursor position,
2924  * automatically "wrapping" existing text (at spaces) when necessary to
2925  * avoid placing any text into the last column, and clearing every line
2926  * before placing any text in that line.  Also, allow "newline" to force
2927  * a "wrap" to the next line.  Advance the cursor as needed so sequential
2928  * calls to this function will work correctly.
2929  *
2930  * Once this function has been called, the cursor should not be moved
2931  * until all the related "c_roff()" calls to the window are complete.
2932  *
2933  * This function will correctly handle any width up to the maximum legal
2934  * value of 256, though it works best for a standard 80 character width.
2935  */
2936 void c_roff(byte a, cptr str)
2937 {
2938         int x, y;
2939
2940         int w, h;
2941
2942         cptr s;
2943
2944         /* Obtain the size */
2945         (void)Term_get_size(&w, &h);
2946
2947         /* Obtain the cursor */
2948         (void)Term_locate(&x, &y);
2949
2950         /* Hack -- No more space */
2951         if( y == h - 1 && x > w - 3) return;
2952
2953         /* Process the string */
2954         for (s = str; *s; s++)
2955         {
2956                 char ch;
2957
2958 #ifdef JP
2959                 int k_flag = iskanji(*s);
2960 #endif
2961                 /* Force wrap */
2962                 if (*s == '\n')
2963                 {
2964                         /* Wrap */
2965                         x = 0;
2966                         y++;
2967
2968                         /* No more space */
2969                         if( y == h ) break;
2970
2971                         /* Clear line, move cursor */
2972                         Term_erase(x, y, 255);
2973                 }
2974
2975                 /* Clean up the char */
2976 #ifdef JP
2977                 ch = ((isprint(*s) || k_flag) ? *s : ' ');
2978 #else
2979                 ch = (isprint(*s) ? *s : ' ');
2980 #endif
2981
2982
2983                 /* Wrap words as needed */
2984 #ifdef JP
2985                 if (( x >= ( (k_flag) ? w - 2 : w - 1 ) ) && (ch != ' '))
2986 #else
2987                 if ((x >= w - 1) && (ch != ' '))
2988 #endif
2989
2990                 {
2991                         int i, n = 0;
2992
2993                         byte av[256];
2994                         char cv[256];
2995
2996                         /* Wrap word */
2997                         if (x < w)
2998 #ifdef JP
2999                         {
3000                         /* ¸½ºß¤¬È¾³Ñʸ»ú¤Î¾ì¹ç */
3001                         if( !k_flag )
3002 #endif
3003                         {
3004                                 /* Scan existing text */
3005                                 for (i = w - 2; i >= 0; i--)
3006                                 {
3007                                         /* Grab existing attr/char */
3008                                         Term_what(i, y, &av[i], &cv[i]);
3009
3010                                         /* Break on space */
3011                                         if (cv[i] == ' ') break;
3012
3013                                         /* Track current word */
3014                                         n = i;
3015 #ifdef JP
3016                                         if (cv[i] == '(') break;
3017 #endif
3018                                 }
3019                         }
3020
3021 #ifdef JP
3022                         else
3023                         {
3024                                 /* ¸½ºß¤¬Á´³Ñʸ»ú¤Î¤È¤­ */
3025                                 /* Ê¸Æ¬¤¬¡Ö¡£¡×¡Ö¡¢¡×Åù¤Ë¤Ê¤ë¤È¤­¤Ï¡¢¤½¤Î£±¤ÄÁ°¤Î¸ì¤Ç²þ¹Ô */
3026                                 if (strncmp(s, "¡£", 2) == 0 || strncmp(s, "¡¢", 2) == 0
3027 #if 0                   /* °ìÈÌŪ¤Ë¤Ï¡Ö¥£¡×¡Ö¡¼¡×¤Ï¶Ø§¤ÎÂоݳ° */
3028                                         || strncmp(s, "¥£", 2) == 0 || strncmp(s, "¡¼", 2) == 0
3029 #endif
3030                                ){
3031                                         Term_what(x  , y, &av[x  ], &cv[x  ]);
3032                                         Term_what(x-1, y, &av[x-1], &cv[x-1]);
3033                                         Term_what(x-2, y, &av[x-2], &cv[x-2]);
3034                                         n = x - 2;
3035                                         cv[ x ] = '\0';
3036                                 }
3037                         }
3038                         }
3039 #endif
3040                         /* Special case */
3041                         if (n == 0) n = w;
3042
3043                         /* Clear line */
3044                         Term_erase(n, y, 255);
3045
3046                         /* Wrap */
3047                         x = 0;
3048                         y++;
3049
3050                         /* No more space */
3051                         if( y == h ) break;
3052
3053                         /* Clear line, move cursor */
3054                         Term_erase(x, y, 255);
3055
3056                         /* Wrap the word (if any) */
3057                         for (i = n; i < w - 1; i++)
3058                         {
3059 #ifdef JP
3060                                 if( cv[i] == '\0' ) break;
3061 #endif
3062                                 /* Dump */
3063                                 Term_addch(av[i], cv[i]);
3064
3065                                 /* Advance (no wrap) */
3066                                 if (++x > w) x = w;
3067                         }
3068                 }
3069
3070                 /* Dump */
3071 #ifdef JP
3072                 Term_addch((byte)(a|0x10), ch);
3073 #else
3074                 Term_addch(a, ch);
3075 #endif
3076
3077
3078 #ifdef JP
3079                 if (k_flag)
3080                 {
3081                         s++;
3082                         x++;
3083                         ch = *s;
3084                         Term_addch((byte)(a|0x20), ch);
3085                 }
3086 #endif
3087                 /* Advance */
3088                 if (++x > w) x = w;
3089         }
3090 }
3091
3092 /*
3093  * As above, but in "white"
3094  */
3095 void roff(cptr str)
3096 {
3097         /* Spawn */
3098         c_roff(TERM_WHITE, str);
3099 }
3100
3101
3102
3103
3104 /*
3105  * Clear part of the screen
3106  */
3107 void clear_from(int row)
3108 {
3109         int y;
3110
3111         /* Erase requested rows */
3112         for (y = row; y < Term->hgt; y++)
3113         {
3114                 /* Erase part of the screen */
3115                 Term_erase(0, y, 255);
3116         }
3117 }
3118
3119
3120
3121
3122 /*
3123  * Get some input at the cursor location.
3124  * Assume the buffer is initialized to a default string.
3125  * Note that this string is often "empty" (see below).
3126  * The default buffer is displayed in yellow until cleared.
3127  * Pressing RETURN right away accepts the default entry.
3128  * Normal chars clear the default and append the char.
3129  * Backspace clears the default or deletes the final char.
3130  * ESCAPE clears the buffer and the window and returns FALSE.
3131  * RETURN accepts the current buffer contents and returns TRUE.
3132  */
3133 bool askfor_aux(char *buf, int len)
3134 {
3135         int y, x;
3136
3137         int i = 0;
3138
3139         int k = 0;
3140
3141         bool done = FALSE;
3142
3143
3144 #ifdef JP
3145     int k_flag[128];
3146 #endif
3147         /* Locate the cursor */
3148         Term_locate(&x, &y);
3149
3150
3151         /* Paranoia -- check len */
3152         if (len < 1) len = 1;
3153
3154         /* Paranoia -- check column */
3155         if ((x < 0) || (x >= 80)) x = 0;
3156
3157         /* Restrict the length */
3158         if (x + len > 80) len = 80 - x;
3159
3160
3161         /* Paranoia -- Clip the default entry */
3162         buf[len] = '\0';
3163
3164
3165         /* Display the default answer */
3166         Term_erase(x, y, len);
3167         Term_putstr(x, y, -1, TERM_YELLOW, buf);
3168
3169
3170         /* Process input */
3171         while (!done)
3172         {
3173                 /* Place cursor */
3174                 Term_gotoxy(x + k, y);
3175
3176                 /* Get a key */
3177                 i = inkey();
3178
3179                 /* Analyze the key */
3180                 switch (i)
3181                 {
3182                 case ESCAPE:
3183                         k = 0;
3184                         done = TRUE;
3185                         break;
3186
3187                 case '\n':
3188                 case '\r':
3189                         k = strlen(buf);
3190                         done = TRUE;
3191                         break;
3192
3193                 case 0x7F:
3194                 case '\010':
3195 #ifdef JP
3196                                 if (k > 0)
3197                                 {
3198                                         k--;
3199                                         if (k_flag[k] != 0)
3200                                                 k--;
3201                                 }
3202 #else
3203                         if (k > 0) k--;
3204 #endif
3205
3206                         break;
3207
3208                 default:
3209 #ifdef JP
3210        {                        /* ÊÒ»³¤µ¤óºîÀ® */
3211                 int next;
3212
3213                                 if (iskanji (i)) {
3214                                         inkey_base = TRUE;
3215                                         next = inkey ();
3216                                         if (k+1 < len) {
3217                                                 buf[k++] = i;
3218                                                 buf[k] = next;
3219                                                 k_flag[k++] = 1;
3220                                         } else
3221                                                 bell();
3222                                 } else {
3223 #ifdef SJIS
3224                     if(k<len && (isprint(i) || (0xa0<=i && i<=0xdf))){
3225 #else
3226                     if(k<len && isprint(i)){
3227 #endif
3228                                                 buf[k] = i;
3229                                                 k_flag[k++] = 0;
3230                                         } else
3231                                                 bell();
3232                                }
3233                  }
3234 #else
3235                         if ((k < len) && (isprint(i)))
3236                         {
3237                                 buf[k++] = i;
3238                         }
3239                         else
3240                         {
3241                                 bell();
3242                         }
3243 #endif
3244
3245                         break;
3246                 }
3247
3248                 /* Terminate */
3249                 buf[k] = '\0';
3250
3251                 /* Update the entry */
3252                 Term_erase(x, y, len);
3253                 Term_putstr(x, y, -1, TERM_WHITE, buf);
3254         }
3255
3256         /* Aborted */
3257         if (i == ESCAPE) return (FALSE);
3258
3259         /* Success */
3260         return (TRUE);
3261 }
3262
3263
3264 /*
3265  * Get a string from the user
3266  *
3267  * The "prompt" should take the form "Prompt: "
3268  *
3269  * Note that the initial contents of the string is used as
3270  * the default response, so be sure to "clear" it if needed.
3271  *
3272  * We clear the input, and return FALSE, on "ESCAPE".
3273  */
3274 bool get_string(cptr prompt, char *buf, int len)
3275 {
3276         bool res;
3277
3278         /* Paranoia XXX XXX XXX */
3279         msg_print(NULL);
3280
3281         /* Display prompt */
3282         prt(prompt, 0, 0);
3283
3284         /* Ask the user for a string */
3285         res = askfor_aux(buf, len);
3286
3287         /* Clear prompt */
3288         prt("", 0, 0);
3289
3290         /* Result */
3291         return (res);
3292 }
3293
3294
3295 /*
3296  * Verify something with the user
3297  *
3298  * The "prompt" should take the form "Query? "
3299  *
3300  * Note that "[y/n]" is appended to the prompt.
3301  */
3302 bool get_check(cptr prompt)
3303 {
3304         int i;
3305
3306         char buf[80];
3307
3308         if (auto_more)
3309         {
3310                 p_ptr->window |= PW_MESSAGE;
3311                 window_stuff();
3312                 num_more = 0;
3313         }
3314
3315         /* Paranoia XXX XXX XXX */
3316         msg_print(NULL);
3317
3318         /* Hack -- Build a "useful" prompt */
3319         (void)strnfmt(buf, 78, "%.70s[y/n] ", prompt);
3320
3321         /* Prompt for it */
3322         prt(buf, 0, 0);
3323
3324         /* Get an acceptable answer */
3325         while (TRUE)
3326         {
3327                 i = inkey();
3328 /*              if (quick_messages) break; */
3329                 if (i == ESCAPE) break;
3330                 if (strchr("YyNn", i)) break;
3331                 bell();
3332         }
3333
3334         /* Erase the prompt */
3335         prt("", 0, 0);
3336
3337         /* Normal negation */
3338         if ((i != 'Y') && (i != 'y')) return (FALSE);
3339
3340         /* Success */
3341         return (TRUE);
3342 }
3343
3344
3345 /*
3346  * Prompts for a keypress
3347  *
3348  * The "prompt" should take the form "Command: "
3349  *
3350  * Returns TRUE unless the character is "Escape"
3351  */
3352 bool get_com(cptr prompt, char *command, bool z_escape)
3353 {
3354         /* Paranoia XXX XXX XXX */
3355         msg_print(NULL);
3356
3357         /* Display a prompt */
3358         prt(prompt, 0, 0);
3359
3360         /* Get a key */
3361         *command = inkey();
3362
3363         /* Clear the prompt */
3364         prt("", 0, 0);
3365
3366         /* Handle "cancel" */
3367         if (*command == ESCAPE) return (FALSE);
3368         if (z_escape && ((*command == 'z') || (*command == 'Z'))) return (FALSE);
3369
3370         /* Success */
3371         return (TRUE);
3372 }
3373
3374
3375 /*
3376  * Request a "quantity" from the user
3377  *
3378  * Hack -- allow "command_arg" to specify a quantity
3379  */
3380 s16b get_quantity(cptr prompt, int max)
3381 {
3382         int amt;
3383
3384         char tmp[80];
3385
3386         char buf[80];
3387
3388
3389         /* Use "command_arg" */
3390         if (command_arg)
3391         {
3392                 /* Extract a number */
3393                 amt = command_arg;
3394
3395                 /* Clear "command_arg" */
3396                 command_arg = 0;
3397
3398                 /* Enforce the maximum */
3399                 if (amt > max) amt = max;
3400
3401                 /* Use it */
3402                 return (amt);
3403         }
3404
3405 #ifdef ALLOW_REPEAT /* TNB */
3406
3407         /* Get the item index */
3408         if ((max != 1) && repeat_pull(&amt))
3409         {
3410                 /* Enforce the maximum */
3411                 if (amt > max) amt = max;
3412
3413                 /* Enforce the minimum */
3414                 if (amt < 0) amt = 0;
3415
3416                 /* Use it */
3417                 return (amt);
3418         }
3419
3420 #endif /* ALLOW_REPEAT -- TNB */
3421
3422         /* Build a prompt if needed */
3423         if (!prompt)
3424         {
3425                 /* Build a prompt */
3426 #ifdef JP
3427                         sprintf(tmp, "¤¤¤¯¤Ä¤Ç¤¹¤« (1-%d): ", max);
3428 #else
3429                 sprintf(tmp, "Quantity (1-%d): ", max);
3430 #endif
3431
3432
3433                 /* Use that prompt */
3434                 prompt = tmp;
3435         }
3436
3437
3438         /* Default to one */
3439         amt = 1;
3440
3441         /* Build the default */
3442         sprintf(buf, "%d", amt);
3443
3444         /* Ask for a quantity */
3445         if (!get_string(prompt, buf, 6)) return (0);
3446
3447         /* Extract a number */
3448         amt = atoi(buf);
3449
3450         /* A letter means "all" */
3451         if (isalpha(buf[0])) amt = max;
3452
3453         /* Enforce the maximum */
3454         if (amt > max) amt = max;
3455
3456         /* Enforce the minimum */
3457         if (amt < 0) amt = 0;
3458
3459 #ifdef ALLOW_REPEAT /* TNB */
3460
3461         if (amt) repeat_push(amt);
3462
3463 #endif /* ALLOW_REPEAT -- TNB */
3464
3465         /* Return the result */
3466         return (amt);
3467 }
3468
3469
3470 /*
3471  * Pause for user response XXX XXX XXX
3472  */
3473 void pause_line(int row)
3474 {
3475         int i;
3476         prt("", row, 0);
3477 #ifdef JP
3478         put_str("[ ²¿¤«¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤ ]", row, 26);
3479 #else
3480         put_str("[Press any key to continue]", row, 23);
3481 #endif
3482
3483         i = inkey();
3484         prt("", row, 0);
3485 }
3486
3487
3488 /*
3489  * Hack -- special buffer to hold the action of the current keymap
3490  */
3491 static char request_command_buffer[256];
3492
3493
3494
3495 typedef struct
3496 {
3497         cptr name;
3498         byte cmd;
3499         bool fin;
3500 } menu_naiyou;
3501
3502 #ifdef JP
3503 menu_naiyou menu_info[10][10] =
3504 {
3505         {
3506                 {"ËâË¡/ÆüìǽÎÏ", 1, FALSE},
3507                 {"¹ÔÆ°", 2, FALSE},
3508                 {"Æ»¶ñ(»ÈÍÑ)", 3, FALSE},
3509                 {"Æ»¶ñ(¤½¤Î¾)", 4, FALSE},
3510                 {"ÁõÈ÷", 5, FALSE},
3511                 {"Èâ/È¢", 6, FALSE},
3512                 {"¾ðÊó", 7, FALSE},
3513                 {"ÀßÄê", 8, FALSE},
3514                 {"¤½¤Î¾", 9, FALSE},
3515                 {"", 0, FALSE},
3516         },
3517
3518         {
3519                 {"»È¤¦(m)", 'm', TRUE},
3520                 {"Ä´¤Ù¤ë(b/P)", 'b', TRUE},
3521                 {"³Ð¤¨¤ë(G)", 'G', TRUE},
3522                 {"ÆüìǽÎϤò»È¤¦(U/O)", 'U', TRUE},
3523                 {"", 0, FALSE},
3524                 {"", 0, FALSE},
3525                 {"", 0, FALSE},
3526                 {"", 0, FALSE},
3527                 {"", 0, FALSE},
3528                 {"", 0, FALSE}
3529         },
3530
3531         {
3532                 {"µÙ©¤¹¤ë(R)", 'R', TRUE},
3533                 {"¥È¥é¥Ã¥×²ò½ü(D)", 'D', TRUE},
3534                 {"õ¤¹(s)", 's', TRUE},
3535                 {"¼þ¤ê¤òÄ´¤Ù¤ë(l/x)", 'l', TRUE},
3536                 {"¥¿¡¼¥²¥Ã¥È»ØÄê(*)", '*', TRUE},
3537                 {"·ê¤ò·¡¤ë(T/^t)", 'T', TRUE},
3538                 {"³¬Ãʤò¾å¤ë(<)", '<', TRUE},
3539                 {"³¬Ãʤò²¼¤ê¤ë(>)", '>', TRUE},
3540                 {"¥Ú¥Ã¥È¤ËÌ¿Î᤹¤ë(p)", 'p', TRUE},
3541                 {"õº÷¥â¡¼¥É¤ÎON/OFF(S/#)", 'S', TRUE}
3542         },
3543
3544         {
3545                 {"Æɤà(r)", 'r', TRUE},
3546                 {"°û¤à(q)", 'q', TRUE},
3547                 {"¾ó¤ò»È¤¦(u/Z)", 'u', TRUE},
3548                 {"ËâË¡ËÀ¤ÇÁÀ¤¦(a/z)", 'a', TRUE},
3549                 {"¥í¥Ã¥É¤ò¿¶¤ë(z/a)", 'z', TRUE},
3550                 {"»ÏÆ°¤¹¤ë(A)", 'A', TRUE},
3551                 {"¿©¤Ù¤ë(E)", 'E', TRUE},
3552                 {"Èô¤ÓÆ»¶ñ¤Ç·â¤Ä(f/t)", 'f', TRUE},
3553                 {"Åꤲ¤ë(v)", 'v', TRUE},
3554                 {"", 0, FALSE}
3555         },
3556
3557         {
3558                 {"½¦¤¦(g)", 'g', TRUE},
3559                 {"Íî¤È¤¹(d)", 'd', TRUE},
3560                 {"²õ¤¹(k/^d)", 'k', TRUE},
3561                 {"Ìäò¹ï¤à({)", '{', TRUE},
3562                 {"Ìäò¾Ã¤¹(})", '}', TRUE},
3563                 {"Ä´ºº(I)", 'I', TRUE},
3564                 {"¥¢¥¤¥Æ¥à°ìÍ÷(i)", 'i', TRUE},
3565                 {"", 0, FALSE},
3566                 {"", 0, FALSE},
3567                 {"", 0, FALSE}
3568         },
3569
3570         {
3571                 {"ÁõÈ÷¤¹¤ë(w)", 'w', TRUE},
3572                 {"ÁõÈ÷¤ò³°¤¹(t/T)", 't', TRUE},
3573                 {"dzÎÁ¤òÊäµë(F)", 'F', TRUE},
3574                 {"ÁõÈ÷°ìÍ÷(e)", 'e', TRUE},
3575                 {"", 0, FALSE},
3576                 {"", 0, FALSE},
3577                 {"", 0, FALSE},
3578                 {"", 0, FALSE},
3579                 {"", 0, FALSE},
3580                 {"", 0, FALSE}
3581         },
3582
3583         {
3584                 {"³«¤±¤ë(o)", 'o', TRUE},
3585                 {"ÊĤ¸¤ë(c)", 'c', TRUE},
3586                 {"ÂÎÅö¤¿¤ê¤¹¤ë(B/f)", 'B', TRUE},
3587                 {"¤¯¤µ¤Ó¤òÂǤÄ(j/S)", 'j', TRUE},
3588                 {"", 0, FALSE},
3589                 {"", 0, FALSE},
3590                 {"", 0, FALSE},
3591                 {"", 0, FALSE},
3592                 {"", 0, FALSE},
3593                 {"", 0, FALSE}
3594         },
3595
3596         {
3597                 {"¥À¥ó¥¸¥ç¥ó¤ÎÁ´ÂοÞ(M)", 'M', TRUE},
3598                 {"°ÌÃÖ¤ò³Îǧ(L/W)", 'L', TRUE},
3599                 {"³¬¤ÎÊ·°Ïµ¤(^f)", KTRL('F'), TRUE},
3600                 {"¥¹¥Æ¡¼¥¿¥¹(C)", 'C', TRUE},
3601                 {"ʸ»ú¤ÎÀâÌÀ(/)", '/', TRUE},
3602                 {"¥á¥Ã¥»¡¼¥¸ÍúÎò(^p)", KTRL('P'), TRUE},
3603                 {"¸½ºß¤Î»þ¹ï(^t/')", KTRL('T'), TRUE},
3604                 {"¸½ºß¤ÎÃμ±(~)", '~', TRUE},
3605                 {"¥×¥ì¥¤µ­Ï¿(|)", '|', TRUE},
3606                 {"", 0, FALSE}
3607         },
3608
3609         {
3610                 {"¥ª¥×¥·¥ç¥ó(=)", '=', TRUE},
3611                 {"¥Þ¥¯¥í(@)", '@', TRUE},
3612                 {"²èÌÌɽ¼¨(%)", '%', TRUE},
3613                 {"¥«¥é¡¼(&)", '&', TRUE},
3614                 {"ÀßÄêÊѹ¹¥³¥Þ¥ó¥É(\")", '\"', TRUE},
3615                 {"¼«Æ°½¦¤¤¤ò¥í¡¼¥É($)", '$', TRUE},
3616                 {"¥·¥¹¥Æ¥à(!)", '!', TRUE},
3617                 {"", 0, FALSE},
3618                 {"", 0, FALSE},
3619                 {"", 0, FALSE}
3620         },
3621
3622         {
3623                 {"¥»¡¼¥Ö&ÃæÃÇ(^x)", KTRL('X'), TRUE},
3624                 {"¥»¡¼¥Ö(^s)", KTRL('S'), TRUE},
3625                 {"¥Ø¥ë¥×(?)", '?', TRUE},
3626                 {"ºÆÉÁ²è(^r)", KTRL('R'), TRUE},
3627                 {"¥á¥â(:)", ':', TRUE},
3628                 {"µ­Ç°»£±Æ())", ')', TRUE},
3629                 {"µ­Ç°»£±Æ¤Îɽ¼¨(()", '(', TRUE},
3630                 {"¥Ð¡¼¥¸¥ç¥ó¾ðÊó(V)", 'V', TRUE},
3631                 {"°úÂह¤ë(Q)", 'Q', TRUE},
3632                 {"", 0, FALSE}
3633         },
3634 };
3635 #else
3636 menu_naiyou menu_info[10][10] =
3637 {
3638         {
3639                 {"Magic/Special", 1, FALSE},
3640                 {"Action", 2, FALSE},
3641                 {"Items(use)", 3, FALSE},
3642                 {"Items(other)", 4, FALSE},
3643                 {"Equip", 5, FALSE},
3644                 {"Door/Box", 6, FALSE},
3645                 {"Infomations", 7, FALSE},
3646                 {"Options", 8, FALSE},
3647                 {"Other commands", 9, FALSE},
3648                 {"", 0, FALSE},
3649         },
3650
3651         {
3652                 {"Use(m)", 'm', TRUE},
3653                 {"See tips(b/P)", 'b', TRUE},
3654                 {"Study(G)", 'G', TRUE},
3655                 {"Special abilities(U/O)", 'U', TRUE},
3656                 {"", 0, FALSE},
3657                 {"", 0, FALSE},
3658                 {"", 0, FALSE},
3659                 {"", 0, FALSE},
3660                 {"", 0, FALSE},
3661                 {"", 0, FALSE}
3662         },
3663
3664         {
3665                 {"Rest(R)", 'R', TRUE},
3666                 {"Disarm a trap(D)", 'D', TRUE},
3667                 {"Search(s)", 's', TRUE},
3668                 {"Look(l/x)", 'l', TRUE},
3669                 {"Target(*)", '*', TRUE},
3670                 {"Dig(T/^t)", 'T', TRUE},
3671                 {"Go up stairs(<)", '<', TRUE},
3672                 {"Go down staies(>)", '>', TRUE},
3673                 {"Command pets(p)", 'p', TRUE},
3674                 {"Search mode ON/OFF(S/#)", 'S', TRUE}
3675         },
3676
3677         {
3678                 {"Read a scroll(r)", 'r', TRUE},
3679                 {"Drink a potion(q)", 'q', TRUE},
3680                 {"Use a staff(u/Z)", 'u', TRUE},
3681                 {"Aim a wand(a/z)", 'a', TRUE},
3682                 {"Zap a rod(z/a)", 'z', TRUE},
3683                 {"Activate an equipment(A)", 'A', TRUE},
3684                 {"Eat(E)", 'E', TRUE},
3685                 {"Fire missile weapon(f/t)", 'f', TRUE},
3686                 {"Throw an item(v)", 'v', TRUE},
3687                 {"", 0, FALSE}
3688         },
3689
3690         {
3691                 {"Get items(g)", 'g', TRUE},
3692                 {"Drop an item(d)", 'd', TRUE},
3693                 {"Destroy an item(k/^d)", 'k', TRUE},
3694                 {"Inscribe an item({)", '{', TRUE},
3695                 {"Uninscribe an item(})", '}', TRUE},
3696                 {"Info about an item(I)", 'I', TRUE},
3697                 {"Inventory list(i)", 'i', TRUE},
3698                 {"", 0, FALSE},
3699                 {"", 0, FALSE},
3700                 {"", 0, FALSE}
3701         },
3702
3703         {
3704                 {"Wear(w)", 'w', TRUE},
3705                 {"Take off(t/T)", 't', TRUE},
3706                 {"Refuel(F)", 'F', TRUE},
3707                 {"Equipment list(e)", 'e', TRUE},
3708                 {"", 0, FALSE},
3709                 {"", 0, FALSE},
3710                 {"", 0, FALSE},
3711                 {"", 0, FALSE},
3712                 {"", 0, FALSE},
3713                 {"", 0, FALSE}
3714         },
3715
3716         {
3717                 {"Open(o)", 'o', TRUE},
3718                 {"Close(c)", 'c', TRUE},
3719                 {"Bash a door(B/f)", 'B', TRUE},
3720                 {"Jam a door(j/S)", 'j', TRUE},
3721                 {"", 0, FALSE},
3722                 {"", 0, FALSE},
3723                 {"", 0, FALSE},
3724                 {"", 0, FALSE},
3725                 {"", 0, FALSE},
3726                 {"", 0, FALSE}
3727         },
3728
3729         {
3730                 {"Full map(M)", 'M', TRUE},
3731                 {"Map(L/W)", 'L', TRUE},
3732                 {"Level feeling(^f)", KTRL('F'), TRUE},
3733                 {"Character status(C)", 'C', TRUE},
3734                 {"Identify symbol(/)", '/', TRUE},
3735                 {"Show prev messages(^p)", KTRL('P'), TRUE},
3736                 {"Current time(^t/')", KTRL('T'), TRUE},
3737                 {"Various infomations(~)", '~', TRUE},
3738                 {"Play record menu(|)", '|', TRUE},
3739                 {"", 0, FALSE}
3740         },
3741
3742         {
3743                 {"Set options(=)", '=', TRUE},
3744                 {"Interact with macros(@)", '@', TRUE},
3745                 {"Interact w/ visuals(%)", '%', TRUE},
3746                 {"Interact with colors(&)", '&', TRUE},
3747                 {"Enter a user pref(\")", '\"', TRUE},
3748                 {"Reload auto-pick pref($)", '$', TRUE},
3749                 {"", 0, FALSE},
3750                 {"", 0, FALSE},
3751                 {"", 0, FALSE},
3752                 {"", 0, FALSE}
3753         },
3754
3755         {
3756                 {"Save and quit(^x)", KTRL('X'), TRUE},
3757                 {"Save(^s)", KTRL('S'), TRUE},
3758                 {"Help(obsoleted)(?)", '?', TRUE},
3759                 {"Redraw(^r)", KTRL('R'), TRUE},
3760                 {"Take note(:)", ':', TRUE},
3761                 {"Dump screen dump(()", ')', TRUE},
3762                 {"Load screen dump())", '(', TRUE},
3763                 {"Version info(V)", 'V', TRUE},
3764                 {"Quit(Q)", 'Q', TRUE},
3765                 {"", 0, FALSE}
3766         },
3767 };
3768 #endif
3769
3770 typedef struct
3771 {
3772         cptr name;
3773         byte window;
3774         byte number;
3775         byte jouken;
3776         byte jouken_naiyou;
3777 } special_menu_naiyou;
3778
3779 #define MENU_CLASS 1
3780 #define MENU_WILD 2
3781
3782 #ifdef JP
3783 special_menu_naiyou special_menu_info[] =
3784 {
3785         {"ĶǽÎÏ/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_MINDCRAFTER},
3786         {"¤â¤Î¤Þ¤Í/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_IMITATOR},
3787         {"ɬ»¦µ»/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_SAMURAI},
3788         {"Îýµ¤½Ñ/ËâË¡/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_FORCETRAINER},
3789         {"¶ÀËâË¡/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_MIRROR_MASTER},
3790         {"¹­°è¥Þ¥Ã¥×(<)", 2, 6, MENU_WILD, FALSE},
3791         {"Ä̾ï¥Þ¥Ã¥×(>)", 2, 7, MENU_WILD, TRUE},
3792         {"", 0, 0, 0, 0},
3793 };
3794 #else
3795 special_menu_naiyou special_menu_info[] =
3796 {
3797         {"MindCraft/Special", 0, 0, MENU_CLASS, CLASS_MINDCRAFTER},
3798         {"Imitation/Special", 0, 0, MENU_CLASS, CLASS_IMITATOR},
3799         {"Technique/Special", 0, 0, MENU_CLASS, CLASS_SAMURAI},
3800         {"Mind/Magic/Special", 0, 0, MENU_CLASS, CLASS_FORCETRAINER},
3801         {"MirrorMagic/Special", 0, 0, MENU_CLASS, CLASS_MIRROR_MASTER},
3802         {"Enter global map(<)", 2, 6, MENU_WILD, FALSE},
3803         {"Enter local map(>)", 2, 7, MENU_WILD, TRUE},
3804         {"", 0, 0, 0, 0},
3805 };
3806 #endif
3807
3808 /*
3809  * Request a command from the user.
3810  *
3811  * Sets p_ptr->command_cmd, p_ptr->command_dir, p_ptr->command_rep,
3812  * p_ptr->command_arg.  May modify p_ptr->command_new.
3813  *
3814  * Note that "caret" ("^") is treated specially, and is used to
3815  * allow manual input of control characters.  This can be used
3816  * on many machines to request repeated tunneling (Ctrl-H) and
3817  * on the Macintosh to request "Control-Caret".
3818  *
3819  * Note that "backslash" is treated specially, and is used to bypass any
3820  * keymap entry for the following character.  This is useful for macros.
3821  *
3822  * Note that this command is used both in the dungeon and in
3823  * stores, and must be careful to work in both situations.
3824  *
3825  * Note that "p_ptr->command_new" may not work any more.  XXX XXX XXX
3826  */
3827 void request_command(int shopping)
3828 {
3829         int i;
3830
3831         unsigned char cmd;
3832
3833         int mode;
3834
3835         cptr act;
3836
3837 #ifdef JP
3838         int caretcmd = 0;
3839 #endif
3840         /* Roguelike */
3841         if (rogue_like_commands)
3842         {
3843                 mode = KEYMAP_MODE_ROGUE;
3844         }
3845
3846         /* Original */
3847         else
3848         {
3849                 mode = KEYMAP_MODE_ORIG;
3850         }
3851
3852
3853         /* No command yet */
3854         command_cmd = 0;
3855
3856         /* No "argument" yet */
3857         command_arg = 0;
3858
3859         /* No "direction" yet */
3860         command_dir = 0;
3861
3862         use_menu = FALSE;
3863
3864
3865         /* Get command */
3866         while (1)
3867         {
3868                 /* Hack -- auto-commands */
3869                 if (command_new)
3870                 {
3871                         /* Flush messages */
3872                         msg_print(NULL);
3873
3874                         /* Use auto-command */
3875                         cmd = (unsigned char)command_new;
3876
3877                         /* Forget it */
3878                         command_new = 0;
3879                 }
3880
3881                 /* Get a keypress in "command" mode */
3882                 else
3883                 {
3884                         char sub_cmd;
3885
3886                         /* Hack -- no flush needed */
3887                         msg_flag = FALSE;
3888                         num_more = 0;
3889
3890                         /* Activate "command mode" */
3891                         inkey_flag = TRUE;
3892
3893                         /* Get a command */
3894                         sub_cmd = inkey();
3895
3896                         if (!shopping && command_menu && ((sub_cmd == '\r') || (sub_cmd == 'x') || (sub_cmd == 'X'))
3897                             && !keymap_act[mode][(byte)(sub_cmd)])
3898                         {
3899                                 int basey, basex;
3900                                 int num = 0, max_num, old_num = 0;
3901                                 int menu = 0;
3902                                 bool kisuu;
3903
3904                                 if (py - panel_row_min > 10) basey = 2;
3905                                 else basey = 13;
3906                                 basex = 15;
3907
3908                                 /* Clear top line */
3909                                 prt("", 0, 0);
3910
3911                                 screen_save();
3912
3913                                 while(1)
3914                                 {
3915                                         cptr menu_name;
3916                                         if (!menu) old_num = num;
3917                                         put_str("+----------------------------------------------------+", basey, basex);
3918                                         put_str("|                                                    |", basey+1, basex);
3919                                         put_str("|                                                    |", basey+2, basex);
3920                                         put_str("|                                                    |", basey+3, basex);
3921                                         put_str("|                                                    |", basey+4, basex);
3922                                         put_str("|                                                    |", basey+5, basex);
3923                                         put_str("+----------------------------------------------------+", basey+6, basex);
3924
3925                                         for(i = 0; i < 10; i++)
3926                                         {
3927                                                 int hoge;
3928                                                 if (!menu_info[menu][i].cmd) break;
3929                                                 menu_name = menu_info[menu][i].name;
3930                                                 for(hoge = 0; ; hoge++)
3931                                                 {
3932                                                         if (!special_menu_info[hoge].name[0]) break;
3933                                                         if ((menu != special_menu_info[hoge].window) || (i != special_menu_info[hoge].number)) continue;
3934                                                         switch(special_menu_info[hoge].jouken)
3935                                                         {
3936                                                                 case MENU_CLASS:
3937                                                                 if (p_ptr->pclass == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
3938                                                                 break;
3939                                                                 case MENU_WILD:
3940                                                                 if (!dun_level && !p_ptr->inside_arena && !p_ptr->inside_quest)
3941                                                                 {
3942                                                                         if ((byte)p_ptr->wild_mode == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
3943                                                                 }
3944                                                                 break;
3945                                                                 default:
3946                                                                 break;
3947                                                         }
3948                                                 }
3949                                                 put_str(menu_name, basey + 1 + i / 2, basex + 4 + (i % 2) * 24);
3950                                         }
3951                                         max_num = i;
3952                                         kisuu = max_num % 2;
3953 #ifdef JP
3954                                         put_str("¡Õ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
3955 #else
3956                                         put_str("> ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
3957 #endif
3958
3959                                         /* Place the cursor on the player */
3960                                         move_cursor_relative(py, px);
3961
3962                                         /* Get a command */
3963                                         sub_cmd = inkey();
3964                                         if ((sub_cmd == ' ') || (sub_cmd == 'x') || (sub_cmd == 'X') || (sub_cmd == '\r'))
3965                                         {
3966                                                 if (menu_info[menu][num].fin)
3967                                                 {
3968                                                         cmd = menu_info[menu][num].cmd;
3969                                                         use_menu = TRUE;
3970                                                         break;
3971                                                 }
3972                                                 else
3973                                                 {
3974                                                         menu = menu_info[menu][num].cmd;
3975                                                         num = 0;
3976                                                         basey += 2;
3977                                                         basex += 8;
3978                                                 }
3979                                         }
3980                                         else if ((sub_cmd == ESCAPE) || (sub_cmd == 'z') || (sub_cmd == 'Z') || (sub_cmd == '0'))
3981                                         {
3982                                                 if (!menu)
3983                                                 {
3984                                                         cmd = ESCAPE;
3985                                                         break;
3986                                                 }
3987                                                 else
3988                                                 {
3989                                                         menu = 0;
3990                                                         num = old_num;
3991                                                         basey -= 2;
3992                                                         basex -= 8;
3993                                                         screen_load();
3994                                                         screen_save();
3995                                                 }
3996                                         }
3997                                         else if ((sub_cmd == '2') || (sub_cmd == 'j') || (sub_cmd == 'J'))
3998                                         {
3999                                                 if (kisuu)
4000                                                 {
4001                                                         if (num % 2)
4002                                                                 num = (num + 2) % (max_num - 1);
4003                                                         else
4004                                                                 num = (num + 2) % (max_num + 1);
4005                                                 }
4006                                                 else num = (num + 2) % max_num;
4007                                         }
4008                                         else if ((sub_cmd == '8') || (sub_cmd == 'k') || (sub_cmd == 'K'))
4009                                         {
4010                                                 if (kisuu)
4011                                                 {
4012                                                         if (num % 2)
4013                                                                 num = (num + max_num - 3) % (max_num - 1);
4014                                                         else
4015                                                                 num = (num + max_num - 1) % (max_num + 1);
4016                                                 }
4017                                                 else num = (num + max_num - 2) % max_num;
4018                                         }
4019                                         else if ((sub_cmd == '4') || (sub_cmd == '6') || (sub_cmd == 'h') || (sub_cmd == 'H') || (sub_cmd == 'l') || (sub_cmd == 'L'))
4020                                         {
4021                                                 if ((num % 2) || (num == max_num - 1))
4022                                                 {
4023                                                         num--;
4024                                                 }
4025                                                 else if (num < max_num - 1)
4026                                                 {
4027                                                         num++;
4028                                                 }
4029                                         }
4030                                 }
4031
4032                                 screen_load();
4033                                 if (!inkey_next) inkey_next = "";
4034                         }
4035                         else cmd = sub_cmd;
4036                 }
4037
4038                 /* Clear top line */
4039                 prt("", 0, 0);
4040
4041
4042                 /* Command Count */
4043                 if (cmd == '0')
4044                 {
4045                         int old_arg = command_arg;
4046
4047                         /* Reset */
4048                         command_arg = 0;
4049
4050                         /* Begin the input */
4051 #ifdef JP
4052                         prt("²ó¿ô: ", 0, 0);
4053 #else
4054                         prt("Count: ", 0, 0);
4055 #endif
4056
4057
4058                         /* Get a command count */
4059                         while (1)
4060                         {
4061                                 /* Get a new keypress */
4062                                 cmd = inkey();
4063
4064                                 /* Simple editing (delete or backspace) */
4065                                 if ((cmd == 0x7F) || (cmd == KTRL('H')))
4066                                 {
4067                                         /* Delete a digit */
4068                                         command_arg = command_arg / 10;
4069
4070                                         /* Show current count */
4071 #ifdef JP
4072                                         prt(format("²ó¿ô: %d", command_arg), 0, 0);
4073 #else
4074                                         prt(format("Count: %d", command_arg), 0, 0);
4075 #endif
4076
4077                                 }
4078
4079                                 /* Actual numeric data */
4080                                 else if (cmd >= '0' && cmd <= '9')
4081                                 {
4082                                         /* Stop count at 9999 */
4083                                         if (command_arg >= 1000)
4084                                         {
4085                                                 /* Warn */
4086                                                 bell();
4087
4088                                                 /* Limit */
4089                                                 command_arg = 9999;
4090                                         }
4091
4092                                         /* Increase count */
4093                                         else
4094                                         {
4095                                                 /* Incorporate that digit */
4096                                                 command_arg = command_arg * 10 + D2I(cmd);
4097                                         }
4098
4099                                         /* Show current count */
4100 #ifdef JP
4101                                         prt(format("²ó¿ô: %d", command_arg), 0, 0);
4102 #else
4103                                         prt(format("Count: %d", command_arg), 0, 0);
4104 #endif
4105
4106                                 }
4107
4108                                 /* Exit on "unusable" input */
4109                                 else
4110                                 {
4111                                         break;
4112                                 }
4113                         }
4114
4115                         /* Hack -- Handle "zero" */
4116                         if (command_arg == 0)
4117                         {
4118                                 /* Default to 99 */
4119                                 command_arg = 99;
4120
4121                                 /* Show current count */
4122 #ifdef JP
4123                                 prt(format("²ó¿ô: %d", command_arg), 0, 0);
4124 #else
4125                                 prt(format("Count: %d", command_arg), 0, 0);
4126 #endif
4127
4128                         }
4129
4130                         /* Hack -- Handle "old_arg" */
4131                         if (old_arg != 0)
4132                         {
4133                                 /* Restore old_arg */
4134                                 command_arg = old_arg;
4135
4136                                 /* Show current count */
4137 #ifdef JP
4138 prt(format("²ó¿ô: %d", command_arg), 0, 0);
4139 #else
4140                                 prt(format("Count: %d", command_arg), 0, 0);
4141 #endif
4142
4143                         }
4144
4145                         /* Hack -- white-space means "enter command now" */
4146                         if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r'))
4147                         {
4148                                 /* Get a real command */
4149 #ifdef JP
4150                                 if (!get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE))
4151 #else
4152                                 if (!get_com("Command: ", (char *)&cmd, FALSE))
4153 #endif
4154
4155                                 {
4156                                         /* Clear count */
4157                                         command_arg = 0;
4158
4159                                         /* Continue */
4160                                         continue;
4161                                 }
4162                         }
4163                 }
4164
4165
4166                 /* Allow "keymaps" to be bypassed */
4167                 if (cmd == '\\')
4168                 {
4169                         /* Get a real command */
4170 #ifdef JP
4171                         (void)get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE);
4172 #else
4173                         (void)get_com("Command: ", (char *)&cmd, FALSE);
4174 #endif
4175
4176
4177                         /* Hack -- bypass keymaps */
4178                         if (!inkey_next) inkey_next = "";
4179                 }
4180
4181
4182                 /* Allow "control chars" to be entered */
4183                 if (cmd == '^')
4184                 {
4185                         /* Get a new command and controlify it */
4186 #ifdef JP
4187                         if (get_com("CTRL: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
4188 #else
4189                         if (get_com("Control: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
4190 #endif
4191
4192                 }
4193
4194
4195                 /* Look up applicable keymap */
4196                 act = keymap_act[mode][(byte)(cmd)];
4197
4198                 /* Apply keymap if not inside a keymap already */
4199                 if (act && !inkey_next)
4200                 {
4201                         /* Install the keymap (limited buffer size) */
4202                         (void)strnfmt(request_command_buffer, 256, "%s", act);
4203
4204                         /* Start using the buffer */
4205                         inkey_next = request_command_buffer;
4206
4207                         /* Continue */
4208                         continue;
4209                 }
4210
4211
4212                 /* Paranoia */
4213                 if (!cmd) continue;
4214
4215
4216                 /* Use command */
4217                 command_cmd = cmd;
4218
4219                 /* Done */
4220                 break;
4221         }
4222
4223         /* Hack -- Auto-repeat certain commands */
4224         if (always_repeat && (command_arg <= 0))
4225         {
4226                 /* Hack -- auto repeat certain commands */
4227                 if (strchr("TBDoc+", command_cmd))
4228                 {
4229                         /* Repeat 99 times */
4230                         command_arg = 99;
4231                 }
4232         }
4233
4234         /* Shopping */
4235         if (shopping == 1)
4236         {
4237                 /* Convert */
4238                 switch (command_cmd)
4239                 {
4240                         /* Command "p" -> "purchase" (get) */
4241                 case 'p': command_cmd = 'g'; break;
4242
4243                         /* Command "m" -> "purchase" (get) */
4244                 case 'm': command_cmd = 'g'; break;
4245
4246                         /* Command "s" -> "sell" (drop) */
4247                 case 's': command_cmd = 'd'; break;
4248                 }
4249         }
4250
4251 #ifdef JP
4252         for (i = 0; i < 256; i++)
4253         {
4254                 cptr s;
4255                 if ((s = keymap_act[mode][i]) != NULL)
4256                 {
4257                         if (*s == command_cmd && *(s+1) == 0)
4258                         {
4259                                 caretcmd = i;
4260                                 break;
4261                         }
4262                 }
4263         }
4264         if (!caretcmd)
4265                 caretcmd = command_cmd;
4266 #endif
4267         /* Hack -- Scan equipment */
4268         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4269         {
4270                 cptr s;
4271
4272                 object_type *o_ptr = &inventory[i];
4273
4274                 /* Skip non-objects */
4275                 if (!o_ptr->k_idx) continue;
4276
4277                 /* No inscription */
4278                 if (!o_ptr->inscription) continue;
4279
4280                 /* Obtain the inscription */
4281                 s = quark_str(o_ptr->inscription);
4282
4283                 /* Find a '^' */
4284                 s = strchr(s, '^');
4285
4286                 /* Process preventions */
4287                 while (s)
4288                 {
4289                         /* Check the "restriction" character */
4290 #ifdef JP
4291                         if ((s[1] == caretcmd) || (s[1] == '*'))
4292 #else
4293                         if ((s[1] == command_cmd) || (s[1] == '*'))
4294 #endif
4295
4296                         {
4297                                 /* Hack -- Verify command */
4298 #ifdef JP
4299                                 if (!get_check("ËÜÅö¤Ç¤¹¤«? "))
4300 #else
4301                                 if (!get_check("Are you sure? "))
4302 #endif
4303
4304                                 {
4305                                         /* Hack -- Use space */
4306                                         command_cmd = ' ';
4307                                 }
4308                         }
4309
4310                         /* Find another '^' */
4311                         s = strchr(s + 1, '^');
4312                 }
4313         }
4314
4315
4316         /* Hack -- erase the message line. */
4317         prt("", 0, 0);
4318 }
4319
4320
4321
4322 /*
4323  * Check a char for "vowel-hood"
4324  */
4325 bool is_a_vowel(int ch)
4326 {
4327         switch (ch)
4328         {
4329         case 'a':
4330         case 'e':
4331         case 'i':
4332         case 'o':
4333         case 'u':
4334         case 'A':
4335         case 'E':
4336         case 'I':
4337         case 'O':
4338         case 'U':
4339                 return (TRUE);
4340         }
4341
4342         return (FALSE);
4343 }
4344
4345
4346
4347 #if 0
4348
4349 /*
4350  * Replace the first instance of "target" in "buf" with "insert"
4351  * If "insert" is NULL, just remove the first instance of "target"
4352  * In either case, return TRUE if "target" is found.
4353  *
4354  * XXX Could be made more efficient, especially in the
4355  * case where "insert" is smaller than "target".
4356  */
4357 static bool insert_str(char *buf, cptr target, cptr insert)
4358 {
4359         int   i, len;
4360         int                b_len, t_len, i_len;
4361
4362         /* Attempt to find the target (modify "buf") */
4363         buf = strstr(buf, target);
4364
4365         /* No target found */
4366         if (!buf) return (FALSE);
4367
4368         /* Be sure we have an insertion string */
4369         if (!insert) insert = "";
4370
4371         /* Extract some lengths */
4372         t_len = strlen(target);
4373         i_len = strlen(insert);
4374         b_len = strlen(buf);
4375
4376         /* How much "movement" do we need? */
4377         len = i_len - t_len;
4378
4379         /* We need less space (for insert) */
4380         if (len < 0)
4381         {
4382                 for (i = t_len; i < b_len; ++i) buf[i+len] = buf[i];
4383         }
4384
4385         /* We need more space (for insert) */
4386         else if (len > 0)
4387         {
4388                 for (i = b_len-1; i >= t_len; --i) buf[i+len] = buf[i];
4389         }
4390
4391         /* If movement occured, we need a new terminator */
4392         if (len) buf[b_len+len] = '\0';
4393
4394         /* Now copy the insertion string */
4395         for (i = 0; i < i_len; ++i) buf[i] = insert[i];
4396
4397         /* Successful operation */
4398         return (TRUE);
4399 }
4400
4401
4402 #endif
4403
4404
4405 /*
4406  * GH
4407  * Called from cmd4.c and a few other places. Just extracts
4408  * a direction from the keymap for ch (the last direction,
4409  * in fact) byte or char here? I'm thinking that keymaps should
4410  * generally only apply to single keys, which makes it no more
4411  * than 128, so a char should suffice... but keymap_act is 256...
4412  */
4413 int get_keymap_dir(char ch)
4414 {
4415         cptr act, s;
4416         int d = 0;
4417
4418         if (rogue_like_commands)
4419         {
4420                 act = keymap_act[KEYMAP_MODE_ROGUE][(byte)ch];
4421         }
4422         else
4423         {
4424                 act = keymap_act[KEYMAP_MODE_ORIG][(byte)ch];
4425         }
4426
4427         if (act)
4428         {
4429                 /* Convert to a direction */
4430                 for (s = act; *s; ++s)
4431                 {
4432                         /* Use any digits in keymap */
4433                         if (isdigit(*s)) d = D2I(*s);
4434                 }
4435         }
4436         return d;
4437 }
4438
4439
4440 #ifdef ALLOW_REPEAT /* TNB */
4441
4442 #define REPEAT_MAX              20
4443
4444 /* Number of chars saved */
4445 static int repeat__cnt = 0;
4446
4447 /* Current index */
4448 static int repeat__idx = 0;
4449
4450 /* Saved "stuff" */
4451 static int repeat__key[REPEAT_MAX];
4452
4453
4454 void repeat_push(int what)
4455 {
4456         /* Too many keys */
4457         if (repeat__cnt == REPEAT_MAX) return;
4458
4459         /* Push the "stuff" */
4460         repeat__key[repeat__cnt++] = what;
4461
4462         /* Prevents us from pulling keys */
4463         ++repeat__idx;
4464 }
4465
4466
4467 bool repeat_pull(int *what)
4468 {
4469         /* All out of keys */
4470         if (repeat__idx == repeat__cnt) return (FALSE);
4471
4472         /* Grab the next key, advance */
4473         *what = repeat__key[repeat__idx++];
4474
4475         /* Success */
4476         return (TRUE);
4477 }
4478
4479 void repeat_check(void)
4480 {
4481         int             what;
4482
4483         /* Ignore some commands */
4484         if (command_cmd == ESCAPE) return;
4485         if (command_cmd == ' ') return;
4486         if (command_cmd == '\r') return;
4487         if (command_cmd == '\n') return;
4488
4489         /* Repeat Last Command */
4490         if (command_cmd == 'n')
4491         {
4492                 /* Reset */
4493                 repeat__idx = 0;
4494
4495                 /* Get the command */
4496                 if (repeat_pull(&what))
4497                 {
4498                         /* Save the command */
4499                         command_cmd = what;
4500                 }
4501         }
4502
4503         /* Start saving new command */
4504         else
4505         {
4506                 /* Reset */
4507                 repeat__cnt = 0;
4508                 repeat__idx = 0;
4509
4510                 what = command_cmd;
4511
4512                 /* Save this command */
4513                 repeat_push(what);
4514         }
4515 }
4516
4517 #endif /* ALLOW_REPEAT -- TNB */
4518
4519
4520 #ifdef SORT_R_INFO
4521
4522 /*
4523  * Array size for which InsertionSort
4524  * is used instead of QuickSort
4525  */
4526 #define CUTOFF 4
4527
4528
4529 /*
4530  * Exchange two sort-entries
4531  * (should probably be coded inline
4532  * for speed increase)
4533  */
4534 static void swap(tag_type *a, tag_type *b)
4535 {
4536         tag_type temp;
4537
4538         temp.tag = a->tag;
4539         temp.pointer = a->pointer;
4540
4541         a->tag = b->tag;
4542         a->pointer = b->pointer;
4543
4544         b->tag = temp.tag;
4545         b->pointer = temp.pointer;
4546 }
4547
4548
4549 /*
4550  * Insertion-Sort algorithm
4551  * (used by the Quicksort algorithm)
4552  */
4553 static void InsertionSort(tag_type elements[], int number)
4554 {
4555         int j, P;
4556
4557         tag_type tmp;
4558
4559         for (P = 1; P < number; P++)
4560         {
4561                 tmp = elements[P];
4562                 for (j = P; (j > 0) && (elements[j - 1].tag > tmp.tag); j--)
4563                         elements[j] = elements[j - 1];
4564                 elements[j] = tmp;
4565         }
4566 }
4567
4568
4569 /*
4570  * Helper function for Quicksort
4571  */
4572 static tag_type median3(tag_type elements[], int left, int right)
4573 {
4574         int center = (left + right) / 2;
4575
4576         if (elements[left].tag > elements[center].tag)
4577                 swap(&elements[left], &elements[center]);
4578         if (elements[left].tag > elements[right].tag)
4579                 swap(&elements[left], &elements[right]);
4580         if (elements[center].tag > elements[right].tag)
4581                 swap(&elements[center], &elements[right]);
4582
4583         swap(&elements[center], &elements[right - 1]);
4584         return (elements[right - 1]);
4585 }
4586
4587
4588 /*
4589  * Quicksort algorithm
4590  *
4591  * The "median of three" pivot selection eliminates
4592  * the bad case of already sorted input.
4593  *
4594  * We use InsertionSort for smaller sub-arrays,
4595  * because it is faster in this case.
4596  *
4597  * For details see: "Data Structures and Algorithm
4598  * Analysis in C" by Mark Allen Weiss.
4599  */
4600 static void quicksort(tag_type elements[], int left, int right)
4601 {
4602         int i, j;
4603         tag_type pivot;
4604
4605         if (left + CUTOFF <= right)
4606         {
4607                 pivot = median3(elements, left, right);
4608
4609                 i = left; j = right -1;
4610
4611                 while (TRUE)
4612                 {
4613                         while (elements[++i].tag < pivot.tag);
4614                         while (elements[--j].tag > pivot.tag);
4615
4616                         if (i < j)
4617                                 swap(&elements[i], &elements[j]);
4618                         else
4619                                 break;
4620                 }
4621
4622                 /* Restore pivot */
4623                 swap(&elements[i], &elements[right - 1]);
4624
4625                 quicksort(elements, left, i - 1);
4626                 quicksort(elements, i + 1, right);
4627         }
4628         else
4629         {
4630                 /* Use InsertionSort on small arrays */
4631                 InsertionSort(elements + left, right - left + 1);
4632         }
4633 }
4634
4635
4636 /*
4637  * Frontend for the sorting algorithm
4638  *
4639  * Sorts an array of tagged pointers
4640  * with <number> elements.
4641  */
4642 void tag_sort(tag_type elements[], int number)
4643 {
4644         quicksort(elements, 0, number - 1);
4645 }
4646
4647 #endif /* SORT_R_INFO */
4648
4649 #ifdef SUPPORT_GAMMA
4650
4651 /* Table of gamma values */
4652 byte gamma_table[256];
4653
4654 /* Table of ln(x/256) * 256 for x going from 0 -> 255 */
4655 static s16b gamma_helper[256] =
4656 {
4657 0,-1420,-1242,-1138,-1065,-1007,-961,-921,-887,-857,-830,-806,-783,-762,-744,-726,
4658 -710,-694,-679,-666,-652,-640,-628,-617,-606,-596,-586,-576,-567,-577,-549,-541,
4659 -532,-525,-517,-509,-502,-495,-488,-482,-475,-469,-463,-457,-451,-455,-439,-434,
4660 -429,-423,-418,-413,-408,-403,-398,-394,-389,-385,-380,-376,-371,-367,-363,-359,
4661 -355,-351,-347,-343,-339,-336,-332,-328,-325,-321,-318,-314,-311,-308,-304,-301,
4662 -298,-295,-291,-288,-285,-282,-279,-276,-273,-271,-268,-265,-262,-259,-257,-254,
4663 -251,-248,-246,-243,-241,-238,-236,-233,-231,-228,-226,-223,-221,-219,-216,-214,
4664 -212,-209,-207,-205,-203,-200,-198,-196,-194,-192,-190,-188,-186,-184,-182,-180,
4665 -178,-176,-174,-172,-170,-168,-166,-164,-162,-160,-158,-156,-155,-153,-151,-149,
4666 -147,-146,-144,-142,-140,-139,-137,-135,-134,-132,-130,-128,-127,-125,-124,-122,
4667 -120,-119,-117,-116,-114,-112,-111,-109,-108,-106,-105,-103,-102,-100,-99,-97,
4668 -96,-95,-93,-92,-90,-89,-87,-86,-85,-83,-82,-80,-79,-78,-76,-75,
4669 -74,-72,-71,-70,-68,-67,-66,-65,-63,-62,-61,-59,-58,-57,-56,-54,
4670 -53,-52,-51,-50,-48,-47,-46,-45,-44,-42,-41,-40,-39,-38,-37,-35,
4671 -34,-33,-32,-31,-30,-29,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,
4672 -17,-16,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1
4673 };
4674
4675
4676 /* 
4677  * Build the gamma table so that floating point isn't needed.
4678  * 
4679  * Note gamma goes from 0->256.  The old value of 100 is now 128.
4680  */
4681 void build_gamma_table(int gamma)
4682 {
4683         int i, n;
4684         
4685         /*
4686          * value is the current sum.
4687          * diff is the new term to add to the series.
4688          */
4689         long value, diff;
4690         
4691         /* Hack - convergence is bad in these cases. */
4692         gamma_table[0] = 0;
4693         gamma_table[255] = 255;
4694         
4695         for (i = 1; i < 255; i++)
4696         {
4697                 /* 
4698                  * Initialise the Taylor series
4699                  *
4700                  * value and diff have been scaled by 256
4701                  */
4702                 
4703                 n = 1;
4704                 value = 256 * 256;
4705                 diff = ((long)gamma_helper[i]) * (gamma - 256);
4706                 
4707                 while (diff)
4708                 {
4709                         value += diff;
4710                         n++;
4711                         
4712                         
4713                         /*
4714                          * Use the following identiy to calculate the gamma table.
4715                          * exp(x) = 1 + x + x^2/2 + x^3/(2*3) + x^4/(2*3*4) +...
4716                          *
4717                          * n is the current term number.
4718                          * 
4719                          * The gamma_helper array contains a table of
4720                          * ln(x/256) * 256
4721                          * This is used because a^b = exp(b*ln(a))
4722                          *
4723                          * In this case:
4724                          * a is i / 256
4725                          * b is gamma.
4726                          *
4727                          * Note that everything is scaled by 256 for accuracy,
4728                          * plus another factor of 256 for the final result to
4729                          * be from 0-255.  Thus gamma_helper[] * gamma must be
4730                          * divided by 256*256 each itteration, to get back to
4731                          * the original power series.
4732                          */
4733                         diff = (((diff / 256) * gamma_helper[i]) * (gamma - 256)) / (256 * n);
4734                 }
4735                 
4736                 /* 
4737                  * Store the value in the table so that the
4738                  * floating point pow function isn't needed .
4739                  */
4740                 gamma_table[i] = ((long)(value / 256) * i) / 256;
4741         }
4742 }
4743
4744 #endif /* SUPPORT_GAMMA */
4745
4746 void roff_to_buf(cptr str, int maxlen, char *tbuf)
4747 {
4748         int read_pt = 0;
4749         int write_pt = 0;
4750         int line_len = 0;
4751         int word_punct = 0;
4752         unsigned char ch[3];
4753         ch[2] = '\0';
4754
4755         while (str[read_pt])
4756         {
4757 #ifdef JP
4758                 bool kanji;
4759 #endif
4760                 ch[0] = str[read_pt];
4761                 ch[1] = '\0';
4762 #ifdef JP
4763                 kanji  = iskanji(ch[0]);
4764                 if (kanji)
4765                         ch[1] = str[read_pt+1];
4766                 if (!kanji && !isprint(ch[0]))
4767                         ch[0] = ' ';
4768 #else
4769                 if (!isprint(ch[0]))
4770                         ch[0] = ' ';
4771 #endif
4772
4773                 if (line_len >= maxlen - 1 || str[read_pt] == '\n')
4774                 {
4775                         int word_len;
4776
4777                         /* return to better wrapping point. */
4778                         /* Space character at the end of the line need not to be printed. */
4779                         word_len = read_pt - word_punct;
4780                         if (ch[0] != ' ' && word_len < line_len/2)
4781                         {
4782                                 read_pt = word_punct;
4783                                 if (str[word_punct] == ' ')
4784                                         read_pt++;
4785                                 write_pt -= word_len;
4786                         }
4787                         else
4788                                 read_pt++;
4789                         tbuf[write_pt++] = '\0';
4790                         line_len = 0;
4791                         word_punct = read_pt;
4792                         continue;
4793                 }
4794                 if (ch[0] == ' ')
4795                         word_punct = read_pt;
4796 #ifdef JP
4797                 if (kanji &&
4798                     strcmp((char *)ch, "¡£") != 0 && strcmp((char *)ch, "¡¢") != 0 &&
4799                     strcmp((char *)ch, "¥£") != 0 && strcmp((char *)ch, "¡¼") != 0)
4800                         word_punct = read_pt;
4801 #endif
4802                 tbuf[write_pt++] = ch[0];
4803                 line_len++;
4804                 read_pt++;
4805 #ifdef JP
4806                 if (kanji)
4807                 {
4808                         tbuf[write_pt++] = ch[1];
4809                         line_len++;
4810                         read_pt++;
4811                 }
4812 #endif
4813         }
4814         tbuf[write_pt] = '\0';
4815         tbuf[write_pt+1] = '\0';
4816
4817         return;
4818 }
4819