OSDN Git Service

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