OSDN Git Service

広域マップで画面をスクロールすると右端の境界の外までスクロールできてしまうバグ修正。
[hengbandforosx/hengbandosx.git] / src / util.c
index 1c82122..66b3a53 100644 (file)
 
 static int num_more = 0;
 
-#ifndef HAS_MEMSET
-
-/*
- * For those systems that don't have "memset()"
- *
- * Set the value of each of 'n' bytes starting at 's' to 'c', return 's'
- * If 'n' is negative, you will erase a whole lot of memory.
- */
-char *memset(char *s, int c, huge n)
-{
-       char *t;
-       for (t = s; len--; ) *t++ = c;
-       return (s);
-}
-
-#endif
-
-
 #if 0
 #ifndef HAS_STRICMP
 
@@ -57,7 +39,7 @@ int stricmp(cptr a, cptr b)
 
 #ifdef SET_UID
 
-# ifndef HAS_USLEEP
+# ifndef HAVE_USLEEP
 
 /*
  * For those systems that don't have "usleep()" but need it.
@@ -109,10 +91,12 @@ int usleep(huge usecs)
 
 
 /*
-* Hack -- External functions
-*/
-extern struct passwd *getpwuid();
-extern struct passwd *getpwnam();
+ * Hack -- External functions
+ */
+#ifdef SET_UID
+extern struct passwd *getpwuid(uid_t uid);
+extern struct passwd *getpwnam(const char *name);
+#endif
 
 
 /*
@@ -120,7 +104,6 @@ extern struct passwd *getpwnam();
  */
 void user_name(char *buf, int id)
 {
-#ifdef SET_UID
        struct passwd *pw;
 
        /* Look up the user name */
@@ -131,12 +114,15 @@ void user_name(char *buf, int id)
 
 #ifdef CAPITALIZE_USER_NAME
                /* Hack -- capitalize the user name */
-               if (islower(buf[0])) buf[0] = toupper(buf[0]);
+#ifdef JP
+               if (!iskanji(buf[0]))
+#endif
+                       if (islower(buf[0]))
+                               buf[0] = toupper(buf[0]);
 #endif /* CAPITALIZE_USER_NAME */
 
                return;
        }
-#endif /* SET_UID */
 
        /* Oops.  Hack -- default to "PLAYER" */
        strcpy(buf, "PLAYER");
@@ -359,9 +345,23 @@ FILE *my_fopen(cptr file, cptr mode)
 {
        char buf[1024];
 
+#if defined(MACINTOSH) && defined(MAC_MPW)
+       FILE *tempfff;
+#endif
+
        /* Hack -- Try to parse the path */
        if (path_parse(buf, 1024, file)) return (NULL);
 
+#if defined(MACINTOSH) && defined(MAC_MPW)
+       if (strchr(mode, 'w'))
+       {
+               /* setting file type/creator */
+               tempfff = fopen(buf, mode);
+               fsetfileinfo(file, _fcreator, _ftype);
+               fclose(tempfff);
+       }
+#endif
+
        /* Attempt to fopen the file anyway */
        return (fopen(buf, mode));
 }
@@ -616,6 +616,8 @@ errr fd_copy(cptr file, cptr what)
 {
        char buf[1024];
        char aux[1024];
+       int read_num;
+       int src_fd, dst_fd;
 
        /* Hack -- Try to parse the path */
        if (path_parse(buf, 1024, file)) return (-1);
@@ -623,11 +625,26 @@ errr fd_copy(cptr file, cptr what)
        /* Hack -- Try to parse the path */
        if (path_parse(aux, 1024, what)) return (-1);
 
-       /* Copy XXX XXX XXX */
-       /* (void)rename(buf, aux); */
+       /* Open source file */
+       src_fd = fd_open(buf, O_RDONLY);
+       if (src_fd < 0) return (-1);
+
+       /* Open destination file */
+       dst_fd = fd_open(aux, O_WRONLY|O_TRUNC|O_CREAT);
+       if (dst_fd < 0) return (-1);
+
+       /* Copy */
+       while ((read_num = read(src_fd, buf, 1024)) > 0)
+       {
+               write(dst_fd, buf, read_num);
+       }
+
+       /* Close files */
+       fd_close(src_fd);
+       fd_close(dst_fd);
 
        /* XXX XXX XXX */
-       return (1);
+       return (0);
 }
 
 
@@ -664,8 +681,20 @@ int fd_make(cptr file, int mode)
 
 #else /* BEN_HACK */
 
+# if defined(MACINTOSH) && defined(MAC_MPW)
+
+       /* setting file type and creator -- AR */
+       {
+               errr errr_tmp;
+               errr_tmp = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
+               fsetfileinfo(file, _fcreator, _ftype);
+               return(errr_tmp);
+       }
+
+# else
        /* Create the file, fail if exists, write-only, binary */
        return (open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode));
+# endif
 
 #endif /* BEN_HACK */
 
@@ -767,9 +796,6 @@ errr fd_seek(int fd, huge n)
        p = lseek(fd, n, SEEK_SET);
 
        /* Failure */
-       if (p < 0) return (1);
-
-       /* Failure */
        if (p != n) return (1);
 
        /* Success */
@@ -979,6 +1005,130 @@ static int dehex(char c)
 }
 
 
+static int my_stricmp(cptr a, cptr b)
+{
+       cptr s1, s2;
+       char z1, z2;
+
+       /* Scan the strings */
+       for (s1 = a, s2 = b; TRUE; s1++, s2++)
+       {
+               z1 = FORCEUPPER(*s1);
+               z2 = FORCEUPPER(*s2);
+               if (z1 < z2) return (-1);
+               if (z1 > z2) return (1);
+               if (!z1) return (0);
+       }
+}
+
+static int my_strnicmp(cptr a, cptr b, int n)
+{
+       cptr s1, s2;
+       char z1, z2;
+
+       /* Scan the strings */
+       for (s1 = a, s2 = b; n > 0; s1++, s2++, n--)
+       {
+               z1 = FORCEUPPER(*s1);
+               z2 = FORCEUPPER(*s2);
+               if (z1 < z2) return (-1);
+               if (z1 > z2) return (1);
+               if (!z1) return (0);
+       }
+       return 0;
+}
+
+
+static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
+{
+       char *s = *bufptr;
+       cptr str = *strptr;
+       bool mod_status[MAX_MACRO_MOD];
+
+       int i, len = 0;
+       int shiftstatus = 0;
+       cptr key_code;
+
+       if (macro_template == NULL)
+               return;
+       
+       for (i = 0; macro_modifier_chr[i]; i++)
+               mod_status[i] = FALSE;
+       str++;
+
+       /* Examine modifier keys */
+       while (1)
+       {
+               for (i=0; macro_modifier_chr[i]; i++)
+               {
+                       len = strlen(macro_modifier_name[i]);
+                       
+                       if(!my_strnicmp(str, macro_modifier_name[i], len))
+                               break;
+               }
+               if (!macro_modifier_chr[i]) break;
+               str += len;
+               mod_status[i] = TRUE;
+               if ('S' == macro_modifier_chr[i])
+                       shiftstatus = 1;
+       }
+       for (i = 0; i < max_macrotrigger; i++)
+       {
+               len = strlen(macro_trigger_name[i]);
+               if (!my_strnicmp(str, macro_trigger_name[i], len) && ']' == str[len])
+               {
+                       /* a trigger name found */
+                       break;
+               }
+       }
+
+       /* Invalid trigger name? */
+       if (i == max_macrotrigger)
+       {
+               str = strchr(str, ']');
+               if (str)
+               {
+                       *s++ = (char)31;
+                       *s++ = '\r';
+                       *bufptr = s;
+                       *strptr = str; /* where **strptr == ']' */
+               }
+               return;
+       }
+       key_code = macro_trigger_keycode[shiftstatus][i];
+       str += len;
+
+       *s++ = (char)31;
+       for (i = 0; macro_template[i]; i++)
+       {
+               char ch = macro_template[i];
+               int j;
+
+               switch(ch)
+               {
+               case '&':
+                       for (j = 0; macro_modifier_chr[j]; j++) {
+                               if (mod_status[j])
+                                       *s++ = macro_modifier_chr[j];
+                       }
+                       break;
+               case '#':
+                       strcpy(s, key_code);
+                       s += strlen(key_code);
+                       break;
+               default:
+                       *s++ = ch;
+                       break;
+               }
+       }
+       *s++ = '\r';
+
+       *bufptr = s;
+       *strptr = str; /* where **strptr == ']' */
+       return;
+}
+
+
 /*
  * Hack -- convert a printable string into real ascii
  *
@@ -999,6 +1149,13 @@ void text_to_ascii(char *buf, cptr str)
                        /* Skip the backslash */
                        str++;
 
+                       /* Macro Trigger */
+                       if (*str == '[')
+                       {
+                               trigger_text_to_ascii(&s, &str);
+                       }
+                       else
+
                        /* Hex-mode XXX */
                        if (*str == 'x')
                        {
@@ -1105,6 +1262,68 @@ void text_to_ascii(char *buf, cptr str)
 }
 
 
+static bool trigger_ascii_to_text(char **bufptr, cptr *strptr)
+{
+       char *s = *bufptr;
+       cptr str = *strptr;
+       char key_code[100];
+       int i;
+       cptr tmp;
+
+       if (macro_template == NULL)
+               return FALSE;
+
+       *s++ = '\\';
+       *s++ = '[';
+
+       for (i = 0; macro_template[i]; i++)
+       {
+               int j;
+               char ch = macro_template[i];
+
+               switch(ch)
+               {
+               case '&':
+                       while ((tmp = strchr(macro_modifier_chr, *str)))
+                       {
+                               j = (int)(tmp - macro_modifier_chr);
+                               tmp = macro_modifier_name[j];
+                               while(*tmp) *s++ = *tmp++;
+                               str++;
+                       }
+                       break;
+               case '#':
+                       for (j = 0; *str && *str != '\r'; j++)
+                               key_code[j] = *str++;
+                       key_code[j] = '\0';
+                       break;
+               default:
+                       if (ch != *str) return FALSE;
+                       str++;
+               }
+       }
+       if (*str++ != '\r') return FALSE;
+
+       for (i = 0; i < max_macrotrigger; i++)
+       {
+               if (!my_stricmp(key_code, macro_trigger_keycode[0][i])
+                   || !my_stricmp(key_code, macro_trigger_keycode[1][i]))
+                       break;
+       }
+       if (i == max_macrotrigger)
+               return FALSE;
+
+       tmp = macro_trigger_name[i];
+       while (*tmp) *s++ = *tmp++;
+
+       *s++ = ']';
+       
+       *bufptr = s;
+       *strptr = str;
+       return TRUE;
+}
+
+
 /*
  * Hack -- convert a string into a printable form
  */
@@ -1117,6 +1336,17 @@ void ascii_to_text(char *buf, cptr str)
        {
                byte i = (byte)(*str++);
 
+               /* Macro Trigger */
+               if (i == 31)
+               {
+                       if(!trigger_ascii_to_text(&s, &str))
+                       {
+                               *s++ = '^';
+                               *s++ = '_';
+                       }
+               }
+               else
+
                if (i == ESCAPE)
                {
                        *s++ = '\\';
@@ -1382,21 +1612,6 @@ errr macro_add(cptr pat, cptr act)
 
 
 /*
- * Initialize the "macro" package
- */
-errr macro_init(void)
-{
-       /* Macro patterns */
-       C_MAKE(macro__pat, MACRO_MAX, cptr);
-
-       /* Macro actions */
-       C_MAKE(macro__act, MACRO_MAX, cptr);
-
-       /* Success */
-       return (0);
-}
-
-/*
  * Local variable -- we are inside a "macro action"
  *
  * Do not match any macros until "ascii 30" is found.
@@ -1421,7 +1636,7 @@ static bool parse_under = FALSE;
 void flush(void)
 {
        /* Do it later */
-        inkey_xtra = TRUE;
+       inkey_xtra = TRUE;
 }
 
 
@@ -1482,11 +1697,23 @@ static char inkey_aux(void)
 
        char buf[1024];
 
-       /* Hack : ¥­¡¼ÆþÎÏÂÔ¤Á¤Ç»ß¤Þ¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢Î®¤ì¤¿¹Ô¤Îµ­²±¤ÏÉÔÍס£*/
+       /* Hack : ¥­¡¼ÆþÎÏÂÔ¤Á¤Ç»ß¤Þ¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢Î®¤ì¤¿¹Ô¤Îµ­²±¤ÏÉÔÍס£ */
        num_more = 0;
 
-       /* Wait for a keypress */
-       (void)(Term_inkey(&ch, TRUE, TRUE));
+       if (parse_macro)
+       {
+               /* Scan next keypress from macro action */
+               if (Term_inkey(&ch, FALSE, TRUE))
+               {
+                       /* Over-flowed? Cancel macro action */
+                       parse_macro = FALSE;
+               }
+       }
+       else
+       {
+               /* Wait for a keypress */
+               (void) (Term_inkey(&ch, TRUE, TRUE));
+       }
 
 
        /* End "macro action" */
@@ -1501,6 +1728,8 @@ static char inkey_aux(void)
        /* Inside "macro trigger" */
        if (parse_under) return (ch);
 
+       /* Parse special key only */
+       if (inkey_special && ch != 31) return (ch);
 
        /* Save the first key, advance */
        buf[p++] = ch;
@@ -1705,10 +1934,6 @@ char inkey(void)
        bool done = FALSE;
        term *old = Term;
 
-#ifdef USE_SCRIPT
-       char result;
-#endif /* USE_SCRIPT */
-
        /* Hack -- Use the "inkey_next" pointer */
        if (inkey_next && *inkey_next && !inkey_xtra)
        {
@@ -1716,7 +1941,7 @@ char inkey(void)
                ch = *inkey_next++;
 
                /* Cancel the various "global parameters" */
-               inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
+               inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
 
                /* Accept result */
                return (ch);
@@ -1732,7 +1957,7 @@ char inkey(void)
        if (inkey_hack && ((ch = (*inkey_hack)(inkey_xtra)) != 0))
        {
                /* Cancel the various "global parameters" */
-               inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
+               inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
 
                /* Accept result */
                return (ch);
@@ -1740,18 +1965,6 @@ char inkey(void)
 
 #endif /* ALLOW_BORG */
 
-#ifdef USE_SCRIPT
-
-       if ((result = inkey_borg_callback(inkey_base, inkey_xtra, inkey_flag, inkey_scan)))
-       {
-               /* Cancel the various "global parameters" */
-               inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
-
-               return (result);
-       }
-
-#endif /* USE_SCRIPT */
-
 
        /* Hack -- handle delayed "flush()" */
        if (inkey_xtra)
@@ -1880,7 +2093,7 @@ char inkey(void)
 
 
                /* Treat back-quote as escape */
-//             if (ch == '`') ch = ESCAPE;
+/*             if (ch == '`') ch = ESCAPE; */
 
 
                /* End "macro trigger" */
@@ -1929,13 +2142,7 @@ char inkey(void)
 
 
        /* Cancel the various "global parameters" */
-       inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
-
-#ifdef USE_SCRIPT
-
-       if ((result = inkey_callback(ch))) return result;
-
-#endif /* USE_SCRIPT */
+       inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
 
        /* Return the keypress */
        return (ch);
@@ -2164,7 +2371,7 @@ void message_add(cptr str)
  for (t = buf; *t && (*t != '<' || (*(t+1) != 'x' )); t++) 
      if( iskanji(*t))t++;
 #else
-                for (t = buf; *t && (*t != '<'); t++);
+               for (t = buf; *t && (*t != '<'); t++);
 #endif
 
                if (*t)
@@ -2199,7 +2406,7 @@ void message_add(cptr str)
                }
                else
                {
-                       num_more++;/*ή¤ì¤¿¹Ô¤Î¿ô¤ò¿ô¤¨¤Æ¤ª¤¯*/
+                       num_more++;/*ή¤ì¤¿¹Ô¤Î¿ô¤ò¿ô¤¨¤Æ¤ª¤¯ */
                        now_message++;
                }
 
@@ -2382,7 +2589,7 @@ static void msg_flush(int x)
        }
        now_damaged = FALSE;
 
-       if (!nagasu)
+       if (!p_ptr->playing || !nagasu)
        {
                /* Pause for response */
 #ifdef JP
@@ -2397,13 +2604,13 @@ static void msg_flush(int x)
                {
                        int cmd = inkey();
                        if (cmd == ESCAPE) {
-                           num_more = -9999; /*auto_more¤Î¤È¤­¡¢Á´¤Æή¤¹¡£*/
+                           num_more = -9999; /*auto_more¤Î¤È¤­¡¢Á´¤Æή¤¹¡£ */
                            break;
                        } else if (cmd == ' ') {
-                           num_more = 0; /*£±²èÌ̤À¤±Î®¤¹¡£*/
+                           num_more = 0; /*£±²èÌ̤À¤±Î®¤¹¡£ */
                            break;
                        } else if ((cmd == '\n') || (cmd == '\r')) {
-                           num_more--; /*£±¹Ô¤À¤±Î®¤¹¡£*/
+                           num_more--; /*£±¹Ô¤À¤±Î®¤¹¡£ */
                            break;
                        }
                        if (quick_messages) break;
@@ -2757,6 +2964,8 @@ void c_roff(byte a, cptr str)
 
                        /* Clear line, move cursor */
                        Term_erase(x, y, 255);
+
+                       break;
                }
 
                /* Clean up the char */
@@ -2856,7 +3065,7 @@ void c_roff(byte a, cptr str)
 
                /* Dump */
 #ifdef JP
-                Term_addch(a|0x10, ch);
+               Term_addch((byte)(a|0x10), ch);
 #else
                Term_addch(a, ch);
 #endif
@@ -2868,7 +3077,7 @@ void c_roff(byte a, cptr str)
                        s++;
                        x++;
                        ch = *s;
-                       Term_addch(a|0x20, ch);
+                       Term_addch((byte)(a|0x20), ch);
                }
 #endif
                /* Advance */
@@ -2995,28 +3204,28 @@ bool askfor_aux(char *buf, int len)
                default:
 #ifdef JP
        {                       /* ÊÒ»³¤µ¤óºîÀ® */
-                int next;
-
-                                if (iskanji (i)) {
-                                        inkey_base = TRUE;
-                                        next = inkey ();
-                                        if (k+1 < len) {
-                                                buf[k++] = i;
-                                                buf[k] = next;
-                                                k_flag[k++] = 1;
-                                        } else
-                                                bell();
-                                } else {
+               int next;
+
+                               if (iskanji (i)) {
+                                       inkey_base = TRUE;
+                                       next = inkey ();
+                                       if (k+1 < len) {
+                                               buf[k++] = i;
+                                               buf[k] = next;
+                                               k_flag[k++] = 1;
+                                       } else
+                                               bell();
+                               } else {
 #ifdef SJIS
-                    if(k<len && (isprint(i) || (0xa0<=i && i<=0xdf))){
+                   if(k<len && (isprint(i) || (0xa0<=i && i<=0xdf))){
 #else
-                    if(k<len && isprint(i)){
+                   if(k<len && isprint(i)){
 #endif
-                                                buf[k] = i;
-                                                k_flag[k++] = 0;
-                                        } else
-                                                bell();
-                              }
+                                               buf[k] = i;
+                                               k_flag[k++] = 0;
+                                       } else
+                                               bell();
+                              }
                 }
 #else
                        if ((k < len) && (isprint(i)))
@@ -3088,8 +3297,19 @@ bool get_string(cptr prompt, char *buf, int len)
  */
 bool get_check(cptr prompt)
 {
-       int i;
+       return get_check_strict(prompt, 0);
+}
 
+/*
+ * Verify something with the user strictly
+ *
+ * mode & CHECK_OKAY_CANCEL : force user to answer 'O'kay or 'C'ancel
+ * mode & CHECK_NO_ESCAPE   : don't allow ESCAPE key
+ * mode & CHECK_NO_HISTORY  : no message_add
+ */
+bool get_check_strict(cptr prompt, int mode)
+{
+       int i;
        char buf[80];
 
        if (auto_more)
@@ -3102,19 +3322,61 @@ bool get_check(cptr prompt)
        /* Paranoia XXX XXX XXX */
        msg_print(NULL);
 
+       if (!rogue_like_commands)
+               mode &= ~CHECK_OKAY_CANCEL;
+
+
        /* Hack -- Build a "useful" prompt */
-       (void)strnfmt(buf, 78, "%.70s[y/n] ", prompt);
+       if (mode & CHECK_OKAY_CANCEL)
+       {
+               my_strcpy(buf, prompt, sizeof(buf)-15);
+               strcat(buf, "[(O)k/(C)ancel]");
+       }
+       else
+       {
+               my_strcpy(buf, prompt, sizeof(buf)-5);
+               strcat(buf, "[y/n]");
+       }
 
        /* Prompt for it */
        prt(buf, 0, 0);
 
+       if (!(mode & CHECK_NO_HISTORY) && p_ptr->playing)
+       {
+               /* HACK : Add the line to message buffer */
+               message_add(buf);
+               p_ptr->window |= (PW_MESSAGE);
+               window_stuff();
+       }
+
        /* Get an acceptable answer */
        while (TRUE)
        {
                i = inkey();
-//             if (quick_messages) break;
-               if (i == ESCAPE) break;
-               if (strchr("YyNn", i)) break;
+               if (mode & CHECK_OKAY_CANCEL)
+               {
+                       if ( i == 'o' || i == 'O' )
+                       {
+                               i = 'Y';
+                               break;
+                       }
+               }
+               else if (i == 'y' || i == 'Y')
+               {
+                               break;
+               }
+               if (!(mode & CHECK_NO_ESCAPE) && (i == ESCAPE)) break;
+               if ( mode & CHECK_OKAY_CANCEL )
+               {
+                       if ( i == 'c' || i == 'C' )
+                       {
+                               break;
+                       }
+               }
+               else if (i == 'n' || i == 'N')
+               {
+                               break;
+               }
                bell();
        }
 
@@ -3592,6 +3854,150 @@ special_menu_naiyou special_menu_info[] =
 };
 #endif
 
+static char inkey_from_menu(void)
+{
+       char cmd;
+       int basey, basex;
+       int num = 0, max_num, old_num = 0;
+       int menu = 0;
+       bool kisuu;
+
+       if (py - panel_row_min > 10) basey = 2;
+       else basey = 13;
+       basex = 15;
+
+       /* Clear top line */
+       prt("", 0, 0);
+
+       screen_save();
+
+       while(1)
+       {
+               int i;
+               char sub_cmd;
+               cptr menu_name;
+               if (!menu) old_num = num;
+               put_str("+----------------------------------------------------+", basey, basex);
+               put_str("|                                                    |", basey+1, basex);
+               put_str("|                                                    |", basey+2, basex);
+               put_str("|                                                    |", basey+3, basex);
+               put_str("|                                                    |", basey+4, basex);
+               put_str("|                                                    |", basey+5, basex);
+               put_str("+----------------------------------------------------+", basey+6, basex);
+
+               for(i = 0; i < 10; i++)
+               {
+                       int hoge;
+                       if (!menu_info[menu][i].cmd) break;
+                       menu_name = menu_info[menu][i].name;
+                       for(hoge = 0; ; hoge++)
+                       {
+                               if (!special_menu_info[hoge].name[0]) break;
+                               if ((menu != special_menu_info[hoge].window) || (i != special_menu_info[hoge].number)) continue;
+                               switch(special_menu_info[hoge].jouken)
+                               {
+                               case MENU_CLASS:
+                                       if (p_ptr->pclass == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
+                                       break;
+                               case MENU_WILD:
+                                       if (!dun_level && !p_ptr->inside_arena && !p_ptr->inside_quest)
+                                       {
+                                               if ((byte)p_ptr->wild_mode == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                               }
+                       }
+                       put_str(menu_name, basey + 1 + i / 2, basex + 4 + (i % 2) * 24);
+               }
+               max_num = i;
+               kisuu = max_num % 2;
+#ifdef JP
+               put_str("¡Õ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
+#else
+               put_str("> ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
+#endif
+
+               /* Place the cursor on the player */
+               move_cursor_relative(py, px);
+
+               /* Get a command */
+               sub_cmd = inkey();
+               if ((sub_cmd == ' ') || (sub_cmd == 'x') || (sub_cmd == 'X') || (sub_cmd == '\r') || (sub_cmd == '\n'))
+               {
+                       if (menu_info[menu][num].fin)
+                       {
+                               cmd = menu_info[menu][num].cmd;
+                               use_menu = TRUE;
+                               break;
+                       }
+                       else
+                       {
+                               menu = menu_info[menu][num].cmd;
+                               num = 0;
+                               basey += 2;
+                               basex += 8;
+                       }
+               }
+               else if ((sub_cmd == ESCAPE) || (sub_cmd == 'z') || (sub_cmd == 'Z') || (sub_cmd == '0'))
+               {
+                       if (!menu)
+                       {
+                               cmd = ESCAPE;
+                               break;
+                       }
+                       else
+                       {
+                               menu = 0;
+                               num = old_num;
+                               basey -= 2;
+                               basex -= 8;
+                               screen_load();
+                               screen_save();
+                       }
+               }
+               else if ((sub_cmd == '2') || (sub_cmd == 'j') || (sub_cmd == 'J'))
+               {
+                       if (kisuu)
+                       {
+                               if (num % 2)
+                                       num = (num + 2) % (max_num - 1);
+                               else
+                                       num = (num + 2) % (max_num + 1);
+                       }
+                       else num = (num + 2) % max_num;
+               }
+               else if ((sub_cmd == '8') || (sub_cmd == 'k') || (sub_cmd == 'K'))
+               {
+                       if (kisuu)
+                       {
+                               if (num % 2)
+                                       num = (num + max_num - 3) % (max_num - 1);
+                               else
+                                       num = (num + max_num - 1) % (max_num + 1);
+                       }
+                       else num = (num + max_num - 2) % max_num;
+               }
+               else if ((sub_cmd == '4') || (sub_cmd == '6') || (sub_cmd == 'h') || (sub_cmd == 'H') || (sub_cmd == 'l') || (sub_cmd == 'L'))
+               {
+                       if ((num % 2) || (num == max_num - 1))
+                       {
+                               num--;
+                       }
+                       else if (num < max_num - 1)
+                       {
+                               num++;
+                       }
+               }
+       }
+
+       screen_load();
+       if (!inkey_next) inkey_next = "";
+
+       return (cmd);
+}
+
 /*
  * Request a command from the user.
  *
@@ -3615,14 +4021,13 @@ void request_command(int shopping)
 {
        int i;
 
-       unsigned char cmd;
-
+       char cmd;
        int mode;
 
        cptr act;
 
 #ifdef JP
-        int caretcmd = 0;
+       int caretcmd = 0;
 #endif
        /* Roguelike */
        if (rogue_like_commands)
@@ -3659,7 +4064,7 @@ void request_command(int shopping)
                        msg_print(NULL);
 
                        /* Use auto-command */
-                       cmd = (unsigned char)command_new;
+                       cmd = command_new;
 
                        /* Forget it */
                        command_new = 0;
@@ -3668,8 +4073,6 @@ void request_command(int shopping)
                /* Get a keypress in "command" mode */
                else
                {
-                       char sub_cmd;
-
                        /* Hack -- no flush needed */
                        msg_flag = FALSE;
                        num_more = 0;
@@ -3678,148 +4081,11 @@ void request_command(int shopping)
                        inkey_flag = TRUE;
 
                        /* Get a command */
-                       sub_cmd = inkey();
-
-                       if (!shopping && command_menu && ((sub_cmd == '\r') || (sub_cmd == 'x') || (sub_cmd == 'X'))
-                           && !keymap_act[mode][(byte)(sub_cmd)])
-                       {
-                               int basey, basex;
-                               int num = 0, max_num, old_num = 0;
-                               int menu = 0;
-                               bool kisuu;
-
-                               if (py - panel_row_min > 10) basey = 2;
-                               else basey = 13;
-                               basex = 15;
+                       cmd = inkey();
 
-                               /* Clear top line */
-                               prt("", 0, 0);
-
-                               screen_save();
-
-                               while(1)
-                               {
-                                       cptr menu_name;
-                                       if (!menu) old_num = num;
-                                       put_str("+----------------------------------------------------+", basey, basex);
-                                       put_str("|                                                    |", basey+1, basex);
-                                       put_str("|                                                    |", basey+2, basex);
-                                       put_str("|                                                    |", basey+3, basex);
-                                       put_str("|                                                    |", basey+4, basex);
-                                       put_str("|                                                    |", basey+5, basex);
-                                       put_str("+----------------------------------------------------+", basey+6, basex);
-
-                                       for(i = 0; i < 10; i++)
-                                       {
-                                               int hoge;
-                                               if (!menu_info[menu][i].cmd) break;
-                                               menu_name = menu_info[menu][i].name;
-                                               for(hoge = 0; ; hoge++)
-                                               {
-                                                       if (!special_menu_info[hoge].name[0]) break;
-                                                       if ((menu != special_menu_info[hoge].window) || (i != special_menu_info[hoge].number)) continue;
-                                                       switch(special_menu_info[hoge].jouken)
-                                                       {
-                                                               case MENU_CLASS:
-                                                               if (p_ptr->pclass == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
-                                                               break;
-                                                               case MENU_WILD:
-                                                               if (!dun_level && !p_ptr->inside_arena && !p_ptr->inside_quest)
-                                                               {
-                                                                       if ((byte)p_ptr->wild_mode == special_menu_info[hoge].jouken_naiyou) menu_name = special_menu_info[hoge].name;
-                                                               }
-                                                               break;
-                                                               default:
-                                                               break;
-                                                       }
-                                               }
-                                               put_str(menu_name, basey + 1 + i / 2, basex + 4 + (i % 2) * 24);
-                                       }
-                                       max_num = i;
-                                       kisuu = max_num % 2;
-#ifdef JP
-                                       put_str("¡Õ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
-#else
-                                       put_str("> ",basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
-#endif
-
-                                       /* Place the cursor on the player */
-                                       move_cursor_relative(py, px);
-
-                                       /* Get a command */
-                                       sub_cmd = inkey();
-                                       if ((sub_cmd == ' ') || (sub_cmd == 'x') || (sub_cmd == 'X') || (sub_cmd == '\r'))
-                                       {
-                                               if (menu_info[menu][num].fin)
-                                               {
-                                                       cmd = menu_info[menu][num].cmd;
-                                                       use_menu = TRUE;
-                                                       break;
-                                               }
-                                               else
-                                               {
-                                                       menu = menu_info[menu][num].cmd;
-                                                       num = 0;
-                                                       basey += 2;
-                                                       basex += 8;
-                                               }
-                                       }
-                                       else if ((sub_cmd == ESCAPE) || (sub_cmd == 'z') || (sub_cmd == 'Z') || (sub_cmd == '0'))
-                                       {
-                                               if (!menu)
-                                               {
-                                                       cmd = ESCAPE;
-                                                       break;
-                                               }
-                                               else
-                                               {
-                                                       menu = 0;
-                                                       num = old_num;
-                                                       basey -= 2;
-                                                       basex -= 8;
-                                                       screen_load();
-                                                       screen_save();
-                                               }
-                                       }
-                                       else if ((sub_cmd == '2') || (sub_cmd == 'j') || (sub_cmd == 'J'))
-                                       {
-                                               if (kisuu)
-                                               {
-                                                       if (num % 2)
-                                                               num = (num + 2) % (max_num - 1);
-                                                       else
-                                                               num = (num + 2) % (max_num + 1);
-                                               }
-                                               else num = (num + 2) % max_num;
-                                       }
-                                       else if ((sub_cmd == '8') || (sub_cmd == 'k') || (sub_cmd == 'K'))
-                                       {
-                                               if (kisuu)
-                                               {
-                                                       if (num % 2)
-                                                               num = (num + max_num - 3) % (max_num - 1);
-                                                       else
-                                                               num = (num + max_num - 1) % (max_num + 1);
-                                               }
-                                               else num = (num + max_num - 2) % max_num;
-                                       }
-                                       else if ((sub_cmd == '4') || (sub_cmd == '6') || (sub_cmd == 'h') || (sub_cmd == 'H') || (sub_cmd == 'l') || (sub_cmd == 'L'))
-                                       {
-                                               if ((num % 2) || (num == max_num - 1))
-                                               {
-                                                       num--;
-                                               }
-                                               else if (num < max_num - 1)
-                                               {
-                                                       num++;
-                                               }
-                                       }
-                               }
-
-                               screen_load();
-                               if (!inkey_next) inkey_next = "";
-                       }
-                       else cmd = sub_cmd;
+                       if (!shopping && command_menu && ((cmd == '\r') || (cmd == '\n') || (cmd == 'x') || (cmd == 'X'))
+                           && !keymap_act[mode][(byte)(cmd)])
+                               cmd = inkey_from_menu();
                }
 
                /* Clear top line */
@@ -3934,9 +4200,9 @@ prt(format("
                        {
                                /* Get a real command */
 #ifdef JP
-                               if (!get_com("¥³¥Þ¥ó¥É: ", &cmd, FALSE))
+                               if (!get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE))
 #else
-                               if (!get_com("Command: ", &cmd, FALSE))
+                               if (!get_com("Command: ", (char *)&cmd, FALSE))
 #endif
 
                                {
@@ -3955,9 +4221,9 @@ prt(format("
                {
                        /* Get a real command */
 #ifdef JP
-                       (void)get_com("¥³¥Þ¥ó¥É: ", &cmd, FALSE);
+                       (void)get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE);
 #else
-                       (void)get_com("Command: ", &cmd, FALSE);
+                       (void)get_com("Command: ", (char *)&cmd, FALSE);
 #endif
 
 
@@ -3971,9 +4237,9 @@ prt(format("
                {
                        /* Get a new command and controlify it */
 #ifdef JP
-                       if (get_com("CTRL: ", &cmd, FALSE)) cmd = KTRL(cmd);
+                       if (get_com("CTRL: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
 #else
-                       if (get_com("Control: ", &cmd, FALSE)) cmd = KTRL(cmd);
+                       if (get_com("Control: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
 #endif
 
                }
@@ -4001,7 +4267,7 @@ prt(format("
 
 
                /* Use command */
-               command_cmd = cmd;
+               command_cmd = (byte)cmd;
 
                /* Done */
                break;
@@ -4036,20 +4302,20 @@ prt(format("
        }
 
 #ifdef JP
-        for (i = 0; i < 256; i++)
-        {
-                cptr s;
-                if ((s = keymap_act[mode][i]) != NULL)
-                {
-                        if (*s == command_cmd && *(s+1) == 0)
-                        {
-                                caretcmd = i;
-                                break;
-                        }
-                }
-        }
-        if (!caretcmd)
-                caretcmd = command_cmd;
+       for (i = 0; i < 256; i++)
+       {
+               cptr s;
+               if ((s = keymap_act[mode][i]) != NULL)
+               {
+                       if (*s == command_cmd && *(s+1) == 0)
+                       {
+                               caretcmd = i;
+                               break;
+                       }
+               }
+       }
+       if (!caretcmd)
+               caretcmd = command_cmd;
 #endif
        /* Hack -- Scan equipment */
        for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
@@ -4075,7 +4341,7 @@ prt(format("
                {
                        /* Check the "restriction" character */
 #ifdef JP
-                        if ((s[1] == caretcmd) || (s[1] == '*'))
+                       if ((s[1] == caretcmd) || (s[1] == '*'))
 #else
                        if ((s[1] == command_cmd) || (s[1] == '*'))
 #endif
@@ -4199,28 +4465,50 @@ static bool insert_str(char *buf, cptr target, cptr insert)
  */
 int get_keymap_dir(char ch)
 {
-       cptr act, s;
        int d = 0;
 
-       if (rogue_like_commands)
+       /* Already a direction? */
+       if (isdigit(ch))
        {
-               act = keymap_act[KEYMAP_MODE_ROGUE][(byte)ch];
+               d = D2I(ch);
        }
        else
        {
-               act = keymap_act[KEYMAP_MODE_ORIG][(byte)ch];
-       }
+               int mode;
+               cptr act, s;
 
-       if (act)
-       {
-               /* Convert to a direction */
-               for (s = act; *s; ++s)
+               /* Roguelike */
+               if (rogue_like_commands)
                {
-                       /* Use any digits in keymap */
-                       if (isdigit(*s)) d = D2I(*s);
+                       mode = KEYMAP_MODE_ROGUE;
+               }
+
+               /* Original */
+               else
+               {
+                       mode = KEYMAP_MODE_ORIG;
+               }
+
+               /* Extract the action (if any) */
+               act = keymap_act[mode][(byte)(ch)];
+
+               /* Analyze */
+               if (act)
+               {
+                       /* Convert to a direction */
+                       for (s = act; *s; ++s)
+                       {
+                               /* Use any digits in keymap */
+                               if (isdigit(*s)) d = D2I(*s);
+                       }
                }
        }
-       return d;
+
+       /* Paranoia */
+       if (d == 5) d = 0;
+
+       /* Return direction */
+       return (d);
 }
 
 
@@ -4536,43 +4824,63 @@ void roff_to_buf(cptr str, int maxlen, char *tbuf)
        int write_pt = 0;
        int line_len = 0;
        int word_punct = 0;
-       unsigned char ch[3];
+       char ch[3];
        ch[2] = '\0';
 
        while (str[read_pt])
        {
 #ifdef JP
+               bool kinsoku = FALSE;
                bool kanji;
 #endif
+               int ch_len = 1;
+
+               /* Prepare one character */
                ch[0] = str[read_pt];
                ch[1] = '\0';
 #ifdef JP
                kanji  = iskanji(ch[0]);
+
                if (kanji)
+               {
                        ch[1] = str[read_pt+1];
-               if (!kanji && !isprint(ch[0]))
+                       ch_len = 2;
+
+                       if (strcmp(ch, "¡£") == 0 ||
+                           strcmp(ch, "¡¢") == 0 ||
+                           strcmp(ch, "¥£") == 0 ||
+                           strcmp(ch, "¡¼") == 0)
+                               kinsoku = TRUE;
+               }
+               else if (!isprint(ch[0]))
                        ch[0] = ' ';
 #else
                if (!isprint(ch[0]))
                        ch[0] = ' ';
 #endif
 
-               if (line_len >= maxlen || str[read_pt] == '\n')
+               if (line_len + ch_len > maxlen - 1 || str[read_pt] == '\n')
                {
                        int word_len;
 
                        /* return to better wrapping point. */
                        /* Space character at the end of the line need not to be printed. */
                        word_len = read_pt - word_punct;
-                       if (ch[0] != ' ' && word_len < line_len/2)
+#ifdef JP
+                       if (kanji && !kinsoku)
+                               /* nothing */ ;
+                       else
+#endif
+                       if (ch[0] == ' ' || word_len >= line_len/2)
+                               read_pt++;
+                       else
                        {
                                read_pt = word_punct;
                                if (str[word_punct] == ' ')
                                        read_pt++;
                                write_pt -= word_len;
                        }
-                       else
-                               read_pt++;
+
                        tbuf[write_pt++] = '\0';
                        line_len = 0;
                        word_punct = read_pt;
@@ -4581,10 +4889,7 @@ void roff_to_buf(cptr str, int maxlen, char *tbuf)
                if (ch[0] == ' ')
                        word_punct = read_pt;
 #ifdef JP
-               if (kanji &&
-                   strcmp(ch, "¡£") != 0 && strcmp(ch, "¡¢") != 0 &&
-                   strcmp(ch, "¥£") != 0 && strcmp(ch, "¡¼") != 0)
-                       word_punct = read_pt;
+               if (!kinsoku) word_punct = read_pt;
 #endif
                tbuf[write_pt++] = ch[0];
                line_len++;
@@ -4603,3 +4908,96 @@ void roff_to_buf(cptr str, int maxlen, char *tbuf)
 
        return;
 }
+
+
+/*
+ * The my_strcpy() function copies up to 'bufsize'-1 characters from 'src'
+ * to 'buf' and NUL-terminates the result.  The 'buf' and 'src' strings may
+ * not overlap.
+ *
+ * my_strcpy() returns strlen(src).  This makes checking for truncation
+ * easy.  Example: if (my_strcpy(buf, src, sizeof(buf)) >= sizeof(buf)) ...;
+ *
+ * This function should be equivalent to the strlcpy() function in BSD.
+ */
+size_t my_strcpy(char *buf, const char *src, size_t bufsize)
+{
+#ifdef JP
+
+       char *d = buf;
+       const char *s = src;
+       size_t len = 0;
+
+       /* reserve for NUL termination */
+       bufsize--;
+
+       /* Copy as many bytes as will fit */
+       while (len < bufsize)
+       {
+               if (iskanji(*s))
+               {
+                       if (len + 1 >= bufsize || !*(s+1)) break;
+                       *d++ = *s++;
+                       *d++ = *s++;
+                       len += 2;
+               }
+               else
+               {
+                       *d++ = *s++;
+                       len++;
+               }
+       }
+       *d = '\0';
+       while(*s++) len++;
+
+       return len;
+
+#else
+
+       size_t len = strlen(src);
+       size_t ret = len;
+
+       /* Paranoia */
+       if (bufsize == 0) return ret;
+
+       /* Truncate */
+       if (len >= bufsize) len = bufsize - 1;
+
+       /* Copy the string and terminate it */
+       (void)memcpy(buf, src, len);
+       buf[len] = '\0';
+
+       /* Return strlen(src) */
+       return ret;
+
+#endif
+}
+
+
+/*
+ * The my_strcat() tries to append a string to an existing NUL-terminated string.
+ * It never writes more characters into the buffer than indicated by 'bufsize' and
+ * NUL-terminates the buffer.  The 'buf' and 'src' strings may not overlap.
+ *
+ * my_strcat() returns strlen(buf) + strlen(src).  This makes checking for
+ * truncation easy.  Example:
+ * if (my_strcat(buf, src, sizeof(buf)) >= sizeof(buf)) ...;
+ *
+ * This function should be equivalent to the strlcat() function in BSD.
+ */
+size_t my_strcat(char *buf, const char *src, size_t bufsize)
+{
+       size_t dlen = strlen(buf);
+
+       /* Is there room left in the buffer? */
+       if (dlen < bufsize - 1)
+       {
+               /* Append as much as possible  */
+               return (dlen + my_strcpy(buf + dlen, src, bufsize - dlen));
+       }
+       else
+       {
+               /* Return without appending */
+               return (dlen + strlen(src));
+       }
+}