OSDN Git Service

get_check()の中の、漢字を含むメッセージに対して先頭の 70"byte"をコピーという危険な処理
[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         /* Hack -- Use the "inkey_next" pointer */
1922         if (inkey_next && *inkey_next && !inkey_xtra)
1923         {
1924                 /* Get next character, and advance */
1925                 ch = *inkey_next++;
1926
1927                 /* Cancel the various "global parameters" */
1928                 inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
1929
1930                 /* Accept result */
1931                 return (ch);
1932         }
1933
1934         /* Forget pointer */
1935         inkey_next = NULL;
1936
1937
1938 #ifdef ALLOW_BORG
1939
1940         /* Mega-Hack -- Use the special hook */
1941         if (inkey_hack && ((ch = (*inkey_hack)(inkey_xtra)) != 0))
1942         {
1943                 /* Cancel the various "global parameters" */
1944                 inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
1945
1946                 /* Accept result */
1947                 return (ch);
1948         }
1949
1950 #endif /* ALLOW_BORG */
1951
1952
1953         /* Hack -- handle delayed "flush()" */
1954         if (inkey_xtra)
1955         {
1956                 /* End "macro action" */
1957                 parse_macro = FALSE;
1958
1959                 /* End "macro trigger" */
1960                 parse_under = FALSE;
1961
1962                 /* Forget old keypresses */
1963                 Term_flush();
1964         }
1965
1966
1967         /* Access cursor state */
1968         (void)Term_get_cursor(&v);
1969
1970         /* Show the cursor if waiting, except sometimes in "command" mode */
1971         if (!inkey_scan && (!inkey_flag || hilite_player || character_icky))
1972         {
1973                 /* Show the cursor */
1974                 (void)Term_set_cursor(1);
1975         }
1976
1977
1978         /* Hack -- Activate main screen */
1979         Term_activate(angband_term[0]);
1980
1981
1982         /* Get a key */
1983         while (!ch)
1984         {
1985                 /* Hack -- Handle "inkey_scan" */
1986                 if (!inkey_base && inkey_scan &&
1987                         (0 != Term_inkey(&kk, FALSE, FALSE)))
1988                 {
1989                         break;
1990                 }
1991
1992
1993                 /* Hack -- Flush output once when no key ready */
1994                 if (!done && (0 != Term_inkey(&kk, FALSE, FALSE)))
1995                 {
1996                         /* Hack -- activate proper term */
1997                         Term_activate(old);
1998
1999                         /* Flush output */
2000                         Term_fresh();
2001
2002                         /* Hack -- activate main screen */
2003                         Term_activate(angband_term[0]);
2004
2005                         /* Mega-Hack -- reset saved flag */
2006                         character_saved = FALSE;
2007
2008                         /* Mega-Hack -- reset signal counter */
2009                         signal_count = 0;
2010
2011                         /* Only once */
2012                         done = TRUE;
2013                 }
2014
2015
2016                 /* Hack -- Handle "inkey_base" */
2017                 if (inkey_base)
2018                 {
2019                         int w = 0;
2020
2021                         /* Wait forever */
2022                         if (!inkey_scan)
2023                         {
2024                                 /* Wait for (and remove) a pending key */
2025                                 if (0 == Term_inkey(&ch, TRUE, TRUE))
2026                                 {
2027                                         /* Done */
2028                                         break;
2029                                 }
2030
2031                                 /* Oops */
2032                                 break;
2033                         }
2034
2035                         /* Wait */
2036                         while (TRUE)
2037                         {
2038                                 /* Check for (and remove) a pending key */
2039                                 if (0 == Term_inkey(&ch, FALSE, TRUE))
2040                                 {
2041                                         /* Done */
2042                                         break;
2043                                 }
2044
2045                                 /* No key ready */
2046                                 else
2047                                 {
2048                                         /* Increase "wait" */
2049                                         w += 10;
2050
2051                                         /* Excessive delay */
2052                                         if (w >= 100) break;
2053
2054                                         /* Delay */
2055                                         Term_xtra(TERM_XTRA_DELAY, w);
2056                                 }
2057                         }
2058
2059                         /* Done */
2060                         break;
2061                 }
2062
2063
2064                 /* Get a key (see above) */
2065                 ch = inkey_aux();
2066
2067
2068                 /* Handle "control-right-bracket" */
2069                 if (ch == 29)
2070                 {
2071                         /* Strip this key */
2072                         ch = 0;
2073
2074                         /* Continue */
2075                         continue;
2076                 }
2077
2078
2079                 /* Treat back-quote as escape */
2080 /*              if (ch == '`') ch = ESCAPE; */
2081
2082
2083                 /* End "macro trigger" */
2084                 if (parse_under && (ch <= 32))
2085                 {
2086                         /* Strip this key */
2087                         ch = 0;
2088
2089                         /* End "macro trigger" */
2090                         parse_under = FALSE;
2091                 }
2092
2093
2094                 /* Handle "control-caret" */
2095                 if (ch == 30)
2096                 {
2097                         /* Strip this key */
2098                         ch = 0;
2099                 }
2100
2101                 /* Handle "control-underscore" */
2102                 else if (ch == 31)
2103                 {
2104                         /* Strip this key */
2105                         ch = 0;
2106
2107                         /* Begin "macro trigger" */
2108                         parse_under = TRUE;
2109                 }
2110
2111                 /* Inside "macro trigger" */
2112                 else if (parse_under)
2113                 {
2114                         /* Strip this key */
2115                         ch = 0;
2116                 }
2117         }
2118
2119
2120         /* Hack -- restore the term */
2121         Term_activate(old);
2122
2123
2124         /* Restore the cursor */
2125         Term_set_cursor(v);
2126
2127
2128         /* Cancel the various "global parameters" */
2129         inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
2130
2131         /* Return the keypress */
2132         return (ch);
2133 }
2134
2135
2136
2137
2138 /*
2139  * We use a global array for all inscriptions to reduce the memory
2140  * spent maintaining inscriptions.  Of course, it is still possible
2141  * to run out of inscription memory, especially if too many different
2142  * inscriptions are used, but hopefully this will be rare.
2143  *
2144  * We use dynamic string allocation because otherwise it is necessary
2145  * to pre-guess the amount of quark activity.  We limit the total
2146  * number of quarks, but this is much easier to "expand" as needed.
2147  *
2148  * Any two items with the same inscription will have the same "quark"
2149  * index, which should greatly reduce the need for inscription space.
2150  *
2151  * Note that "quark zero" is NULL and should not be "dereferenced".
2152  */
2153
2154 /*
2155  * Add a new "quark" to the set of quarks.
2156  */
2157 s16b quark_add(cptr str)
2158 {
2159         int i;
2160
2161         /* Look for an existing quark */
2162         for (i = 1; i < quark__num; i++)
2163         {
2164                 /* Check for equality */
2165                 if (streq(quark__str[i], str)) return (i);
2166         }
2167
2168         /* Paranoia -- Require room */
2169         if (quark__num == QUARK_MAX) return (0);
2170
2171         /* New maximal quark */
2172         quark__num = i + 1;
2173
2174         /* Add a new quark */
2175         quark__str[i] = string_make(str);
2176
2177         /* Return the index */
2178         return (i);
2179 }
2180
2181
2182 /*
2183  * This function looks up a quark
2184  */
2185 cptr quark_str(s16b i)
2186 {
2187         cptr q;
2188
2189         /* Verify */
2190         if ((i < 0) || (i >= quark__num)) i = 0;
2191
2192         /* Access the quark */
2193         q = quark__str[i];
2194
2195         /* Return the quark */
2196         return (q);
2197 }
2198
2199
2200
2201
2202 /*
2203  * Second try for the "message" handling routines.
2204  *
2205  * Each call to "message_add(s)" will add a new "most recent" message
2206  * to the "message recall list", using the contents of the string "s".
2207  *
2208  * The messages will be stored in such a way as to maximize "efficiency",
2209  * that is, we attempt to maximize the number of sequential messages that
2210  * can be retrieved, given a limited amount of storage space.
2211  *
2212  * We keep a buffer of chars to hold the "text" of the messages, not
2213  * necessarily in "order", and an array of offsets into that buffer,
2214  * representing the actual messages.  This is made more complicated
2215  * by the fact that both the array of indexes, and the buffer itself,
2216  * are both treated as "circular arrays" for efficiency purposes, but
2217  * the strings may not be "broken" across the ends of the array.
2218  *
2219  * The "message_add()" function is rather "complex", because it must be
2220  * extremely efficient, both in space and time, for use with the Borg.
2221  */
2222
2223
2224
2225 /*
2226  * How many messages are "available"?
2227  */
2228 s16b message_num(void)
2229 {
2230         int last, next, n;
2231
2232         /* Extract the indexes */
2233         last = message__last;
2234         next = message__next;
2235
2236         /* Handle "wrap" */
2237         if (next < last) next += MESSAGE_MAX;
2238
2239         /* Extract the space */
2240         n = (next - last);
2241
2242         /* Return the result */
2243         return (n);
2244 }
2245
2246
2247
2248 /*
2249  * Recall the "text" of a saved message
2250  */
2251 cptr message_str(int age)
2252 {
2253         s16b x;
2254         s16b o;
2255         cptr s;
2256
2257         /* Forgotten messages have no text */
2258         if ((age < 0) || (age >= message_num())) return ("");
2259
2260         /* Acquire the "logical" index */
2261         x = (message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX;
2262
2263         /* Get the "offset" for the message */
2264         o = message__ptr[x];
2265
2266         /* Access the message text */
2267         s = &message__buf[o];
2268
2269         /* Return the message text */
2270         return (s);
2271 }
2272
2273
2274
2275 /*
2276  * Add a new message, with great efficiency
2277  */
2278 void message_add(cptr str)
2279 {
2280         int i, k, x, m, n;
2281
2282         char u[1024];
2283         char splitted1[81];
2284         cptr splitted2;
2285
2286         /*** Step 1 -- Analyze the message ***/
2287
2288         /* Hack -- Ignore "non-messages" */
2289         if (!str) return;
2290
2291         /* Message length */
2292         n = strlen(str);
2293
2294         /* Important Hack -- Ignore "long" messages */
2295         if (n >= MESSAGE_BUF / 4) return;
2296
2297         /* extra step -- split the message if n>80.   (added by Mogami) */
2298         if (n > 80) {
2299 #ifdef JP
2300           cptr t = str;
2301
2302           for (n = 0; n < 80; n++, t++)
2303             if(iskanji(*t)) {
2304               t++;
2305               n++;
2306             }
2307           if (n == 81) n = 79; /* ºÇ¸å¤Îʸ»ú¤¬´Á»úȾʬ */
2308 #else
2309           for (n = 80; n > 60; n--)
2310                   if (str[n] == ' ') break;
2311           if (n == 60)
2312                   n = 80;
2313 #endif
2314           splitted2 = str + n;
2315           strncpy(splitted1, str ,n);
2316           splitted1[n] = '\0';
2317           str = splitted1;
2318         } else {
2319           splitted2 = NULL;
2320         }
2321
2322         /*** Step 2 -- Attempt to optimize ***/
2323
2324         /* Limit number of messages to check */
2325         m = message_num();
2326
2327         k = m / 4;
2328
2329         /* Limit number of messages to check */
2330         if (k > MESSAGE_MAX / 32) k = MESSAGE_MAX / 32;
2331
2332         /* Check previous message */
2333         for (i = message__next; m; m--)
2334         {
2335                 int j = 1;
2336
2337                 char buf[1024];
2338                 char *t;
2339
2340                 cptr old;
2341
2342                 /* Back up and wrap if needed */
2343                 if (i-- == 0) i = MESSAGE_MAX - 1;
2344
2345                 /* Access the old string */
2346                 old = &message__buf[message__ptr[i]];
2347
2348                 /* Skip small messages */
2349                 if (!old) continue;
2350
2351                 strcpy(buf, old);
2352
2353                 /* Find multiple */
2354 #ifdef JP
2355  for (t = buf; *t && (*t != '<' || (*(t+1) != 'x' )); t++) 
2356      if( iskanji(*t))t++;
2357 #else
2358                 for (t = buf; *t && (*t != '<'); t++);
2359 #endif
2360
2361                 if (*t)
2362                 {
2363                         /* Message is too small */
2364                         if (strlen(buf) < 6) break;
2365
2366                         /* Drop the space */
2367                         *(t - 1) = '\0';
2368
2369                         /* Get multiplier */
2370                         j = atoi(t+2);
2371                 }
2372
2373                 /* Limit the multiplier to 1000 */
2374                 if (buf && streq(buf, str) && (j < 1000))
2375                 {
2376                         j++;
2377
2378                         /* Overwrite */
2379                         message__next = i;
2380
2381                         str = u;
2382
2383                         /* Write it out */
2384                         sprintf(u, "%s <x%d>", buf, j);
2385
2386                         /* Message length */
2387                         n = strlen(str);
2388
2389                         if (!now_message) now_message++;
2390                 }
2391                 else
2392                 {
2393                         num_more++;/*ή¤ì¤¿¹Ô¤Î¿ô¤ò¿ô¤¨¤Æ¤ª¤¯ */
2394                         now_message++;
2395                 }
2396
2397                 /* Done */
2398                 break;
2399         }
2400
2401         /* Check the last few messages (if any to count) */
2402         for (i = message__next; k; k--)
2403         {
2404                 u16b q;
2405
2406                 cptr old;
2407
2408                 /* Back up and wrap if needed */
2409                 if (i-- == 0) i = MESSAGE_MAX - 1;
2410
2411                 /* Stop before oldest message */
2412                 if (i == message__last) break;
2413
2414                 /* Extract "distance" from "head" */
2415                 q = (message__head + MESSAGE_BUF - message__ptr[i]) % MESSAGE_BUF;
2416
2417                 /* Do not optimize over large distance */
2418                 if (q > MESSAGE_BUF / 2) continue;
2419
2420                 /* Access the old string */
2421                 old = &message__buf[message__ptr[i]];
2422
2423                 /* Compare */
2424                 if (!streq(old, str)) continue;
2425
2426                 /* Get the next message index, advance */
2427                 x = message__next++;
2428
2429                 /* Handle wrap */
2430                 if (message__next == MESSAGE_MAX) message__next = 0;
2431
2432                 /* Kill last message if needed */
2433                 if (message__next == message__last) message__last++;
2434
2435                 /* Handle wrap */
2436                 if (message__last == MESSAGE_MAX) message__last = 0;
2437
2438                 /* Assign the starting address */
2439                 message__ptr[x] = message__ptr[i];
2440
2441                 /* Success */
2442                 /* return; */
2443                 goto end_of_message_add;
2444
2445         }
2446
2447
2448         /*** Step 3 -- Ensure space before end of buffer ***/
2449
2450         /* Kill messages and Wrap if needed */
2451         if (message__head + n + 1 >= MESSAGE_BUF)
2452         {
2453                 /* Kill all "dead" messages */
2454                 for (i = message__last; TRUE; i++)
2455                 {
2456                         /* Wrap if needed */
2457                         if (i == MESSAGE_MAX) i = 0;
2458
2459                         /* Stop before the new message */
2460                         if (i == message__next) break;
2461
2462                         /* Kill "dead" messages */
2463                         if (message__ptr[i] >= message__head)
2464                         {
2465                                 /* Track oldest message */
2466                                 message__last = i + 1;
2467                         }
2468                 }
2469
2470                 /* Wrap "tail" if needed */
2471                 if (message__tail >= message__head) message__tail = 0;
2472
2473                 /* Start over */
2474                 message__head = 0;
2475         }
2476
2477
2478         /*** Step 4 -- Ensure space before next message ***/
2479
2480         /* Kill messages if needed */
2481         if (message__head + n + 1 > message__tail)
2482         {
2483                 /* Grab new "tail" */
2484                 message__tail = message__head + n + 1;
2485
2486                 /* Advance tail while possible past first "nul" */
2487                 while (message__buf[message__tail-1]) message__tail++;
2488
2489                 /* Kill all "dead" messages */
2490                 for (i = message__last; TRUE; i++)
2491                 {
2492                         /* Wrap if needed */
2493                         if (i == MESSAGE_MAX) i = 0;
2494
2495                         /* Stop before the new message */
2496                         if (i == message__next) break;
2497
2498                         /* Kill "dead" messages */
2499                         if ((message__ptr[i] >= message__head) &&
2500                                 (message__ptr[i] < message__tail))
2501                         {
2502                                 /* Track oldest message */
2503                                 message__last = i + 1;
2504                         }
2505                 }
2506         }
2507
2508
2509         /*** Step 5 -- Grab a new message index ***/
2510
2511         /* Get the next message index, advance */
2512         x = message__next++;
2513
2514         /* Handle wrap */
2515         if (message__next == MESSAGE_MAX) message__next = 0;
2516
2517         /* Kill last message if needed */
2518         if (message__next == message__last) message__last++;
2519
2520         /* Handle wrap */
2521         if (message__last == MESSAGE_MAX) message__last = 0;
2522
2523
2524
2525         /*** Step 6 -- Insert the message text ***/
2526
2527         /* Assign the starting address */
2528         message__ptr[x] = message__head;
2529
2530         /* Append the new part of the message */
2531         for (i = 0; i < n; i++)
2532         {
2533                 /* Copy the message */
2534                 message__buf[message__head + i] = str[i];
2535         }
2536
2537         /* Terminate */
2538         message__buf[message__head + i] = '\0';
2539
2540         /* Advance the "head" pointer */
2541         message__head += n + 1;
2542
2543         /* recursively add splitted message (added by Mogami) */
2544  end_of_message_add:
2545         if (splitted2 != NULL)
2546           message_add(splitted2);
2547 }
2548
2549
2550
2551 /*
2552  * Hack -- flush
2553  */
2554 static void msg_flush(int x)
2555 {
2556         byte a = TERM_L_BLUE;
2557         bool nagasu = FALSE;
2558
2559         if ((auto_more && !now_damaged) || num_more < 0){
2560                 int i;
2561                 for (i = 0; i < 8; i++)
2562                 {
2563                         if (angband_term[i] && (window_flag[i] & PW_MESSAGE)) break;
2564                 }
2565                 if (i < 8)
2566                 {
2567                         if (num_more < angband_term[i]->hgt) nagasu = TRUE;
2568                 }
2569                 else
2570                 {
2571                         nagasu = TRUE;
2572                 }
2573         }
2574         now_damaged = FALSE;
2575
2576         if (!alive || !nagasu)
2577         {
2578                 /* Pause for response */
2579 #ifdef JP
2580                 Term_putstr(x, 0, -1, a, "-³¤¯-");
2581 #else
2582                 Term_putstr(x, 0, -1, a, "-more-");
2583 #endif
2584
2585
2586                 /* Get an acceptable keypress */
2587                 while (1)
2588                 {
2589                         int cmd = inkey();
2590                         if (cmd == ESCAPE) {
2591                             num_more = -9999; /*auto_more¤Î¤È¤­¡¢Á´¤Æή¤¹¡£ */
2592                             break;
2593                         } else if (cmd == ' ') {
2594                             num_more = 0; /*£±²èÌ̤À¤±Î®¤¹¡£ */
2595                             break;
2596                         } else if ((cmd == '\n') || (cmd == '\r')) {
2597                             num_more--; /*£±¹Ô¤À¤±Î®¤¹¡£ */
2598                             break;
2599                         }
2600                         if (quick_messages) break;
2601                         bell();
2602                 }
2603         }
2604
2605         /* Clear the line */
2606         Term_erase(0, 0, 255);
2607 }
2608
2609
2610 /*
2611  * Output a message to the top line of the screen.
2612  *
2613  * Break long messages into multiple pieces (40-72 chars).
2614  *
2615  * Allow multiple short messages to "share" the top line.
2616  *
2617  * Prompt the user to make sure he has a chance to read them.
2618  *
2619  * These messages are memorized for later reference (see above).
2620  *
2621  * We could do "Term_fresh()" to provide "flicker" if needed.
2622  *
2623  * The global "msg_flag" variable can be cleared to tell us to
2624  * "erase" any "pending" messages still on the screen.
2625  *
2626  * XXX XXX XXX Note that we must be very careful about using the
2627  * "msg_print()" functions without explicitly calling the special
2628  * "msg_print(NULL)" function, since this may result in the loss
2629  * of information if the screen is cleared, or if anything is
2630  * displayed on the top line.
2631  *
2632  * XXX XXX XXX Note that "msg_print(NULL)" will clear the top line
2633  * even if no messages are pending.  This is probably a hack.
2634  */
2635 void msg_print(cptr msg)
2636 {
2637         static int p = 0;
2638
2639         int n;
2640
2641         char *t;
2642
2643         char buf[1024];
2644
2645         if (world_monster) return;
2646
2647         /* Hack -- Reset */
2648         if (!msg_flag) {
2649                 /* Clear the line */
2650                 Term_erase(0, 0, 255);
2651                 p = 0;
2652         }
2653
2654         /* Message Length */
2655         n = (msg ? strlen(msg) : 0);
2656
2657         /* Hack -- flush when requested or needed */
2658         if (p && (!msg || ((p + n) > 72)))
2659         {
2660                 /* Flush */
2661                 msg_flush(p);
2662
2663                 /* Forget it */
2664                 msg_flag = FALSE;
2665
2666                 /* Reset */
2667                 p = 0;
2668         }
2669
2670
2671         /* No message */
2672         if (!msg) return;
2673
2674         /* Paranoia */
2675         if (n > 1000) return;
2676
2677
2678         /* Memorize the message */
2679         if (character_generated) message_add(msg);
2680
2681
2682         /* Copy it */
2683         strcpy(buf, msg);
2684
2685         /* Analyze the buffer */
2686         t = buf;
2687
2688         /* Split message */
2689         while (n > 72)
2690         {
2691                 char oops;
2692                 int check, split = 72;
2693
2694 #ifdef JP
2695                 bool k_flag = FALSE;
2696                 int wordlen = 0;
2697
2698                 /* Find the "best" split point */
2699                 for (check = 0; check < 72; check++)
2700                 {
2701                         if (k_flag)
2702                         {
2703                                 k_flag = FALSE;
2704                                 continue;
2705                         }
2706
2707                         /* Found a valid split point */
2708                         if (iskanji(t[check]))
2709                         {
2710                                 k_flag = TRUE;
2711                                 split = check;
2712                         }
2713                         else if (t[check] == ' ')
2714                         {
2715                                 split = check;
2716                                 wordlen = 0;
2717                         }
2718                         else
2719                         {
2720                                 wordlen++;
2721                                 if (wordlen > 20)
2722                                         split = check;
2723                         }
2724                 }
2725 #else
2726                 /* Find the "best" split point */
2727                 for (check = 40; check < 72; check++)
2728                 {
2729                         /* Found a valid split point */
2730                         if (t[check] == ' ') split = check;
2731                 }
2732 #endif
2733
2734                 /* Save the split character */
2735                 oops = t[split];
2736
2737                 /* Split the message */
2738                 t[split] = '\0';
2739
2740                 /* Display part of the message */
2741                 Term_putstr(0, 0, split, TERM_WHITE, t);
2742
2743                 /* Flush it */
2744                 msg_flush(split + 1);
2745
2746                 /* Memorize the piece */
2747                 /* if (character_generated) message_add(t); */
2748
2749                 /* Restore the split character */
2750                 t[split] = oops;
2751
2752                 /* Insert a space */
2753                 t[--split] = ' ';
2754
2755                 /* Prepare to recurse on the rest of "buf" */
2756                 t += split; n -= split;
2757         }
2758
2759
2760         /* Display the tail of the message */
2761         Term_putstr(p, 0, n, TERM_WHITE, t);
2762
2763         /* Memorize the tail */
2764         /* if (character_generated) message_add(t); */
2765
2766         /* Window stuff */
2767         p_ptr->window |= (PW_MESSAGE);
2768         window_stuff();
2769
2770         /* Remember the message */
2771         msg_flag = TRUE;
2772
2773         /* Remember the position */
2774 #ifdef JP
2775         p += n;
2776 #else
2777         p += n + 1;
2778 #endif
2779
2780
2781         /* Optional refresh */
2782         if (fresh_message) Term_fresh();
2783 }
2784
2785
2786 /*
2787  * Hack -- prevent "accidents" in "screen_save()" or "screen_load()"
2788  */
2789 static int screen_depth = 0;
2790
2791
2792 /*
2793  * Save the screen, and increase the "icky" depth.
2794  *
2795  * This function must match exactly one call to "screen_load()".
2796  */
2797 void screen_save(void)
2798 {
2799         /* Hack -- Flush messages */
2800         msg_print(NULL);
2801
2802         /* Save the screen (if legal) */
2803         if (screen_depth++ == 0) Term_save();
2804
2805         /* Increase "icky" depth */
2806         character_icky++;
2807 }
2808
2809
2810 /*
2811  * Load the screen, and decrease the "icky" depth.
2812  *
2813  * This function must match exactly one call to "screen_save()".
2814  */
2815 void screen_load(void)
2816 {
2817         /* Hack -- Flush messages */
2818         msg_print(NULL);
2819
2820         /* Load the screen (if legal) */
2821         if (--screen_depth == 0) Term_load();
2822
2823         /* Decrease "icky" depth */
2824         character_icky--;
2825 }
2826
2827
2828 /*
2829  * Display a formatted message, using "vstrnfmt()" and "msg_print()".
2830  */
2831 void msg_format(cptr fmt, ...)
2832 {
2833         va_list vp;
2834
2835         char buf[1024];
2836
2837         /* Begin the Varargs Stuff */
2838         va_start(vp, fmt);
2839
2840         /* Format the args, save the length */
2841         (void)vstrnfmt(buf, 1024, fmt, vp);
2842
2843         /* End the Varargs Stuff */
2844         va_end(vp);
2845
2846         /* Display */
2847         msg_print(buf);
2848 }
2849
2850
2851
2852 /*
2853  * Display a string on the screen using an attribute.
2854  *
2855  * At the given location, using the given attribute, if allowed,
2856  * add the given string.  Do not clear the line.
2857  */
2858 void c_put_str(byte attr, cptr str, int row, int col)
2859 {
2860         /* Position cursor, Dump the attr/text */
2861         Term_putstr(col, row, -1, attr, str);
2862 }
2863
2864 /*
2865  * As above, but in "white"
2866  */
2867 void put_str(cptr str, int row, int col)
2868 {
2869         /* Spawn */
2870         Term_putstr(col, row, -1, TERM_WHITE, str);
2871 }
2872
2873
2874
2875 /*
2876  * Display a string on the screen using an attribute, and clear
2877  * to the end of the line.
2878  */
2879 void c_prt(byte attr, cptr str, int row, int col)
2880 {
2881         /* Clear line, position cursor */
2882         Term_erase(col, row, 255);
2883
2884         /* Dump the attr/text */
2885         Term_addstr(-1, attr, str);
2886 }
2887
2888 /*
2889  * As above, but in "white"
2890  */
2891 void prt(cptr str, int row, int col)
2892 {
2893         /* Spawn */
2894         c_prt(TERM_WHITE, str, row, col);
2895 }
2896
2897
2898
2899
2900 /*
2901  * Print some (colored) text to the screen at the current cursor position,
2902  * automatically "wrapping" existing text (at spaces) when necessary to
2903  * avoid placing any text into the last column, and clearing every line
2904  * before placing any text in that line.  Also, allow "newline" to force
2905  * a "wrap" to the next line.  Advance the cursor as needed so sequential
2906  * calls to this function will work correctly.
2907  *
2908  * Once this function has been called, the cursor should not be moved
2909  * until all the related "c_roff()" calls to the window are complete.
2910  *
2911  * This function will correctly handle any width up to the maximum legal
2912  * value of 256, though it works best for a standard 80 character width.
2913  */
2914 void c_roff(byte a, cptr str)
2915 {
2916         int x, y;
2917
2918         int w, h;
2919
2920         cptr s;
2921
2922         /* Obtain the size */
2923         (void)Term_get_size(&w, &h);
2924
2925         /* Obtain the cursor */
2926         (void)Term_locate(&x, &y);
2927
2928         /* Hack -- No more space */
2929         if( y == h - 1 && x > w - 3) return;
2930
2931         /* Process the string */
2932         for (s = str; *s; s++)
2933         {
2934                 char ch;
2935
2936 #ifdef JP
2937                 int k_flag = iskanji(*s);
2938 #endif
2939                 /* Force wrap */
2940                 if (*s == '\n')
2941                 {
2942                         /* Wrap */
2943                         x = 0;
2944                         y++;
2945
2946                         /* No more space */
2947                         if( y == h ) break;
2948
2949                         /* Clear line, move cursor */
2950                         Term_erase(x, y, 255);
2951                 }
2952
2953                 /* Clean up the char */
2954 #ifdef JP
2955                 ch = ((isprint(*s) || k_flag) ? *s : ' ');
2956 #else
2957                 ch = (isprint(*s) ? *s : ' ');
2958 #endif
2959
2960
2961                 /* Wrap words as needed */
2962 #ifdef JP
2963                 if (( x >= ( (k_flag) ? w - 2 : w - 1 ) ) && (ch != ' '))
2964 #else
2965                 if ((x >= w - 1) && (ch != ' '))
2966 #endif
2967
2968                 {
2969                         int i, n = 0;
2970
2971                         byte av[256];
2972                         char cv[256];
2973
2974                         /* Wrap word */
2975                         if (x < w)
2976 #ifdef JP
2977                         {
2978                         /* ¸½ºß¤¬È¾³Ñʸ»ú¤Î¾ì¹ç */
2979                         if( !k_flag )
2980 #endif
2981                         {
2982                                 /* Scan existing text */
2983                                 for (i = w - 2; i >= 0; i--)
2984                                 {
2985                                         /* Grab existing attr/char */
2986                                         Term_what(i, y, &av[i], &cv[i]);
2987
2988                                         /* Break on space */
2989                                         if (cv[i] == ' ') break;
2990
2991                                         /* Track current word */
2992                                         n = i;
2993 #ifdef JP
2994                                         if (cv[i] == '(') break;
2995 #endif
2996                                 }
2997                         }
2998
2999 #ifdef JP
3000                         else
3001                         {
3002                                 /* ¸½ºß¤¬Á´³Ñʸ»ú¤Î¤È¤­ */
3003                                 /* Ê¸Æ¬¤¬¡Ö¡£¡×¡Ö¡¢¡×Åù¤Ë¤Ê¤ë¤È¤­¤Ï¡¢¤½¤Î£±¤ÄÁ°¤Î¸ì¤Ç²þ¹Ô */
3004                                 if (strncmp(s, "¡£", 2) == 0 || strncmp(s, "¡¢", 2) == 0
3005 #if 0                   /* °ìÈÌŪ¤Ë¤Ï¡Ö¥£¡×¡Ö¡¼¡×¤Ï¶Ø§¤ÎÂоݳ° */
3006                                         || strncmp(s, "¥£", 2) == 0 || strncmp(s, "¡¼", 2) == 0
3007 #endif
3008                                ){
3009                                         Term_what(x  , y, &av[x  ], &cv[x  ]);
3010                                         Term_what(x-1, y, &av[x-1], &cv[x-1]);
3011                                         Term_what(x-2, y, &av[x-2], &cv[x-2]);
3012                                         n = x - 2;
3013                                         cv[ x ] = '\0';
3014                                 }
3015                         }
3016                         }
3017 #endif
3018                         /* Special case */
3019                         if (n == 0) n = w;
3020
3021                         /* Clear line */
3022                         Term_erase(n, y, 255);
3023
3024                         /* Wrap */
3025                         x = 0;
3026                         y++;
3027
3028                         /* No more space */
3029                         if( y == h ) break;
3030
3031                         /* Clear line, move cursor */
3032                         Term_erase(x, y, 255);
3033
3034                         /* Wrap the word (if any) */
3035                         for (i = n; i < w - 1; i++)
3036                         {
3037 #ifdef JP
3038                                 if( cv[i] == '\0' ) break;
3039 #endif
3040                                 /* Dump */
3041                                 Term_addch(av[i], cv[i]);
3042
3043                                 /* Advance (no wrap) */
3044                                 if (++x > w) x = w;
3045                         }
3046                 }
3047
3048                 /* Dump */
3049 #ifdef JP
3050                 Term_addch((byte)(a|0x10), ch);
3051 #else
3052                 Term_addch(a, ch);
3053 #endif
3054
3055
3056 #ifdef JP
3057                 if (k_flag)
3058                 {
3059                         s++;
3060                         x++;
3061                         ch = *s;
3062                         Term_addch((byte)(a|0x20), ch);
3063                 }
3064 #endif
3065                 /* Advance */
3066                 if (++x > w) x = w;
3067         }
3068 }
3069
3070 /*
3071  * As above, but in "white"
3072  */
3073 void roff(cptr str)
3074 {
3075         /* Spawn */
3076         c_roff(TERM_WHITE, str);
3077 }
3078
3079
3080
3081
3082 /*
3083  * Clear part of the screen
3084  */
3085 void clear_from(int row)
3086 {
3087         int y;
3088
3089         /* Erase requested rows */
3090         for (y = row; y < Term->hgt; y++)
3091         {
3092                 /* Erase part of the screen */
3093                 Term_erase(0, y, 255);
3094         }
3095 }
3096
3097
3098
3099
3100 /*
3101  * Get some input at the cursor location.
3102  * Assume the buffer is initialized to a default string.
3103  * Note that this string is often "empty" (see below).
3104  * The default buffer is displayed in yellow until cleared.
3105  * Pressing RETURN right away accepts the default entry.
3106  * Normal chars clear the default and append the char.
3107  * Backspace clears the default or deletes the final char.
3108  * ESCAPE clears the buffer and the window and returns FALSE.
3109  * RETURN accepts the current buffer contents and returns TRUE.
3110  */
3111 bool askfor_aux(char *buf, int len)
3112 {
3113         int y, x;
3114
3115         int i = 0;
3116
3117         int k = 0;
3118
3119         bool done = FALSE;
3120
3121
3122 #ifdef JP
3123     int k_flag[128];
3124 #endif
3125         /* Locate the cursor */
3126         Term_locate(&x, &y);
3127
3128
3129         /* Paranoia -- check len */
3130         if (len < 1) len = 1;
3131
3132         /* Paranoia -- check column */
3133         if ((x < 0) || (x >= 80)) x = 0;
3134
3135         /* Restrict the length */
3136         if (x + len > 80) len = 80 - x;
3137
3138
3139         /* Paranoia -- Clip the default entry */
3140         buf[len] = '\0';
3141
3142
3143         /* Display the default answer */
3144         Term_erase(x, y, len);
3145         Term_putstr(x, y, -1, TERM_YELLOW, buf);
3146
3147
3148         /* Process input */
3149         while (!done)
3150         {
3151                 /* Place cursor */
3152                 Term_gotoxy(x + k, y);
3153
3154                 /* Get a key */
3155                 i = inkey();
3156
3157                 /* Analyze the key */
3158                 switch (i)
3159                 {
3160                 case ESCAPE:
3161                         k = 0;
3162                         done = TRUE;
3163                         break;
3164
3165                 case '\n':
3166                 case '\r':
3167                         k = strlen(buf);
3168                         done = TRUE;
3169                         break;
3170
3171                 case 0x7F:
3172                 case '\010':
3173 #ifdef JP
3174                                 if (k > 0)
3175                                 {
3176                                         k--;
3177                                         if (k_flag[k] != 0)
3178                                                 k--;
3179                                 }
3180 #else
3181                         if (k > 0) k--;
3182 #endif
3183
3184                         break;
3185
3186                 default:
3187 #ifdef JP
3188        {                        /* ÊÒ»³¤µ¤óºîÀ® */
3189                 int next;
3190
3191                                 if (iskanji (i)) {
3192                                         inkey_base = TRUE;
3193                                         next = inkey ();
3194                                         if (k+1 < len) {
3195                                                 buf[k++] = i;
3196                                                 buf[k] = next;
3197                                                 k_flag[k++] = 1;
3198                                         } else
3199                                                 bell();
3200                                 } else {
3201 #ifdef SJIS
3202                     if(k<len && (isprint(i) || (0xa0<=i && i<=0xdf))){
3203 #else
3204                     if(k<len && isprint(i)){
3205 #endif
3206                                                 buf[k] = i;
3207                                                 k_flag[k++] = 0;
3208                                         } else
3209                                                 bell();
3210                                }
3211                  }
3212 #else
3213                         if ((k < len) && (isprint(i)))
3214                         {
3215                                 buf[k++] = i;
3216                         }
3217                         else
3218                         {
3219                                 bell();
3220                         }
3221 #endif
3222
3223                         break;
3224                 }
3225
3226                 /* Terminate */
3227                 buf[k] = '\0';
3228
3229                 /* Update the entry */
3230                 Term_erase(x, y, len);
3231                 Term_putstr(x, y, -1, TERM_WHITE, buf);
3232         }
3233
3234         /* Aborted */
3235         if (i == ESCAPE) return (FALSE);
3236
3237         /* Success */
3238         return (TRUE);
3239 }
3240
3241
3242 /*
3243  * Get a string from the user
3244  *
3245  * The "prompt" should take the form "Prompt: "
3246  *
3247  * Note that the initial contents of the string is used as
3248  * the default response, so be sure to "clear" it if needed.
3249  *
3250  * We clear the input, and return FALSE, on "ESCAPE".
3251  */
3252 bool get_string(cptr prompt, char *buf, int len)
3253 {
3254         bool res;
3255
3256         /* Paranoia XXX XXX XXX */
3257         msg_print(NULL);
3258
3259         /* Display prompt */
3260         prt(prompt, 0, 0);
3261
3262         /* Ask the user for a string */
3263         res = askfor_aux(buf, len);
3264
3265         /* Clear prompt */
3266         prt("", 0, 0);
3267
3268         /* Result */
3269         return (res);
3270 }
3271
3272
3273 /*
3274  * Verify something with the user
3275  *
3276  * The "prompt" should take the form "Query? "
3277  *
3278  * Note that "[y/n]" is appended to the prompt.
3279  */
3280 bool get_check(cptr prompt)
3281 {
3282         return get_check_strict(prompt, 0);
3283 }
3284
3285 /*
3286  * Verify something with the user strictly
3287  *
3288  * mode & 0x01 : force user to answer "YES" or "N"
3289  * mode & 0x02 : don't allow ESCAPE key
3290  */
3291 bool get_check_strict(cptr prompt, int mode)
3292 {
3293         int i;
3294         char buf[80];
3295
3296         if (auto_more)
3297         {
3298                 p_ptr->window |= PW_MESSAGE;
3299                 window_stuff();
3300                 num_more = 0;
3301         }
3302
3303         /* Paranoia XXX XXX XXX */
3304         msg_print(NULL);
3305
3306         if (!rogue_like_commands)
3307                 mode &= ~1;
3308
3309         /* Hack -- Build a "useful" prompt */
3310         if (mode & 1)
3311         {
3312 #ifdef JP
3313                 mb_strlcpy(buf, prompt, 78-8);
3314 #else
3315                 strncpy(buf, prompt, 78-8);
3316 #endif
3317                 strcat(buf, "[yes/no]");
3318         }
3319         else
3320         {
3321 #ifdef JP
3322                 mb_strlcpy(buf, prompt, 78-5);
3323 #else
3324                 strncpy(buf, prompt, 78-5);
3325 #endif
3326                 strcat(buf, "[y/n]");
3327         }
3328
3329         /* Prompt for it */
3330         prt(buf, 0, 0);
3331
3332         /* Get an acceptable answer */
3333         while (TRUE)
3334         {
3335                 i = inkey();
3336
3337                 if (i == 'y' || i == 'Y')
3338                 {
3339                         if (!(mode & 1))
3340                                 break;
3341                         else
3342                         {
3343 #ifdef JP
3344                                 prt("y (YES¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤)", 0, strlen(buf));
3345 #else
3346                                 prt("y (Please answer YES.)", 0, strlen(buf));
3347 #endif
3348                                 i = inkey();
3349                                 if (i == 'e' || i == 'E')
3350                                 {
3351 #ifdef JP
3352                                         prt("e (YES¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤)", 0, strlen(buf)+1);
3353 #else
3354                                         prt("e (Please answer YES.)", 0, strlen(buf)+1);
3355 #endif
3356                                         i = inkey();
3357                                         if (i == 's' || i == 'S')
3358                                         {
3359                                                 i = 'y';
3360                                                 break;
3361                                         }
3362                                         prt("", 0, strlen(buf)+1);
3363                                 }
3364                                 prt("", 0, strlen(buf));
3365                         }
3366                 }
3367                 if (!(mode & 2) && (i == ESCAPE)) break;
3368                 if (strchr("Nn", i)) break;
3369                 bell();
3370         }
3371
3372         /* Erase the prompt */
3373         prt("", 0, 0);
3374
3375         /* Normal negation */
3376         if ((i != 'Y') && (i != 'y')) return (FALSE);
3377
3378         /* Success */
3379         return (TRUE);
3380 }
3381
3382
3383 /*
3384  * Prompts for a keypress
3385  *
3386  * The "prompt" should take the form "Command: "
3387  *
3388  * Returns TRUE unless the character is "Escape"
3389  */
3390 bool get_com(cptr prompt, char *command, bool z_escape)
3391 {
3392         /* Paranoia XXX XXX XXX */
3393         msg_print(NULL);
3394
3395         /* Display a prompt */
3396         prt(prompt, 0, 0);
3397
3398         /* Get a key */
3399         *command = inkey();
3400
3401         /* Clear the prompt */
3402         prt("", 0, 0);
3403
3404         /* Handle "cancel" */
3405         if (*command == ESCAPE) return (FALSE);
3406         if (z_escape && ((*command == 'z') || (*command == 'Z'))) return (FALSE);
3407
3408         /* Success */
3409         return (TRUE);
3410 }
3411
3412
3413 /*
3414  * Request a "quantity" from the user
3415  *
3416  * Hack -- allow "command_arg" to specify a quantity
3417  */
3418 s16b get_quantity(cptr prompt, int max)
3419 {
3420         int amt;
3421
3422         char tmp[80];
3423
3424         char buf[80];
3425
3426
3427         /* Use "command_arg" */
3428         if (command_arg)
3429         {
3430                 /* Extract a number */
3431                 amt = command_arg;
3432
3433                 /* Clear "command_arg" */
3434                 command_arg = 0;
3435
3436                 /* Enforce the maximum */
3437                 if (amt > max) amt = max;
3438
3439                 /* Use it */
3440                 return (amt);
3441         }
3442
3443 #ifdef ALLOW_REPEAT /* TNB */
3444
3445         /* Get the item index */
3446         if ((max != 1) && repeat_pull(&amt))
3447         {
3448                 /* Enforce the maximum */
3449                 if (amt > max) amt = max;
3450
3451                 /* Enforce the minimum */
3452                 if (amt < 0) amt = 0;
3453
3454                 /* Use it */
3455                 return (amt);
3456         }
3457
3458 #endif /* ALLOW_REPEAT -- TNB */
3459
3460         /* Build a prompt if needed */
3461         if (!prompt)
3462         {
3463                 /* Build a prompt */
3464 #ifdef JP
3465                         sprintf(tmp, "¤¤¤¯¤Ä¤Ç¤¹¤« (1-%d): ", max);
3466 #else
3467                 sprintf(tmp, "Quantity (1-%d): ", max);
3468 #endif
3469
3470
3471                 /* Use that prompt */
3472                 prompt = tmp;
3473         }
3474
3475
3476         /* Default to one */
3477         amt = 1;
3478
3479         /* Build the default */
3480         sprintf(buf, "%d", amt);
3481
3482         /* Ask for a quantity */
3483         if (!get_string(prompt, buf, 6)) return (0);
3484
3485         /* Extract a number */
3486         amt = atoi(buf);
3487
3488         /* A letter means "all" */
3489         if (isalpha(buf[0])) amt = max;
3490
3491         /* Enforce the maximum */
3492         if (amt > max) amt = max;
3493
3494         /* Enforce the minimum */
3495         if (amt < 0) amt = 0;
3496
3497 #ifdef ALLOW_REPEAT /* TNB */
3498
3499         if (amt) repeat_push(amt);
3500
3501 #endif /* ALLOW_REPEAT -- TNB */
3502
3503         /* Return the result */
3504         return (amt);
3505 }
3506
3507
3508 /*
3509  * Pause for user response XXX XXX XXX
3510  */
3511 void pause_line(int row)
3512 {
3513         int i;
3514         prt("", row, 0);
3515 #ifdef JP
3516         put_str("[ ²¿¤«¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤ ]", row, 26);
3517 #else
3518         put_str("[Press any key to continue]", row, 23);
3519 #endif
3520
3521         i = inkey();
3522         prt("", row, 0);
3523 }
3524
3525
3526 /*
3527  * Hack -- special buffer to hold the action of the current keymap
3528  */
3529 static char request_command_buffer[256];
3530
3531
3532
3533 typedef struct
3534 {
3535         cptr name;
3536         byte cmd;
3537         bool fin;
3538 } menu_naiyou;
3539
3540 #ifdef JP
3541 menu_naiyou menu_info[10][10] =
3542 {
3543         {
3544                 {"ËâË¡/ÆüìǽÎÏ", 1, FALSE},
3545                 {"¹ÔÆ°", 2, FALSE},
3546                 {"Æ»¶ñ(»ÈÍÑ)", 3, FALSE},
3547                 {"Æ»¶ñ(¤½¤Î¾)", 4, FALSE},
3548                 {"ÁõÈ÷", 5, FALSE},
3549                 {"Èâ/È¢", 6, FALSE},
3550                 {"¾ðÊó", 7, FALSE},
3551                 {"ÀßÄê", 8, FALSE},
3552                 {"¤½¤Î¾", 9, FALSE},
3553                 {"", 0, FALSE},
3554         },
3555
3556         {
3557                 {"»È¤¦(m)", 'm', TRUE},
3558                 {"Ä´¤Ù¤ë(b/P)", 'b', TRUE},
3559                 {"³Ð¤¨¤ë(G)", 'G', TRUE},
3560                 {"ÆüìǽÎϤò»È¤¦(U/O)", 'U', TRUE},
3561                 {"", 0, FALSE},
3562                 {"", 0, FALSE},
3563                 {"", 0, FALSE},
3564                 {"", 0, FALSE},
3565                 {"", 0, FALSE},
3566                 {"", 0, FALSE}
3567         },
3568
3569         {
3570                 {"µÙ©¤¹¤ë(R)", 'R', TRUE},
3571                 {"¥È¥é¥Ã¥×²ò½ü(D)", 'D', TRUE},
3572                 {"õ¤¹(s)", 's', TRUE},
3573                 {"¼þ¤ê¤òÄ´¤Ù¤ë(l/x)", 'l', TRUE},
3574                 {"¥¿¡¼¥²¥Ã¥È»ØÄê(*)", '*', TRUE},
3575                 {"·ê¤ò·¡¤ë(T/^t)", 'T', TRUE},
3576                 {"³¬Ãʤò¾å¤ë(<)", '<', TRUE},
3577                 {"³¬Ãʤò²¼¤ê¤ë(>)", '>', TRUE},
3578                 {"¥Ú¥Ã¥È¤ËÌ¿Î᤹¤ë(p)", 'p', TRUE},
3579                 {"õº÷¥â¡¼¥É¤ÎON/OFF(S/#)", 'S', TRUE}
3580         },
3581
3582         {
3583                 {"Æɤà(r)", 'r', TRUE},
3584                 {"°û¤à(q)", 'q', TRUE},
3585                 {"¾ó¤ò»È¤¦(u/Z)", 'u', TRUE},
3586                 {"ËâË¡ËÀ¤ÇÁÀ¤¦(a/z)", 'a', TRUE},
3587                 {"¥í¥Ã¥É¤ò¿¶¤ë(z/a)", 'z', TRUE},
3588                 {"»ÏÆ°¤¹¤ë(A)", 'A', TRUE},
3589                 {"¿©¤Ù¤ë(E)", 'E', TRUE},
3590                 {"Èô¤ÓÆ»¶ñ¤Ç·â¤Ä(f/t)", 'f', TRUE},
3591                 {"Åꤲ¤ë(v)", 'v', TRUE},
3592                 {"", 0, FALSE}
3593         },
3594
3595         {
3596                 {"½¦¤¦(g)", 'g', TRUE},
3597                 {"Íî¤È¤¹(d)", 'd', TRUE},
3598                 {"²õ¤¹(k/^d)", 'k', TRUE},
3599                 {"Ìäò¹ï¤à({)", '{', TRUE},
3600                 {"Ìäò¾Ã¤¹(})", '}', TRUE},
3601                 {"Ä´ºº(I)", 'I', TRUE},
3602                 {"¥¢¥¤¥Æ¥à°ìÍ÷(i)", 'i', TRUE},
3603                 {"", 0, FALSE},
3604                 {"", 0, FALSE},
3605                 {"", 0, FALSE}
3606         },
3607
3608         {
3609                 {"ÁõÈ÷¤¹¤ë(w)", 'w', TRUE},
3610                 {"ÁõÈ÷¤ò³°¤¹(t/T)", 't', TRUE},
3611                 {"dzÎÁ¤òÊäµë(F)", 'F', TRUE},
3612                 {"ÁõÈ÷°ìÍ÷(e)", 'e', TRUE},
3613                 {"", 0, FALSE},
3614                 {"", 0, FALSE},
3615                 {"", 0, FALSE},
3616                 {"", 0, FALSE},
3617                 {"", 0, FALSE},
3618                 {"", 0, FALSE}
3619         },
3620
3621         {
3622                 {"³«¤±¤ë(o)", 'o', TRUE},
3623                 {"ÊĤ¸¤ë(c)", 'c', TRUE},
3624                 {"ÂÎÅö¤¿¤ê¤¹¤ë(B/f)", 'B', TRUE},
3625                 {"¤¯¤µ¤Ó¤òÂǤÄ(j/S)", 'j', TRUE},
3626                 {"", 0, FALSE},
3627                 {"", 0, FALSE},
3628                 {"", 0, FALSE},
3629                 {"", 0, FALSE},
3630                 {"", 0, FALSE},
3631                 {"", 0, FALSE}
3632         },
3633
3634         {
3635                 {"¥À¥ó¥¸¥ç¥ó¤ÎÁ´ÂοÞ(M)", 'M', TRUE},
3636                 {"°ÌÃÖ¤ò³Îǧ(L/W)", 'L', TRUE},
3637                 {"³¬¤ÎÊ·°Ïµ¤(^f)", KTRL('F'), TRUE},
3638                 {"¥¹¥Æ¡¼¥¿¥¹(C)", 'C', TRUE},
3639                 {"ʸ»ú¤ÎÀâÌÀ(/)", '/', TRUE},
3640                 {"¥á¥Ã¥»¡¼¥¸ÍúÎò(^p)", KTRL('P'), TRUE},
3641                 {"¸½ºß¤Î»þ¹ï(^t/')", KTRL('T'), TRUE},
3642                 {"¸½ºß¤ÎÃμ±(~)", '~', TRUE},
3643                 {"¥×¥ì¥¤µ­Ï¿(|)", '|', TRUE},
3644                 {"", 0, FALSE}
3645         },
3646
3647         {
3648                 {"¥ª¥×¥·¥ç¥ó(=)", '=', TRUE},
3649                 {"¥Þ¥¯¥í(@)", '@', TRUE},
3650                 {"²èÌÌɽ¼¨(%)", '%', TRUE},
3651                 {"¥«¥é¡¼(&)", '&', TRUE},
3652                 {"ÀßÄêÊѹ¹¥³¥Þ¥ó¥É(\")", '\"', TRUE},
3653                 {"¼«Æ°½¦¤¤¤ò¥í¡¼¥É($)", '$', TRUE},
3654                 {"¥·¥¹¥Æ¥à(!)", '!', TRUE},
3655                 {"", 0, FALSE},
3656                 {"", 0, FALSE},
3657                 {"", 0, FALSE}
3658         },
3659
3660         {
3661                 {"¥»¡¼¥Ö&ÃæÃÇ(^x)", KTRL('X'), TRUE},
3662                 {"¥»¡¼¥Ö(^s)", KTRL('S'), TRUE},
3663                 {"¥Ø¥ë¥×(?)", '?', TRUE},
3664                 {"ºÆÉÁ²è(^r)", KTRL('R'), TRUE},
3665                 {"¥á¥â(:)", ':', TRUE},
3666                 {"µ­Ç°»£±Æ())", ')', TRUE},
3667                 {"µ­Ç°»£±Æ¤Îɽ¼¨(()", '(', TRUE},
3668                 {"¥Ð¡¼¥¸¥ç¥ó¾ðÊó(V)", 'V', TRUE},
3669                 {"°úÂह¤ë(Q)", 'Q', TRUE},
3670                 {"", 0, FALSE}
3671         },
3672 };
3673 #else
3674 menu_naiyou menu_info[10][10] =
3675 {
3676         {
3677                 {"Magic/Special", 1, FALSE},
3678                 {"Action", 2, FALSE},
3679                 {"Items(use)", 3, FALSE},
3680                 {"Items(other)", 4, FALSE},
3681                 {"Equip", 5, FALSE},
3682                 {"Door/Box", 6, FALSE},
3683                 {"Infomations", 7, FALSE},
3684                 {"Options", 8, FALSE},
3685                 {"Other commands", 9, FALSE},
3686                 {"", 0, FALSE},
3687         },
3688
3689         {
3690                 {"Use(m)", 'm', TRUE},
3691                 {"See tips(b/P)", 'b', TRUE},
3692                 {"Study(G)", 'G', TRUE},
3693                 {"Special abilities(U/O)", 'U', TRUE},
3694                 {"", 0, FALSE},
3695                 {"", 0, FALSE},
3696                 {"", 0, FALSE},
3697                 {"", 0, FALSE},
3698                 {"", 0, FALSE},
3699                 {"", 0, FALSE}
3700         },
3701
3702         {
3703                 {"Rest(R)", 'R', TRUE},
3704                 {"Disarm a trap(D)", 'D', TRUE},
3705                 {"Search(s)", 's', TRUE},
3706                 {"Look(l/x)", 'l', TRUE},
3707                 {"Target(*)", '*', TRUE},
3708                 {"Dig(T/^t)", 'T', TRUE},
3709                 {"Go up stairs(<)", '<', TRUE},
3710                 {"Go down staies(>)", '>', TRUE},
3711                 {"Command pets(p)", 'p', TRUE},
3712                 {"Search mode ON/OFF(S/#)", 'S', TRUE}
3713         },
3714
3715         {
3716                 {"Read a scroll(r)", 'r', TRUE},
3717                 {"Drink a potion(q)", 'q', TRUE},
3718                 {"Use a staff(u/Z)", 'u', TRUE},
3719                 {"Aim a wand(a/z)", 'a', TRUE},
3720                 {"Zap a rod(z/a)", 'z', TRUE},
3721                 {"Activate an equipment(A)", 'A', TRUE},
3722                 {"Eat(E)", 'E', TRUE},
3723                 {"Fire missile weapon(f/t)", 'f', TRUE},
3724                 {"Throw an item(v)", 'v', TRUE},
3725                 {"", 0, FALSE}
3726         },
3727
3728         {
3729                 {"Get items(g)", 'g', TRUE},
3730                 {"Drop an item(d)", 'd', TRUE},
3731                 {"Destroy an item(k/^d)", 'k', TRUE},
3732                 {"Inscribe an item({)", '{', TRUE},
3733                 {"Uninscribe an item(})", '}', TRUE},
3734                 {"Info about an item(I)", 'I', TRUE},
3735                 {"Inventory list(i)", 'i', TRUE},
3736                 {"", 0, FALSE},
3737                 {"", 0, FALSE},
3738                 {"", 0, FALSE}
3739         },
3740
3741         {
3742                 {"Wear(w)", 'w', TRUE},
3743                 {"Take off(t/T)", 't', TRUE},
3744                 {"Refuel(F)", 'F', TRUE},
3745                 {"Equipment list(e)", 'e', TRUE},
3746                 {"", 0, FALSE},
3747                 {"", 0, FALSE},
3748                 {"", 0, FALSE},
3749                 {"", 0, FALSE},
3750                 {"", 0, FALSE},
3751                 {"", 0, FALSE}
3752         },
3753
3754         {
3755                 {"Open(o)", 'o', TRUE},
3756                 {"Close(c)", 'c', TRUE},
3757                 {"Bash a door(B/f)", 'B', TRUE},
3758                 {"Jam a door(j/S)", 'j', TRUE},
3759                 {"", 0, FALSE},
3760                 {"", 0, FALSE},
3761                 {"", 0, FALSE},
3762                 {"", 0, FALSE},
3763                 {"", 0, FALSE},
3764                 {"", 0, FALSE}
3765         },
3766
3767         {
3768                 {"Full map(M)", 'M', TRUE},
3769                 {"Map(L/W)", 'L', TRUE},
3770                 {"Level feeling(^f)", KTRL('F'), TRUE},
3771                 {"Character status(C)", 'C', TRUE},
3772                 {"Identify symbol(/)", '/', TRUE},
3773                 {"Show prev messages(^p)", KTRL('P'), TRUE},
3774                 {"Current time(^t/')", KTRL('T'), TRUE},
3775                 {"Various infomations(~)", '~', TRUE},
3776                 {"Play record menu(|)", '|', TRUE},
3777                 {"", 0, FALSE}
3778         },
3779
3780         {
3781                 {"Set options(=)", '=', TRUE},
3782                 {"Interact with macros(@)", '@', TRUE},
3783                 {"Interact w/ visuals(%)", '%', TRUE},
3784                 {"Interact with colors(&)", '&', TRUE},
3785                 {"Enter a user pref(\")", '\"', TRUE},
3786                 {"Reload auto-pick pref($)", '$', TRUE},
3787                 {"", 0, FALSE},
3788                 {"", 0, FALSE},
3789                 {"", 0, FALSE},
3790                 {"", 0, FALSE}
3791         },
3792
3793         {
3794                 {"Save and quit(^x)", KTRL('X'), TRUE},
3795                 {"Save(^s)", KTRL('S'), TRUE},
3796                 {"Help(obsoleted)(?)", '?', TRUE},
3797                 {"Redraw(^r)", KTRL('R'), TRUE},
3798                 {"Take note(:)", ':', TRUE},
3799                 {"Dump screen dump(()", ')', TRUE},
3800                 {"Load screen dump())", '(', TRUE},
3801                 {"Version info(V)", 'V', TRUE},
3802                 {"Quit(Q)", 'Q', TRUE},
3803                 {"", 0, FALSE}
3804         },
3805 };
3806 #endif
3807
3808 typedef struct
3809 {
3810         cptr name;
3811         byte window;
3812         byte number;
3813         byte jouken;
3814         byte jouken_naiyou;
3815 } special_menu_naiyou;
3816
3817 #define MENU_CLASS 1
3818 #define MENU_WILD 2
3819
3820 #ifdef JP
3821 special_menu_naiyou special_menu_info[] =
3822 {
3823         {"ĶǽÎÏ/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_MINDCRAFTER},
3824         {"¤â¤Î¤Þ¤Í/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_IMITATOR},
3825         {"ɬ»¦µ»/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_SAMURAI},
3826         {"Îýµ¤½Ñ/ËâË¡/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_FORCETRAINER},
3827         {"¶ÀËâË¡/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_MIRROR_MASTER},
3828         {"¹­°è¥Þ¥Ã¥×(<)", 2, 6, MENU_WILD, FALSE},
3829         {"Ä̾ï¥Þ¥Ã¥×(>)", 2, 7, MENU_WILD, TRUE},
3830         {"", 0, 0, 0, 0},
3831 };
3832 #else
3833 special_menu_naiyou special_menu_info[] =
3834 {
3835         {"MindCraft/Special", 0, 0, MENU_CLASS, CLASS_MINDCRAFTER},
3836         {"Imitation/Special", 0, 0, MENU_CLASS, CLASS_IMITATOR},
3837         {"Technique/Special", 0, 0, MENU_CLASS, CLASS_SAMURAI},
3838         {"Mind/Magic/Special", 0, 0, MENU_CLASS, CLASS_FORCETRAINER},
3839         {"MirrorMagic/Special", 0, 0, MENU_CLASS, CLASS_MIRROR_MASTER},
3840         {"Enter global map(<)", 2, 6, MENU_WILD, FALSE},
3841         {"Enter local map(>)", 2, 7, MENU_WILD, TRUE},
3842         {"", 0, 0, 0, 0},
3843 };
3844 #endif
3845
3846 /*
3847  * Request a command from the user.
3848  *
3849  * Sets p_ptr->command_cmd, p_ptr->command_dir, p_ptr->command_rep,
3850  * p_ptr->command_arg.  May modify p_ptr->command_new.
3851  *
3852  * Note that "caret" ("^") is treated specially, and is used to
3853  * allow manual input of control characters.  This can be used
3854  * on many machines to request repeated tunneling (Ctrl-H) and
3855  * on the Macintosh to request "Control-Caret".
3856  *
3857  * Note that "backslash" is treated specially, and is used to bypass any
3858  * keymap entry for the following character.  This is useful for macros.
3859  *
3860  * Note that this command is used both in the dungeon and in
3861  * stores, and must be careful to work in both situations.
3862  *
3863  * Note that "p_ptr->command_new" may not work any more.  XXX XXX XXX
3864  */
3865 void request_command(int shopping)
3866 {
3867         int i;
3868
3869         unsigned char cmd;
3870
3871         int mode;
3872
3873         cptr act;
3874
3875 #ifdef JP
3876         int caretcmd = 0;
3877 #endif
3878         /* Roguelike */
3879         if (rogue_like_commands)
3880         {
3881                 mode = KEYMAP_MODE_ROGUE;
3882         }
3883
3884         /* Original */
3885         else
3886         {
3887                 mode = KEYMAP_MODE_ORIG;
3888         }
3889
3890
3891         /* No command yet */
3892         command_cmd = 0;
3893
3894         /* No "argument" yet */
3895         command_arg = 0;
3896
3897         /* No "direction" yet */
3898         command_dir = 0;
3899
3900         use_menu = FALSE;
3901
3902
3903         /* Get command */
3904         while (1)
3905         {
3906                 /* Hack -- auto-commands */
3907                 if (command_new)
3908                 {
3909                         /* Flush messages */
3910                         msg_print(NULL);
3911
3912                         /* Use auto-command */
3913                         cmd = (unsigned char)command_new;
3914
3915                         /* Forget it */
3916                         command_new = 0;
3917                 }
3918
3919                 /* Get a keypress in "command" mode */
3920                 else
3921                 {
3922                         char sub_cmd;
3923
3924                         /* Hack -- no flush needed */
3925                         msg_flag = FALSE;
3926                         num_more = 0;
3927
3928                         /* Activate "command mode" */
3929                         inkey_flag = TRUE;
3930
3931                         /* Get a command */
3932                         sub_cmd = inkey();
3933
3934                         if (!shopping && command_menu && ((sub_cmd == '\r') || (sub_cmd == 'x') || (sub_cmd == 'X'))
3935                             && !keymap_act[mode][(byte)(sub_cmd)])
3936                         {
3937                                 int basey, basex;
3938                                 int num = 0, max_num, old_num = 0;
3939                                 int menu = 0;
3940                                 bool kisuu;
3941
3942                                 if (py - panel_row_min > 10) basey = 2;
3943                                 else basey = 13;
3944                                 basex = 15;
3945
3946                                 /* Clear top line */
3947                                 prt("", 0, 0);
3948
3949                                 screen_save();
3950
3951                                 while(1)
3952                                 {
3953                                         cptr menu_name;
3954                                         if (!menu) old_num = num;
3955                                         put_str("+----------------------------------------------------+", basey, basex);
3956                                         put_str("|                                                    |", basey+1, basex);
3957                                         put_str("|                                                    |", basey+2, basex);
3958                                         put_str("|                                                    |", basey+3, basex);
3959                                         put_str("|                                                    |", basey+4, basex);
3960                                         put_str("|                                                    |", basey+5, basex);
3961                                         put_str("+----------------------------------------------------+", basey+6, basex);
3962
3963                                         for(i = 0; i < 10; i++)
3964                                         {
3965                                                 int hoge;
3966                                                 if (!menu_info[menu][i].cmd) break;
3967                                                 menu_name = menu_info[menu][i].name;
3968                                                 for(hoge = 0; ; hoge++)
3969                                                 {
3970                                                         if (!special_menu_info[hoge].name[0]) break;
3971                                                         if ((menu != special_menu_info[hoge].window) || (i != special_menu_info[hoge].number)) continue;
3972                                                         switch(special_menu_info[hoge].jouken)
3973                                                         {
3974                                                                 case MENU_CLASS:
3975                                                                 if (p_ptr->pclass == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
3976                                                                 break;
3977                                                                 case MENU_WILD:
3978                                                                 if (!dun_level && !p_ptr->inside_arena && !p_ptr->inside_quest)
3979                                                                 {
3980                                                                         if ((byte)p_ptr->wild_mode == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
3981                                                                 }
3982                                                                 break;
3983                                                                 default:
3984                                                                 break;
3985                                                         }
3986                                                 }
3987                                                 put_str(menu_name, basey + 1 + i / 2, basex + 4 + (i % 2) * 24);
3988                                         }
3989                                         max_num = i;
3990                                         kisuu = max_num % 2;
3991 #ifdef JP
3992                                         put_str("¡Õ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
3993 #else
3994                                         put_str("> ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
3995 #endif
3996
3997                                         /* Place the cursor on the player */
3998                                         move_cursor_relative(py, px);
3999
4000                                         /* Get a command */
4001                                         sub_cmd = inkey();
4002                                         if ((sub_cmd == ' ') || (sub_cmd == 'x') || (sub_cmd == 'X') || (sub_cmd == '\r'))
4003                                         {
4004                                                 if (menu_info[menu][num].fin)
4005                                                 {
4006                                                         cmd = menu_info[menu][num].cmd;
4007                                                         use_menu = TRUE;
4008                                                         break;
4009                                                 }
4010                                                 else
4011                                                 {
4012                                                         menu = menu_info[menu][num].cmd;
4013                                                         num = 0;
4014                                                         basey += 2;
4015                                                         basex += 8;
4016                                                 }
4017                                         }
4018                                         else if ((sub_cmd == ESCAPE) || (sub_cmd == 'z') || (sub_cmd == 'Z') || (sub_cmd == '0'))
4019                                         {
4020                                                 if (!menu)
4021                                                 {
4022                                                         cmd = ESCAPE;
4023                                                         break;
4024                                                 }
4025                                                 else
4026                                                 {
4027                                                         menu = 0;
4028                                                         num = old_num;
4029                                                         basey -= 2;
4030                                                         basex -= 8;
4031                                                         screen_load();
4032                                                         screen_save();
4033                                                 }
4034                                         }
4035                                         else if ((sub_cmd == '2') || (sub_cmd == 'j') || (sub_cmd == 'J'))
4036                                         {
4037                                                 if (kisuu)
4038                                                 {
4039                                                         if (num % 2)
4040                                                                 num = (num + 2) % (max_num - 1);
4041                                                         else
4042                                                                 num = (num + 2) % (max_num + 1);
4043                                                 }
4044                                                 else num = (num + 2) % max_num;
4045                                         }
4046                                         else if ((sub_cmd == '8') || (sub_cmd == 'k') || (sub_cmd == 'K'))
4047                                         {
4048                                                 if (kisuu)
4049                                                 {
4050                                                         if (num % 2)
4051                                                                 num = (num + max_num - 3) % (max_num - 1);
4052                                                         else
4053                                                                 num = (num + max_num - 1) % (max_num + 1);
4054                                                 }
4055                                                 else num = (num + max_num - 2) % max_num;
4056                                         }
4057                                         else if ((sub_cmd == '4') || (sub_cmd == '6') || (sub_cmd == 'h') || (sub_cmd == 'H') || (sub_cmd == 'l') || (sub_cmd == 'L'))
4058                                         {
4059                                                 if ((num % 2) || (num == max_num - 1))
4060                                                 {
4061                                                         num--;
4062                                                 }
4063                                                 else if (num < max_num - 1)
4064                                                 {
4065                                                         num++;
4066                                                 }
4067                                         }
4068                                 }
4069
4070                                 screen_load();
4071                                 if (!inkey_next) inkey_next = "";
4072                         }
4073                         else cmd = sub_cmd;
4074                 }
4075
4076                 /* Clear top line */
4077                 prt("", 0, 0);
4078
4079
4080                 /* Command Count */
4081                 if (cmd == '0')
4082                 {
4083                         int old_arg = command_arg;
4084
4085                         /* Reset */
4086                         command_arg = 0;
4087
4088                         /* Begin the input */
4089 #ifdef JP
4090                         prt("²ó¿ô: ", 0, 0);
4091 #else
4092                         prt("Count: ", 0, 0);
4093 #endif
4094
4095
4096                         /* Get a command count */
4097                         while (1)
4098                         {
4099                                 /* Get a new keypress */
4100                                 cmd = inkey();
4101
4102                                 /* Simple editing (delete or backspace) */
4103                                 if ((cmd == 0x7F) || (cmd == KTRL('H')))
4104                                 {
4105                                         /* Delete a digit */
4106                                         command_arg = command_arg / 10;
4107
4108                                         /* Show current count */
4109 #ifdef JP
4110                                         prt(format("²ó¿ô: %d", command_arg), 0, 0);
4111 #else
4112                                         prt(format("Count: %d", command_arg), 0, 0);
4113 #endif
4114
4115                                 }
4116
4117                                 /* Actual numeric data */
4118                                 else if (cmd >= '0' && cmd <= '9')
4119                                 {
4120                                         /* Stop count at 9999 */
4121                                         if (command_arg >= 1000)
4122                                         {
4123                                                 /* Warn */
4124                                                 bell();
4125
4126                                                 /* Limit */
4127                                                 command_arg = 9999;
4128                                         }
4129
4130                                         /* Increase count */
4131                                         else
4132                                         {
4133                                                 /* Incorporate that digit */
4134                                                 command_arg = command_arg * 10 + D2I(cmd);
4135                                         }
4136
4137                                         /* Show current count */
4138 #ifdef JP
4139                                         prt(format("²ó¿ô: %d", command_arg), 0, 0);
4140 #else
4141                                         prt(format("Count: %d", command_arg), 0, 0);
4142 #endif
4143
4144                                 }
4145
4146                                 /* Exit on "unusable" input */
4147                                 else
4148                                 {
4149                                         break;
4150                                 }
4151                         }
4152
4153                         /* Hack -- Handle "zero" */
4154                         if (command_arg == 0)
4155                         {
4156                                 /* Default to 99 */
4157                                 command_arg = 99;
4158
4159                                 /* Show current count */
4160 #ifdef JP
4161                                 prt(format("²ó¿ô: %d", command_arg), 0, 0);
4162 #else
4163                                 prt(format("Count: %d", command_arg), 0, 0);
4164 #endif
4165
4166                         }
4167
4168                         /* Hack -- Handle "old_arg" */
4169                         if (old_arg != 0)
4170                         {
4171                                 /* Restore old_arg */
4172                                 command_arg = old_arg;
4173
4174                                 /* Show current count */
4175 #ifdef JP
4176 prt(format("²ó¿ô: %d", command_arg), 0, 0);
4177 #else
4178                                 prt(format("Count: %d", command_arg), 0, 0);
4179 #endif
4180
4181                         }
4182
4183                         /* Hack -- white-space means "enter command now" */
4184                         if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r'))
4185                         {
4186                                 /* Get a real command */
4187 #ifdef JP
4188                                 if (!get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE))
4189 #else
4190                                 if (!get_com("Command: ", (char *)&cmd, FALSE))
4191 #endif
4192
4193                                 {
4194                                         /* Clear count */
4195                                         command_arg = 0;
4196
4197                                         /* Continue */
4198                                         continue;
4199                                 }
4200                         }
4201                 }
4202
4203
4204                 /* Allow "keymaps" to be bypassed */
4205                 if (cmd == '\\')
4206                 {
4207                         /* Get a real command */
4208 #ifdef JP
4209                         (void)get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE);
4210 #else
4211                         (void)get_com("Command: ", (char *)&cmd, FALSE);
4212 #endif
4213
4214
4215                         /* Hack -- bypass keymaps */
4216                         if (!inkey_next) inkey_next = "";
4217                 }
4218
4219
4220                 /* Allow "control chars" to be entered */
4221                 if (cmd == '^')
4222                 {
4223                         /* Get a new command and controlify it */
4224 #ifdef JP
4225                         if (get_com("CTRL: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
4226 #else
4227                         if (get_com("Control: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
4228 #endif
4229
4230                 }
4231
4232
4233                 /* Look up applicable keymap */
4234                 act = keymap_act[mode][(byte)(cmd)];
4235
4236                 /* Apply keymap if not inside a keymap already */
4237                 if (act && !inkey_next)
4238                 {
4239                         /* Install the keymap (limited buffer size) */
4240                         (void)strnfmt(request_command_buffer, 256, "%s", act);
4241
4242                         /* Start using the buffer */
4243                         inkey_next = request_command_buffer;
4244
4245                         /* Continue */
4246                         continue;
4247                 }
4248
4249
4250                 /* Paranoia */
4251                 if (!cmd) continue;
4252
4253
4254                 /* Use command */
4255                 command_cmd = cmd;
4256
4257                 /* Done */
4258                 break;
4259         }
4260
4261         /* Hack -- Auto-repeat certain commands */
4262         if (always_repeat && (command_arg <= 0))
4263         {
4264                 /* Hack -- auto repeat certain commands */
4265                 if (strchr("TBDoc+", command_cmd))
4266                 {
4267                         /* Repeat 99 times */
4268                         command_arg = 99;
4269                 }
4270         }
4271
4272         /* Shopping */
4273         if (shopping == 1)
4274         {
4275                 /* Convert */
4276                 switch (command_cmd)
4277                 {
4278                         /* Command "p" -> "purchase" (get) */
4279                 case 'p': command_cmd = 'g'; break;
4280
4281                         /* Command "m" -> "purchase" (get) */
4282                 case 'm': command_cmd = 'g'; break;
4283
4284                         /* Command "s" -> "sell" (drop) */
4285                 case 's': command_cmd = 'd'; break;
4286                 }
4287         }
4288
4289 #ifdef JP
4290         for (i = 0; i < 256; i++)
4291         {
4292                 cptr s;
4293                 if ((s = keymap_act[mode][i]) != NULL)
4294                 {
4295                         if (*s == command_cmd && *(s+1) == 0)
4296                         {
4297                                 caretcmd = i;
4298                                 break;
4299                         }
4300                 }
4301         }
4302         if (!caretcmd)
4303                 caretcmd = command_cmd;
4304 #endif
4305         /* Hack -- Scan equipment */
4306         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4307         {
4308                 cptr s;
4309
4310                 object_type *o_ptr = &inventory[i];
4311
4312                 /* Skip non-objects */
4313                 if (!o_ptr->k_idx) continue;
4314
4315                 /* No inscription */
4316                 if (!o_ptr->inscription) continue;
4317
4318                 /* Obtain the inscription */
4319                 s = quark_str(o_ptr->inscription);
4320
4321                 /* Find a '^' */
4322                 s = strchr(s, '^');
4323
4324                 /* Process preventions */
4325                 while (s)
4326                 {
4327                         /* Check the "restriction" character */
4328 #ifdef JP
4329                         if ((s[1] == caretcmd) || (s[1] == '*'))
4330 #else
4331                         if ((s[1] == command_cmd) || (s[1] == '*'))
4332 #endif
4333
4334                         {
4335                                 /* Hack -- Verify command */
4336 #ifdef JP
4337                                 if (!get_check("ËÜÅö¤Ç¤¹¤«? "))
4338 #else
4339                                 if (!get_check("Are you sure? "))
4340 #endif
4341
4342                                 {
4343                                         /* Hack -- Use space */
4344                                         command_cmd = ' ';
4345                                 }
4346                         }
4347
4348                         /* Find another '^' */
4349                         s = strchr(s + 1, '^');
4350                 }
4351         }
4352
4353
4354         /* Hack -- erase the message line. */
4355         prt("", 0, 0);
4356 }
4357
4358
4359
4360 /*
4361  * Check a char for "vowel-hood"
4362  */
4363 bool is_a_vowel(int ch)
4364 {
4365         switch (ch)
4366         {
4367         case 'a':
4368         case 'e':
4369         case 'i':
4370         case 'o':
4371         case 'u':
4372         case 'A':
4373         case 'E':
4374         case 'I':
4375         case 'O':
4376         case 'U':
4377                 return (TRUE);
4378         }
4379
4380         return (FALSE);
4381 }
4382
4383
4384
4385 #if 0
4386
4387 /*
4388  * Replace the first instance of "target" in "buf" with "insert"
4389  * If "insert" is NULL, just remove the first instance of "target"
4390  * In either case, return TRUE if "target" is found.
4391  *
4392  * XXX Could be made more efficient, especially in the
4393  * case where "insert" is smaller than "target".
4394  */
4395 static bool insert_str(char *buf, cptr target, cptr insert)
4396 {
4397         int   i, len;
4398         int                b_len, t_len, i_len;
4399
4400         /* Attempt to find the target (modify "buf") */
4401         buf = strstr(buf, target);
4402
4403         /* No target found */
4404         if (!buf) return (FALSE);
4405
4406         /* Be sure we have an insertion string */
4407         if (!insert) insert = "";
4408
4409         /* Extract some lengths */
4410         t_len = strlen(target);
4411         i_len = strlen(insert);
4412         b_len = strlen(buf);
4413
4414         /* How much "movement" do we need? */
4415         len = i_len - t_len;
4416
4417         /* We need less space (for insert) */
4418         if (len < 0)
4419         {
4420                 for (i = t_len; i < b_len; ++i) buf[i+len] = buf[i];
4421         }
4422
4423         /* We need more space (for insert) */
4424         else if (len > 0)
4425         {
4426                 for (i = b_len-1; i >= t_len; --i) buf[i+len] = buf[i];
4427         }
4428
4429         /* If movement occured, we need a new terminator */
4430         if (len) buf[b_len+len] = '\0';
4431
4432         /* Now copy the insertion string */
4433         for (i = 0; i < i_len; ++i) buf[i] = insert[i];
4434
4435         /* Successful operation */
4436         return (TRUE);
4437 }
4438
4439
4440 #endif
4441
4442
4443 /*
4444  * GH
4445  * Called from cmd4.c and a few other places. Just extracts
4446  * a direction from the keymap for ch (the last direction,
4447  * in fact) byte or char here? I'm thinking that keymaps should
4448  * generally only apply to single keys, which makes it no more
4449  * than 128, so a char should suffice... but keymap_act is 256...
4450  */
4451 int get_keymap_dir(char ch)
4452 {
4453         cptr act, s;
4454         int d = 0;
4455
4456         if (rogue_like_commands)
4457         {
4458                 act = keymap_act[KEYMAP_MODE_ROGUE][(byte)ch];
4459         }
4460         else
4461         {
4462                 act = keymap_act[KEYMAP_MODE_ORIG][(byte)ch];
4463         }
4464
4465         if (act)
4466         {
4467                 /* Convert to a direction */
4468                 for (s = act; *s; ++s)
4469                 {
4470                         /* Use any digits in keymap */
4471                         if (isdigit(*s)) d = D2I(*s);
4472                 }
4473         }
4474         return d;
4475 }
4476
4477
4478 #ifdef ALLOW_REPEAT /* TNB */
4479
4480 #define REPEAT_MAX              20
4481
4482 /* Number of chars saved */
4483 static int repeat__cnt = 0;
4484
4485 /* Current index */
4486 static int repeat__idx = 0;
4487
4488 /* Saved "stuff" */
4489 static int repeat__key[REPEAT_MAX];
4490
4491
4492 void repeat_push(int what)
4493 {
4494         /* Too many keys */
4495         if (repeat__cnt == REPEAT_MAX) return;
4496
4497         /* Push the "stuff" */
4498         repeat__key[repeat__cnt++] = what;
4499
4500         /* Prevents us from pulling keys */
4501         ++repeat__idx;
4502 }
4503
4504
4505 bool repeat_pull(int *what)
4506 {
4507         /* All out of keys */
4508         if (repeat__idx == repeat__cnt) return (FALSE);
4509
4510         /* Grab the next key, advance */
4511         *what = repeat__key[repeat__idx++];
4512
4513         /* Success */
4514         return (TRUE);
4515 }
4516
4517 void repeat_check(void)
4518 {
4519         int             what;
4520
4521         /* Ignore some commands */
4522         if (command_cmd == ESCAPE) return;
4523         if (command_cmd == ' ') return;
4524         if (command_cmd == '\r') return;
4525         if (command_cmd == '\n') return;
4526
4527         /* Repeat Last Command */
4528         if (command_cmd == 'n')
4529         {
4530                 /* Reset */
4531                 repeat__idx = 0;
4532
4533                 /* Get the command */
4534                 if (repeat_pull(&what))
4535                 {
4536                         /* Save the command */
4537                         command_cmd = what;
4538                 }
4539         }
4540
4541         /* Start saving new command */
4542         else
4543         {
4544                 /* Reset */
4545                 repeat__cnt = 0;
4546                 repeat__idx = 0;
4547
4548                 what = command_cmd;
4549
4550                 /* Save this command */
4551                 repeat_push(what);
4552         }
4553 }
4554
4555 #endif /* ALLOW_REPEAT -- TNB */
4556
4557
4558 #ifdef SORT_R_INFO
4559
4560 /*
4561  * Array size for which InsertionSort
4562  * is used instead of QuickSort
4563  */
4564 #define CUTOFF 4
4565
4566
4567 /*
4568  * Exchange two sort-entries
4569  * (should probably be coded inline
4570  * for speed increase)
4571  */
4572 static void swap(tag_type *a, tag_type *b)
4573 {
4574         tag_type temp;
4575
4576         temp.tag = a->tag;
4577         temp.pointer = a->pointer;
4578
4579         a->tag = b->tag;
4580         a->pointer = b->pointer;
4581
4582         b->tag = temp.tag;
4583         b->pointer = temp.pointer;
4584 }
4585
4586
4587 /*
4588  * Insertion-Sort algorithm
4589  * (used by the Quicksort algorithm)
4590  */
4591 static void InsertionSort(tag_type elements[], int number)
4592 {
4593         int j, P;
4594
4595         tag_type tmp;
4596
4597         for (P = 1; P < number; P++)
4598         {
4599                 tmp = elements[P];
4600                 for (j = P; (j > 0) && (elements[j - 1].tag > tmp.tag); j--)
4601                         elements[j] = elements[j - 1];
4602                 elements[j] = tmp;
4603         }
4604 }
4605
4606
4607 /*
4608  * Helper function for Quicksort
4609  */
4610 static tag_type median3(tag_type elements[], int left, int right)
4611 {
4612         int center = (left + right) / 2;
4613
4614         if (elements[left].tag > elements[center].tag)
4615                 swap(&elements[left], &elements[center]);
4616         if (elements[left].tag > elements[right].tag)
4617                 swap(&elements[left], &elements[right]);
4618         if (elements[center].tag > elements[right].tag)
4619                 swap(&elements[center], &elements[right]);
4620
4621         swap(&elements[center], &elements[right - 1]);
4622         return (elements[right - 1]);
4623 }
4624
4625
4626 /*
4627  * Quicksort algorithm
4628  *
4629  * The "median of three" pivot selection eliminates
4630  * the bad case of already sorted input.
4631  *
4632  * We use InsertionSort for smaller sub-arrays,
4633  * because it is faster in this case.
4634  *
4635  * For details see: "Data Structures and Algorithm
4636  * Analysis in C" by Mark Allen Weiss.
4637  */
4638 static void quicksort(tag_type elements[], int left, int right)
4639 {
4640         int i, j;
4641         tag_type pivot;
4642
4643         if (left + CUTOFF <= right)
4644         {
4645                 pivot = median3(elements, left, right);
4646
4647                 i = left; j = right -1;
4648
4649                 while (TRUE)
4650                 {
4651                         while (elements[++i].tag < pivot.tag);
4652                         while (elements[--j].tag > pivot.tag);
4653
4654                         if (i < j)
4655                                 swap(&elements[i], &elements[j]);
4656                         else
4657                                 break;
4658                 }
4659
4660                 /* Restore pivot */
4661                 swap(&elements[i], &elements[right - 1]);
4662
4663                 quicksort(elements, left, i - 1);
4664                 quicksort(elements, i + 1, right);
4665         }
4666         else
4667         {
4668                 /* Use InsertionSort on small arrays */
4669                 InsertionSort(elements + left, right - left + 1);
4670         }
4671 }
4672
4673
4674 /*
4675  * Frontend for the sorting algorithm
4676  *
4677  * Sorts an array of tagged pointers
4678  * with <number> elements.
4679  */
4680 void tag_sort(tag_type elements[], int number)
4681 {
4682         quicksort(elements, 0, number - 1);
4683 }
4684
4685 #endif /* SORT_R_INFO */
4686
4687 #ifdef SUPPORT_GAMMA
4688
4689 /* Table of gamma values */
4690 byte gamma_table[256];
4691
4692 /* Table of ln(x/256) * 256 for x going from 0 -> 255 */
4693 static s16b gamma_helper[256] =
4694 {
4695 0,-1420,-1242,-1138,-1065,-1007,-961,-921,-887,-857,-830,-806,-783,-762,-744,-726,
4696 -710,-694,-679,-666,-652,-640,-628,-617,-606,-596,-586,-576,-567,-577,-549,-541,
4697 -532,-525,-517,-509,-502,-495,-488,-482,-475,-469,-463,-457,-451,-455,-439,-434,
4698 -429,-423,-418,-413,-408,-403,-398,-394,-389,-385,-380,-376,-371,-367,-363,-359,
4699 -355,-351,-347,-343,-339,-336,-332,-328,-325,-321,-318,-314,-311,-308,-304,-301,
4700 -298,-295,-291,-288,-285,-282,-279,-276,-273,-271,-268,-265,-262,-259,-257,-254,
4701 -251,-248,-246,-243,-241,-238,-236,-233,-231,-228,-226,-223,-221,-219,-216,-214,
4702 -212,-209,-207,-205,-203,-200,-198,-196,-194,-192,-190,-188,-186,-184,-182,-180,
4703 -178,-176,-174,-172,-170,-168,-166,-164,-162,-160,-158,-156,-155,-153,-151,-149,
4704 -147,-146,-144,-142,-140,-139,-137,-135,-134,-132,-130,-128,-127,-125,-124,-122,
4705 -120,-119,-117,-116,-114,-112,-111,-109,-108,-106,-105,-103,-102,-100,-99,-97,
4706 -96,-95,-93,-92,-90,-89,-87,-86,-85,-83,-82,-80,-79,-78,-76,-75,
4707 -74,-72,-71,-70,-68,-67,-66,-65,-63,-62,-61,-59,-58,-57,-56,-54,
4708 -53,-52,-51,-50,-48,-47,-46,-45,-44,-42,-41,-40,-39,-38,-37,-35,
4709 -34,-33,-32,-31,-30,-29,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,
4710 -17,-16,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1
4711 };
4712
4713
4714 /* 
4715  * Build the gamma table so that floating point isn't needed.
4716  * 
4717  * Note gamma goes from 0->256.  The old value of 100 is now 128.
4718  */
4719 void build_gamma_table(int gamma)
4720 {
4721         int i, n;
4722         
4723         /*
4724          * value is the current sum.
4725          * diff is the new term to add to the series.
4726          */
4727         long value, diff;
4728         
4729         /* Hack - convergence is bad in these cases. */
4730         gamma_table[0] = 0;
4731         gamma_table[255] = 255;
4732         
4733         for (i = 1; i < 255; i++)
4734         {
4735                 /* 
4736                  * Initialise the Taylor series
4737                  *
4738                  * value and diff have been scaled by 256
4739                  */
4740                 
4741                 n = 1;
4742                 value = 256 * 256;
4743                 diff = ((long)gamma_helper[i]) * (gamma - 256);
4744                 
4745                 while (diff)
4746                 {
4747                         value += diff;
4748                         n++;
4749                         
4750                         
4751                         /*
4752                          * Use the following identiy to calculate the gamma table.
4753                          * exp(x) = 1 + x + x^2/2 + x^3/(2*3) + x^4/(2*3*4) +...
4754                          *
4755                          * n is the current term number.
4756                          * 
4757                          * The gamma_helper array contains a table of
4758                          * ln(x/256) * 256
4759                          * This is used because a^b = exp(b*ln(a))
4760                          *
4761                          * In this case:
4762                          * a is i / 256
4763                          * b is gamma.
4764                          *
4765                          * Note that everything is scaled by 256 for accuracy,
4766                          * plus another factor of 256 for the final result to
4767                          * be from 0-255.  Thus gamma_helper[] * gamma must be
4768                          * divided by 256*256 each itteration, to get back to
4769                          * the original power series.
4770                          */
4771                         diff = (((diff / 256) * gamma_helper[i]) * (gamma - 256)) / (256 * n);
4772                 }
4773                 
4774                 /* 
4775                  * Store the value in the table so that the
4776                  * floating point pow function isn't needed .
4777                  */
4778                 gamma_table[i] = ((long)(value / 256) * i) / 256;
4779         }
4780 }
4781
4782 #endif /* SUPPORT_GAMMA */
4783
4784 void roff_to_buf(cptr str, int maxlen, char *tbuf)
4785 {
4786         int read_pt = 0;
4787         int write_pt = 0;
4788         int line_len = 0;
4789         int word_punct = 0;
4790         unsigned char ch[3];
4791         ch[2] = '\0';
4792
4793         while (str[read_pt])
4794         {
4795 #ifdef JP
4796                 bool kanji;
4797 #endif
4798                 ch[0] = str[read_pt];
4799                 ch[1] = '\0';
4800 #ifdef JP
4801                 kanji  = iskanji(ch[0]);
4802                 if (kanji)
4803                         ch[1] = str[read_pt+1];
4804                 if (!kanji && !isprint(ch[0]))
4805                         ch[0] = ' ';
4806 #else
4807                 if (!isprint(ch[0]))
4808                         ch[0] = ' ';
4809 #endif
4810
4811                 if (line_len >= maxlen - 1 || str[read_pt] == '\n')
4812                 {
4813                         int word_len;
4814
4815                         /* return to better wrapping point. */
4816                         /* Space character at the end of the line need not to be printed. */
4817                         word_len = read_pt - word_punct;
4818                         if (ch[0] != ' ' && word_len < line_len/2)
4819                         {
4820                                 read_pt = word_punct;
4821                                 if (str[word_punct] == ' ')
4822                                         read_pt++;
4823                                 write_pt -= word_len;
4824                         }
4825                         else
4826                                 read_pt++;
4827                         tbuf[write_pt++] = '\0';
4828                         line_len = 0;
4829                         word_punct = read_pt;
4830                         continue;
4831                 }
4832                 if (ch[0] == ' ')
4833                         word_punct = read_pt;
4834 #ifdef JP
4835                 if (kanji &&
4836                     strcmp((char *)ch, "¡£") != 0 && strcmp((char *)ch, "¡¢") != 0 &&
4837                     strcmp((char *)ch, "¥£") != 0 && strcmp((char *)ch, "¡¼") != 0)
4838                         word_punct = read_pt;
4839 #endif
4840                 tbuf[write_pt++] = ch[0];
4841                 line_len++;
4842                 read_pt++;
4843 #ifdef JP
4844                 if (kanji)
4845                 {
4846                         tbuf[write_pt++] = ch[1];
4847                         line_len++;
4848                         read_pt++;
4849                 }
4850 #endif
4851         }
4852         tbuf[write_pt] = '\0';
4853         tbuf[write_pt+1] = '\0';
4854
4855         return;
4856 }
4857