X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Futil.c;h=3836437f80343e2c1479e4c2068a5789ff8a7bdf;hb=c3cb0895f7f484477e7206df820821c97fc4db1e;hp=91f2c359334d9c40a02479245d99f089aa2b316c;hpb=58f6d1ebd3895f8b972ad7bc0cffadb0158576aa;p=hengband%2Fhengband.git diff --git a/src/util.c b/src/util.c index 91f2c3593..3836437f8 100644 --- a/src/util.c +++ b/src/util.c @@ -1,4 +1,4 @@ -/* File: util.c */ +/* File: util.c */ /* * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke @@ -13,10 +13,11 @@ #include "angband.h" - - static int num_more = 0; +/* Save macro trigger string for use in inkey_special() */ +static char inkey_macro_trigger_string[1024]; + #if 0 #ifndef HAS_STRICMP @@ -71,13 +72,7 @@ int usleep(huge usecs) /* 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); @@ -214,7 +209,7 @@ errr path_parse(char *buf, int max, cptr file) 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); @@ -292,7 +287,11 @@ static errr path_temp(char *buf, int max) 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); @@ -355,19 +354,19 @@ FILE *my_fopen(cptr file, cptr mode) { 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 @@ -447,6 +446,10 @@ errr my_fgets(FILE *fff, char *buf, huge n) /* 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++) { @@ -481,7 +484,7 @@ errr my_fgets(FILE *fff, char *buf, huge n) buf[i++] = ' '; /* Append some more spaces */ - while (!(i % 8)) buf[i++] = ' '; + while (0 != (i % 8)) buf[i++] = ' '; } #ifdef JP @@ -491,17 +494,16 @@ errr my_fgets(FILE *fff, char *buf, huge n) 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; @@ -657,7 +659,19 @@ errr fd_copy(cptr file, cptr what) /* 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 */ @@ -702,16 +716,16 @@ int fd_make(cptr file, int mode) #else /* BEN_HACK */ -# if defined(MACINTOSH) && defined(MAC_MPW) - - /* setting file type and creator -- AR */ +#if defined(MAC_MPW) || defined(MACH_O_CARBON) { - errr errr_tmp; - errr_tmp = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode); - fsetfileinfo(file, _fcreator, _ftype); - return(errr_tmp); + 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)); @@ -835,7 +849,7 @@ errr fd_chop(int fd, huge n) /* 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 @@ -1106,7 +1120,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr) /* Invalid trigger name? */ if (i == max_macrotrigger) { - str = strchr(str, ']'); + str = my_strchr(str, ']'); if (str) { *s++ = (char)31; @@ -1308,7 +1322,7 @@ static bool trigger_ascii_to_text(char **bufptr, cptr *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]; @@ -1692,6 +1706,109 @@ void sound(int val) 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; + } + +} + /* @@ -1721,7 +1838,7 @@ static char inkey_aux(void) char *buf = inkey_macro_trigger_string; - /* Hack : ¥­¡¼ÆþÎÏÂÔ¤Á¤Ç»ß¤Þ¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢Î®¤ì¤¿¹Ô¤Îµ­²±¤ÏÉÔÍס£ */ + /* Hack : キー入力待ちで止まっているので、流れた行の記憶は不要。 */ num_more = 0; if (parse_macro) @@ -1788,10 +1905,10 @@ static char inkey_aux(void) else { /* Increase "wait" */ - w += 10; + w += 1; /* Excessive delay */ - if (w >= 100) break; + if (w >= 10) break; /* Delay */ Term_xtra(TERM_XTRA_DELAY, w); @@ -1861,6 +1978,33 @@ static char inkey_aux(void) /* + * 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 @@ -2189,6 +2333,22 @@ char inkey(void) */ /* + * 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) @@ -2202,8 +2362,8 @@ 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; @@ -2223,8 +2383,8 @@ cptr quark_str(s16b i) { 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]; @@ -2259,10 +2419,11 @@ cptr quark_str(s16b i) -/* - * How many messages are "available"? +/*! + * @brief 保存中の過去ゲームメッセージの数を返す。 / How many messages are "available"? + * @return 残っているメッセージの数 */ -s16b message_num(void) +s32b message_num(void) { int last, next, n; @@ -2281,14 +2442,15 @@ 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 */ @@ -2308,15 +2470,16 @@ cptr message_str(int age) } - -/* - * 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; @@ -2331,39 +2494,37 @@ void message_add(cptr str) /* 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 */ @@ -2389,8 +2550,8 @@ void message_add(cptr str) /* 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++); #endif @@ -2408,7 +2569,7 @@ void message_add(cptr str) } /* Limit the multiplier to 1000 */ - if (buf && streq(buf, str) && (j < 1000)) + if (streq(buf, str) && (j < 1000)) { j++; @@ -2427,7 +2588,7 @@ void message_add(cptr str) } else { - num_more++;/*ή¤ì¤¿¹Ô¤Î¿ô¤ò¿ô¤¨¤Æ¤ª¤¯ */ + num_more++;/*流れた行の数を数えておく */ now_message++; } @@ -2438,8 +2599,7 @@ void message_add(cptr str) /* 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 */ @@ -2578,7 +2738,7 @@ void message_add(cptr str) 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); } @@ -2613,25 +2773,20 @@ static void msg_flush(int x) 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; @@ -2672,11 +2827,8 @@ static void msg_flush(int x) void msg_print(cptr msg) { static int p = 0; - int n; - char *t; - char buf[1024]; if (world_monster) return; @@ -2688,7 +2840,7 @@ void msg_print(cptr msg) p = 0; } - /* Message Length */ + /* Original Message Length */ n = (msg ? strlen(msg) : 0); /* Hack -- flush when requested or needed */ @@ -2704,20 +2856,27 @@ void msg_print(cptr msg) p = 0; } - /* No message */ if (!msg) return; /* Paranoia */ if (n > 1000) return; + /* Copy it */ + if (!cheat_turn) + { + strcpy(buf, msg); + } + else + { + sprintf(buf, ("T:%d - %s"), turn, msg); + } - /* Memorize the message */ - if (character_generated) message_add(msg); - + /* New Message Length */ + n = (buf ? strlen(buf) : 0); - /* Copy it */ - strcpy(buf, msg); + /* Memorize the message */ + if (character_generated) message_add(buf); /* Analyze the buffer */ t = buf; @@ -2793,7 +2952,6 @@ void msg_print(cptr msg) t += split; n -= split; } - /* Display the tail of the message */ Term_putstr(p, 0, n, TERM_WHITE, t); @@ -2814,11 +2972,28 @@ void msg_print(cptr msg) 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); + + if (cheat_diary_output) + { + do_cmd_write_nikki(NIKKI_WIZARD_LOG, 0, buf); + } + +} /* * Hack -- prevent "accidents" in "screen_save()" or "screen_load()" @@ -2884,6 +3059,32 @@ void msg_format(cptr fmt, ...) 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); +} + /* @@ -2991,7 +3192,7 @@ void c_roff(byte a, cptr str) /* Clean up the char */ #ifdef JP - ch = ((isprint(*s) || k_flag) ? *s : ' '); + ch = ((k_flag || isprint(*s)) ? *s : ' '); #else ch = (isprint(*s) ? *s : ' '); #endif @@ -3014,7 +3215,7 @@ void c_roff(byte a, cptr str) if (x < w) #ifdef JP { - /* ¸½ºß¤¬È¾³Ñʸ»ú¤Î¾ì¹ç */ + /* 現在が半角文字の場合 */ if( !k_flag ) #endif { @@ -3038,11 +3239,11 @@ void c_roff(byte a, cptr str) #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, "ィ", 2) == 0 || strncmp(s, "ー", 2) == 0 #endif ){ Term_what(x , y, &av[x ], &cv[x ]); @@ -3137,34 +3338,37 @@ void clear_from(int row) /* - * 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; @@ -3174,107 +3378,232 @@ bool askfor_aux(char *buf, int len) /* 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; + case SKEY_LEFT: + case KTRL('b'): + { + int i = 0; + + /* Now on insert mode */ + color = TERM_WHITE; + + /* No move at beginning of line */ + if (0 == pos) break; + + while (TRUE) + { + 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; + 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; + +#ifdef JP + /* Move right */ + if (iskanji(buf[pos])) pos += 2; + else pos++; +#else + pos++; +#endif + + break; + + case ESCAPE: + /* Cancel input */ + buf[0] = '\0'; + return FALSE; case '\n': case '\r': - k = strlen(buf); - done = TRUE; - break; + /* Success */ + return TRUE; - case 0x7F: 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) + { + int next_pos = i + 1; + #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; + + /* 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; + } default: + { + /* Insert a character */ + + char tmp[100]; + char c; + + /* Ignore special keys */ + if (skey & SKEY_MASK) break; + + /* 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 - { /* ÊÒ»³¤µ¤óºîÀ® */ - 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)", '>', 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}, @@ -3673,10 +4009,10 @@ menu_naiyou menu_info[10][10] = }, { - {"³«¤±¤ë(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}, @@ -3686,41 +4022,41 @@ menu_naiyou menu_info[10][10] = }, { - {"¥À¥ó¥¸¥ç¥ó¤ÎÁ´ÂοÞ(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}, + {"ステータス(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}, + {"カラー(&)", '&', 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} }, }; @@ -3734,7 +4070,7 @@ menu_naiyou menu_info[10][10] = {"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}, @@ -3761,7 +4097,7 @@ menu_naiyou menu_info[10][10] = {"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} }, @@ -3826,7 +4162,7 @@ menu_naiyou menu_info[10][10] = {"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} }, @@ -3874,13 +4210,17 @@ typedef struct #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 @@ -3888,9 +4228,13 @@ special_menu_naiyou special_menu_info[] = { {"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}, @@ -3905,7 +4249,7 @@ static char inkey_from_menu(void) 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; @@ -3956,14 +4300,10 @@ static char inkey_from_menu(void) } 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(); @@ -4144,12 +4484,7 @@ void request_command(int shopping) 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) @@ -4164,12 +4499,7 @@ void request_command(int shopping) 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 */ @@ -4193,12 +4523,7 @@ void request_command(int shopping) } /* 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 */ @@ -4215,12 +4540,7 @@ void request_command(int shopping) 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" */ @@ -4230,24 +4550,14 @@ void request_command(int shopping) 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; @@ -4263,12 +4573,7 @@ prt(format(" 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 = ""; @@ -4279,12 +4584,7 @@ prt(format(" 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); } @@ -4320,7 +4620,7 @@ prt(format(" 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; @@ -4361,11 +4661,6 @@ prt(format(" caretcmd = command_cmd; #endif -#ifdef JP -#undef strchr -#define strchr strchr_j -#endif - /* Hack -- Scan equipment */ for (i = INVEN_RARM; i < INVEN_TOTAL; i++) { @@ -4383,7 +4678,7 @@ prt(format(" s = quark_str(o_ptr->inscription); /* Find a '^' */ - s = strchr(s, '^'); + s = my_strchr(s, '^'); /* Process preventions */ while (s) @@ -4397,12 +4692,7 @@ prt(format(" { /* 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 = ' '; @@ -4410,7 +4700,7 @@ prt(format(" } /* Find another '^' */ - s = strchr(s + 1, '^'); + s = my_strchr(s + 1, '^'); } } @@ -4462,7 +4752,7 @@ static bool insert_str(char *buf, cptr target, cptr insert) 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); @@ -4659,14 +4949,9 @@ static void swap(tag_type *a, tag_type *b) { 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; } @@ -4941,10 +5226,10 @@ void roff_to_buf(cptr str, int maxlen, char *tbuf, size_t bufsize) ch[1] = str[read_pt+1]; ch_len = 2; - if (strcmp(ch, "¡£") == 0 || - strcmp(ch, "¡¢") == 0 || - strcmp(ch, "¥£") == 0 || - strcmp(ch, "¡¼") == 0) + if (strcmp(ch, "。") == 0 || + strcmp(ch, "、") == 0 || + strcmp(ch, "ィ") == 0 || + strcmp(ch, "ー") == 0) kinsoku = TRUE; } else if (!isprint(ch[0])) @@ -5027,26 +5312,29 @@ size_t my_strcpy(char *buf, const char *src, size_t bufsize) const char *s = src; size_t len = 0; - /* reserve for NUL termination */ - bufsize--; + if (bufsize > 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 + /* Copy as many bytes as will fit */ + while (*s && (len < bufsize)) { - *d++ = *s++; - len++; + if (iskanji(*s)) + { + if (len + 1 >= bufsize || !*(s+1)) break; + *d++ = *s++; + *d++ = *s++; + len += 2; + } + else + { + *d++ = *s++; + len++; + } } + *d = '\0'; } - *d = '\0'; + while(*s++) len++; return len; @@ -5100,3 +5388,247 @@ size_t my_strcat(char *buf, const char *src, size_t bufsize) 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); +}