OSDN Git Service

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