-/* File: util.c */
+/* File: util.c */
-/* Purpose: Angband utilities -BEN- */
+/*
+ * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
+ *
+ * This software may be copied and distributed for educational, research,
+ * and not for profit purposes provided that this copyright and statement
+ * are included in all such copies. Other copyrights may also apply.
+ */
+/* Purpose: Angband utilities -BEN- */
#include "angband.h"
-
-
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
-
+/* Save macro trigger string for use in inkey_special() */
+static char inkey_macro_trigger_string[1024];
#if 0
#ifndef HAS_STRICMP
#ifdef SET_UID
-# ifndef HAS_USLEEP
+# ifndef HAVE_USLEEP
/*
* For those systems that don't have "usleep()" but need it.
/* Paranoia -- No excessive sleeping */
-#ifdef JP
- if (usecs > 4000000L) core("ÉÔÅö¤Ê usleep() ¸Æ¤Ó½Ð¤·");
-#else
- if (usecs > 4000000L) core("Illegal usleep() call");
-#endif
-
-
+ if (usecs > 4000000L) core(_("不当な usleep() 呼び出し", "Illegal usleep() call"));
/* Wait for it */
Timer.tv_sec = (usecs / 1000000L);
/*
-* 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
/*
*/
void user_name(char *buf, int id)
{
-#ifdef SET_UID
struct passwd *pw;
/* Look up the user name */
return;
}
-#endif /* SET_UID */
/* Oops. Hack -- default to "PLAYER" */
strcpy(buf, "PLAYER");
/* File needs no parsing */
if (file[0] != '~')
{
- strcpy(buf, file);
+ (void)strnfmt(buf, max, "%s", file);
return (0);
}
u = file+1;
/* Look for non-user portion of the file */
- s = strstr(u, PATH_SEP);
+ s = my_strstr(u, PATH_SEP);
/* Hack -- no long user names */
if (s && (s >= u + sizeof(user))) return (1);
if (!pw) return (1);
/* Make use of the info */
- (void)strcpy(buf, pw->pw_dir);
-
- /* Append the rest of the filename, if any */
- if (s) (void)strcat(buf, s);
+ if (s) strnfmt(buf, max, "%s%s", pw->pw_dir, s);
+ else strnfmt(buf, max, "%s", pw->pw_dir);
/* Success */
return (0);
/* Accept the filename */
(void)strnfmt(buf, max, "%s", file);
+#if defined(MAC_MPW) && defined(CARBON)
+ /* Fix it according to the current operating system */
+ convert_pathname(buf);
+#endif /* MAC_MPW && CARBON */
+
/* Success */
return (0);
}
if (!s) return (-1);
/* Format to length */
+#if !defined(WIN32) || (defined(_MSC_VER) && (_MSC_VER >= 1900))
(void)strnfmt(buf, max, "%s", s);
+#else
+ (void)strnfmt(buf, max, ".%s", s);
+#endif
/* Success */
return (0);
{
char buf[1024];
-#if defined(MACINTOSH) && defined(MAC_MPW)
+#if defined(MAC_MPW) || defined(MACH_O_CARBON)
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'))
+#if defined(MAC_MPW) || defined(MACH_O_CARBON)
+ if (my_strchr(mode, 'w'))
{
/* setting file type/creator */
tempfff = fopen(buf, mode);
- fsetfileinfo(file, _fcreator, _ftype);
+ fsetfileinfo(buf, _fcreator, _ftype);
fclose(tempfff);
}
#endif
int fd;
/* Prepare the buffer for mkstemp */
- (void)strnfmt(buf, max, "%s", "/tmp/anXXXXXX");
+ strncpy(buf, "/tmp/anXXXXXX", max);
/* Secure creation of a temporary file */
fd = mkstemp(buf);
/* Read a line */
if (fgets(tmp, 1024, fff))
{
+#ifdef JP
+ guess_convert_to_system_encoding(tmp, sizeof(tmp));
+#endif
+
/* Convert weirdness */
for (s = tmp; *s; s++)
{
+#if defined(MACINTOSH) || defined(MACH_O_CARBON)
+
+ /*
+ * Be nice to the Macintosh, where a file can have Mac or Unix
+ * end of line, especially since the introduction of OS X.
+ * MPW tools were also very tolerant to the Unix EOL.
+ */
+ if (*s == '\r') *s = '\n';
+
+#endif /* MACINTOSH || MACH_O_CARBON */
+
/* Handle newline */
if (*s == '\n')
{
buf[i++] = ' ';
/* Append some more spaces */
- while (!(i % 8)) buf[i++] = ' ';
+ while (0 != (i % 8)) buf[i++] = ' ';
}
#ifdef JP
buf[i++] = *s++;
buf[i++] = *s;
}
-# ifndef EUC
- /* Ⱦ³Ñ¤«¤Ê¤ËÂбþ */
- else if ((((int)*s & 0xff) > 0xa1) && (((int)*s & 0xff ) < 0xdf))
+
+ /* 半角かなに対応 */
+ else if (iskana(*s))
{
buf[i++] = *s;
if (i >= n) break;
}
-# endif
#endif
/* Handle printables */
- else if (isprint(*s))
+ else if (isprint((unsigned char)*s))
{
/* Copy */
buf[i++] = *s;
/* Copy */
while ((read_num = read(src_fd, buf, 1024)) > 0)
{
- write(dst_fd, buf, read_num);
+ int write_num = 0;
+ while (write_num < read_num)
+ {
+ int ret = write(dst_fd, buf + write_num, read_num - write_num);
+ if (ret < 0) {
+ /* Close files */
+ fd_close(src_fd);
+ fd_close(dst_fd);
+
+ return ret;
+ }
+ write_num += ret;
+ }
}
/* Close files */
#else /* BEN_HACK */
-# if defined(MACINTOSH) && defined(MAC_MPW)
-
- /* setting file type and creator -- AR */
- errr_tmp = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
- fsetfileinfo(file, _fcreator, _ftype);
- return(errr_tmp);
-
+#if defined(MAC_MPW) || defined(MACH_O_CARBON)
+ {
+ int fdes;
+ /* Create the file, fail if exists, write-only, binary */
+ fdes = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
+ /* Set creator and type if the file is successfully opened */
+ if (fdes >= 0) fsetfileinfo(buf, _fcreator, _ftype);
+ /* Return the descriptor */
+ return (fdes);
+ }
# else
/* Create the file, fail if exists, write-only, binary */
return (open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode));
p = lseek(fd, n, SEEK_SET);
/* Failure */
- if (p < 0) return (1);
-
- /* Failure */
if (p != n) return (1);
/* Success */
/* Verify the fd */
if (fd < 0) return (-1);
-#if defined(SUNOS) || defined(ULTRIX) || defined(NeXT)
+#if defined(ULTRIX) || defined(NeXT)
/* Truncate */
ftruncate(fd, n);
#endif
/* Invalid trigger name? */
if (i == max_macrotrigger)
{
- str = strchr(str, ']');
+ str = my_strchr(str, ']');
if (str)
{
*s++ = (char)31;
/* Skip the backslash */
str++;
- /* Macro Trigger */
+ /* Paranoia */
+ if (!(*str)) break;
+
+ /* Macro Trigger */
if (*str == '[')
{
trigger_text_to_ascii(&s, &str);
}
-bool trigger_ascii_to_text(char **bufptr, cptr *strptr)
+static bool trigger_ascii_to_text(char **bufptr, cptr *strptr)
{
char *s = *bufptr;
cptr str = *strptr;
switch(ch)
{
case '&':
- while ((tmp = strchr(macro_modifier_chr, *str)))
+ while ((tmp = my_strchr(macro_modifier_chr, *str)))
{
j = (int)(tmp - macro_modifier_chr);
tmp = macro_modifier_name[j];
/*
- * 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.
void flush(void)
{
/* Do it later */
- inkey_xtra = TRUE;
+ inkey_xtra = TRUE;
}
Term_xtra(TERM_XTRA_SOUND, val);
}
+/*
+ * Hack -- Play a music
+ */
+errr play_music(int type, int val)
+{
+ /* No sound */
+ if (!use_music) return 1;
+
+ /* Make a sound (if allowed) */
+ return Term_xtra(type, val);
+}
+
+/*
+ * Hack -- Select floor music.
+ */
+void select_floor_music()
+{
+ int i;
+ /* No sound */
+ if (!use_music) return;
+
+ if(ambush_flag)
+ {
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_AMBUSH);
+ return;
+ }
+
+ if(p_ptr->wild_mode)
+ {
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_WILD);
+ return;
+ }
+
+ if(p_ptr->inside_arena)
+ {
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_ARENA);
+ return;
+ }
+
+ if(p_ptr->inside_battle)
+ {
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BATTLE);
+ return;
+ }
+
+ if(p_ptr->inside_quest)
+ {
+ if(play_music(TERM_XTRA_MUSIC_QUEST, p_ptr->inside_quest))
+ {
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_QUEST);
+ }
+ return;
+ }
+
+ for(i = 0; i < max_quests; i++)
+ { // TODO マクロで類似条件を統合すること
+ if(quest[i].status == QUEST_STATUS_TAKEN &&
+ (quest[i].type == QUEST_TYPE_KILL_LEVEL || quest[i].type == QUEST_TYPE_RANDOM) &&
+ quest[i].level == dun_level && dungeon_type == quest[i].dungeon)
+ {
+ if(play_music(TERM_XTRA_MUSIC_QUEST, i))
+ {
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_QUEST);
+ }
+ return;
+ }
+ }
+
+ if(dungeon_type)
+ {
+ if(p_ptr->feeling == 2) play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_DUN_FEEL2);
+ else if(p_ptr->feeling >= 3 && p_ptr->feeling <= 5) play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_DUN_FEEL1);
+ else
+ {
+ if(play_music(TERM_XTRA_MUSIC_DUNGEON, dungeon_type))
+ {
+ if(dun_level < 40) play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_DUN_LOW);
+ else if(dun_level < 80) play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_DUN_MED);
+ else play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_DUN_HIGH);
+ }
+ }
+ return;
+ }
+
+ if(p_ptr->town_num)
+ {
+ if(play_music(TERM_XTRA_MUSIC_TOWN, p_ptr->town_num))
+ {
+ play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_TOWN);
+ }
+ return;
+ }
+
+ if(!dun_level)
+ {
+ if(p_ptr->lev >= 45) play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_FIELD3);
+ else if(p_ptr->lev >= 25) play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_FIELD2);
+ else play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_FIELD1);
+ return;
+ }
+
+}
+
/*
cptr pat, act;
- char buf[1024];
+ char *buf = inkey_macro_trigger_string;
- /* 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" */
/* Inside "macro trigger" */
if (parse_under) return (ch);
-
/* Save the first key, advance */
buf[p++] = ch;
buf[p] = '\0';
else
{
/* Increase "wait" */
- w += 10;
+ w += 1;
/* Excessive delay */
- if (w >= 100) break;
+ if (w >= 10) break;
/* Delay */
Term_xtra(TERM_XTRA_DELAY, w);
/*
+ * Cancel macro action on the queue
+ */
+static void forget_macro_action(void)
+{
+ if (!parse_macro) return;
+
+ /* Drop following macro action string */
+ while (TRUE)
+ {
+ char ch;
+
+ /* End loop if no key ready */
+ if (Term_inkey(&ch, FALSE, TRUE)) break;
+
+ /* End loop if no key ready */
+ if (ch == 0) break;
+
+ /* End of "macro action" */
+ if (ch == 30) break;
+ }
+
+ /* No longer inside "macro action" */
+ parse_macro = FALSE;
+}
+
+
+/*
* Mega-Hack -- special "inkey_next" pointer. XXX XXX XXX
*
* This special pointer allows a sequence of keys to be "inserted" into
*/
/*
+ * Initialize the quark array
+ */
+void quark_init(void)
+{
+ /* Quark variables */
+ C_MAKE(quark__str, QUARK_MAX, cptr);
+
+ /* Prepare first quark, which is used when quark_add() is failed */
+ quark__str[1] = string_make("");
+
+ /* There is one quark (+ NULL) */
+ quark__num = 2;
+}
+
+
+/*
* Add a new "quark" to the set of quarks.
*/
s16b quark_add(cptr str)
if (streq(quark__str[i], str)) return (i);
}
- /* Paranoia -- Require room */
- if (quark__num == QUARK_MAX) return (0);
+ /* Return "" when no room is available */
+ if (quark__num == QUARK_MAX) return 1;
/* New maximal quark */
quark__num = i + 1;
{
cptr q;
- /* Verify */
- if ((i < 0) || (i >= quark__num)) i = 0;
+ /* Return NULL for an invalid index */
+ if ((i < 1) || (i >= quark__num)) return NULL;
/* Access the quark */
q = quark__str[i];
-/*
- * How many messages are "available"?
+/*!
+ * @brief 保存中の過去ゲームメッセージの数を返す。 / How many messages are "available"?
+ * @return 残っているメッセージの数
*/
s16b message_num(void)
{
}
-
-/*
- * Recall the "text" of a saved message
+/*!
+ * @brief 過去のゲームメッセージを返す。 / Recall the "text" of a saved message
+ * @params age メッセージの世代
+ * @return メッセージの文字列ポインタ
*/
cptr message_str(int age)
{
- s16b x;
- s16b o;
+ s32b x;
+ s32b o;
cptr s;
/* Forgotten messages have no text */
}
-
-/*
- * Add a new message, with great efficiency
+/*!
+ * @brief ゲームメッセージをログに追加する。 / Add a new message, with great efficiency
+ * @params str 保存したいメッセージ
+ * @return なし
*/
void message_add(cptr str)
{
int i, k, x, m, n;
- char u[1024];
+ char u[4096];
char splitted1[81];
cptr splitted2;
/* Important Hack -- Ignore "long" messages */
if (n >= MESSAGE_BUF / 4) return;
- /* extra step -- split the message if n>80. (added by Mogami) */
+ /* extra step -- split the message if n>80.(added by Mogami) */
if (n > 80) {
#ifdef JP
- cptr t = str;
-
- for (n = 0; n < 80; n++, t++)
- if(iskanji(*t)) {
- t++;
- n++;
- }
- if (n == 81) n = 79; /* ºÇ¸å¤Îʸ»ú¤¬´Á»úȾʬ */
+ cptr t = str;
+
+ for (n = 0; n < 80; n++, t++)
+ {
+ if(iskanji(*t)) {
+ t++;
+ n++;
+ }
+ }
+ if (n == 81) n = 79; /* 最後の文字が漢字半分 */
#else
- for (n = 80; n > 60; n--)
- if (str[n] == ' ') break;
- if (n == 60)
- n = 80;
+ for (n = 80; n > 60; n--)
+ if (str[n] == ' ') break;
+ if (n == 60) n = 80;
#endif
- splitted2 = str + n;
- strncpy(splitted1, str ,n);
- splitted1[n] = '\0';
- str = splitted1;
+ splitted2 = str + n;
+ strncpy(splitted1, str ,n);
+ splitted1[n] = '\0';
+ str = splitted1;
} else {
- splitted2 = NULL;
+ splitted2 = NULL;
}
- /*** Step 2 -- Attempt to optimize ***/
+ /*** Step 2 -- 最適化の試行 / Attempt to optimize ***/
/* Limit number of messages to check */
m = message_num();
-
k = m / 4;
-
- /* Limit number of messages to check */
if (k > MESSAGE_MAX / 32) k = MESSAGE_MAX / 32;
/* Check previous message */
/* Find multiple */
#ifdef JP
- for (t = buf; *t && (*t != '<' || (*(t+1) != 'x' )); t++)
- if( iskanji(*t))t++;
+ 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)
}
/* Limit the multiplier to 1000 */
- if (buf && streq(buf, str) && (j < 1000))
+ if (streq(buf, str) && (j < 1000))
{
j++;
}
else
{
- num_more++;/*ή¤ì¤¿¹Ô¤Î¿ô¤ò¿ô¤¨¤Æ¤ª¤¯ */
+ num_more++;/*流れた行の数を数えておく */
now_message++;
}
/* Check the last few messages (if any to count) */
for (i = message__next; k; k--)
{
- u16b q;
-
+ int q;
cptr old;
/* Back up and wrap if needed */
message__head += n + 1;
/* recursively add splitted message (added by Mogami) */
- end_of_message_add:
+end_of_message_add:
if (splitted2 != NULL)
message_add(splitted2);
}
}
now_damaged = FALSE;
- if (!alive || !nagasu)
+ if (!p_ptr->playing || !nagasu)
{
/* Pause for response */
-#ifdef JP
- Term_putstr(x, 0, -1, a, "-³¤¯-");
-#else
- Term_putstr(x, 0, -1, a, "-more-");
-#endif
-
+ Term_putstr(x, 0, -1, a, _("-続く-", "-more-"));
/* Get an acceptable keypress */
while (1)
{
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; /*1画面だけ流す。 */
break;
} else if ((cmd == '\n') || (cmd == '\r')) {
- num_more--; /*£±¹Ô¤À¤±Î®¤¹¡£ */
+ num_more--; /*1行だけ流す。 */
break;
}
if (quick_messages) break;
void msg_print(cptr msg)
{
static int p = 0;
-
int n;
-
char *t;
-
char buf[1024];
if (world_monster) return;
p = 0;
}
-
/* No message */
if (!msg) return;
t += split; n -= split;
}
-
/* Display the tail of the message */
Term_putstr(p, 0, n, TERM_WHITE, t);
p += n + 1;
#endif
-
/* Optional refresh */
if (fresh_message) Term_fresh();
}
+void msg_print_wizard(int cheat_type, cptr msg)
+{
+ if (!cheat_room && cheat_type == CHEAT_DUNGEON) return;
+ if (!cheat_peek && cheat_type == CHEAT_OBJECT) return;
+ if (!cheat_hear && cheat_type == CHEAT_MONSTER) return;
+ if (!cheat_xtra && cheat_type == CHEAT_MISC) return;
+
+ cptr cheat_mes[] = {"ITEM", "MONS", "DUNG", "MISC"};
+ char buf[1024];
+ sprintf(buf, "WIZ-%s:%s", cheat_mes[cheat_type], msg);
+ msg_print(buf);
+}
/*
* Hack -- prevent "accidents" in "screen_save()" or "screen_load()"
msg_print(buf);
}
+/*
+ * Display a formatted message, using "vstrnfmt()" and "msg_print()".
+ */
+void msg_format_wizard(int cheat_type, cptr fmt, ...)
+{
+ if(!cheat_room && cheat_type == CHEAT_DUNGEON) return;
+ if(!cheat_peek && cheat_type == CHEAT_OBJECT) return;
+ if(!cheat_hear && cheat_type == CHEAT_MONSTER) return;
+ if(!cheat_xtra && cheat_type == CHEAT_MISC) return;
+
+ va_list vp;
+ char buf[1024];
+
+ /* Begin the Varargs Stuff */
+ va_start(vp, fmt);
+
+ /* Format the args, save the length */
+ (void)vstrnfmt(buf, 1024, fmt, vp);
+
+ /* End the Varargs Stuff */
+ va_end(vp);
+
+ /* Display */
+ msg_print_wizard(cheat_type, buf);
+}
+
/*
/* Clear line, move cursor */
Term_erase(x, y, 255);
+
+ break;
}
/* Clean up the char */
#ifdef JP
- ch = ((isprint(*s) || k_flag) ? *s : ' ');
+ ch = ((k_flag || isprint(*s)) ? *s : ' ');
#else
ch = (isprint(*s) ? *s : ' ');
#endif
if (x < w)
#ifdef JP
{
- /* ¸½ºß¤¬È¾³Ñʸ»ú¤Î¾ì¹ç */
+ /* 現在が半角文字の場合 */
if( !k_flag )
#endif
{
#ifdef JP
else
{
- /* ¸½ºß¤¬Á´³Ñʸ»ú¤Î¤È¤ */
- /* ʸƬ¤¬¡Ö¡£¡×¡Ö¡¢¡×Åù¤Ë¤Ê¤ë¤È¤¤Ï¡¢¤½¤Î£±¤ÄÁ°¤Î¸ì¤Ç²þ¹Ô */
- if (strncmp(s, "¡£", 2) == 0 || strncmp(s, "¡¢", 2) == 0
-#if 0 /* °ìÈÌŪ¤Ë¤Ï¡Ö¥£¡×¡Ö¡¼¡×¤Ï¶Ø§¤ÎÂоݳ° */
- || strncmp(s, "¥£", 2) == 0 || strncmp(s, "¡¼", 2) == 0
+ /* 現在が全角文字のとき */
+ /* 文頭が「。」「、」等になるときは、その1つ前の語で改行 */
+ if (strncmp(s, "。", 2) == 0 || strncmp(s, "、", 2) == 0
+#if 0 /* 一般的には「ィ」「ー」は禁則の対象外 */
+ || strncmp(s, "ã\82£", 2) == 0 || strncmp(s, "ã\83¼", 2) == 0
#endif
){
Term_what(x , y, &av[x ], &cv[x ]);
/* Dump */
#ifdef JP
- Term_addch((byte)(a|0x10), ch);
+ Term_addch((byte)(a|0x10), ch);
#else
Term_addch(a, ch);
#endif
/*
- * Get some input at the cursor location.
+ * Get some string input at the cursor location.
* Assume the buffer is initialized to a default string.
- * Note that this string is often "empty" (see below).
- * The default buffer is displayed in yellow until cleared.
- * Pressing RETURN right away accepts the default entry.
- * Normal chars clear the default and append the char.
- * Backspace clears the default or deletes the final char.
+ *
+ * The default buffer is in Overwrite mode and displayed in yellow at
+ * first. Normal chars clear the yellow text and append the char in
+ * white text.
+ *
+ * LEFT (^B) and RIGHT (^F) movement keys move the cursor position.
+ * If the text is still displayed in yellow (Overwite mode), it will
+ * turns into white (Insert mode) when cursor moves.
+ *
+ * DELETE (^D) deletes a char at the cursor position.
+ * BACKSPACE (^H) deletes a char at the left of cursor position.
* ESCAPE clears the buffer and the window and returns FALSE.
* RETURN accepts the current buffer contents and returns TRUE.
*/
-bool askfor_aux(char *buf, int len)
+bool askfor_aux(char *buf, int len, bool numpad_cursor)
{
int y, x;
+ int pos = 0;
- int i = 0;
-
- int k = 0;
-
- bool done = FALSE;
-
+ /*
+ * Text color
+ * TERM_YELLOW : Overwrite mode
+ * TERM_WHITE : Insert mode
+ */
+ byte color = TERM_YELLOW;
-#ifdef JP
- int k_flag[128];
-#endif
- /* Locate the cursor */
+ /* Locate the cursor position */
Term_locate(&x, &y);
-
/* Paranoia -- check len */
if (len < 1) len = 1;
/* Restrict the length */
if (x + len > 80) len = 80 - x;
-
/* Paranoia -- Clip the default entry */
buf[len] = '\0';
- /* Display the default answer */
- Term_erase(x, y, len);
- Term_putstr(x, y, -1, TERM_YELLOW, buf);
-
-
/* Process input */
- while (!done)
+ while (TRUE)
{
+ int skey;
+
+ /* Display the string */
+ Term_erase(x, y, len);
+ Term_putstr(x, y, -1, color, buf);
+
/* Place cursor */
- Term_gotoxy(x + k, y);
+ Term_gotoxy(x + pos, y);
- /* Get a key */
- i = inkey();
+ /* Get a special key code */
+ skey = inkey_special(numpad_cursor);
/* Analyze the key */
- switch (i)
+ switch (skey)
{
- case ESCAPE:
- k = 0;
- done = TRUE;
- break;
+ case SKEY_LEFT:
+ case KTRL('b'):
+ {
+ int i = 0;
- case '\n':
- case '\r':
- k = strlen(buf);
- done = TRUE;
- break;
+ /* Now on insert mode */
+ color = TERM_WHITE;
+
+ /* No move at beginning of line */
+ if (0 == pos) break;
+
+ while (TRUE)
+ {
+ int next_pos = i + 1;
- case 0x7F:
- case '\010':
#ifdef JP
- if (k > 0)
- {
- k--;
- if (k_flag[k] != 0)
- k--;
- }
-#else
- if (k > 0) k--;
+ if (iskanji(buf[i])) next_pos++;
#endif
+ /* Is there the cursor at next position? */
+ if (next_pos >= pos) break;
+
+ /* Move to next */
+ i = next_pos;
+ }
+
+ /* Get previous position */
+ pos = i;
+
break;
+ }
+
+ case SKEY_RIGHT:
+ case KTRL('f'):
+ /* Now on insert mode */
+ color = TERM_WHITE;
+
+ /* No move at end of line */
+ if ('\0' == buf[pos]) break;
- 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 {
-#ifdef SJIS
- if(k<len && (isprint(i) || (0xa0<=i && i<=0xdf))){
+ /* Move right */
+ if (iskanji(buf[pos])) pos += 2;
+ else pos++;
#else
- if(k<len && isprint(i)){
+ pos++;
#endif
- buf[k] = i;
- k_flag[k++] = 0;
- } else
- bell();
- }
- }
-#else
- if ((k < len) && (isprint(i)))
- {
- buf[k++] = i;
- }
- else
+
+ break;
+
+ case ESCAPE:
+ /* Cancel input */
+ buf[0] = '\0';
+ return FALSE;
+
+ case '\n':
+ case '\r':
+ /* Success */
+ return TRUE;
+
+ case '\010':
+ /* Backspace */
+ {
+ int i = 0;
+
+ /* Now on insert mode */
+ color = TERM_WHITE;
+
+ /* No move at beginning of line */
+ if (0 == pos) break;
+
+ while (TRUE)
{
- bell();
+ int next_pos = i + 1;
+
+#ifdef JP
+ if (iskanji(buf[i])) next_pos++;
+#endif
+
+ /* Is there the cursor at next position? */
+ if (next_pos >= pos) break;
+
+ /* Move to next */
+ i = next_pos;
}
+
+ /* Get previous position */
+ pos = i;
+
+ /* Fall through to 'Delete key' */
+ }
+
+ case 0x7F:
+ case KTRL('d'):
+ /* Delete key */
+ {
+ int dst, src;
+
+ /* Now on insert mode */
+ color = TERM_WHITE;
+
+ /* No move at end of line */
+ if ('\0' == buf[pos]) break;
+
+ /* Position of next character */
+ src = pos + 1;
+
+#ifdef JP
+ /* Next character is one more byte away */
+ if (iskanji(buf[pos])) src++;
#endif
+ dst = pos;
+
+ /* Move characters at src to dst */
+ while ('\0' != (buf[dst++] = buf[src++]))
+ /* loop */;
+
break;
}
- /* Terminate */
- buf[k] = '\0';
+ default:
+ {
+ /* Insert a character */
- /* Update the entry */
- Term_erase(x, y, len);
- Term_putstr(x, y, -1, TERM_WHITE, buf);
- }
+ char tmp[100];
+ char c;
- /* Aborted */
- if (i == ESCAPE) return (FALSE);
+ /* Ignore special keys */
+ if (skey & SKEY_MASK) break;
- /* Success */
- return (TRUE);
+ /* Get a character code */
+ c = (char)skey;
+
+ if (color == TERM_YELLOW)
+ {
+ /* Overwrite default string */
+ buf[0] = '\0';
+
+ /* Go to insert mode */
+ color = TERM_WHITE;
+ }
+
+ /* Save right part of string */
+ strcpy(tmp, buf + pos);
+#ifdef JP
+ if (iskanji(c))
+ {
+ char next;
+
+ /* Bypass macro processing */
+ inkey_base = TRUE;
+ next = inkey();
+
+ if (pos + 1 < len)
+ {
+ buf[pos++] = c;
+ buf[pos++] = next;
+ }
+ else
+ {
+ bell();
+ }
+ }
+ else
+#endif
+ {
+#ifdef JP
+ if (pos < len && (isprint(c) || iskana(c)))
+#else
+ if (pos < len && isprint(c))
+#endif
+ {
+ buf[pos++] = c;
+ }
+ else
+ {
+ bell();
+ }
+ }
+
+ /* Terminate */
+ buf[pos] = '\0';
+
+ /* Write back the left part of string */
+ my_strcat(buf, tmp, len + 1);
+
+ break;
+ } /* default: */
+
+ }
+
+ } /* while (TRUE) */
+}
+
+
+/*
+ * Get some string input at the cursor location.
+ *
+ * Allow to use numpad keys as cursor keys.
+ */
+bool askfor(char *buf, int len)
+{
+ return askfor_aux(buf, len, TRUE);
}
prt(prompt, 0, 0);
/* Ask the user for a string */
- res = askfor_aux(buf, len);
+ res = askfor(buf, len);
/* Clear prompt */
prt("", 0, 0);
/*
* Verify something with the user strictly
*
- * mode & 0x01 : force user to answer "YES" or "N"
- * mode & 0x02 : don't allow ESCAPE key
+ * 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
+ * mode & CHECK_DEFAULT_Y : accept any key as y, except n and Esc.
*/
-#define CHECK_STRICT 0
bool get_check_strict(cptr prompt, int mode)
{
int i;
char buf[80];
+ bool flag = FALSE;
if (auto_more)
{
msg_print(NULL);
if (!rogue_like_commands)
- mode &= ~1;
+ mode &= ~CHECK_OKAY_CANCEL;
/* Hack -- Build a "useful" prompt */
- if (mode & 1)
+ if (mode & CHECK_OKAY_CANCEL)
{
-#if CHECK_STRICT
-#ifdef JP
- /* (79-8)¥Ð¥¤¥È¤Î»ØÄê, prompt¤¬Ä¹¤«¤Ã¤¿¾ì¹ç,
- (79-9)ʸ»ú¤Î¸å½ªÃ¼Ê¸»ú¤¬½ñ¤¹þ¤Þ¤ì¤ë.
- ±Ñ¸ì¤ÎÊý¤Îstrncpy¤È¤Ï°ã¤¦¤Î¤ÇÃí°Õ.
- else¤ÎÊý¤Îʬ´ô¤âƱÍÍ. --henkma
- */
- mb_strlcpy(buf, prompt, 80-8);
-#else
- strncpy(buf, prompt, 79-8);
- buf[79-8]='\0';
-#endif
- strcat(buf, "[yes/no]");
-#else
-#ifdef JP
- /* (79-8)¥Ð¥¤¥È¤Î»ØÄê, prompt¤¬Ä¹¤«¤Ã¤¿¾ì¹ç,
- (79-9)ʸ»ú¤Î¸å½ªÃ¼Ê¸»ú¤¬½ñ¤¹þ¤Þ¤ì¤ë.
- ±Ñ¸ì¤ÎÊý¤Îstrncpy¤È¤Ï°ã¤¦¤Î¤ÇÃí°Õ.
- else¤ÎÊý¤Îʬ´ô¤âƱÍÍ. --henkma
- */
- mb_strlcpy(buf, prompt, 80-15);
-#else
- strncpy(buf, prompt, 79-15);
- buf[79-8]='\0';
-#endif
+ my_strcpy(buf, prompt, sizeof(buf)-15);
strcat(buf, "[(O)k/(C)ancel]");
-
-#endif
+ }
+ else if (mode & CHECK_DEFAULT_Y)
+ {
+ my_strcpy(buf, prompt, sizeof(buf)-5);
+ strcat(buf, "[Y/n]");
}
else
{
-#ifdef JP
- mb_strlcpy(buf, prompt, 80-5);
-#else
- strncpy(buf, prompt, 79-5);
- buf[79-5]='\0';
-#endif
+ 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 CHECK_STRICT /* ¤³¤³¤«¤é(¤Á¤ç¤Ã¤ÈŤ¤¤Î¤Ç¥³¥á¥ó¥È) */
- if (i == 'y' || i == 'Y')
+
+ if (!(mode & CHECK_NO_ESCAPE))
{
- if (!(mode & 1))
- break;
- else
+ if (i == ESCAPE)
{
-#ifdef JP
- prt("y (YES¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤)", 0, strlen(buf));
-#else
- prt("y (Please answer YES.)", 0, strlen(buf));
-#endif
- i = inkey();
- if (i == 'e' || i == 'E')
- {
-#ifdef JP
- prt("e (YES¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤)", 0, strlen(buf)+1);
-#else
- prt("e (Please answer YES.)", 0, strlen(buf)+1);
-#endif
- i = inkey();
- if (i == 's' || i == 'S')
- {
- i = 'y';
- break;
- }
- prt("", 0, strlen(buf)+1);
- }
- prt("", 0, strlen(buf));
+ flag = FALSE;
+ break;
}
}
- if (!(mode & 2) && (i == ESCAPE)) break;
- if (i == 'N' || i == 'n')
+
+ if (mode & CHECK_OKAY_CANCEL)
{
- if (!(mode & 1))
- break;
- else
+ if (i == 'o' || i == 'O')
{
-#ifdef JP
- prt("n (NO¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤)", 0, strlen(buf));
-#else
- prt("n (Please answer NO.)", 0, strlen(buf));
-#endif
- i = inkey();
- if (i == 'o' || i == 'O')
- {
- break;
- }
- prt("", 0, strlen(buf));
+ flag = TRUE;
+ break;
}
- }
-#else
- if ( mode & 1 )
- {
- if ( i == 'o' || i == 'O' )
+ else if (i == 'c' || i == 'C')
{
- i = 'Y';
+ flag = FALSE;
break;
}
}
- else if (i == 'y' || i == 'Y')
+ else
{
+ if (i == 'y' || i == 'Y')
+ {
+ flag = TRUE;
break;
- }
- if (!(mode & 2) && (i == ESCAPE)) break;
- if ( mode & 1 )
- {
- if ( i == 'c' || i == 'C' )
+ }
+ else if (i == 'n' || i == 'N')
{
+ flag = FALSE;
break;
}
}
- else if (i == 'n' || i == 'N')
+
+ if (mode & CHECK_DEFAULT_Y)
{
- break;
+ flag = TRUE;
+ break;
}
-#endif /* ¤³¤³¤Þ¤Ç(¤Á¤ç¤Ã¤ÈŤ¤¤Î¤Ç¥³¥á¥ó¥È) */
+
bell();
}
/* Erase the prompt */
prt("", 0, 0);
- /* Normal negation */
- if ((i != 'Y') && (i != 'y')) return (FALSE);
-
- /* Success */
- return (TRUE);
+ /* Return the flag */
+ return flag;
}
prt(prompt, 0, 0);
/* Get a key */
- *command = inkey();
+ if (get_com_no_macros)
+ *command = inkey_special(FALSE);
+ else
+ *command = inkey();
/* Clear the prompt */
prt("", 0, 0);
*/
s16b get_quantity(cptr prompt, int max)
{
+ bool res;
int amt;
-
char tmp[80];
-
char buf[80];
if (!prompt)
{
/* Build a prompt */
-#ifdef JP
- sprintf(tmp, "¤¤¤¯¤Ä¤Ç¤¹¤« (1-%d): ", max);
-#else
- sprintf(tmp, "Quantity (1-%d): ", max);
-#endif
-
+ sprintf(tmp, _("いくつですか (1-%d): ", "Quantity (1-%d): "), max);
/* Use that prompt */
prompt = tmp;
}
+ /* Paranoia XXX XXX XXX */
+ msg_print(NULL);
+
+ /* Display prompt */
+ prt(prompt, 0, 0);
/* Default to one */
amt = 1;
/* Build the default */
sprintf(buf, "%d", amt);
- /* Ask for a quantity */
- if (!get_string(prompt, buf, 6)) return (0);
+ /*
+ * Ask for a quantity
+ * Don't allow to use numpad as cursor key.
+ */
+ res = askfor_aux(buf, 6, FALSE);
+
+ /* Clear prompt */
+ prt("", 0, 0);
+
+ /* Cancelled */
+ if (!res) return 0;
/* Extract a number */
amt = atoi(buf);
*/
void pause_line(int row)
{
- int i;
prt("", row, 0);
-#ifdef JP
- put_str("[ ²¿¤«¥¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤ ]", row, 26);
-#else
- put_str("[Press any key to continue]", row, 23);
-#endif
+ put_str(_("[ 何かキーを押して下さい ]", "[Press any key to continue]"), row, _(26, 23));
- i = inkey();
+ (void)inkey();
prt("", row, 0);
}
menu_naiyou menu_info[10][10] =
{
{
- {"ËâË¡/ÆüìǽÎÏ", 1, FALSE},
- {"¹ÔÆ°", 2, FALSE},
- {"Æ»¶ñ(»ÈÍÑ)", 3, FALSE},
- {"Æ»¶ñ(¤½¤Î¾)", 4, FALSE},
- {"ÁõÈ÷", 5, FALSE},
- {"Èâ/È¢", 6, FALSE},
- {"¾ðÊó", 7, FALSE},
- {"ÀßÄê", 8, FALSE},
- {"¤½¤Î¾", 9, FALSE},
+ {"魔法/特殊能力", 1, FALSE},
+ {"行動", 2, FALSE},
+ {"道具(使用)", 3, FALSE},
+ {"道具(その他)", 4, FALSE},
+ {"装備", 5, FALSE},
+ {"扉/箱", 6, FALSE},
+ {"情報", 7, FALSE},
+ {"設定", 8, FALSE},
+ {"その他", 9, FALSE},
{"", 0, FALSE},
},
{
- {"»È¤¦(m)", 'm', TRUE},
- {"Ä´¤Ù¤ë(b/P)", 'b', TRUE},
- {"³Ð¤¨¤ë(G)", 'G', TRUE},
- {"ÆüìǽÎϤò»È¤¦(U/O)", 'U', TRUE},
+ {"使う(m)", 'm', TRUE},
+ {"調べる(b/P)", 'b', TRUE},
+ {"覚える(G)", 'G', TRUE},
+ {"特殊能力を使う(U/O)", 'U', TRUE},
{"", 0, FALSE},
{"", 0, FALSE},
{"", 0, FALSE},
},
{
- {"µÙ©¤¹¤ë(R)", 'R', TRUE},
- {"¥È¥é¥Ã¥×²ò½ü(D)", 'D', TRUE},
- {"õ¤¹(s)", 's', TRUE},
- {"¼þ¤ê¤òÄ´¤Ù¤ë(l/x)", 'l', TRUE},
- {"¥¿¡¼¥²¥Ã¥È»ØÄê(*)", '*', TRUE},
- {"·ê¤ò·¡¤ë(T/^t)", 'T', TRUE},
- {"³¬Ãʤò¾å¤ë(<)", '<', TRUE},
- {"³¬Ãʤò²¼¤ê¤ë(>)", '>', TRUE},
- {"¥Ú¥Ã¥È¤ËÌ¿Î᤹¤ë(p)", 'p', TRUE},
- {"õº÷¥â¡¼¥É¤ÎON/OFF(S/#)", 'S', TRUE}
+ {"休息する(R)", 'R', TRUE},
+ {"トラップ解除(D)", 'D', TRUE},
+ {"探す(s)", 's', TRUE},
+ {"周りを調べる(l/x)", 'l', TRUE},
+ {"ターゲット指定(*)", '*', TRUE},
+ {"穴を掘る(T/^t)", 'T', TRUE},
+ {"階段を上る(<)", '<', TRUE},
+ {"階段を下りる(>)", '>', TRUE},
+ {"ペットに命令する(p)", 'p', TRUE},
+ {"探索モードのON/OFF(S/#)", 'S', TRUE}
},
{
- {"Æɤà(r)", 'r', TRUE},
- {"°û¤à(q)", 'q', TRUE},
- {"¾ó¤ò»È¤¦(u/Z)", 'u', TRUE},
- {"ËâË¡ËÀ¤ÇÁÀ¤¦(a/z)", 'a', TRUE},
- {"¥í¥Ã¥É¤ò¿¶¤ë(z/a)", 'z', TRUE},
- {"»ÏÆ°¤¹¤ë(A)", 'A', TRUE},
- {"¿©¤Ù¤ë(E)", 'E', TRUE},
- {"Èô¤ÓÆ»¶ñ¤Ç·â¤Ä(f/t)", 'f', TRUE},
- {"Åꤲ¤ë(v)", 'v', TRUE},
+ {"読む(r)", 'r', TRUE},
+ {"飲む(q)", 'q', TRUE},
+ {"杖を使う(u/Z)", 'u', TRUE},
+ {"魔法棒で狙う(a/z)", 'a', TRUE},
+ {"ロッドを振る(z/a)", 'z', TRUE},
+ {"始動する(A)", 'A', TRUE},
+ {"食べる(E)", 'E', TRUE},
+ {"飛び道具で撃つ(f/t)", 'f', TRUE},
+ {"投げる(v)", 'v', TRUE},
{"", 0, FALSE}
},
{
- {"½¦¤¦(g)", 'g', TRUE},
- {"Íî¤È¤¹(d)", 'd', TRUE},
- {"²õ¤¹(k/^d)", 'k', TRUE},
- {"Ìäò¹ï¤à({)", '{', TRUE},
- {"Ìäò¾Ã¤¹(})", '}', TRUE},
- {"Ä´ºº(I)", 'I', TRUE},
- {"¥¢¥¤¥Æ¥à°ìÍ÷(i)", 'i', TRUE},
+ {"拾う(g)", 'g', TRUE},
+ {"落とす(d)", 'd', TRUE},
+ {"壊す(k/^d)", 'k', TRUE},
+ {"銘を刻む({)", '{', TRUE},
+ {"銘を消す(})", '}', TRUE},
+ {"調査(I)", 'I', TRUE},
+ {"アイテム一覧(i)", 'i', TRUE},
{"", 0, FALSE},
{"", 0, FALSE},
{"", 0, FALSE}
},
{
- {"ÁõÈ÷¤¹¤ë(w)", 'w', TRUE},
- {"ÁõÈ÷¤ò³°¤¹(t/T)", 't', TRUE},
- {"dzÎÁ¤òÊäµë(F)", 'F', TRUE},
- {"ÁõÈ÷°ìÍ÷(e)", 'e', TRUE},
+ {"装備する(w)", 'w', TRUE},
+ {"装備を外す(t/T)", 't', TRUE},
+ {"燃料を補給(F)", 'F', TRUE},
+ {"装備一覧(e)", 'e', TRUE},
{"", 0, FALSE},
{"", 0, FALSE},
{"", 0, FALSE},
},
{
- {"³«¤±¤ë(o)", 'o', TRUE},
- {"ÊĤ¸¤ë(c)", 'c', TRUE},
- {"ÂÎÅö¤¿¤ê¤¹¤ë(B/f)", 'B', TRUE},
- {"¤¯¤µ¤Ó¤òÂǤÄ(j/S)", 'j', TRUE},
+ {"開ける(o)", 'o', TRUE},
+ {"閉じる(c)", 'c', TRUE},
+ {"体当たりする(B/f)", 'B', TRUE},
+ {"くさびを打つ(j/S)", 'j', TRUE},
{"", 0, FALSE},
{"", 0, FALSE},
{"", 0, FALSE},
},
{
- {"¥À¥ó¥¸¥ç¥ó¤ÎÁ´ÂοÞ(M)", 'M', TRUE},
- {"°ÌÃÖ¤ò³Îǧ(L/W)", 'L', TRUE},
- {"³¬¤ÎÊ·°Ïµ¤(^f)", KTRL('F'), TRUE},
- {"¥¹¥Æ¡¼¥¿¥¹(C)", 'C', TRUE},
- {"ʸ»ú¤ÎÀâÌÀ(/)", '/', TRUE},
- {"¥á¥Ã¥»¡¼¥¸ÍúÎò(^p)", KTRL('P'), TRUE},
- {"¸½ºß¤Î»þ¹ï(^t/')", KTRL('T'), TRUE},
- {"¸½ºß¤ÎÃμ±(~)", '~', TRUE},
- {"¥×¥ì¥¤µÏ¿(|)", '|', TRUE},
+ {"ダンジョンの全体図(M)", 'M', TRUE},
+ {"位置を確認(L/W)", 'L', TRUE},
+ {"階の雰囲気(^f)", KTRL('F'), TRUE},
+ {"ã\82¹ã\83\86ã\83¼ã\82¿ã\82¹(C)", 'C', TRUE},
+ {"文字の説明(/)", '/', TRUE},
+ {"メッセージ履歴(^p)", KTRL('P'), TRUE},
+ {"現在の時刻(^t/')", KTRL('T'), TRUE},
+ {"現在の知識(~)", '~', TRUE},
+ {"プレイ記録(|)", '|', TRUE},
{"", 0, FALSE}
},
{
- {"¥ª¥×¥·¥ç¥ó(=)", '=', TRUE},
- {"¥Þ¥¯¥í(@)", '@', TRUE},
- {"²èÌÌɽ¼¨(%)", '%', TRUE},
- {"¥«¥é¡¼(&)", '&', TRUE},
- {"ÀßÄêÊѹ¹¥³¥Þ¥ó¥É(\")", '\"', TRUE},
- {"¼«Æ°½¦¤¤¤ò¥í¡¼¥É($)", '$', TRUE},
- {"¥·¥¹¥Æ¥à(!)", '!', TRUE},
+ {"オプション(=)", '=', TRUE},
+ {"マクロ(@)", '@', TRUE},
+ {"画面表示(%)", '%', TRUE},
+ {"ã\82«ã\83©ã\83¼(&)", '&', TRUE},
+ {"設定変更コマンド(\")", '\"', TRUE},
+ {"自動拾いをロード($)", '$', TRUE},
+ {"システム(!)", '!', TRUE},
{"", 0, FALSE},
{"", 0, FALSE},
{"", 0, FALSE}
},
{
- {"¥»¡¼¥Ö&ÃæÃÇ(^x)", KTRL('X'), TRUE},
- {"¥»¡¼¥Ö(^s)", KTRL('S'), TRUE},
- {"¥Ø¥ë¥×(?)", '?', TRUE},
- {"ºÆÉÁ²è(^r)", KTRL('R'), TRUE},
- {"¥á¥â(:)", ':', TRUE},
- {"µÇ°»£±Æ())", ')', TRUE},
- {"µÇ°»£±Æ¤Îɽ¼¨(()", '(', TRUE},
- {"¥Ð¡¼¥¸¥ç¥ó¾ðÊó(V)", 'V', TRUE},
- {"°úÂह¤ë(Q)", 'Q', TRUE},
+ {"セーブ&中断(^x)", KTRL('X'), TRUE},
+ {"セーブ(^s)", KTRL('S'), TRUE},
+ {"ヘルプ(?)", '?', TRUE},
+ {"再描画(^r)", KTRL('R'), TRUE},
+ {"メモ(:)", ':', TRUE},
+ {"記念撮影())", ')', TRUE},
+ {"記念撮影の表示(()", '(', TRUE},
+ {"バージョン情報(V)", 'V', TRUE},
+ {"引退する(Q)", 'Q', TRUE},
{"", 0, FALSE}
},
};
{"Items(other)", 4, FALSE},
{"Equip", 5, FALSE},
{"Door/Box", 6, FALSE},
- {"Infomations", 7, FALSE},
+ {"Informations", 7, FALSE},
{"Options", 8, FALSE},
{"Other commands", 9, FALSE},
{"", 0, FALSE},
{"Target(*)", '*', TRUE},
{"Dig(T/^t)", 'T', TRUE},
{"Go up stairs(<)", '<', TRUE},
- {"Go down staies(>)", '>', TRUE},
+ {"Go down stairs(>)", '>', TRUE},
{"Command pets(p)", 'p', TRUE},
{"Search mode ON/OFF(S/#)", 'S', TRUE}
},
{"Identify symbol(/)", '/', TRUE},
{"Show prev messages(^p)", KTRL('P'), TRUE},
{"Current time(^t/')", KTRL('T'), TRUE},
- {"Various infomations(~)", '~', TRUE},
+ {"Various informations(~)", '~', TRUE},
{"Play record menu(|)", '|', TRUE},
{"", 0, FALSE}
},
#ifdef JP
special_menu_naiyou special_menu_info[] =
{
- {"ĶǽÎÏ/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_MINDCRAFTER},
- {"¤â¤Î¤Þ¤Í/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_IMITATOR},
- {"ɬ»¦µ»/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_SAMURAI},
- {"Îýµ¤½Ñ/ËâË¡/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_FORCETRAINER},
- {"¶ÀËâË¡/ÆüìǽÎÏ", 0, 0, MENU_CLASS, CLASS_MIRROR_MASTER},
- {"¹°è¥Þ¥Ã¥×(<)", 2, 6, MENU_WILD, FALSE},
- {"Ä̾ï¥Þ¥Ã¥×(>)", 2, 7, MENU_WILD, TRUE},
+ {"超能力/特殊能力", 0, 0, MENU_CLASS, CLASS_MINDCRAFTER},
+ {"ものまね/特殊能力", 0, 0, MENU_CLASS, CLASS_IMITATOR},
+ {"歌/特殊能力", 0, 0, MENU_CLASS, CLASS_BARD},
+ {"必殺技/特殊能力", 0, 0, MENU_CLASS, CLASS_SAMURAI},
+ {"練気術/魔法/特殊能力", 0, 0, MENU_CLASS, CLASS_FORCETRAINER},
+ {"技/特殊能力", 0, 0, MENU_CLASS, CLASS_BERSERKER},
+ {"技術/特殊能力", 0, 0, MENU_CLASS, CLASS_SMITH},
+ {"鏡魔法/特殊能力", 0, 0, MENU_CLASS, CLASS_MIRROR_MASTER},
+ {"忍術/特殊能力", 0, 0, MENU_CLASS, CLASS_NINJA},
+ {"広域マップ(<)", 2, 6, MENU_WILD, FALSE},
+ {"通常マップ(>)", 2, 7, MENU_WILD, TRUE},
{"", 0, 0, 0, 0},
};
#else
{
{"MindCraft/Special", 0, 0, MENU_CLASS, CLASS_MINDCRAFTER},
{"Imitation/Special", 0, 0, MENU_CLASS, CLASS_IMITATOR},
+ {"Song/Special", 0, 0, MENU_CLASS, CLASS_BARD},
{"Technique/Special", 0, 0, MENU_CLASS, CLASS_SAMURAI},
{"Mind/Magic/Special", 0, 0, MENU_CLASS, CLASS_FORCETRAINER},
+ {"BrutalPower/Special", 0, 0, MENU_CLASS, CLASS_BERSERKER},
+ {"Technique/Special", 0, 0, MENU_CLASS, CLASS_SMITH},
{"MirrorMagic/Special", 0, 0, MENU_CLASS, CLASS_MIRROR_MASTER},
+ {"Ninjutsu/Special", 0, 0, MENU_CLASS, CLASS_NINJA},
{"Enter global map(<)", 2, 6, MENU_WILD, FALSE},
{"Enter local map(>)", 2, 7, MENU_WILD, TRUE},
{"", 0, 0, 0, 0},
int menu = 0;
bool kisuu;
- if (py - panel_row_min > 10) basey = 2;
+ if (p_ptr->y - panel_row_min > 10) basey = 2;
else basey = 13;
basex = 15;
}
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
+ put_str(_("》", "> "),basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
/* Place the cursor on the player */
- move_cursor_relative(py, px);
+ move_cursor_relative(p_ptr->y, p_ptr->x);
/* Get a command */
sub_cmd = inkey();
cptr act;
#ifdef JP
- int caretcmd = 0;
+ int caretcmd = 0;
#endif
/* Roguelike */
if (rogue_like_commands)
command_arg = 0;
/* Begin the input */
-#ifdef JP
- prt("²ó¿ô: ", 0, 0);
-#else
- prt("Count: ", 0, 0);
-#endif
-
+ prt(_("回数: ", "Count: "), 0, 0);
/* Get a command count */
while (1)
command_arg = command_arg / 10;
/* Show current count */
-#ifdef JP
- prt(format("²ó¿ô: %d", command_arg), 0, 0);
-#else
- prt(format("Count: %d", command_arg), 0, 0);
-#endif
-
+ prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
}
/* Actual numeric data */
}
/* Show current count */
-#ifdef JP
- prt(format("²ó¿ô: %d", command_arg), 0, 0);
-#else
- prt(format("Count: %d", command_arg), 0, 0);
-#endif
-
+ prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
}
/* Exit on "unusable" input */
command_arg = 99;
/* Show current count */
-#ifdef JP
- prt(format("²ó¿ô: %d", command_arg), 0, 0);
-#else
- prt(format("Count: %d", command_arg), 0, 0);
-#endif
-
+ prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
}
/* Hack -- Handle "old_arg" */
command_arg = old_arg;
/* Show current count */
-#ifdef JP
-prt(format("²ó¿ô: %d", command_arg), 0, 0);
-#else
- prt(format("Count: %d", command_arg), 0, 0);
-#endif
-
+ prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
}
/* Hack -- white-space means "enter command now" */
if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r'))
{
/* Get a real command */
-#ifdef JP
- if (!get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE))
-#else
- if (!get_com("Command: ", (char *)&cmd, FALSE))
-#endif
-
+ if (!get_com(_("コマンド: ", "Command: "), (char *)&cmd, FALSE))
{
/* Clear count */
command_arg = 0;
if (cmd == '\\')
{
/* Get a real command */
-#ifdef JP
- (void)get_com("¥³¥Þ¥ó¥É: ", (char *)&cmd, FALSE);
-#else
- (void)get_com("Command: ", (char *)&cmd, FALSE);
-#endif
-
+ (void)get_com(_("コマンド: ", "Command: "), (char *)&cmd, FALSE);
/* Hack -- bypass keymaps */
if (!inkey_next) inkey_next = "";
if (cmd == '^')
{
/* Get a new command and controlify it */
-#ifdef JP
- if (get_com("CTRL: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
-#else
- if (get_com("Control: ", (char *)&cmd, FALSE)) cmd = KTRL(cmd);
-#endif
-
+ if (get_com(_("CTRL: ", "Control: "), (char *)&cmd, FALSE)) cmd = KTRL(cmd);
}
if (always_repeat && (command_arg <= 0))
{
/* Hack -- auto repeat certain commands */
- if (strchr("TBDoc+", command_cmd))
+ if (my_strchr("TBDoc+", command_cmd))
{
/* Repeat 99 times */
command_arg = 99;
}
#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++)
{
s = quark_str(o_ptr->inscription);
/* Find a '^' */
- s = strchr(s, '^');
+ s = my_strchr(s, '^');
/* Process preventions */
while (s)
{
/* 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
{
/* Hack -- Verify command */
-#ifdef JP
- if (!get_check("ËÜÅö¤Ç¤¹¤«? "))
-#else
- if (!get_check("Are you sure? "))
-#endif
-
+ if (!get_check(_("本当ですか? ", "Are you sure? ")))
{
/* Hack -- Use space */
command_cmd = ' ';
}
/* Find another '^' */
- s = strchr(s + 1, '^');
+ s = my_strchr(s + 1, '^');
}
}
int b_len, t_len, i_len;
/* Attempt to find the target (modify "buf") */
- buf = strstr(buf, target);
+ buf = my_strstr(buf, target);
/* No target found */
if (!buf) return (FALSE);
*/
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);
}
{
tag_type temp;
- temp.tag = a->tag;
- temp.pointer = a->pointer;
-
- a->tag = b->tag;
- a->pointer = b->pointer;
-
- b->tag = temp.tag;
- b->pointer = temp.pointer;
+ temp = *a;
+ *a = *b;
+ *b = temp;
}
#endif /* SUPPORT_GAMMA */
-void roff_to_buf(cptr str, int maxlen, char *tbuf)
+
+/*
+ * Add a series of keypresses to the "queue".
+ *
+ * Return any errors generated by Term_keypress() in doing so, or SUCCESS
+ * if there are none.
+ *
+ * Catch the "out of space" error before anything is printed.
+ *
+ * NB: The keys added here will be interpreted by any macros or keymaps.
+ */
+errr type_string(cptr str, uint len)
+{
+ errr err = 0;
+ cptr s;
+
+ term *old = Term;
+
+ /* Paranoia - no string. */
+ if (!str) return -1;
+
+ /* Hack - calculate the string length here if none given. */
+ if (!len) len = strlen(str);
+
+ /* Activate the main window, as all pastes go there. */
+ Term_activate(term_screen);
+
+ for (s = str; s < str+len; s++)
+ {
+ /* Catch end of string */
+ if (*s == '\0') break;
+
+ err = Term_keypress(*s);
+
+ /* Catch errors */
+ if (err) break;
+ }
+
+ /* Activate the original window. */
+ Term_activate(old);
+
+ return err;
+}
+
+
+
+void roff_to_buf(cptr str, int maxlen, char *tbuf, size_t bufsize)
{
int read_pt = 0;
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 - 1 || 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;
if (ch[0] == ' ')
word_punct = read_pt;
#ifdef JP
- if (kanji &&
- strcmp((char *)ch, "¡£") != 0 && strcmp((char *)ch, "¡¢") != 0 &&
- strcmp((char *)ch, "¥£") != 0 && strcmp((char *)ch, "¡¼") != 0)
- word_punct = read_pt;
+ if (!kinsoku) word_punct = read_pt;
#endif
+
+ /* Not enough buffer size */
+ if ((size_t)(write_pt + 3) >= bufsize) break;
+
tbuf[write_pt++] = ch[0];
line_len++;
read_pt++;
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;
+
+ if (bufsize > 0) {
+ /* reserve for NUL termination */
+ bufsize--;
+
+ /* Copy as many bytes as will fit */
+ while (*s && (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));
+ }
+}
+
+
+/*
+ * A copy of ANSI strstr()
+ *
+ * my_strstr() can handle Kanji strings correctly.
+ */
+char *my_strstr(const char *haystack, const char *needle)
+{
+ int i;
+ int l1 = strlen(haystack);
+ int l2 = strlen(needle);
+
+ if (l1 >= l2)
+ {
+ for(i = 0; i <= l1 - l2; i++)
+ {
+ if(!strncmp(haystack + i, needle, l2))
+ return (char *)haystack + i;
+
+#ifdef JP
+ if (iskanji(*(haystack + i))) i++;
+#endif
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * A copy of ANSI strchr()
+ *
+ * my_strchr() can handle Kanji strings correctly.
+ */
+char *my_strchr(const char *ptr, char ch)
+{
+ for ( ; *ptr != '\0'; ptr++)
+ {
+ if (*ptr == ch) return (char *)ptr;
+
+#ifdef JP
+ if (iskanji(*ptr)) ptr++;
+#endif
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Convert string to lower case
+ */
+void str_tolower(char *str)
+{
+ /* Force to be lower case string */
+ for (; *str; str++)
+ {
+#ifdef JP
+ if (iskanji(*str))
+ {
+ str++;
+ continue;
+ }
+#endif
+ *str = tolower(*str);
+ }
+}
+
+
+/*
+ * Get a keypress from the user.
+ * And interpret special keys as internal code.
+ *
+ * This function is a Mega-Hack and depend on pref-xxx.prf's.
+ * Currently works on Linux(UNIX), Windows, and Macintosh only.
+ */
+int inkey_special(bool numpad_cursor)
+{
+ static const struct {
+ cptr keyname;
+ int keyflag;
+ } modifier_key_list[] = {
+ {"shift-", SKEY_MOD_SHIFT},
+ {"control-", SKEY_MOD_CONTROL},
+ {NULL, 0},
+ };
+
+ static const struct {
+ bool numpad;
+ cptr keyname;
+ int keycode;
+ } special_key_list[] = {
+ {FALSE, "Down]", SKEY_DOWN},
+ {FALSE, "Left]", SKEY_LEFT},
+ {FALSE, "Right]", SKEY_RIGHT},
+ {FALSE, "Up]", SKEY_UP},
+ {FALSE, "Page_Up]", SKEY_PGUP},
+ {FALSE, "Page_Down]", SKEY_PGDOWN},
+ {FALSE, "Home]", SKEY_TOP},
+ {FALSE, "End]", SKEY_BOTTOM},
+ {TRUE, "KP_Down]", SKEY_DOWN},
+ {TRUE, "KP_Left]", SKEY_LEFT},
+ {TRUE, "KP_Right]", SKEY_RIGHT},
+ {TRUE, "KP_Up]", SKEY_UP},
+ {TRUE, "KP_Page_Up]", SKEY_PGUP},
+ {TRUE, "KP_Page_Down]", SKEY_PGDOWN},
+ {TRUE, "KP_Home]", SKEY_TOP},
+ {TRUE, "KP_End]", SKEY_BOTTOM},
+ {TRUE, "KP_2]", SKEY_DOWN},
+ {TRUE, "KP_4]", SKEY_LEFT},
+ {TRUE, "KP_6]", SKEY_RIGHT},
+ {TRUE, "KP_8]", SKEY_UP},
+ {TRUE, "KP_9]", SKEY_PGUP},
+ {TRUE, "KP_3]", SKEY_PGDOWN},
+ {TRUE, "KP_7]", SKEY_TOP},
+ {TRUE, "KP_1]", SKEY_BOTTOM},
+ {FALSE, NULL, 0},
+ };
+
+ static const struct {
+ cptr keyname;
+ int keycode;
+ } gcu_special_key_list[] = {
+ {"A", SKEY_UP},
+ {"B", SKEY_DOWN},
+ {"C", SKEY_RIGHT},
+ {"D", SKEY_LEFT},
+ {"1~", SKEY_TOP},
+ {"4~", SKEY_BOTTOM},
+ {"5~", SKEY_PGUP},
+ {"6~", SKEY_PGDOWN},
+ {NULL, 0},
+ };
+
+ char buf[1024];
+ cptr str = buf;
+ char key;
+ int skey = 0;
+ int modifier = 0;
+ int i;
+ size_t trig_len;
+
+ /*
+ * Forget macro trigger ----
+ * It's important if we are already expanding macro action
+ */
+ inkey_macro_trigger_string[0] = '\0';
+
+ /* Get a keypress */
+ key = inkey();
+
+ /* Examine trigger string */
+ trig_len = strlen(inkey_macro_trigger_string);
+
+ /* Already known that no special key */
+ if (!trig_len) return (int)((unsigned char)key);
+
+ /*
+ * Hack -- Ignore macro defined on ASCII characters.
+ */
+ if (trig_len == 1 && parse_macro)
+ {
+ char c = inkey_macro_trigger_string[0];
+
+ /* Cancel macro action on the queue */
+ forget_macro_action();
+
+ /* Return the originaly pressed key */
+ return (int)((unsigned char)c);
+ }
+
+ /* Convert the trigger */
+ ascii_to_text(buf, inkey_macro_trigger_string);
+
+ /* Check the prefix "\[" */
+ if (prefix(str, "\\["))
+ {
+ /* Skip "\[" */
+ str += 2;
+
+ /* Examine modifier keys */
+ while (TRUE)
+ {
+ for (i = 0; modifier_key_list[i].keyname; i++)
+ {
+ if (prefix(str, modifier_key_list[i].keyname))
+ {
+ /* Get modifier key flag */
+ str += strlen(modifier_key_list[i].keyname);
+ modifier |= modifier_key_list[i].keyflag;
+ }
+ }
+
+ /* No more modifier key found */
+ if (!modifier_key_list[i].keyname) break;
+ }
+
+ /* numpad_as_cursorkey option force numpad keys to input numbers */
+ if (!numpad_as_cursorkey) numpad_cursor = FALSE;
+
+ /* Get a special key code */
+ for (i = 0; special_key_list[i].keyname; i++)
+ {
+ if ((!special_key_list[i].numpad || numpad_cursor) &&
+ streq(str, special_key_list[i].keyname))
+ {
+ skey = special_key_list[i].keycode;
+ break;
+ }
+ }
+
+ /* A special key found */
+ if (skey)
+ {
+ /* Cancel macro action on the queue */
+ forget_macro_action();
+
+ /* Return special key code and modifier flags */
+ return (skey | modifier);
+ }
+ }
+
+ if (prefix(str, "\\e["))
+ {
+ str += 3;
+
+ for (i = 0; gcu_special_key_list[i].keyname; i++)
+ {
+ if (streq(str, gcu_special_key_list[i].keyname))
+ {
+ return gcu_special_key_list[i].keycode;
+ }
+ }
+ }
+
+ /* No special key found? */
+
+ /* Don't bother with this trigger no more */
+ inkey_macro_trigger_string[0] = '\0';
+
+ /* Return normal keycode */
+ return (int)((unsigned char)key);
+}