OSDN Git Service

アイテムの外見(flavor)の処理方法を変更。flavor.c内に直にデータを書くのでは無く
[hengband/hengband.git] / src / cmd4.c
index 0da0a74..9046c15 100644 (file)
@@ -1,56 +1,98 @@
 /* File: cmd4.c */
 
-/* Purpose: Interface commands */
-
 /*
- * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
+ * 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.
+ * 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: Interface commands */
+
 #include "angband.h"
 
 
+
+/*
+ * A set of functions to maintain automatic dumps of various kinds.
+ * -Mogami-
+ *
+ * remove_auto_dump(orig_file, mark)
+ *     Remove the old automatic dump of type "mark".
+ * auto_dump_printf(fmt, ...)
+ *     Dump a formatted string using fprintf().
+ * open_auto_dump(buf, mark)
+ *     Open a file, remove old dump, and add new header.
+ * close_auto_dump(void)
+ *     Add a footer, and close the file.
+ *
+ *    The dump commands of original Angband simply add new lines to
+ * existing files; these files will become bigger and bigger unless
+ * an user deletes some or all of these files by hand at some
+ * point.
+ *
+ *     These three functions automatically delete old dumped lines 
+ * before adding new ones.  Since there are various kinds of automatic 
+ * dumps in a single file, we add a header and a footer with a type 
+ * name for every automatic dump, and kill old lines only when the 
+ * lines have the correct type of header and footer.
+ *
+ *     We need to be quite paranoid about correctness; the user might 
+ * (mistakenly) edit the file by hand, and see all their work come
+ * to nothing on the next auto dump otherwise.  The current code only 
+ * detects changes by noting inconsistencies between the actual number 
+ * of lines and the number written in the footer.  Note that this will 
+ * not catch single-line edits.
+ */
+
 /*
- *  mark strings for auto dump
+ *  Mark strings for auto dump
  */
 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
 
 /*
+ * Variables for auto dump
+ */
+static FILE *auto_dump_stream;
+static cptr auto_dump_mark;
+static int auto_dump_line_num;
+
+/*
  * Remove old lines automatically generated before.
  */
-static void remove_auto_dump(cptr orig_file, cptr mark)
+static void remove_auto_dump(cptr orig_file)
 {
        FILE *tmp_fff, *orig_fff;
 
        char tmp_file[1024];
        char buf[1024];
        bool between_mark = FALSE;
-       bool success = FALSE;
+       bool changed = FALSE;
        int line_num = 0;
        long header_location = 0;
        char header_mark_str[80];
        char footer_mark_str[80];
        size_t mark_len;
 
-       sprintf(header_mark_str, auto_dump_header, mark);
-       sprintf(footer_mark_str, auto_dump_footer, mark);
+       /* Prepare a header/footer mark string */
+       sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
+       sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
 
        mark_len = strlen(footer_mark_str);
 
-       /* If original file is not exist, nothing to do */
+       /* Open an old dump file in read-only mode */
        orig_fff = my_fopen(orig_file, "r");
-       if (!orig_fff)
-       {
-               return;
-       }
 
-       /* Open a new file */
+       /* If original file does not exist, nothing to do */
+       if (!orig_fff) return;
+
+       /* Open a new (temporary) file */
        tmp_fff = my_fopen_temp(tmp_file, 1024);
-       if (!tmp_fff) {
+
+       if (!tmp_fff)
+       {
 #ifdef JP
            msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", tmp_file);
 #else
@@ -59,100 +101,180 @@ static void remove_auto_dump(cptr orig_file, cptr mark)
            msg_print(NULL);
            return;
        }
-       
-       while (1)
+
+       /* Loop for every line */
+       while (TRUE)
        {
+               /* Read a line */
                if (my_fgets(orig_fff, buf, sizeof(buf)))
                {
+                       /* Read error: Assume End of File */
+
+                       /*
+                        * Was looking for the footer, but not found.
+                        *
+                        * Since automatic dump might be edited by hand,
+                        * it's dangerous to kill these lines.
+                        * Seek back to the next line of the (pseudo) header,
+                        * and read again.
+                        */
                        if (between_mark)
                        {
                                fseek(orig_fff, header_location, SEEK_SET);
                                between_mark = FALSE;
                                continue;
                        }
+
+                       /* Success -- End the loop */
                        else
                        {
                                break;
                        }
                }
 
+               /* We are looking for the header mark of automatic dump */
                if (!between_mark)
                {
+                       /* Is this line a header? */
                        if (!strcmp(buf, header_mark_str))
                        {
+                               /* Memorise seek point of this line */
                                header_location = ftell(orig_fff);
+
+                               /* Initialize counter for number of lines */
                                line_num = 0;
+
+                               /* Look for the footer from now */
                                between_mark = TRUE;
-                               success = TRUE;
+
+                               /* There are some changes */
+                               changed = TRUE;
                        }
+
+                       /* Not a header */
                        else
                        {
+                               /* Copy orginally lines */
                                fprintf(tmp_fff, "%s\n", buf);
                        }
                }
+
+               /* We are looking for the footer mark of automatic dump */
                else
                {
+                       /* Is this line a footer? */
                        if (!strncmp(buf, footer_mark_str, mark_len))
                        {
                                int tmp;
 
-                               if (!sscanf(buf + mark_len, " (%d)", &tmp)
+                               /*
+                                * Compare the number of lines
+                                *
+                                * If there is an inconsistency between
+                                * actual number of lines and the
+                                * number here, the automatic dump
+                                * might be edited by hand.  So it's
+                                * dangerous to kill these lines.
+                                * Seek back to the next line of the
+                                * (pseudo) header, and read again.
+                                */
+                               if (!sscanf(buf + mark_len, " (%d)", &tmp)
                                    || tmp != line_num)
                                {
                                        fseek(orig_fff, header_location, SEEK_SET);
                                }
 
+                               /* Look for another header */
                                between_mark = FALSE;
                        }
+
+                       /* Not a footer */
                        else
                        {
+                               /* Ignore old line, and count number of lines */
                                line_num++;
                        }
                }
        }
+
+       /* Close files */
        my_fclose(orig_fff);
        my_fclose(tmp_fff);
 
-       if (success)
+       /* If there are some changes, overwrite the original file with new one */
+       if (changed)
        {
-               /* copy contents of temporally file */
+               /* Copy contents of temporary file */
 
                tmp_fff = my_fopen(tmp_file, "r");
                orig_fff = my_fopen(orig_file, "w");
-               
+
                while (!my_fgets(tmp_fff, buf, sizeof(buf)))
                        fprintf(orig_fff, "%s\n", buf);
-               
+
                my_fclose(orig_fff);
                my_fclose(tmp_fff);
        }
+
+       /* Kill the temporary file */
        fd_kill(tmp_file);
 
        return;
 }
 
+
+/*
+ * Dump a formatted line, using "vstrnfmt()".
+ */
+static void auto_dump_printf(cptr fmt, ...)
+{
+       cptr p;
+       va_list vp;
+
+       char buf[1024];
+
+       /* Begin the Varargs Stuff */
+       va_start(vp, fmt);
+
+       /* Format the args, save the length */
+       (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
+
+       /* End the Varargs Stuff */
+       va_end(vp);
+
+       /* Count number of lines */
+       for (p = buf; *p; p++)
+       {
+               if (*p == '\n') auto_dump_line_num++;
+       }
+
+       /* Dump it */
+       fprintf(auto_dump_stream, "%s", buf);
+}
+
+
 /*
  *  Open file to append auto dump.
  */
-static FILE *open_auto_dump(cptr buf, cptr mark, int *line)
+static bool open_auto_dump(cptr buf, cptr mark)
 {
-       FILE *fff;
 
        char header_mark_str[80];
 
-       /* Drop priv's */
-       safe_setuid_drop();
+       /* Save the mark string */
+       auto_dump_mark = mark;
 
-       sprintf(header_mark_str, auto_dump_header, mark);
+       /* Prepare a header mark string */
+       sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
 
        /* Remove old macro dumps */
-       remove_auto_dump(buf, mark);
+       remove_auto_dump(buf);
 
        /* Append to the file */
-       fff = my_fopen(buf, "a");
+       auto_dump_stream = my_fopen(buf, "a");
 
        /* Failure */
-       if (!fff) {
+       if (!auto_dump_stream) {
 #ifdef JP
                msg_format("%s ¤ò³«¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", buf);
 #else
@@ -160,61 +282,81 @@ static FILE *open_auto_dump(cptr buf, cptr mark, int *line)
 #endif
                msg_print(NULL);
 
-               /* Grab priv's */
-               safe_setuid_grab();
-               
-               return NULL;
+               /* Failed */
+               return FALSE;
        }
 
        /* Start dumping */
-       fprintf(fff, "%s\n", header_mark_str);
+       fprintf(auto_dump_stream, "%s\n", header_mark_str);
+
+       /* Initialize counter */
+       auto_dump_line_num = 0;
 
 #ifdef JP
-       fprintf(fff, "# *·Ù¹ð!!* °Ê¹ß¤Î¹Ô¤Ï¼«Æ°À¸À®¤µ¤ì¤¿¤â¤Î¤Ç¤¹¡£\n");
-       fprintf(fff, "# *·Ù¹ð!!* ¸å¤Ç¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤ë¤Î¤ÇÊÔ½¸¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£\n");
+       auto_dump_printf("# *·Ù¹ð!!* °Ê¹ß¤Î¹Ô¤Ï¼«Æ°À¸À®¤µ¤ì¤¿¤â¤Î¤Ç¤¹¡£\n");
+       auto_dump_printf("# *·Ù¹ð!!* ¸å¤Ç¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤ë¤Î¤ÇÊÔ½¸¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£\n");
 #else
-       fprintf(fff, "# *Warning!!* The lines below are automatic dump.\n");
-       fprintf(fff, "# *Warning!!* Don't edit these! These lines will be deleted automaticaly.\n");
+       auto_dump_printf("# *Warning!*  The lines below are an automatic dump.\n");
+       auto_dump_printf("# Don't edit them; changes will be deleted and replaced automatically.\n");
 #endif
-       *line = 2;
 
-       return fff;
+       /* Success */
+       return TRUE;
 }
 
 /*
  *  Append foot part and close auto dump.
  */
-static void close_auto_dump(FILE *fff, cptr mark, int line_num)
+static void close_auto_dump(void)
 {
        char footer_mark_str[80];
 
-       sprintf(footer_mark_str, auto_dump_footer, mark);
+       /* Prepare a footer mark string */
+       sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
 
-       /* End of dumping */
 #ifdef JP
-       fprintf(fff, "# *·Ù¹ð!!* °Ê¾å¤Î¹Ô¤Ï¼«Æ°À¸À®¤µ¤ì¤¿¤â¤Î¤Ç¤¹¡£\n");
-       fprintf(fff, "# *·Ù¹ð!!* ¸å¤Ç¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤ë¤Î¤ÇÊÔ½¸¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£\n");
+       auto_dump_printf("# *·Ù¹ð!!* °Ê¾å¤Î¹Ô¤Ï¼«Æ°À¸À®¤µ¤ì¤¿¤â¤Î¤Ç¤¹¡£\n");
+       auto_dump_printf("# *·Ù¹ð!!* ¸å¤Ç¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤ë¤Î¤ÇÊÔ½¸¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£\n");
 #else
-       fprintf(fff, "# *Warning!!* The lines above are automatic dump.\n");
-       fprintf(fff, "# *Warning!!* Don't edit these! These lines will be deleted automaticaly.\n");
+       auto_dump_printf("# *Warning!*  The lines above are an automatic dump.\n");
+       auto_dump_printf("# Don't edit them; changes will be deleted and replaced automatically.\n");
 #endif
-       line_num += 2;
 
-       fprintf(fff, "%s (%d)\n", footer_mark_str, line_num);
+       /* End of dump */
+       fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
 
-       my_fclose(fff);
+       /* Close */
+       my_fclose(auto_dump_stream);
 
-       /* Grab priv's */
-       safe_setuid_grab();
-               
        return;
 }
 
 
+#ifndef JP
 /*
- *   Take note to the dialy.
+ * Return suffix of ordinal number
  */
+cptr get_ordinal_number_suffix(int num)
+{
+       num = ABS(num) % 100;
+       switch (num % 10)
+       {
+       case 1:
+               return (num == 11) ? "th" : "st";
+       case 2:
+               return (num == 12) ? "th" : "nd";
+       case 3:
+               return (num == 13) ? "th" : "rd";
+       default:
+               return "th";
+       }
+}
+#endif
+
 
+/*
+ *   Take note to the diary.
+ */
 errr do_cmd_write_nikki(int type, int num, cptr note)
 {
        int day, hour, min;
@@ -223,6 +365,8 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
        char buf[1024];
        cptr note_level = "";
        bool do_level = TRUE;
+       char note_level_buf[40];
+       int q_idx;
 
        static bool disable_nikki = FALSE;
 
@@ -244,7 +388,7 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
                /* Get the quest text */
                init_flags = INIT_ASSIGN;
 
-               process_dungeon_file("q_info_j.txt", 0, 0, 0, 0);
+               process_dungeon_file("q_info.txt", 0, 0, 0, 0);
 
                /* Reset the old quest number */
                p_ptr->inside_quest = old_quest;
@@ -257,9 +401,6 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
        sprintf(file_name,"playrec-%s.txt",savefile_base);
 #endif
 
-       /* Hack -- drop permissions */
-       safe_setuid_drop();
-
        /* Build the filename */
        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
 
@@ -271,8 +412,6 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
        /* Failure */
        if (!fff)
        {
-               /* Hack -- grab permissions */
-               safe_setuid_grab();
 #ifdef JP
                msg_format("%s ¤ò³«¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£¥×¥ì¥¤µ­Ï¿¤ò°ì»þÄä»ß¤·¤Þ¤¹¡£", buf);
 #else
@@ -283,6 +422,8 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
                return (-1);
        }
 
+       q_idx = quest_number(dun_level);
+
        if (write_level)
        {
                if (p_ptr->inside_arena)
@@ -297,18 +438,22 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #else
                        note_level = "Surface:";
 #endif
-               else if (quest_number(dun_level) && ((quest_number(dun_level) < MIN_RANDOM_QUEST) && !(quest_number(dun_level) == QUEST_OBERON || quest_number(dun_level) == QUEST_SERPENT)))
+               else if (q_idx && (is_fixed_quest_idx(q_idx)
+                        && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
 #ifdef JP
                        note_level = "¥¯¥¨¥¹¥È:";
 #else
                        note_level = "Quest:";
 #endif
                else
+               {
 #ifdef JP
-                       note_level = format("%d³¬(%s):", dun_level, d_name+d_info[dungeon_type].name);
+                       sprintf(note_level_buf, "%d³¬(%s):", dun_level, d_name+d_info[dungeon_type].name);
 #else
-                       note_level = format("%s L%d:", d_name+d_info[dungeon_type].name, dun_level);
+                       sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, dun_level);
 #endif
+                       note_level = note_level_buf;
+               }
        }
 
        switch(type)
@@ -339,7 +484,7 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s %s¤òȯ¸«¤·¤¿¡£\n", hour, min, note_level, note);
 #else
-                       fprintf(fff, " %2d:%02d %20s discover %s.\n", hour, min, note_level, note);
+                       fprintf(fff, " %2d:%02d %20s discovered %s.\n", hour, min, note_level, note);
 #endif
                        break;
                }
@@ -415,7 +560,8 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
                case NIKKI_STAIR:
                {
                        cptr to;
-                       if (quest_number(dun_level) && ((quest_number(dun_level) < MIN_RANDOM_QUEST) && !(quest_number(dun_level) == QUEST_OBERON || quest_number(dun_level) == QUEST_SERPENT)))
+                       if (q_idx && (is_fixed_quest_idx(q_idx)
+                            && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
                        {
 #ifdef JP
                                to = "ÃϾå";
@@ -429,11 +575,11 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
                                if (!(dun_level+num)) to = "ÃϾå";
                                else to = format("%d³¬", dun_level+num);
 #else
-                               if (!(dun_level+num)) to = "the surfice";
+                               if (!(dun_level+num)) to = "the surface";
                                else to = format("level %d", dun_level+num);
 #endif
                        }
-                               
+
 #ifdef JP 
                        fprintf(fff, " %2d:%02d %20s %s¤Ø%s¡£\n", hour, min, note_level, to, note);
 #else
@@ -447,13 +593,13 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                                fprintf(fff, " %2d:%02d %20s µ¢´Ô¤ò»È¤Ã¤Æ%s¤Î%d³¬¤Ø²¼¤ê¤¿¡£\n", hour, min, note_level, d_name+d_info[dungeon_type].name, max_dlv[dungeon_type]);
 #else
-                               fprintf(fff, " %2d:%02d %20s recall to dungeon level %d of %s.\n", hour, min, note_level, max_dlv[dungeon_type], d_name+d_info[dungeon_type].name);
+                               fprintf(fff, " %2d:%02d %20s recalled to dungeon level %d of %s.\n", hour, min, note_level, max_dlv[dungeon_type], d_name+d_info[dungeon_type].name);
 #endif
                        else
 #ifdef JP
                                fprintf(fff, " %2d:%02d %20s µ¢´Ô¤ò»È¤Ã¤ÆÃϾå¤Ø¤ÈÌá¤Ã¤¿¡£\n", hour, min, note_level);
 #else
-                               fprintf(fff, " %2d:%02d %20s recall from dungeon to surface.\n", hour, min, note_level);
+                               fprintf(fff, " %2d:%02d %20s recalled from dungeon to surface.\n", hour, min, note_level);
 #endif
                        break;
                }
@@ -463,44 +609,16 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s ¥¯¥¨¥¹¥È¡Ö%s¡×¤Ø¤ÈÆÍÆþ¤·¤¿¡£\n", hour, min, note_level, quest[num].name);
 #else
-                       fprintf(fff, " %2d:%02d %20s enter quest '%s'.\n", hour, min, note_level, quest[num].name);
+                       fprintf(fff, " %2d:%02d %20s entered the quest '%s'.\n", hour, min, note_level, quest[num].name);
 #endif
                        break;
                }
                case NIKKI_TELE_LEV:
                {
-                       cptr to;
-                       if (!dun_level)
-                       {
-#ifdef JP
-                               to = "1³¬";
-#else
-                               to = "level 1";
-#endif
-                       }
-                       else if (quest_number(dun_level) && ((quest_number(dun_level) < MIN_RANDOM_QUEST) && !(quest_number(dun_level) == QUEST_OBERON || quest_number(dun_level) == QUEST_SERPENT)))
-                       {
-#ifdef JP
-                               to = "ÃϾå";
-#else
-                               to = "the surface";
-#endif
-                       }
-                       else
-                       {
-#ifdef JP
-                               if (!(dun_level+num)) to = "ÃϾå";
-                               else to = format("%d³¬", dun_level+num);
-#else
-                               if (!(dun_level+num)) to = "surface";
-                               else to = format("level %d", dun_level+num);
-#endif
-                       }
-                               
 #ifdef JP
-                       fprintf(fff, " %2d:%02d %20s %s¤Ø¤È¥Æ¥ì¥Ý¡¼¥È¤Ç°ÜÆ°¤·¤¿¡£\n", hour, min, note_level, to);
+                       fprintf(fff, " %2d:%02d %20s ¥ì¥Ù¥ë¡¦¥Æ¥ì¥Ý¡¼¥È¤Çæ½Ð¤·¤¿¡£\n", hour, min, note_level);
 #else
-                       fprintf(fff, " %2d:%02d %20s teleport level to %s.\n", hour, min, note_level, to);
+                       fprintf(fff, " %2d:%02d %20s Got out using teleport level.\n", hour, min, note_level);
 #endif
                        break;
                }
@@ -509,7 +627,7 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s %s¤ò¹ØÆþ¤·¤¿¡£\n", hour, min, note_level, note);
 #else
-                       fprintf(fff, " %2d:%02d %20s buy %s.\n", hour, min, note_level, note);
+                       fprintf(fff, " %2d:%02d %20s bought %s.\n", hour, min, note_level, note);
 #endif
                        break;
                }
@@ -518,34 +636,33 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s %s¤òÇäµÑ¤·¤¿¡£\n", hour, min, note_level, note);
 #else
-                       fprintf(fff, " %2d:%02d %20s sell %s.\n", hour, min, note_level, note);
+                       fprintf(fff, " %2d:%02d %20s sold %s.\n", hour, min, note_level, note);
 #endif
                        break;
                }
                case NIKKI_ARENA:
                {
-                       if (num == 99)
+                       if (num < 0)
                        {
-
 #ifdef JP
-                               fprintf(fff, " %2d:%02d %20s Æ®µ»¾ì¤Î%d²óÀï¤Ç¡¢%s¤ÎÁ°¤ËÇÔ¤ìµî¤Ã¤¿¡£\n", hour, min, note_level, p_ptr->arena_number + 1, note);
+                               fprintf(fff, " %2d:%02d %20s Æ®µ»¾ì¤Î%d²óÀï¤Ç¡¢%s¤ÎÁ°¤ËÇÔ¤ìµî¤Ã¤¿¡£\n", hour, min, note_level, -num, note);
 #else
-                               int n =  p_ptr->arena_number + 1;
-                               fprintf(fff, " %2d:%02d %20s beaten by %s in the %d%s fight.\n", hour, min, note_level, note, n, (n%10==1?"st":n%10==2?"nd":n%10==3?"rd":"th"));
+                               int n = -num;
+                               fprintf(fff, " %2d:%02d %20s beaten by %s in the %d%s fight.\n", hour, min, note_level, note, n, get_ordinal_number_suffix(n));
 #endif
                                break;
                        }
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s Æ®µ»¾ì¤Î%d²óÀï(%s)¤Ë¾¡Íø¤·¤¿¡£\n", hour, min, note_level, num, note);
 #else
-                       fprintf(fff, " %2d:%02d %20s win the %d%s fight (%s).\n", hour, min, note_level, num, (num%10==1?"st":num%10==2?"nd":num%10==3?"rd":"th"), note);
+                       fprintf(fff, " %2d:%02d %20s won the %d%s fight (%s).\n", hour, min, note_level, num, get_ordinal_number_suffix(num), note);
 #endif
                        if (num == MAX_ARENA_MONS)
                        {
 #ifdef JP
                                fprintf(fff, "                 Æ®µ»¾ì¤Î¤¹¤Ù¤Æ¤ÎŨ¤Ë¾¡Íø¤·¡¢¥Á¥ã¥ó¥Ô¥ª¥ó¤È¤Ê¤Ã¤¿¡£\n");
 #else
-                               fprintf(fff, "                 win all fight to become a Chanpion.\n");
+                               fprintf(fff, "                 won all fight to become a Chanpion.\n");
 #endif
                                do_level = FALSE;
                        }
@@ -556,7 +673,7 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s %s¤ò¼±Ê̤·¤¿¡£\n", hour, min, note_level, note);
 #else
-                       fprintf(fff, " %2d:%02d %20s identify %s.\n", hour, min, note_level, note);
+                       fprintf(fff, " %2d:%02d %20s identified %s.\n", hour, min, note_level, note);
 #endif
                        break;
                }
@@ -575,7 +692,7 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #else
                                to = format("level %d of %s", dun_level, d_name+d_info[dungeon_type].name);
 #endif
-                               
+
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s %s¤Ø¤È¥¦¥£¥¶¡¼¥É¡¦¥Æ¥ì¥Ý¡¼¥È¤Ç°ÜÆ°¤·¤¿¡£\n", hour, min, note_level, to);
 #else
@@ -598,11 +715,11 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #else
                                to = format("level %d of %s", dun_level, d_name+d_info[dungeon_type].name);
 #endif
-                               
+
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s %s¤Ø¤È¥Ñ¥¿¡¼¥ó¤ÎÎϤǰÜÆ°¤·¤¿¡£\n", hour, min, note_level, to);
 #else
-                       fprintf(fff, " %2d:%02d %20s use Pattern to teleport to %s.\n", hour, min, note_level, to);
+                       fprintf(fff, " %2d:%02d %20s used Pattern to teleport to %s.\n", hour, min, note_level, to);
 #endif
                        break;
                }
@@ -611,7 +728,7 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                        fprintf(fff, " %2d:%02d %20s ¥ì¥Ù¥ë¤¬%d¤Ë¾å¤¬¤Ã¤¿¡£\n", hour, min, note_level, num);
 #else
-                       fprintf(fff, " %2d:%02d %20s reach player level %d.\n", hour, min, note_level, num);
+                       fprintf(fff, " %2d:%02d %20s reached player level %d.\n", hour, min, note_level, num);
 #endif
                        break;
                }
@@ -636,56 +753,56 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 #ifdef JP
                                        fprintf(fff, "%s¤òι¤Îͧ¤Ë¤¹¤ë¤³¤È¤Ë·è¤á¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "decide to travel together with %s.\n", note);
+                                       fprintf(fff, "decided to travel together with %s.\n", note);
 #endif
                                        break;
                                case 1:
 #ifdef JP
                                        fprintf(fff, "%s¤Î̾Á°¤ò¾Ã¤·¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "unname %s.\n", note);
+                                       fprintf(fff, "unnamed %s.\n", note);
 #endif
                                        break;
                                case 2:
 #ifdef JP
                                        fprintf(fff, "%s¤ò²òÊü¤·¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "dismiss %s.\n", note);
+                                       fprintf(fff, "dismissed %s.\n", note);
 #endif
                                        break;
                                case 3:
 #ifdef JP
                                        fprintf(fff, "%s¤¬»à¤ó¤Ç¤·¤Þ¤Ã¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "%s die.\n", note);
+                                       fprintf(fff, "%s died.\n", note);
 #endif
                                        break;
                                case 4:
 #ifdef JP
                                        fprintf(fff, "%s¤ò¤ª¤¤¤ÆÊ̤ΥޥåפذÜÆ°¤·¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "move to other map leaving %s behind.\n", note);
+                                       fprintf(fff, "moved to another map leaving %s behind.\n", note);
 #endif
                                        break;
                                case 5:
 #ifdef JP
                                        fprintf(fff, "%s¤È¤Ï¤°¤ì¤Æ¤·¤Þ¤Ã¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "lose sight of %s.\n", note);
+                                       fprintf(fff, "lost sight of %s.\n", note);
 #endif
                                        break;
                                case 6:
 #ifdef JP
                                        fprintf(fff, "%s¤¬*Ç˲õ*¤Ë¤è¤Ã¤Æ¾Ã¤¨µî¤Ã¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "%s is made disappeared by *destruction*.\n", note);
+                                       fprintf(fff, "%s was made disappeared by *destruction*.\n", note);
 #endif
                                        break;
                                case 7:
 #ifdef JP
                                        fprintf(fff, "%s¤¬´äÀФ˲¡¤·ÄÙ¤µ¤ì¤¿¡£\n", note);
 #else
-                                       fprintf(fff, "%s is crushed by falling rocks.\n", note);
+                                       fprintf(fff, "%s was crushed by falling rocks.\n", note);
 #endif
                                        break;
                                default:
@@ -700,9 +817,6 @@ errr do_cmd_write_nikki(int type, int num, cptr note)
 
        my_fclose(fff);
 
-       /* Hack -- grab permissions */
-       safe_setuid_grab();
-
        if (do_level) write_level = FALSE;
 
        return (0);
@@ -789,9 +903,6 @@ static void do_cmd_disp_nikki(void)
        sprintf(file_name,"playrec-%s.txt",savefile_base);
 #endif
 
-       /* Hack -- drop permissions */
-       safe_setuid_drop();
-
        /* Build the filename */
        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
 
@@ -811,9 +922,6 @@ static void do_cmd_disp_nikki(void)
 
        /* Display the file contents */
        show_file(FALSE, buf, nikki_title, -1, 0);
-
-       /* Hack -- grab permissions */
-       safe_setuid_grab();
 }
 
 static void do_cmd_bunshou(void)
@@ -876,9 +984,6 @@ static void do_cmd_erase_nikki(void)
        sprintf(file_name,"playrec-%s.txt",savefile_base);
 #endif
 
-       /* Hack -- drop permissions */
-       safe_setuid_drop();
-
        /* Build the filename */
        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
 
@@ -901,19 +1006,8 @@ static void do_cmd_erase_nikki(void)
 #endif
        }
        msg_print(NULL);
-
-       /* Hack -- grab permissions */
-       safe_setuid_grab();
 }
 
-#if 0
-void do_debug(void)
-{
-       msg_format("%d %d %d:%d",py,px, p_ptr->energy, p_ptr->skill_dis);
-       msg_print(NULL);
-       battle_monsters();
-}
-#endif
 
 void do_cmd_nikki(void)
 {
@@ -981,11 +1075,6 @@ void do_cmd_nikki(void)
                case '4':
                        do_cmd_erase_nikki();
                        break;
-#if 0
-               case ':':
-                       do_debug();
-                       break;
-#endif
                default: /* Unknown option */
                        bell();
                }
@@ -1127,8 +1216,8 @@ void do_cmd_change_name(void)
                {
                        get_name();
 
-                        /* Process the player name */
-                        process_player_name(FALSE);
+                       /* Process the player name */
+                       process_player_name(FALSE);
                }
 
                /* File dump */
@@ -1144,7 +1233,7 @@ void do_cmd_change_name(void)
                        {
                                if (tmp[0] && (tmp[0] != ' '))
                                {
-                                       file_character(tmp, TRUE);
+                                       file_character(tmp);
                                }
                        }
                }
@@ -1202,17 +1291,19 @@ void do_cmd_message_one(void)
  */
 void do_cmd_messages(int num_now)
 {
-       int i, j, k, n;
-       uint q;
+       int i, n;
 
        char shower[80];
        char finder[80];
        int wid, hgt;
-
+       int num_lines;
 
        /* Get size */
        Term_get_size(&wid, &hgt);
 
+       /* Number of message lines in a screen */
+       num_lines = hgt - 4;
+
        /* Wipe finder */
        strcpy(finder, "");
 
@@ -1226,28 +1317,25 @@ void do_cmd_messages(int num_now)
        /* Start on first message */
        i = 0;
 
-       /* Start at leftmost edge */
-       q = 0;
-
        /* Save the screen */
        screen_save();
 
+       /* Clear screen */
+       Term_clear();
+
        /* Process requests until done */
        while (1)
        {
-               /* Clear screen */
-               Term_clear();
+               int j;
+               int skey;
 
                /* Dump up to 20 lines of messages */
-               for (j = 0; (j < hgt - 4) && (i + j < n); j++)
+               for (j = 0; (j < num_lines) && (i + j < n); j++)
                {
                        cptr msg = message_str(i+j);
 
-                       /* Apply horizontal scroll */
-                       msg = (strlen(msg) >= q) ? (msg + q) : "";
-
                        /* Dump the messages, bottom to top */
-                       Term_putstr(0, hgt-j-3, -1, (bool)(i+j < num_now ? TERM_WHITE : TERM_SLATE), msg);
+                       c_prt((i+j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
 
                        /* Hilite "shower" */
                        if (shower[0])
@@ -1255,12 +1343,12 @@ void do_cmd_messages(int num_now)
                                cptr str = msg;
 
                                /* Display matches */
-                               while ((str = strstr(str, shower)) != NULL)
+                               while ((str = my_strstr(str, shower)) != NULL)
                                {
                                        int len = strlen(shower);
 
                                        /* Display the match */
-                                       Term_putstr(str-msg, hgt-j-3, len, TERM_YELLOW, shower);
+                                       Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
 
                                        /* Advance */
                                        str += len;
@@ -1268,14 +1356,20 @@ void do_cmd_messages(int num_now)
                        }
                }
 
+               /* Erase remaining lines */
+               for (; j < num_lines; j++)
+               {
+                       Term_erase(0, num_lines + 1 - j, 255);
+               }
+
                /* Display header XXX XXX XXX */
 #ifdef JP
                /* translation */
-               prt(format("°ÊÁ°¤Î¥á¥Ã¥»¡¼¥¸ %d-%d Á´Éô¤Ç(%d) ¥ª¥Õ¥»¥Ã¥È(%d)",
-                          i, i+j-1, n, q), 0, 0);
+               prt(format("°ÊÁ°¤Î¥á¥Ã¥»¡¼¥¸ %d-%d Á´Éô¤Ç(%d)",
+                          i, i+j-1, n), 0, 0);
 #else
-               prt(format("Message Recall (%d-%d of %d), Offset %d",
-                   i, i+j-1, n, q), 0, 0);
+               prt(format("Message Recall (%d-%d of %d)",
+                          i, i+j-1, n), 0, 0);
 #endif
 
 
@@ -1288,36 +1382,16 @@ void do_cmd_messages(int num_now)
 
 
                /* Get a command */
-               k = inkey();
+               skey = inkey_special(TRUE);
 
                /* Exit on Escape */
-               if (k == ESCAPE) break;
+               if (skey == ESCAPE) break;
 
                /* Hack -- Save the old index */
                j = i;
 
-               /* Horizontal scroll */
-               if (k == '4')
-               {
-                       /* Scroll left */
-                       q = (q >= 40) ? (q - 40) : 0;
-
-                       /* Success */
-                       continue;
-               }
-
-               /* Horizontal scroll */
-               if (k == '6')
-               {
-                       /* Scroll right */
-                       q = q + 40;
-
-                       /* Success */
-                       continue;
-               }
-
                /* Hack -- handle show */
-               if (k == '=')
+               if (skey == '=')
                {
                        /* Prompt */
 #ifdef JP
@@ -1328,14 +1402,14 @@ void do_cmd_messages(int num_now)
 
 
                        /* Get a "shower" string, or continue */
-                       if (!askfor_aux(shower, 80)) continue;
+                       if (!askfor(shower, 80)) continue;
 
                        /* Okay */
                        continue;
                }
 
                /* Hack -- handle find */
-               if (k == '/')
+               if (skey == '/' || skey == KTRL('s'))
                {
                        int z;
 
@@ -1348,7 +1422,7 @@ void do_cmd_messages(int num_now)
 
 
                        /* Get a "finder" string, or continue */
-                       if (!askfor_aux(finder, 80)) continue;
+                       if (!askfor(finder, 80)) continue;
 
                        /* Show it */
                        strcpy(shower, finder);
@@ -1359,7 +1433,7 @@ void do_cmd_messages(int num_now)
                                cptr msg = message_str(z);
 
                                /* Search for it */
-                               if (strstr(msg, finder))
+                               if (my_strstr(msg, finder))
                                {
                                        /* New location */
                                        i = z;
@@ -1371,45 +1445,59 @@ void do_cmd_messages(int num_now)
                }
 
                /* Recall 1 older message */
-               if ((k == '8') || (k == '\n') || (k == '\r'))
+               if (skey == SKEY_TOP)
+               {
+                       /* Go to the oldest line */
+                       i = n - num_lines;
+               }
+
+               /* Recall 1 newer message */
+               if (skey == SKEY_BOTTOM)
+               {
+                       /* Go to the newest line */
+                       i = 0;
+               }
+
+               /* Recall 1 older message */
+               if (skey == '8' || skey == SKEY_UP || skey == '\n' || skey == '\r')
                {
-                       /* Go newer if legal */
-                       if (i + 1 < n) i += 1;
+                       /* Go older if legal */
+                       i = MIN(i + 1, n - num_lines);
                }
 
                /* Recall 10 older messages */
-               if (k == '+')
+               if (skey == '+')
                {
                        /* Go older if legal */
-                       if (i + 10 < n) i += 10;
+                       i = MIN(i + 10, n - num_lines);
                }
 
                /* Recall 20 older messages */
-               if ((k == 'p') || (k == KTRL('P')) || (k == ' '))
+               if (skey == 'p' || skey == KTRL('P') || skey == ' ' || skey == SKEY_PGUP)
                {
                        /* Go older if legal */
-                       if (i + 20 < n) i += 20;
+                       i = MIN(i + num_lines, n - num_lines);
                }
 
                /* Recall 20 newer messages */
-               if ((k == 'n') || (k == KTRL('N')))
+               if (skey == 'n' || skey == KTRL('N') || skey == SKEY_PGDOWN)
                {
                        /* Go newer (if able) */
-                       i = (i >= 20) ? (i - 20) : 0;
+                       i = MAX(0, i - num_lines);
                }
 
                /* Recall 10 newer messages */
-               if (k == '-')
+               if (skey == '-')
                {
                        /* Go newer (if able) */
-                       i = (i >= 20) ? (i - 20) : 0;
+                       i = MAX(0, i - 10);
                }
 
                /* Recall 1 newer messages */
-               if (k == '2')
+               if (skey == '2' || skey == SKEY_DOWN)
                {
                        /* Go newer (if able) */
-                       i = (i >= 1) ? (i - 1) : 0;
+                       i = MAX(0, i - 1);
                }
 
                /* Hack -- Error of some kind */
@@ -1438,7 +1526,7 @@ static option_type cheat_info[CHEAT_MAX] =
 #else
        "cheat_peek",           "Peek into object creation"
 #endif
-        },
+       },
 
        { &cheat_hear,          FALSE,  255,    0x02, 0x00,
 #ifdef JP
@@ -1446,7 +1534,7 @@ static option_type cheat_info[CHEAT_MAX] =
 #else
        "cheat_hear",           "Peek into monster creation"
 #endif
-        },
+       },
 
        { &cheat_room,          FALSE,  255,    0x04, 0x00,
 #ifdef JP
@@ -1454,7 +1542,7 @@ static option_type cheat_info[CHEAT_MAX] =
 #else
        "cheat_room",           "Peek into dungeon creation"
 #endif
-        },
+       },
 
        { &cheat_xtra,          FALSE,  255,    0x08, 0x00,
 #ifdef JP
@@ -1462,7 +1550,7 @@ static option_type cheat_info[CHEAT_MAX] =
 #else
        "cheat_xtra",           "Peek into something else"
 #endif
-        },
+       },
 
        { &cheat_know,          FALSE,  255,    0x10, 0x00,
 #ifdef JP
@@ -1470,7 +1558,7 @@ static option_type cheat_info[CHEAT_MAX] =
 #else
        "cheat_know",           "Know complete monster info"
 #endif
-        },
+       },
 
        { &cheat_live,          FALSE,  255,    0x20, 0x00,
 #ifdef JP
@@ -1478,7 +1566,7 @@ static option_type cheat_info[CHEAT_MAX] =
 #else
        "cheat_live",           "Allow player to avoid death"
 #endif
-        },
+       },
 
        { &cheat_save,          FALSE,  255,    0x40, 0x00,
 #ifdef JP
@@ -1486,7 +1574,7 @@ static option_type cheat_info[CHEAT_MAX] =
 #else
        "cheat_save",           "Ask for saving death"
 #endif
-        }
+       }
 };
 
 /*
@@ -1507,7 +1595,7 @@ static void do_cmd_options_cheat(cptr info)
        /* Interact with the player */
        while (TRUE)
        {
-                int dir;
+               int dir;
 
                /* Prompt XXX XXX XXX */
 #ifdef JP
@@ -1609,19 +1697,19 @@ static void do_cmd_options_cheat(cptr info)
                                break;
                        }
 
-                        case '?':
-                        {
+                       case '?':
+                       {
 #ifdef JP
-                                strnfmt(buf, sizeof(buf), "joption.txt#%s", cheat_info[k].o_text);
+                               strnfmt(buf, sizeof(buf), "joption.txt#%s", cheat_info[k].o_text);
 #else
-                                strnfmt(buf, sizeof(buf), "option.txt#%s", cheat_info[k].o_text);
+                               strnfmt(buf, sizeof(buf), "option.txt#%s", cheat_info[k].o_text);
 #endif
-                                /* Peruse the help file */
-                                (void)show_file(TRUE, buf, NULL, 0, 0);
+                               /* Peruse the help file */
+                               (void)show_file(TRUE, buf, NULL, 0, 0);
 
                                Term_clear(); 
-                                break;
-                        }
+                               break;
+                       }
 
                        default:
                        {
@@ -1655,17 +1743,19 @@ static option_type autosave_info[2] =
 
 static s16b toggle_frequency(s16b current)
 {
-       if (current == 0) return 50;
-       if (current == 50) return 100;
-       if (current == 100) return 250;
-       if (current == 250) return 500;
-       if (current == 500) return 1000;
-       if (current == 1000) return 2500;
-       if (current == 2500) return 5000;
-       if (current == 5000) return 10000;
-       if (current == 10000) return 25000;
-
-       return 0;
+       switch (current)
+       {
+       case 0: return 50;
+       case 50: return 100;
+       case 100: return 250;
+       case 250: return 500;
+       case 500: return 1000;
+       case 1000: return 2500;
+       case 2500: return 5000;
+       case 5000: return 10000;
+       case 10000: return 25000;
+       default: return 0;
+       }
 }
 
 
@@ -1780,26 +1870,26 @@ static void do_cmd_options_autosave(cptr info)
                                autosave_freq = toggle_frequency(autosave_freq);
 #ifdef JP
                                prt(format("¼«Æ°¥»¡¼¥Ö¤ÎÉÑÅÙ¡§ %d ¥¿¡¼¥óËè", 
-                                           autosave_freq), 5, 0);
+                                          autosave_freq), 5, 0);
 #else
                                prt(format("Timed autosave frequency: every %d turns",
-                                           autosave_freq), 5, 0);
+                                          autosave_freq), 5, 0);
 #endif
-                                break;
+                               break;
                        }
 
-                        case '?':
-                        {
+                       case '?':
+                       {
 #ifdef JP
-                                (void)show_file(TRUE, "joption.txt#Autosave", NULL, 0, 0);
+                               (void)show_file(TRUE, "joption.txt#Autosave", NULL, 0, 0);
 #else
-                                (void)show_file(TRUE, "option.txt#Autosave", NULL, 0, 0);
+                               (void)show_file(TRUE, "option.txt#Autosave", NULL, 0, 0);
 #endif
 
 
                                Term_clear(); 
-                                break;
-                        }
+                               break;
+                       }
 
                        default:
                        {
@@ -1811,8 +1901,6 @@ static void do_cmd_options_autosave(cptr info)
 }
 
 
-#define PAGE_AUTODESTROY 7
-
 /*
  * Interact with some options
  */
@@ -1822,6 +1910,8 @@ void do_cmd_options_aux(int page, cptr info)
        int     i, k = 0, n = 0, l;
        int     opt[24];
        char    buf[80];
+       bool    browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
+                             (!p_ptr->wizard || !allow_debug_opts);
 
 
        /* Lookup the options */
@@ -1841,23 +1931,23 @@ void do_cmd_options_aux(int page, cptr info)
        /* Interact with the player */
        while (TRUE)
        {
-                int dir;
+               int dir;
 
                /* Prompt XXX XXX XXX */
 #ifdef JP
-               sprintf(buf, "%s (¥ê¥¿¡¼¥ó:¼¡, y/n:Êѹ¹, ESC:½ªÎ», ?:¥Ø¥ë¥×) ", info);
+               sprintf(buf, "%s (¥ê¥¿¡¼¥ó:¼¡, %sESC:½ªÎ», ?:¥Ø¥ë¥×) ", info, browse_only ? "" : "y/n:Êѹ¹, ");
 #else
-               sprintf(buf, "%s (RET:next, y/n:change, ESC:accept, ?:help) ", info);
+               sprintf(buf, "%s (RET:next, %s, ?:help) ", info, browse_only ? "ESC:exit" : "y/n:change, ESC:accept");
 #endif
 
                prt(buf, 0, 0);
 
 
-                /* HACK -- description for easy-auto-destroy options */
+               /* HACK -- description for easy-auto-destroy options */
 #ifdef JP
-                if (page == PAGE_AUTODESTROY) c_prt(TERM_YELLOW, "°Ê²¼¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢´Ê°×¼«Æ°Ç˲õ¤ò»ÈÍѤ¹¤ë¤È¤­¤Î¤ßÍ­¸ú", 6, 6);
+               if (page == OPT_PAGE_AUTODESTROY) c_prt(TERM_YELLOW, "°Ê²¼¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢´Ê°×¼«Æ°Ç˲õ¤ò»ÈÍѤ¹¤ë¤È¤­¤Î¤ßÍ­¸ú", 6, 6);
 #else
-                if (page == PAGE_AUTODESTROY) c_prt(TERM_YELLOW, "Following options will protect items from easy auto-destroyer.", 6, 3);
+               if (page == OPT_PAGE_AUTODESTROY) c_prt(TERM_YELLOW, "Following options will protect items from easy auto-destroyer.", 6, 3);
 #endif
 
                /* Display the options */
@@ -1870,19 +1960,19 @@ void do_cmd_options_aux(int page, cptr info)
 
                        /* Display the option text */
                        sprintf(buf, "%-48s: %s (%.19s)",
-                               option_info[opt[i]].o_desc,
+                               option_info[opt[i]].o_desc,
 #ifdef JP
-                               (*option_info[opt[i]].o_var ? "¤Ï¤¤  " : "¤¤¤¤¤¨"),
+                               (*option_info[opt[i]].o_var ? "¤Ï¤¤  " : "¤¤¤¤¤¨"),
 #else
-                               (*option_info[opt[i]].o_var ? "yes" : "no "),
+                               (*option_info[opt[i]].o_var ? "yes" : "no "),
 #endif
 
-                               option_info[opt[i]].o_text);
-                       if ((page == PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
+                               option_info[opt[i]].o_text);
+                       if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
                        else c_prt(a, buf, i + 2, 0);
                }
 
-               if ((page == PAGE_AUTODESTROY) && (k > 2)) l = 3;
+               if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
                else l = 0;
 
                /* Hilite current option */
@@ -1927,6 +2017,7 @@ void do_cmd_options_aux(int page, cptr info)
                        case 'Y':
                        case '6':
                        {
+                               if (browse_only) break;
                                (*option_info[opt[k]].o_var) = TRUE;
                                k = (k + 1) % n;
                                break;
@@ -1936,6 +2027,7 @@ void do_cmd_options_aux(int page, cptr info)
                        case 'N':
                        case '4':
                        {
+                               if (browse_only) break;
                                (*option_info[opt[k]].o_var) = FALSE;
                                k = (k + 1) % n;
                                break;
@@ -1944,23 +2036,23 @@ void do_cmd_options_aux(int page, cptr info)
                        case 't':
                        case 'T':
                        {
-                               (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
+                               if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
                                break;
                        }
 
-                        case '?':
-                        {
+                       case '?':
+                       {
 #ifdef JP
-                                strnfmt(buf, sizeof(buf), "joption.txt#%s", option_info[opt[k]].o_text);
+                               strnfmt(buf, sizeof(buf), "joption.txt#%s", option_info[opt[k]].o_text);
 #else
-                                strnfmt(buf, sizeof(buf), "option.txt#%s", option_info[opt[k]].o_text);
+                               strnfmt(buf, sizeof(buf), "option.txt#%s", option_info[opt[k]].o_text);
 #endif
-                                /* Peruse the help file */
-                                (void)show_file(TRUE, buf, NULL, 0, 0);
+                               /* Peruse the help file */
+                               (void)show_file(TRUE, buf, NULL, 0, 0);
 
-                               Term_clear(); 
-                                break;
-                        }
+                               Term_clear();
+                               break;
+                       }
 
                        default:
                        {
@@ -2116,18 +2208,18 @@ static void do_cmd_options_win(void)
                                break;
                        }
 
-                        case '?':
-                        {
+                       case '?':
+                       {
 #ifdef JP
-                                (void)show_file(TRUE, "joption.txt#Window", NULL, 0, 0);
+                               (void)show_file(TRUE, "joption.txt#Window", NULL, 0, 0);
 #else
-                                (void)show_file(TRUE, "option.txt#Window", NULL, 0, 0);
+                               (void)show_file(TRUE, "option.txt#Window", NULL, 0, 0);
 #endif
 
 
                                Term_clear(); 
-                                break;
-                        }
+                               break;
+                       }
 
                        default:
                        {
@@ -2186,67 +2278,89 @@ void do_cmd_options(void)
        /* Interact */
        while (1)
        {
-                /* Clear screen */
-                Term_clear();
+               /* Clear screen */
+               Term_clear();
 
                /* Why are we here */
 #ifdef JP
-               prt("[ ¥ª¥×¥·¥ç¥ó¤ÎÀßÄê ]", 2, 0);
+               prt("[ ¥ª¥×¥·¥ç¥ó¤ÎÀßÄê ]", 1, 0);
 #else
-               prt("Options", 2, 0);
+               prt("Options", 1, 0);
 #endif
 
 
                /* Give some choices */
 #ifdef JP
-               prt("(1)     ¥­¡¼ÆþÎÏ          ¥ª¥×¥·¥ç¥ó", 4, 5);
-               prt("(2)     ²èÌ̽ÐÎÏ          ¥ª¥×¥·¥ç¥ó", 5, 5);
-               prt("(3)   ¥²¡¼¥à¥×¥ì¥¤        ¥ª¥×¥·¥ç¥ó", 6, 5);
-               prt("(4)   ¹ÔÆ°Ãæ»ß´Ø·¸        ¥ª¥×¥·¥ç¥ó", 7, 5);
-               prt("(5)      ¸úΨ²½           ¥ª¥×¥·¥ç¥ó", 8, 5);
-               prt("(6) ´Ê°×¥¢¥¤¥Æ¥à¼«Æ°Ç˲õ  ¥ª¥×¥·¥ç¥ó", 9, 5);
-               prt("(R)    ¥×¥ì¥¤µ­Ï¿         ¥ª¥×¥·¥ç¥ó", 10, 5);
+               prt("(1)      ¥­¡¼ÆþÎÏ        ¥ª¥×¥·¥ç¥ó", 2, 5);
+               prt("(2)     ¥Þ¥Ã¥×²èÌÌ       ¥ª¥×¥·¥ç¥ó", 3, 5);
+               prt("(3)    ¥Æ¥­¥¹¥Èɽ¼¨      ¥ª¥×¥·¥ç¥ó", 4, 5);
+               prt("(4)    ¥²¡¼¥à¥×¥ì¥¤      ¥ª¥×¥·¥ç¥ó", 5, 5);
+               prt("(5)    ¹ÔÆ°Ãæ»ß´Ø·¸      ¥ª¥×¥·¥ç¥ó", 6, 5);
+               prt("(6)    ´Ê°×¼«Æ°Ç˲õ      ¥ª¥×¥·¥ç¥ó", 7, 5);
+               prt("(R)     ¥×¥ì¥¤µ­Ï¿       ¥ª¥×¥·¥ç¥ó", 8, 5);
+
                /* Special choices */
-               prt("(D)  ´ðËÜ¥¦¥§¥¤¥ÈÎÌ", 12, 5);
-               prt("(H) Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð", 13, 5);
-               prt("(A)    ¼«Æ°¥»¡¼¥Ö         ¥ª¥×¥·¥ç¥ó", 14, 5);
+               prt("(P)  ¼«Æ°½¦¤¤¥¨¥Ç¥£¥¿", 10, 5);
+               prt("(D)   ´ðËÜ¥¦¥§¥¤¥ÈÎÌ", 11, 5);
+               prt("(H) Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð", 12, 5);
+               prt("(M)    ÄãËâÎÏ¿§ïçÃÍ", 13, 5);
+               prt("(A)     ¼«Æ°¥»¡¼¥Ö       ¥ª¥×¥·¥ç¥ó", 14, 5);
                /* Window flags */
-               prt("(W) ¥¦¥¤¥ó¥É¥¦¥Õ¥é¥°", 15, 5);
-#else
-               prt("(1) Input Options", 4, 5);
-               prt("(2) Output Options", 5, 5);
-               prt("(3) Game-Play Options", 6, 5);
-               prt("(4) Disturbance Options", 7, 5);
-               prt("(5) Efficiency Options", 8, 5);
-               prt("(6) Easy Auto-Destroyer Options", 9, 5);
-               prt("(R) Play-record Options", 10, 5);
-
+               prt("(W)  ¥¦¥¤¥ó¥É¥¦¥Õ¥é¥°", 15, 5);
+#else
+               prt("(1) Input Options", 2, 5);
+               prt("(2) Map Screen Options", 3, 5);
+               prt("(3) Text Display Options", 4, 5);
+               prt("(4) Game-Play Options", 5, 5);
+               prt("(5) Disturbance Options", 6, 5);
+               prt("(6) Easy Auto-Destroyer Options", 7, 5);
+               prt("(R) Play-record Options", 8, 5);
                /* Special choices */
-               prt("(D) Base Delay Factor", 12, 5);
-               prt("(H) Hitpoint Warning", 13, 5);
+               prt("(P) Auto-picker/destroyer editor", 10, 5);
+               prt("(D) Base Delay Factor", 11, 5);
+               prt("(H) Hitpoint Warning", 12, 5);
+               prt("(M) Mana Color Threshold", 13, 5);
                prt("(A) Autosave Options", 14, 5);
-
-
                /* Window flags */
                prt("(W) Window Flags", 15, 5);
 #endif
 
-                if (p_ptr->noscore || allow_debug_opts)
-                {
-                        /* Cheating */
+               if (!p_ptr->wizard || !allow_debug_opts)
+               {
+                       /* Birth */
+#ifdef JP
+                       prt("(B)        ½é´ü          ¥ª¥×¥·¥ç¥ó (»²¾È¤Î¤ß)", 16, 5);
+#else
+                       prt("(B) Birth Options (Browse Only)", 16, 5);
+#endif
+               }
+               else
+               {
+                       /* Birth */
+#ifdef JP
+                       prt("(B)        ½é´ü          ¥ª¥×¥·¥ç¥ó", 16, 5);
+#else
+                       prt("(B) Birth Options", 16, 5);
+#endif
+               }
+
+
+               if (p_ptr->noscore || allow_debug_opts)
+               {
+                       /* Cheating */
 #ifdef JP
-                        prt("(C)       º¾µ½            ¥ª¥×¥·¥ç¥ó", 16, 5);
+                       prt("(C)        º¾µ½          ¥ª¥×¥·¥ç¥ó", 17, 5);
 #else
-                        prt("(C) Cheating Options", 16, 5);
+                       prt("(C) Cheating Options", 17, 5);
 #endif
-                }
+               }
 
 
                /* Prompt */
 #ifdef JP
-               prt("¥³¥Þ¥ó¥É:", 18, 0);
+               prt("¥³¥Þ¥ó¥É:", 19, 0);
 #else
-               prt("Command: ", 18, 0);
+               prt("Command: ", 19, 0);
 #endif
 
 
@@ -2259,105 +2373,113 @@ void do_cmd_options(void)
                /* Analyze */
                switch (k)
                {
-                       /* General Options */
                        case '1':
                        {
                                /* Process the general options */
 #ifdef JP
-                               do_cmd_options_aux(1, "¥­¡¼ÆþÎÏ¥ª¥×¥·¥ç¥ó");
+                               do_cmd_options_aux(OPT_PAGE_INPUT, "¥­¡¼ÆþÎÏ¥ª¥×¥·¥ç¥ó");
 #else
-                               do_cmd_options_aux(1, "Input Options");
+                               do_cmd_options_aux(OPT_PAGE_INPUT, "Input Options");
 #endif
 
                                break;
                        }
 
-                       /* General Options */
                        case '2':
                        {
                                /* Process the general options */
 #ifdef JP
-                               do_cmd_options_aux(2, "²èÌ̽ÐÎÏ¥ª¥×¥·¥ç¥ó");
+                               do_cmd_options_aux(OPT_PAGE_MAPSCREEN, "¥Þ¥Ã¥×²èÌÌ¥ª¥×¥·¥ç¥ó");
 #else
-                               do_cmd_options_aux(2, "Output Options");
+                               do_cmd_options_aux(OPT_PAGE_MAPSCREEN, "Map Screen Options");
 #endif
 
                                break;
                        }
 
-                       /* Inventory Options */
                        case '3':
                        {
                                /* Spawn */
 #ifdef JP
-                               do_cmd_options_aux(3, "¥²¡¼¥à¥×¥ì¥¤¡¦¥ª¥×¥·¥ç¥ó");
+                               do_cmd_options_aux(OPT_PAGE_TEXT, "¥Æ¥­¥¹¥Èɽ¼¨¥ª¥×¥·¥ç¥ó");
 #else
-                               do_cmd_options_aux(3, "Game-Play Options");
+                               do_cmd_options_aux(OPT_PAGE_TEXT, "Text Display Options");
 #endif
 
                                break;
                        }
 
-                       /* Disturbance Options */
                        case '4':
                        {
                                /* Spawn */
 #ifdef JP
-                               do_cmd_options_aux(4, "¹ÔÆ°Ãæ»ß´Ø·¸¤Î¥ª¥×¥·¥ç¥ó");
+                               do_cmd_options_aux(OPT_PAGE_GAMEPLAY, "¥²¡¼¥à¥×¥ì¥¤¡¦¥ª¥×¥·¥ç¥ó");
 #else
-                               do_cmd_options_aux(4, "Disturbance Options");
+                               do_cmd_options_aux(OPT_PAGE_GAMEPLAY, "Game-Play Options");
 #endif
 
                                break;
                        }
 
-                       /* Efficiency Options */
                        case '5':
                        {
                                /* Spawn */
 #ifdef JP
-                               do_cmd_options_aux(5, "¸úΨ²½¥ª¥×¥·¥ç¥ó");
+                               do_cmd_options_aux(OPT_PAGE_DISTURBANCE, "¹ÔÆ°Ãæ»ß´Ø·¸¤Î¥ª¥×¥·¥ç¥ó");
 #else
-                               do_cmd_options_aux(5, "Efficiency Options");
+                               do_cmd_options_aux(OPT_PAGE_DISTURBANCE, "Disturbance Options");
 #endif
 
                                break;
                        }
 
-                        /* Object auto-destruction Options */
-                        case '6':
-                        {
-                                /* Spawn */
+                       case '6':
+                       {
+                               /* Spawn */
+#ifdef JP
+                               do_cmd_options_aux(OPT_PAGE_AUTODESTROY, "´Ê°×¼«Æ°Ç˲õ¥ª¥×¥·¥ç¥ó");
+#else
+                               do_cmd_options_aux(OPT_PAGE_AUTODESTROY, "Easy Auto-Destroyer Options");
+#endif
+                               break;
+                       }
+
+                       /* Play-record Options */
+                       case 'R':
+                       case 'r':
+                       {
+                               /* Spawn */
 #ifdef JP
-                                do_cmd_options_aux(7, "´Ê°×¥¢¥¤¥Æ¥à¼«Æ°Ç˲õ¥ª¥×¥·¥ç¥ó");
+                               do_cmd_options_aux(OPT_PAGE_PLAYRECORD, "¥×¥ì¥¤µ­Ï¿¥ª¥×¥·¥ç¥ó");
 #else
-                                do_cmd_options_aux(7, "Easy Auto-Destroyer Options");
+                               do_cmd_options_aux(OPT_PAGE_PLAYRECORD, "Play-record Options");
 #endif
-                                break;
-                        }
+                               break;
+                       }
 
-                        /* Play-record Options */
-                        case 'R':
-                        case 'r':
-                        {
-                                /* Spawn */
+                       /* Birth Options */
+                       case 'B':
+                       case 'b':
+                       {
+                               /* Spawn */
 #ifdef JP
-                                do_cmd_options_aux(10, "¥×¥ì¥¤µ­Ï¿¥ª¥×¥·¥ç¥ó");
+                               do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ? "½é´ü¥ª¥×¥·¥ç¥ó(»²¾È¤Î¤ß)" : "½é´ü¥ª¥×¥·¥ç¥ó((*)¤Ï¥¹¥³¥¢¤Ë±Æ¶Á)");
 #else
-                                do_cmd_options_aux(10, "Play-record Option");
+                               do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ? "Birth Options(browse only)" : "Birth Options((*)s effect score)");
 #endif
-                                break;
-                        }
+
+                               break;
+                       }
 
                        /* Cheating Options */
                        case 'C':
                        {
-                                if (!p_ptr->noscore && !allow_debug_opts)
-                                {
-                                        /* Cheat options are not permitted */
-                                        bell();
-                                        break;
-                                }
+                               if (!p_ptr->noscore && !allow_debug_opts)
+                               {
+                                       /* Cheat options are not permitted */
+                                       bell();
+                                       break;
+                               }
 
                                /* Spawn */
 #ifdef JP
@@ -2388,9 +2510,17 @@ void do_cmd_options(void)
                                /* Spawn */
                                do_cmd_options_win();
                                p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
-                                                 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
-                                                 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
-                                                 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON);
+                                                 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
+                                                 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
+                                                 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON);
+                               break;
+                       }
+
+                       /* Auto-picker/destroyer editor */
+                       case 'P':
+                       case 'p':
+                       {
+                               do_cmd_edit_autopick();
                                break;
                        }
 
@@ -2400,9 +2530,9 @@ void do_cmd_options(void)
                        {
                                /* Prompt */
 #ifdef JP
-                               prt("¥³¥Þ¥ó¥É: ´ðËÜ¥¦¥§¥¤¥ÈÎÌ", 18, 0);
+                               prt("¥³¥Þ¥ó¥É: ´ðËÜ¥¦¥§¥¤¥ÈÎÌ", 19, 0);
 #else
-                               prt("Command: Base Delay Factor", 18, 0);
+                               prt("Command: Base Delay Factor", 19, 0);
 #endif
 
 
@@ -2412,10 +2542,10 @@ void do_cmd_options(void)
                                        int msec = delay_factor * delay_factor * delay_factor;
 #ifdef JP
                                        prt(format("¸½ºß¤Î¥¦¥§¥¤¥È: %d (%d¥ß¥êÉÃ)",
-                                                  delay_factor, msec), 22, 0);
+                                                  delay_factor, msec), 22, 0);
 #else
                                        prt(format("Current base delay factor: %d (%d msec)",
-                                                  delay_factor, msec), 22, 0);
+                                                  delay_factor, msec), 22, 0);
 #endif
 
 #ifdef JP
@@ -2426,15 +2556,15 @@ void do_cmd_options(void)
 
                                        k = inkey();
                                        if (k == ESCAPE) break;
-                                        else if (k == '?')
-                                        {
+                                       else if (k == '?')
+                                       {
 #ifdef JP
-                                                (void)show_file(TRUE, "joption.txt#BaseDelay", NULL, 0, 0);
+                                               (void)show_file(TRUE, "joption.txt#BaseDelay", NULL, 0, 0);
 #else
-                                                (void)show_file(TRUE, "option.txt#BaseDelay", NULL, 0, 0);
+                                               (void)show_file(TRUE, "option.txt#BaseDelay", NULL, 0, 0);
 #endif
-                                                Term_clear(); 
-                                        }
+                                               Term_clear(); 
+                                       }
                                        else if (isdigit(k)) delay_factor = D2I(k);
                                        else bell();
                                }
@@ -2448,9 +2578,9 @@ void do_cmd_options(void)
                        {
                                /* Prompt */
 #ifdef JP
-                               prt("¥³¥Þ¥ó¥É: Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð", 18, 0);
+                               prt("¥³¥Þ¥ó¥É: Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð", 19, 0);
 #else
-                               prt("Command: Hitpoint Warning", 18, 0);
+                               prt("Command: Hitpoint Warning", 19, 0);
 #endif
 
 
@@ -2458,30 +2588,30 @@ void do_cmd_options(void)
                                while (1)
                                {
 #ifdef JP
-                                        prt(format("¸½ºß¤ÎÄã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð: %d0%%",
-                                                   hitpoint_warn), 22, 0);
+                                       prt(format("¸½ºß¤ÎÄã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð: %d0%%",
+                                                  hitpoint_warn), 22, 0);
 #else
                                        prt(format("Current hitpoint warning: %d0%%",
-                                                  hitpoint_warn), 22, 0);
+                                                  hitpoint_warn), 22, 0);
 #endif
 
 #ifdef JP
-                                        prt("Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð (0-9) ESC¤Ç·èÄê: ", 20, 0);
+                                       prt("Äã¥Ò¥Ã¥È¥Ý¥¤¥ó¥È·Ù¹ð (0-9) ESC¤Ç·èÄê: ", 20, 0);
 #else
                                        prt("Hitpoint Warning (0-9 or ESC to accept): ", 20, 0);
 #endif
 
                                        k = inkey();
                                        if (k == ESCAPE) break;
-                                        else if (k == '?')
-                                        {
+                                       else if (k == '?')
+                                       {
 #ifdef JP
-                                                (void)show_file(TRUE, "joption.txt#Hitpoint", NULL, 0, 0);
+                                               (void)show_file(TRUE, "joption.txt#Hitpoint", NULL, 0, 0);
 #else
-                                                (void)show_file(TRUE, "option.txt#Hitpoint", NULL, 0, 0);
+                                               (void)show_file(TRUE, "option.txt#Hitpoint", NULL, 0, 0);
 #endif
-                                                Term_clear(); 
-                                        }
+                                               Term_clear(); 
+                                       }
                                        else if (isdigit(k)) hitpoint_warn = D2I(k);
                                        else bell();
                                }
@@ -2489,14 +2619,61 @@ void do_cmd_options(void)
                                break;
                        }
 
-                        case '?':
+                       /* Hack -- mana color factor */
+                       case 'M':
+                       case 'm':
+                       {
+                               /* Prompt */
+#ifdef JP
+                               prt("¥³¥Þ¥ó¥É: ÄãËâÎÏ¿§ïçÃÍ", 19, 0);
+#else
+                               prt("Command: Mana Color Threshold", 19, 0);
+#endif
+
+
+                               /* Get a new value */
+                               while (1)
+                               {
+#ifdef JP
+                                       prt(format("¸½ºß¤ÎÄãËâÎÏ¿§ïçÃÍ: %d0%%",
+                                                  mana_warn), 22, 0);
+#else
+                                       prt(format("Current mana color threshold: %d0%%",
+                                                  mana_warn), 22, 0);
+#endif
+
+#ifdef JP
+                                       prt("ÄãËâÎÏïçÃÍ (0-9) ESC¤Ç·èÄê: ", 20, 0);
+#else
+                                       prt("Mana color Threshold (0-9 or ESC to accept): ", 20, 0);
+#endif
+
+                                       k = inkey();
+                                       if (k == ESCAPE) break;
+                                       else if (k == '?')
+                                       {
+#ifdef JP
+                                               (void)show_file(TRUE, "joption.txt#Manapoint", NULL, 0, 0);
+#else
+                                               (void)show_file(TRUE, "option.txt#Manapoint", NULL, 0, 0);
+#endif
+                                               Term_clear(); 
+                                       }
+                                       else if (isdigit(k)) mana_warn = D2I(k);
+                                       else bell();
+                               }
+
+                               break;
+                       }
+
+                       case '?':
 #ifdef JP
-                                (void)show_file(TRUE, "joption.txt", NULL, 0, 0);
+                               (void)show_file(TRUE, "joption.txt", NULL, 0, 0);
 #else
-                                (void)show_file(TRUE, "option.txt", NULL, 0, 0);
+                               (void)show_file(TRUE, "option.txt", NULL, 0, 0);
 #endif
                                Term_clear(); 
-                                break;
+                               break;
 
                        /* Unknown option */
                        default:
@@ -2545,65 +2722,17 @@ void do_cmd_pref(void)
        (void)process_pref_file_command(buf);
 }
 
-void do_cmd_pickpref(void)
+void do_cmd_reload_autopick(void)
 {
-       char buf[80];
-       errr err;
-
 #ifdef JP
-       if(!get_check("¼«Æ°½¦¤¤ÀßÄê¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¤·¤Þ¤¹¤«? ")) return;
+       if (!get_check("¼«Æ°½¦¤¤ÀßÄê¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¤·¤Þ¤¹¤«? ")) return;
 #else
-       if(!get_check("Reload auto-pick preference file? ")) return;
+       if (!get_check("Reload auto-pick preference file? ")) return;
 #endif
 
-       /* Free old entries */
-       init_autopicker();
-
-       /* ¥­¥ã¥éËè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ÎÆɤ߹þ¤ß */
-#ifdef JP
-       sprintf(buf, "picktype-%s.prf", player_name);
-#else
-       sprintf(buf, "pickpref-%s.prf", player_name);
-#endif
-       err = process_pickpref_file(buf);
-
-       if(err == 0)
-       {
-#ifdef JP
-               msg_format("%s¤òÆɤ߹þ¤ß¤Þ¤·¤¿¡£", buf);
-#else
-               msg_format("loaded '%s'.", buf);
-#endif
-       }
-
-       /* ¶¦Ä̤ÎÀßÄê¥Õ¥¡¥¤¥ëÆɤ߹þ¤ß */
-
-       /* Process 'pick????.prf' if 'pick????-<name>.prf' doesn't exist */
-       if (0 > err)
-       {
-#ifdef JP
-               err = process_pickpref_file("picktype.prf");
-#else
-               err = process_pickpref_file("pickpref.prf");
-#endif
-
-               if(err == 0)
-               {
-#ifdef JP
-                       msg_print("picktype.prf¤òÆɤ߹þ¤ß¤Þ¤·¤¿¡£");
-#else
-                       msg_print("loaded 'pickpref.prf'.");
-#endif
-               }
-       }
-
-
-#ifdef JP
-       if(err) msg_print("¼«Æ°½¦¤¤ÀßÄê¥Õ¥¡¥¤¥ë¤ÎÆɤ߹þ¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£");
-#else
-       if(err) msg_print("Failed to reload autopick preference.");
-#endif
-}
+       /* Load the file with messages */
+       autopick_load_pref(TRUE);
+}
 
 #ifdef ALLOW_MACROS
 
@@ -2614,9 +2743,7 @@ static errr macro_dump(cptr fname)
 {
        static cptr mark = "Macro Dump";
 
-       int i, line_num;
-
-       FILE *fff;
+       int i;
 
        char buf[1024];
 
@@ -2627,16 +2754,14 @@ static errr macro_dump(cptr fname)
        FILE_TYPE(FILE_TYPE_TEXT);
 
        /* Append to the file */
-       fff = open_auto_dump(buf, mark, &line_num);
-       if (!fff) return (-1);
+       if (!open_auto_dump(buf, mark)) return (-1);
 
        /* Start dumping */
 #ifdef JP
-       fprintf(fff, "\n# ¼«Æ°¥Þ¥¯¥í¥»¡¼¥Ö\n\n");
+       auto_dump_printf("\n# ¼«Æ°¥Þ¥¯¥í¥»¡¼¥Ö\n\n");
 #else
-       fprintf(fff, "\n# Automatic macro dump\n\n");
+       auto_dump_printf("\n# Automatic macro dump\n\n");
 #endif
-       line_num += 3;
 
        /* Dump them */
        for (i = 0; i < macro__num; i++)
@@ -2645,23 +2770,20 @@ static errr macro_dump(cptr fname)
                ascii_to_text(buf, macro__act[i]);
 
                /* Dump the macro */
-               fprintf(fff, "A:%s\n", buf);
+               auto_dump_printf("A:%s\n", buf);
 
                /* Extract the action */
                ascii_to_text(buf, macro__pat[i]);
 
                /* Dump normal macros */
-               fprintf(fff, "P:%s\n", buf);
+               auto_dump_printf("P:%s\n", buf);
 
                /* End the macro */
-               fprintf(fff, "\n");
-
-               /* count number of lines */
-               line_num += 3;
+               auto_dump_printf("\n");
        }
 
        /* Close */
-       close_auto_dump(fff, mark, line_num);
+       close_auto_dump();
 
        /* Success */
        return (0);
@@ -2762,11 +2884,8 @@ static void do_cmd_macro_aux_keymap(char *buf)
 static errr keymap_dump(cptr fname)
 {
        static cptr mark = "Keymap Dump";
-       int line_num;
        int i;
 
-       FILE *fff;
-
        char key[1024];
        char buf[1024];
 
@@ -2792,16 +2911,14 @@ static errr keymap_dump(cptr fname)
        FILE_TYPE(FILE_TYPE_TEXT);
 
        /* Append to the file */
-       fff = open_auto_dump(buf, mark, &line_num);
-       if (!fff) return -1;
+       if (!open_auto_dump(buf, mark)) return -1;
 
        /* Start dumping */
 #ifdef JP
-       fprintf(fff, "\n# ¼«Æ°¥­¡¼ÇÛÃÖ¥»¡¼¥Ö\n\n");
+       auto_dump_printf("\n# ¼«Æ°¥­¡¼ÇÛÃÖ¥»¡¼¥Ö\n\n");
 #else
-       fprintf(fff, "\n# Automatic keymap dump\n\n");
+       auto_dump_printf("\n# Automatic keymap dump\n\n");
 #endif
-       line_num += 3;
 
        /* Dump them */
        for (i = 0; i < 256; i++)
@@ -2823,13 +2940,12 @@ static errr keymap_dump(cptr fname)
                ascii_to_text(buf, act);
 
                /* Dump the macro */
-               fprintf(fff, "A:%s\n", buf);
-               fprintf(fff, "C:%d:%s\n", mode, key);
-               line_num += 2;
+               auto_dump_printf("A:%s\n", buf);
+               auto_dump_printf("C:%d:%s\n", mode, key);
        }
 
        /* Close */
-       close_auto_dump(fff, mark, line_num);
+       close_auto_dump();
 
        /* Success */
        return (0);
@@ -2914,15 +3030,15 @@ void do_cmd_macros(void)
 
 #ifdef ALLOW_MACROS
 #ifdef JP
-                prt("(2) ¥Õ¥¡¥¤¥ë¤Ë¥Þ¥¯¥í¤òÄɲÃ", 5, 5);
-                prt("(3) ¥Þ¥¯¥í¤Î³Îǧ", 6, 5);
-                prt("(4) ¥Þ¥¯¥í¤ÎºîÀ®", 7, 5);
-                prt("(5) ¥Þ¥¯¥í¤Îºï½ü", 8, 5);
-                prt("(6) ¥Õ¥¡¥¤¥ë¤Ë¥­¡¼ÇÛÃÖ¤òÄɲÃ", 9, 5);
-                prt("(7) ¥­¡¼ÇÛÃ֤γÎǧ", 10, 5);
-                prt("(8) ¥­¡¼ÇÛÃ֤κîÀ®", 11, 5);
-                prt("(9) ¥­¡¼ÇÛÃ֤κï½ü", 12, 5);
-                prt("(0) ¥Þ¥¯¥í¹ÔÆ°¤ÎÆþÎÏ", 13, 5);
+               prt("(2) ¥Õ¥¡¥¤¥ë¤Ë¥Þ¥¯¥í¤òÄɲÃ", 5, 5);
+               prt("(3) ¥Þ¥¯¥í¤Î³Îǧ", 6, 5);
+               prt("(4) ¥Þ¥¯¥í¤ÎºîÀ®", 7, 5);
+               prt("(5) ¥Þ¥¯¥í¤Îºï½ü", 8, 5);
+               prt("(6) ¥Õ¥¡¥¤¥ë¤Ë¥­¡¼ÇÛÃÖ¤òÄɲÃ", 9, 5);
+               prt("(7) ¥­¡¼ÇÛÃ֤γÎǧ", 10, 5);
+               prt("(8) ¥­¡¼ÇÛÃ֤κîÀ®", 11, 5);
+               prt("(9) ¥­¡¼ÇÛÃ֤κï½ü", 12, 5);
+               prt("(0) ¥Þ¥¯¥í¹ÔÆ°¤ÎÆþÎÏ", 13, 5);
 #else
                prt("(2) Append macros to a file", 5, 5);
                prt("(3) Query a macro", 6, 5);
@@ -2976,7 +3092,7 @@ void do_cmd_macros(void)
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Ask for a file */
-                       if (!askfor_aux(tmp, 80)) continue;
+                       if (!askfor(tmp, 80)) continue;
 
                        /* Process the given filename */
                        err = process_pref_file(tmp);
@@ -3032,7 +3148,7 @@ void do_cmd_macros(void)
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Ask for a file */
-                       if (!askfor_aux(tmp, 80)) continue;
+                       if (!askfor(tmp, 80)) continue;
 
                        /* Dump the macros */
                        (void)macro_dump(tmp);
@@ -3132,6 +3248,13 @@ void do_cmd_macros(void)
                        /* Clear */
                        clear_from(20);
 
+                       /* Help message */
+#ifdef JP
+                       c_prt(TERM_L_RED, "¥«¡¼¥½¥ë¥­¡¼¤Îº¸±¦¤Ç¥«¡¼¥½¥ë°ÌÃÖ¤ò°ÜÆ°¡£Backspace¤«Delete¤Ç°ìʸ»úºï½ü¡£", 22, 0);
+#else
+                       c_prt(TERM_L_RED, "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char.", 22, 0);
+#endif
+
                        /* Prompt */
 #ifdef JP
                        prt("¥Þ¥¯¥í¹ÔÆ°: ", 20, 0);
@@ -3144,7 +3267,7 @@ void do_cmd_macros(void)
                        ascii_to_text(tmp, macro__buf);
 
                        /* Get an encoded action */
-                       if (askfor_aux(tmp, 80))
+                       if (askfor(tmp, 80))
                        {
                                /* Convert to ascii */
                                text_to_ascii(macro__buf, tmp);
@@ -3219,7 +3342,7 @@ void do_cmd_macros(void)
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Ask for a file */
-                       if (!askfor_aux(tmp, 80)) continue;
+                       if (!askfor(tmp, 80)) continue;
 
                        /* Dump the macros */
                        (void)keymap_dump(tmp);
@@ -3319,6 +3442,13 @@ void do_cmd_macros(void)
                        /* Clear */
                        clear_from(20);
 
+                       /* Help message */
+#ifdef JP
+                       c_prt(TERM_L_RED, "¥«¡¼¥½¥ë¥­¡¼¤Îº¸±¦¤Ç¥«¡¼¥½¥ë°ÌÃÖ¤ò°ÜÆ°¡£Backspace¤«Delete¤Ç°ìʸ»úºï½ü¡£", 22, 0);
+#else
+                       c_prt(TERM_L_RED, "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char.", 22, 0);
+#endif
+
                        /* Prompt */
 #ifdef JP
                        prt("¹ÔÆ°: ", 20, 0);
@@ -3331,7 +3461,7 @@ void do_cmd_macros(void)
                        ascii_to_text(tmp, macro__buf);
 
                        /* Get an encoded action */
-                       if (askfor_aux(tmp, 80))
+                       if (askfor(tmp, 80))
                        {
                                /* Convert to ascii */
                                text_to_ascii(macro__buf, tmp);
@@ -3399,15 +3529,28 @@ void do_cmd_macros(void)
                        prt("Command: Enter a new action", 16, 0);
 #endif
 
+                       /* Clear */
+                       clear_from(20);
+
+                       /* Help message */
+#ifdef JP
+                       c_prt(TERM_L_RED, "¥«¡¼¥½¥ë¥­¡¼¤Îº¸±¦¤Ç¥«¡¼¥½¥ë°ÌÃÖ¤ò°ÜÆ°¡£Backspace¤«Delete¤Ç°ìʸ»úºï½ü¡£", 22, 0);
+#else
+                       c_prt(TERM_L_RED, "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char.", 22, 0);
+#endif
 
-                       /* Go to the correct location */
-                       Term_gotoxy(0, 22);
+                       /* Prompt */
+#ifdef JP
+                       prt("¥Þ¥¯¥í¹ÔÆ°: ", 20, 0);
+#else
+                       prt("Action: ", 20, 0);
+#endif
 
                        /* Hack -- limit the value */
                        tmp[80] = '\0';
 
                        /* Get an encoded action */
-                       if (!askfor_aux(buf, 80)) continue;
+                       if (!askfor(buf, 80)) continue;
 
                        /* Extract an action */
                        text_to_ascii(macro__buf, buf);
@@ -3431,7 +3574,21 @@ void do_cmd_macros(void)
 }
 
 
-static void cmd_visuals_aux(int i, int *num, int max)
+static cptr lighting_level_str[F_LIT_MAX] =
+{
+#ifdef JP
+       "ɸ½à¿§",
+       "ÌÀ¿§",
+       "°Å¿§",
+#else
+       "standard",
+       "brightly lit",
+       "darkened",
+#endif
+};
+
+
+static bool cmd_visuals_aux(int i, int *num, int max)
 {
        if (iscntrl(i))
        {
@@ -3441,43 +3598,97 @@ static void cmd_visuals_aux(int i, int *num, int max)
                sprintf(str, "%d", *num);
 
                if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
-                       return;
+                       return FALSE;
 
                tmp = strtol(str, NULL, 0);
                if (tmp >= 0 && tmp < max)
                        *num = tmp;
-               return;
        }
        else if (isupper(i))
                *num = (*num + max - 1) % max;
        else
                *num = (*num + 1) % max;
 
-       return;
+       return TRUE;
 }
 
+static void print_visuals_menu(cptr choice_msg)
+{
+#ifdef JP
+       prt("²èÌÌɽ¼¨¤ÎÀßÄê", 1, 0);
+#else
+       prt("Interact with Visuals", 1, 0);
+#endif
+
+       /* Give some choices */
+#ifdef JP
+       prt("(0) ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 3, 5);
+#else
+       prt("(0) Load a user pref file", 3, 5);
+#endif
+
+#ifdef ALLOW_VISUALS
+#ifdef JP
+       prt("(1) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 4, 5);
+       prt("(2) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 5, 5);
+       prt("(3) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 6, 5);
+       prt("(4) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¿ôÃÍÁàºî)", 7, 5);
+       prt("(5) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¿ôÃÍÁàºî)", 8, 5);
+       prt("(6) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¿ôÃÍÁàºî)", 9, 5);
+       prt("(7) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¥·¥ó¥Ü¥ë¥¨¥Ç¥£¥¿)", 10, 5);
+       prt("(8) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¥·¥ó¥Ü¥ë¥¨¥Ç¥£¥¿)", 11, 5);
+       prt("(9) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë (¥·¥ó¥Ü¥ë¥¨¥Ç¥£¥¿)", 12, 5);
+#else
+       prt("(1) Dump monster attr/chars", 4, 5);
+       prt("(2) Dump object attr/chars", 5, 5);
+       prt("(3) Dump feature attr/chars", 6, 5);
+       prt("(4) Change monster attr/chars (numeric operation)", 7, 5);
+       prt("(5) Change object attr/chars (numeric operation)", 8, 5);
+       prt("(6) Change feature attr/chars (numeric operation)", 9, 5);
+       prt("(7) Change monster attr/chars (visual mode)", 10, 5);
+       prt("(8) Change object attr/chars (visual mode)", 11, 5);
+       prt("(9) Change feature attr/chars (visual mode)", 12, 5);
+#endif
+
+#endif /* ALLOW_VISUALS */
+
+#ifdef JP
+       prt("(R) ²èÌÌɽ¼¨ÊýË¡¤Î½é´ü²½", 13, 5);
+#else
+       prt("(R) Reset visuals", 13, 5);
+#endif
+
+       /* Prompt */
+#ifdef JP
+       prt(format("¥³¥Þ¥ó¥É: %s", choice_msg ? choice_msg : ""), 15, 0);
+#else
+       prt(format("Command: %s", choice_msg ? choice_msg : ""), 15, 0);
+#endif
+}
+
+static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, int direct_r_idx);
+static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, int direct_k_idx);
+static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, int direct_f_idx, int *lighting_level);
+
 /*
  * Interact with "visuals"
  */
 void do_cmd_visuals(void)
 {
        int i;
-
-       FILE *fff;
-
        char tmp[160];
-
        char buf[1024];
+       bool need_redraw = FALSE;
+       const char *empty_symbol = "<< ? >>";
 
+       if (use_bigtile) empty_symbol = "<< ?? >>";
 
        /* File type is "TEXT" */
        FILE_TYPE(FILE_TYPE_TEXT);
 
-
        /* Save the screen */
        screen_save();
 
-
        /* Interact until done */
        while (1)
        {
@@ -3485,56 +3696,7 @@ void do_cmd_visuals(void)
                Term_clear();
 
                /* Ask for a choice */
-#ifdef JP
-               prt("²èÌÌɽ¼¨¤ÎÀßÄê", 2, 0);
-#else
-               prt("Interact with Visuals", 2, 0);
-#endif
-
-
-               /* Give some choices */
-#ifdef JP
-               prt("(1) ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 4, 5);
-#else
-               prt("(1) Load a user pref file", 4, 5);
-#endif
-
-#ifdef ALLOW_VISUALS
-#ifdef JP
-               prt("(2) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 5, 5);
-               prt("(3) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 6, 5);
-               prt("(4) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 7, 5);
-               prt("(5) (̤»ÈÍÑ)", 8, 5);
-               prt("(6) ¥â¥ó¥¹¥¿¡¼¤Î ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë", 9, 5);
-               prt("(7) ¥¢¥¤¥Æ¥à¤Î   ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë", 10, 5);
-               prt("(8) ÃÏ·Á¤Î       ¿§/ʸ»ú ¤òÊѹ¹¤¹¤ë", 11, 5);
-               prt("(9) (̤»ÈÍÑ)", 12, 5);
-#else
-               prt("(2) Dump monster attr/chars", 5, 5);
-               prt("(3) Dump object attr/chars", 6, 5);
-               prt("(4) Dump feature attr/chars", 7, 5);
-               prt("(5) (unused)", 8, 5);
-               prt("(6) Change monster attr/chars", 9, 5);
-               prt("(7) Change object attr/chars", 10, 5);
-               prt("(8) Change feature attr/chars", 11, 5);
-               prt("(9) (unused)", 12, 5);
-#endif
-
-#endif
-#ifdef JP
-               prt("(0) ²èÌÌɽ¼¨ÊýË¡¤Î½é´ü²½", 13, 5);
-#else
-               prt("(0) Reset visuals", 13, 5);
-#endif
-
-
-               /* Prompt */
-#ifdef JP
-               prt("¥³¥Þ¥ó¥É:", 18, 0);
-#else
-               prt("Command: ", 15, 0);
-#endif
-
+               print_visuals_menu(NULL);
 
                /* Prompt */
                i = inkey();
@@ -3542,9 +3704,10 @@ void do_cmd_visuals(void)
                /* Done */
                if (i == ESCAPE) break;
 
-               /* Load a 'pref' file */
-               else if (i == '1')
+               switch (i)
                {
+               /* Load a 'pref' file */
+               case '0':
                        /* Prompt */
 #ifdef JP
                        prt("¥³¥Þ¥ó¥É: ¥æ¡¼¥¶¡¼ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥í¡¼¥É", 15, 0);
@@ -3552,32 +3715,31 @@ void do_cmd_visuals(void)
                        prt("Command: Load a user pref file", 15, 0);
 #endif
 
-
                        /* Prompt */
 #ifdef JP
-                       prt("¥Õ¥¡¥¤¥ë: ", 18, 0);
+                       prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
 #else
                        prt("File: ", 17, 0);
 #endif
 
-
                        /* Default filename */
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Query */
-                       if (!askfor_aux(tmp, 70)) continue;
+                       if (!askfor(tmp, 70)) continue;
 
                        /* Process the given filename */
                        (void)process_pref_file(tmp);
-               }
+
+                       need_redraw = TRUE;
+                       break;
 
 #ifdef ALLOW_VISUALS
 
                /* Dump monster attr/chars */
-               else if (i == '2')
+               case '1':
                {
                        static cptr mark = "Monster attr/chars";
-                       int line_num;
 
                        /* Prompt */
 #ifdef JP
@@ -3586,7 +3748,6 @@ void do_cmd_visuals(void)
                        prt("Command: Dump monster attr/chars", 15, 0);
 #endif
 
-
                        /* Prompt */
 #ifdef JP
                        prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
@@ -3594,30 +3755,27 @@ void do_cmd_visuals(void)
                        prt("File: ", 17, 0);
 #endif
 
-
                        /* Default filename */
                        sprintf(tmp, "%s.prf", player_name);
-                       
+
                        /* Get a filename */
-                       if (!askfor_aux(tmp, 70)) continue;
+                       if (!askfor(tmp, 70)) continue;
 
                        /* Build the filename */
                        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
 
                        /* Append to the file */
-                       fff = open_auto_dump(buf, mark, &line_num);
-                       if (!fff) continue;
+                       if (!open_auto_dump(buf, mark)) continue;
 
                        /* Start dumping */
 #ifdef JP
-                       fprintf(fff, "\n# ¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
+                       auto_dump_printf("\n# ¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
 #else
-                       fprintf(fff, "\n# Monster attr/char definitions\n\n");
+                       auto_dump_printf("\n# Monster attr/char definitions\n\n");
 #endif
-                       line_num += 3;
 
                        /* Dump monsters */
-                       for (i = 0; i < max_r_idx; i++)
+                       for (i = 1; i < max_r_idx; i++)
                        {
                                monster_race *r_ptr = &r_info[i];
 
@@ -3625,17 +3783,15 @@ void do_cmd_visuals(void)
                                if (!r_ptr->name) continue;
 
                                /* Dump a comment */
-                               fprintf(fff, "# %s\n", (r_name + r_ptr->name));
-                               line_num++;
+                               auto_dump_printf("# %s\n", (r_name + r_ptr->name));
 
                                /* Dump the monster attr/char info */
-                               fprintf(fff, "R:%d:0x%02X:0x%02X\n\n", i,
-                                       (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
-                               line_num += 2;
+                               auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
+                                       (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
                        }
 
                        /* Close */
-                       close_auto_dump(fff, mark, line_num);
+                       close_auto_dump();
 
                        /* Message */
 #ifdef JP
@@ -3644,13 +3800,13 @@ void do_cmd_visuals(void)
                        msg_print("Dumped monster attr/chars.");
 #endif
 
+                       break;
                }
 
                /* Dump object attr/chars */
-               else if (i == '3')
+               case '2':
                {
                        static cptr mark = "Object attr/chars";
-                       int line_num;
 
                        /* Prompt */
 #ifdef JP
@@ -3659,7 +3815,6 @@ void do_cmd_visuals(void)
                        prt("Command: Dump object attr/chars", 15, 0);
 #endif
 
-
                        /* Prompt */
 #ifdef JP
                        prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
@@ -3667,48 +3822,60 @@ void do_cmd_visuals(void)
                        prt("File: ", 17, 0);
 #endif
 
-
                        /* Default filename */
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Get a filename */
-                       if (!askfor_aux(tmp, 70)) continue;
+                       if (!askfor(tmp, 70)) continue;
 
                        /* Build the filename */
                        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
 
                        /* Append to the file */
-                       fff = open_auto_dump(buf, mark, &line_num);
-                       if (!fff) continue;
+                       if (!open_auto_dump(buf, mark)) continue;
 
                        /* Start dumping */
 #ifdef JP
-                       fprintf(fff, "\n# ¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
+                       auto_dump_printf("\n# ¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
 #else
-                       fprintf(fff, "\n# Object attr/char definitions\n\n");
+                       auto_dump_printf("\n# Object attr/char definitions\n\n");
 #endif
-                       line_num += 3;
 
                        /* Dump objects */
-                       for (i = 0; i < max_k_idx; i++)
+                       for (i = 1; i < max_k_idx; i++)
                        {
+                               char o_name[80];
                                object_kind *k_ptr = &k_info[i];
 
                                /* Skip non-entries */
                                if (!k_ptr->name) continue;
 
+                               if (!k_ptr->flavor)
+                               {
+                                       /* Tidy name */
+                                       strip_name(o_name, i);
+                               }
+                               else
+                               {
+                                       object_type forge;
+
+                                       /* Prepare dummy object */
+                                       object_prep(&forge, i);
+
+                                       /* Get un-shuffled flavor name */
+                                       object_desc(o_name, &forge, OD_FORCE_FLAVOR);
+                               }
+
                                /* Dump a comment */
-                               fprintf(fff, "# %s\n", (k_name + k_ptr->name));
-                               line_num++;
+                               auto_dump_printf("# %s\n", o_name);
 
                                /* Dump the object attr/char info */
-                               fprintf(fff, "K:%d:0x%02X:0x%02X\n\n", i,
-                                       (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
-                               line_num += 2;
+                               auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", i,
+                                       (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
                        }
 
                        /* Close */
-                       close_auto_dump(fff, mark, line_num);
+                       close_auto_dump();
 
                        /* Message */
 #ifdef JP
@@ -3717,13 +3884,13 @@ void do_cmd_visuals(void)
                        msg_print("Dumped object attr/chars.");
 #endif
 
+                       break;
                }
 
                /* Dump feature attr/chars */
-               else if (i == '4')
+               case '3':
                {
                        static cptr mark = "Feature attr/chars";
-                       int line_num;
 
                        /* Prompt */
 #ifdef JP
@@ -3732,7 +3899,6 @@ void do_cmd_visuals(void)
                        prt("Command: Dump feature attr/chars", 15, 0);
 #endif
 
-
                        /* Prompt */
 #ifdef JP
                        prt("¥Õ¥¡¥¤¥ë: ", 17, 0);
@@ -3740,48 +3906,48 @@ void do_cmd_visuals(void)
                        prt("File: ", 17, 0);
 #endif
 
-
                        /* Default filename */
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Get a filename */
-                       if (!askfor_aux(tmp, 70)) continue;
+                       if (!askfor(tmp, 70)) continue;
 
                        /* Build the filename */
                        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
 
                        /* Append to the file */
-                       fff = open_auto_dump(buf, mark, &line_num);
-                       if (!fff) continue;
+                       if (!open_auto_dump(buf, mark)) continue;
 
                        /* Start dumping */
 #ifdef JP
-                       fprintf(fff, "\n# ÃÏ·Á¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
+                       auto_dump_printf("\n# ÃÏ·Á¤Î[¿§/ʸ»ú]¤ÎÀßÄê\n\n");
 #else
-                       fprintf(fff, "\n# Feature attr/char definitions\n\n");
+                       auto_dump_printf("\n# Feature attr/char definitions\n\n");
 #endif
-                       line_num += 3;
 
                        /* Dump features */
-                       for (i = 0; i < max_f_idx; i++)
+                       for (i = 1; i < max_f_idx; i++)
                        {
                                feature_type *f_ptr = &f_info[i];
 
                                /* Skip non-entries */
                                if (!f_ptr->name) continue;
 
+                               /* Skip mimiccing features */
+                               if (f_ptr->mimic != i) continue;
+
                                /* Dump a comment */
-                               fprintf(fff, "# %s\n", (f_name + f_ptr->name));
-                               line_num++;
+                               auto_dump_printf("# %s\n", (f_name + f_ptr->name));
 
                                /* Dump the feature attr/char info */
-                               fprintf(fff, "F:%d:0x%02X:0x%02X\n\n", i,
-                                       (byte)(f_ptr->x_attr), (byte)(f_ptr->x_char));
-                               line_num += 2;
+                               auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
+                                       (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
+                                       (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
+                                       (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
                        }
 
                        /* Close */
-                       close_auto_dump(fff, mark, line_num);
+                       close_auto_dump();
 
                        /* Message */
 #ifdef JP
@@ -3790,21 +3956,25 @@ void do_cmd_visuals(void)
                        msg_print("Dumped feature attr/chars.");
 #endif
 
+                       break;
                }
 
-               /* Modify monster attr/chars */
-               else if (i == '6')
+               /* Modify monster attr/chars (numeric operation) */
+               case '4':
                {
+#ifdef JP
+                       static cptr choice_msg = "¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹";
+#else
+                       static cptr choice_msg = "Change monster attr/chars";
+#endif
                        static int r = 0;
 
-                       /* Prompt */
 #ifdef JP
-                       prt("¥³¥Þ¥ó¥É: ¥â¥ó¥¹¥¿¡¼¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹", 15, 0);
+                       prt(format("¥³¥Þ¥ó¥É: %s", choice_msg), 15, 0);
 #else
-                       prt("Command: Change monster attr/chars", 15, 0);
+                       prt(format("Command: %s", choice_msg), 15, 0);
 #endif
 
-
                        /* Hack -- query until done */
                        while (1)
                        {
@@ -3812,68 +3982,53 @@ void do_cmd_visuals(void)
                                char c;
                                int t;
 
-                               byte da = (r_ptr->d_attr);
-                               byte dc = (r_ptr->d_char);
-                               byte ca = (r_ptr->x_attr);
-                               byte cc = (r_ptr->x_char);
+                               byte da = r_ptr->d_attr;
+                               byte dc = r_ptr->d_char;
+                               byte ca = r_ptr->x_attr;
+                               byte cc = r_ptr->x_char;
 
                                /* Label the object */
 #ifdef JP
                                Term_putstr(5, 17, -1, TERM_WHITE,
-                                           format("¥â¥ó¥¹¥¿¡¼ = %d, Ì¾Á° = %-40.40s",
-                                                  r, (r_name + r_ptr->name)));
+                                           format("¥â¥ó¥¹¥¿¡¼ = %d, Ì¾Á° = %-40.40s",
+                                                  r, (r_name + r_ptr->name)));
 #else
                                Term_putstr(5, 17, -1, TERM_WHITE,
-                                           format("Monster = %d, Name = %-40.40s",
-                                                  r, (r_name + r_ptr->name)));
+                                           format("Monster = %d, Name = %-40.40s",
+                                                  r, (r_name + r_ptr->name)));
 #endif
 
-
                                /* Label the Default values */
 #ifdef JP
                                Term_putstr(10, 19, -1, TERM_WHITE,
-                                           format("½é´üÃÍ  ¿§ / Ê¸»ú = %3u / %3u", da, dc));
+                                           format("½é´üÃÍ  ¿§ / Ê¸»ú = %3u / %3u", da, dc));
 #else
                                Term_putstr(10, 19, -1, TERM_WHITE,
-                                           format("Default attr/char = %3u / %3u", da, dc));
+                                           format("Default attr/char = %3u / %3u", da, dc));
 #endif
 
-                               Term_putstr(40, 19, -1, TERM_WHITE, "<< ? >>");
-                               Term_putch(43, 19, da, dc);
-                               if (use_bigtile)
-                               {
-                                       if (da & 0x80)
-                                               Term_putch(44, 19, 255, -1);
-                                       else
-                                               Term_putch(44, 19, 0, ' ');
-                               }
+                               Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
+                               Term_queue_bigchar(43, 19, da, dc, 0, 0);
 
                                /* Label the Current values */
 #ifdef JP
                                Term_putstr(10, 20, -1, TERM_WHITE,
-                                           format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3u / %3u", ca, cc));
+                                           format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3u / %3u", ca, cc));
 #else
                                Term_putstr(10, 20, -1, TERM_WHITE,
-                                           format("Current attr/char = %3u / %3u", ca, cc));
+                                           format("Current attr/char = %3u / %3u", ca, cc));
 #endif
 
-                               Term_putstr(40, 20, -1, TERM_WHITE, "<< ? >>");
-                               Term_putch(43, 20, ca, cc);
-                               if (use_bigtile)
-                               {
-                                       if (ca & 0x80)
-                                               Term_putch(44, 20, 255, -1);
-                                       else
-                                               Term_putch(44, 20, 0, ' ');
-                               }
+                               Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
+                               Term_queue_bigchar(43, 20, ca, cc, 0, 0);
 
                                /* Prompt */
 #ifdef JP
                                Term_putstr(0, 22, -1, TERM_WHITE,
-                                           "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C): ");
+                                           "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
 #else
                                Term_putstr(0, 22, -1, TERM_WHITE,
-                                           "Command (n/N/^N/a/A/^A/c/C/^C): ");
+                                           "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
 #endif
 
                                /* Get a command */
@@ -3889,35 +4044,60 @@ void do_cmd_visuals(void)
                                switch (c)
                                {
                                case 'n':
-                                       cmd_visuals_aux(i, &r, max_r_idx);
+                                       {
+                                               int prev_r = r;
+                                               do
+                                               {
+                                                       if (!cmd_visuals_aux(i, &r, max_r_idx))
+                                                       {
+                                                               r = prev_r;
+                                                               break;
+                                                       }
+                                               }
+                                               while (!r_info[r].name);
+                                       }
                                        break;
                                case 'a':
                                        t = (int)r_ptr->x_attr;
-                                       cmd_visuals_aux(i, &t, 256);
+                                       (void)cmd_visuals_aux(i, &t, 256);
                                        r_ptr->x_attr = (byte)t;
+                                       need_redraw = TRUE;
                                        break;
                                case 'c':
                                        t = (int)r_ptr->x_char;
-                                       cmd_visuals_aux(i, &t, 256);
+                                       (void)cmd_visuals_aux(i, &t, 256);
                                        r_ptr->x_char = (byte)t;
+                                       need_redraw = TRUE;
+                                       break;
+                               case 'v':
+                                       do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
+
+                                       /* Clear screen */
+                                       Term_clear();
+                                       print_visuals_menu(choice_msg);
                                        break;
                                }
                        }
+
+                       break;
                }
 
-               /* Modify object attr/chars */
-               else if (i == '7')
+               /* Modify object attr/chars (numeric operation) */
+               case '5':
                {
+#ifdef JP
+                       static cptr choice_msg = "¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹";
+#else
+                       static cptr choice_msg = "Change object attr/chars";
+#endif
                        static int k = 0;
 
-                       /* Prompt */
 #ifdef JP
-                       prt("¥³¥Þ¥ó¥É: ¥¢¥¤¥Æ¥à¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹", 15, 0);
+                       prt(format("¥³¥Þ¥ó¥É: %s", choice_msg), 15, 0);
 #else
-                       prt("Command: Change object attr/chars", 15, 0);
+                       prt(format("Command: %s", choice_msg), 15, 0);
 #endif
 
-
                        /* Hack -- query until done */
                        while (1)
                        {
@@ -3925,68 +4105,53 @@ void do_cmd_visuals(void)
                                char c;
                                int t;
 
-                               byte da = (byte)k_ptr->d_attr;
-                               byte dc = (byte)k_ptr->d_char;
-                               byte ca = (byte)k_ptr->x_attr;
-                               byte cc = (byte)k_ptr->x_char;
+                               byte da = k_ptr->d_attr;
+                               byte dc = k_ptr->d_char;
+                               byte ca = k_ptr->x_attr;
+                               byte cc = k_ptr->x_char;
 
                                /* Label the object */
 #ifdef JP
                                Term_putstr(5, 17, -1, TERM_WHITE,
-                                           format("¥¢¥¤¥Æ¥à = %d, Ì¾Á° = %-40.40s",
-                                                  k, (k_name + k_ptr->name)));
+                                           format("¥¢¥¤¥Æ¥à = %d, Ì¾Á° = %-40.40s",
+                                                  k, (k_name + k_ptr->name)));
 #else
                                Term_putstr(5, 17, -1, TERM_WHITE,
-                                           format("Object = %d, Name = %-40.40s",
-                                                  k, (k_name + k_ptr->name)));
+                                           format("Object = %d, Name = %-40.40s",
+                                                  k, (k_name + k_ptr->name)));
 #endif
 
-
                                /* Label the Default values */
 #ifdef JP
                                Term_putstr(10, 19, -1, TERM_WHITE,
-                                           format("½é´üÃÍ  ¿§ / Ê¸»ú = %3d / %3d", da, dc));
+                                           format("½é´üÃÍ  ¿§ / Ê¸»ú = %3d / %3d", da, dc));
 #else
                                Term_putstr(10, 19, -1, TERM_WHITE,
-                                           format("Default attr/char = %3d / %3d", da, dc));
+                                           format("Default attr/char = %3d / %3d", da, dc));
 #endif
 
-                               Term_putstr(40, 19, -1, TERM_WHITE, "<< ? >>");
-                               Term_putch(43, 19, da, dc);
-                               if (use_bigtile)
-                               {
-                                       if (da & 0x80)
-                                               Term_putch(44, 19, 255, -1);
-                                       else
-                                               Term_putch(44, 19, 0, ' ');
-                               }
+                               Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
+                               Term_queue_bigchar(43, 19, da, dc, 0, 0);
 
                                /* Label the Current values */
 #ifdef JP
                                Term_putstr(10, 20, -1, TERM_WHITE,
-                                           format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3d / %3d", ca, cc));
+                                           format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3d / %3d", ca, cc));
 #else
                                Term_putstr(10, 20, -1, TERM_WHITE,
-                                           format("Current attr/char = %3d / %3d", ca, cc));
+                                           format("Current attr/char = %3d / %3d", ca, cc));
 #endif
 
-                               Term_putstr(40, 20, -1, TERM_WHITE, "<< ? >>");
-                               Term_putch(43, 20, ca, cc);
-                               if (use_bigtile)
-                               {
-                                       if (ca & 0x80)
-                                               Term_putch(44, 20, 255, -1);
-                                       else
-                                               Term_putch(44, 20, 0, ' ');
-                               }
+                               Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
+                               Term_queue_bigchar(43, 20, ca, cc, 0, 0);
 
                                /* Prompt */
 #ifdef JP
                                Term_putstr(0, 22, -1, TERM_WHITE,
-                                           "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C): ");
+                                           "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
 #else
                                Term_putstr(0, 22, -1, TERM_WHITE,
-                                           "Command (n/N/^N/a/A/^A/c/C/^C): ");
+                                           "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ");
 #endif
 
                                /* Get a command */
@@ -4002,35 +4167,61 @@ void do_cmd_visuals(void)
                                switch (c)
                                {
                                case 'n':
-                                       cmd_visuals_aux(i, &k, max_k_idx);
+                                       {
+                                               int prev_k = k;
+                                               do
+                                               {
+                                                       if (!cmd_visuals_aux(i, &k, max_k_idx))
+                                                       {
+                                                               k = prev_k;
+                                                               break;
+                                                       }
+                                               }
+                                               while (!k_info[k].name || k_info[k].flavor);
+                                       }
                                        break;
                                case 'a':
-                                       t = (int)k_info[k].x_attr;
-                                       cmd_visuals_aux(i, &t, 256);
-                                       k_info[k].x_attr = (byte)t;
+                                       t = (int)k_ptr->x_attr;
+                                       (void)cmd_visuals_aux(i, &t, 256);
+                                       k_ptr->x_attr = (byte)t;
+                                       need_redraw = TRUE;
                                        break;
                                case 'c':
-                                       t = (int)k_info[k].x_char;
-                                       cmd_visuals_aux(i, &t, 256);
-                                       k_info[k].x_char = (byte)t;
+                                       t = (int)k_ptr->x_char;
+                                       (void)cmd_visuals_aux(i, &t, 256);
+                                       k_ptr->x_char = (byte)t;
+                                       need_redraw = TRUE;
+                                       break;
+                               case 'v':
+                                       do_cmd_knowledge_objects(&need_redraw, TRUE, k);
+
+                                       /* Clear screen */
+                                       Term_clear();
+                                       print_visuals_menu(choice_msg);
                                        break;
                                }
                        }
+
+                       break;
                }
 
-               /* Modify feature attr/chars */
-               else if (i == '8')
+               /* Modify feature attr/chars (numeric operation) */
+               case '6':
                {
+#ifdef JP
+                       static cptr choice_msg = "ÃÏ·Á¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹";
+#else
+                       static cptr choice_msg = "Change feature attr/chars";
+#endif
                        static int f = 0;
+                       static int lighting_level = F_LIT_STANDARD;
 
-                       /* Prompt */
 #ifdef JP
-                       prt("¥³¥Þ¥ó¥É: ÃÏ·Á¤Î[¿§/ʸ»ú]¤òÊѹ¹¤·¤Þ¤¹", 15, 0);
+                       prt(format("¥³¥Þ¥ó¥É: %s", choice_msg), 15, 0);
 #else
-                       prt("Command: Change feature attr/chars", 15, 0);
+                       prt(format("Command: %s", choice_msg), 15, 0);
 #endif
 
-
                        /* Hack -- query until done */
                        while (1)
                        {
@@ -4038,68 +4229,55 @@ void do_cmd_visuals(void)
                                char c;
                                int t;
 
-                               byte da = (byte)f_ptr->d_attr;
-                               byte dc = (byte)f_ptr->d_char;
-                               byte ca = (byte)f_ptr->x_attr;
-                               byte cc = (byte)f_ptr->x_char;
+                               byte da = f_ptr->d_attr[lighting_level];
+                               byte dc = f_ptr->d_char[lighting_level];
+                               byte ca = f_ptr->x_attr[lighting_level];
+                               byte cc = f_ptr->x_char[lighting_level];
 
                                /* Label the object */
+                               prt("", 17, 5);
 #ifdef JP
                                Term_putstr(5, 17, -1, TERM_WHITE,
-                                           format("ÃÏ·Á = %d, Ì¾Á° = %-40.40s",
-                                                  f, (f_name + f_ptr->name)));
+                                           format("ÃÏ·Á = %d, Ì¾Á° = %s, ÌÀÅÙ = %s",
+                                                  f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
 #else
                                Term_putstr(5, 17, -1, TERM_WHITE,
-                                           format("Terrain = %d, Name = %-40.40s",
-                                                  f, (f_name + f_ptr->name)));
+                                           format("Terrain = %d, Name = %s, Lighting = %s",
+                                                  f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
 #endif
 
-
                                /* Label the Default values */
 #ifdef JP
                                Term_putstr(10, 19, -1, TERM_WHITE,
-                                           format("½é´üÃÍ  ¿§ / Ê¸»ú = %3d / %3d", da, dc));
+                                           format("½é´üÃÍ  ¿§ / Ê¸»ú = %3d / %3d", da, dc));
 #else
                                Term_putstr(10, 19, -1, TERM_WHITE,
-                                           format("Default attr/char = %3d / %3d", da, dc));
+                                           format("Default attr/char = %3d / %3d", da, dc));
 #endif
 
-                               Term_putstr(40, 19, -1, TERM_WHITE, "<< ? >>");
-                               Term_putch(43, 19, da, dc);
-                               if (use_bigtile)
-                               {
-                                       if (da & 0x80)
-                                               Term_putch(44, 19, 255, -1);
-                                       else
-                                               Term_putch(44, 19, 0, ' ');
-                               }
+                               Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
+
+                               Term_queue_bigchar(43, 19, da, dc, 0, 0);
 
                                /* Label the Current values */
 #ifdef JP
                                Term_putstr(10, 20, -1, TERM_WHITE,
-                                           format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3d / %3d", ca, cc));
+                                           format("¸½ºßÃÍ  ¿§ / Ê¸»ú = %3d / %3d", ca, cc));
 #else
                                Term_putstr(10, 20, -1, TERM_WHITE,
-                                           format("Current attr/char = %3d / %3d", ca, cc));
+                                           format("Current attr/char = %3d / %3d", ca, cc));
 #endif
 
-                               Term_putstr(40, 20, -1, TERM_WHITE, "<< ? >>");
-                               Term_putch(43, 20, ca, cc);
-                               if (use_bigtile)
-                               {
-                                       if (ca & 0x80)
-                                               Term_putch(44, 20, 255, -1);
-                                       else
-                                               Term_putch(44, 20, 0, ' ');
-                               }
+                               Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
+                               Term_queue_bigchar(43, 20, ca, cc, 0, 0);
 
                                /* Prompt */
 #ifdef JP
                                Term_putstr(0, 22, -1, TERM_WHITE,
-                                           "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C): ");
+                                           "¥³¥Þ¥ó¥É (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
 #else
                                Term_putstr(0, 22, -1, TERM_WHITE,
-                                           "Command (n/N/^N/a/A/^A/c/C/^C): ");
+                                           "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
 #endif
 
                                /* Get a command */
@@ -4115,27 +4293,74 @@ void do_cmd_visuals(void)
                                switch (c)
                                {
                                case 'n':
-                                       cmd_visuals_aux(i, &f, max_f_idx);
+                                       {
+                                               int prev_f = f;
+                                               do
+                                               {
+                                                       if (!cmd_visuals_aux(i, &f, max_f_idx))
+                                                       {
+                                                               f = prev_f;
+                                                               break;
+                                                       }
+                                               }
+                                               while (!f_info[f].name || (f_info[f].mimic != f));
+                                       }
                                        break;
                                case 'a':
-                                       t = (int)f_info[f].x_attr;
-                                       cmd_visuals_aux(i, &t, 256);
-                                       f_info[f].x_attr = (byte)t;
+                                       t = (int)f_ptr->x_attr[lighting_level];
+                                       (void)cmd_visuals_aux(i, &t, 256);
+                                       f_ptr->x_attr[lighting_level] = (byte)t;
+                                       need_redraw = TRUE;
                                        break;
                                case 'c':
-                                       t = (int)f_info[f].x_char;
-                                       cmd_visuals_aux(i, &t, 256);
-                                       f_info[f].x_char = (byte)t;
+                                       t = (int)f_ptr->x_char[lighting_level];
+                                       (void)cmd_visuals_aux(i, &t, 256);
+                                       f_ptr->x_char[lighting_level] = (byte)t;
+                                       need_redraw = TRUE;
+                                       break;
+                               case 'l':
+                                       (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
+                                       break;
+                               case 'd':
+                                       apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
+                                       need_redraw = TRUE;
+                                       break;
+                               case 'v':
+                                       do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
+
+                                       /* Clear screen */
+                                       Term_clear();
+                                       print_visuals_menu(choice_msg);
                                        break;
                                }
                        }
+
+                       break;
                }
 
-#endif
+               /* Modify monster attr/chars (visual mode) */
+               case '7':
+                       do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
+                       break;
 
-               /* Reset visuals */
-               else if (i == '0')
+               /* Modify object attr/chars (visual mode) */
+               case '8':
+                       do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
+                       break;
+
+               /* Modify feature attr/chars (visual mode) */
+               case '9':
                {
+                       int lighting_level = F_LIT_STANDARD;
+                       do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
+                       break;
+               }
+
+#endif /* ALLOW_VISUALS */
+
+               /* Reset visuals */
+               case 'R':
+               case 'r':
                        /* Reset */
                        reset_visuals();
 
@@ -4146,21 +4371,23 @@ void do_cmd_visuals(void)
                        msg_print("Visual attr/char tables reset.");
 #endif
 
-               }
+                       need_redraw = TRUE;
+                       break;
 
                /* Unknown option */
-               else
-               {
+               default:
                        bell();
+                       break;
                }
 
                /* Flush messages */
                msg_print(NULL);
        }
 
-
        /* Restore the screen */
        screen_load();
+
+       if (need_redraw) do_cmd_redraw();
 }
 
 
@@ -4171,8 +4398,6 @@ void do_cmd_colors(void)
 {
        int i;
 
-       FILE *fff;
-
        char tmp[160];
 
        char buf[1024];
@@ -4209,8 +4434,8 @@ void do_cmd_colors(void)
 
 #ifdef ALLOW_COLORS
 #ifdef JP
-                prt("(2) ¥«¥é¡¼¤ÎÀßÄê¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 5, 5);
-                prt("(3) ¥«¥é¡¼¤ÎÀßÄê¤òÊѹ¹¤¹¤ë", 6, 5);
+               prt("(2) ¥«¥é¡¼¤ÎÀßÄê¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹", 5, 5);
+               prt("(3) ¥«¥é¡¼¤ÎÀßÄê¤òÊѹ¹¤¹¤ë", 6, 5);
 #else
                prt("(2) Dump colors", 5, 5);
                prt("(3) Modify colors", 6, 5);
@@ -4255,7 +4480,7 @@ void do_cmd_colors(void)
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Query */
-                       if (!askfor_aux(tmp, 70)) continue;
+                       if (!askfor(tmp, 70)) continue;
 
                        /* Process the given filename */
                        (void)process_pref_file(tmp);
@@ -4273,7 +4498,6 @@ void do_cmd_colors(void)
                else if (i == '2')
                {
                        static cptr mark = "Colors";
-                       int line_num;
 
                        /* Prompt */
 #ifdef JP
@@ -4295,22 +4519,20 @@ void do_cmd_colors(void)
                        sprintf(tmp, "%s.prf", player_name);
 
                        /* Get a filename */
-                       if (!askfor_aux(tmp, 70)) continue;
+                       if (!askfor(tmp, 70)) continue;
 
                        /* Build the filename */
                        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
 
                        /* Append to the file */
-                       fff = open_auto_dump(buf, mark, &line_num);
-                       if (!fff) continue;
+                       if (!open_auto_dump(buf, mark)) continue;
 
                        /* Start dumping */
 #ifdef JP
-                       fprintf(fff, "\n# ¥«¥é¡¼¤ÎÀßÄê\n\n");
+                       auto_dump_printf("\n# ¥«¥é¡¼¤ÎÀßÄê\n\n");
 #else
-                       fprintf(fff, "\n# Color redefinitions\n\n");
+                       auto_dump_printf("\n# Color redefinitions\n\n");
 #endif
-                       line_num += 3;
 
                        /* Dump colors */
                        for (i = 0; i < 256; i++)
@@ -4335,20 +4557,18 @@ void do_cmd_colors(void)
 
                                /* Dump a comment */
 #ifdef JP
-                               fprintf(fff, "# ¥«¥é¡¼ '%s'\n", name);
+                               auto_dump_printf("# ¥«¥é¡¼ '%s'\n", name);
 #else
-                               fprintf(fff, "# Color '%s'\n", name);
+                               auto_dump_printf("# Color '%s'\n", name);
 #endif
-                               line_num++;
 
                                /* Dump the monster attr/char info */
-                               fprintf(fff, "V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
-                                       i, kv, rv, gv, bv);
-                               line_num += 2;
+                               auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
+                                       i, kv, rv, gv, bv);
                        }
 
                        /* Close */
-                       close_auto_dump(fff, mark, line_num);
+                       close_auto_dump();
 
                        /* Message */
 #ifdef JP
@@ -4402,28 +4622,28 @@ void do_cmd_colors(void)
                                /* Describe the color */
 #ifdef JP
                                Term_putstr(5, 10, -1, TERM_WHITE,
-                                           format("¥«¥é¡¼ = %d, Ì¾Á° = %s", a, name));
+                                           format("¥«¥é¡¼ = %d, Ì¾Á° = %s", a, name));
 #else
                                Term_putstr(5, 10, -1, TERM_WHITE,
-                                           format("Color = %d, Name = %s", a, name));
+                                           format("Color = %d, Name = %s", a, name));
 #endif
 
 
                                /* Label the Current values */
                                Term_putstr(5, 12, -1, TERM_WHITE,
-                                           format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
-                                                  angband_color_table[a][0],
-                                                  angband_color_table[a][1],
-                                                  angband_color_table[a][2],
-                                                  angband_color_table[a][3]));
+                                           format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
+                                                  angband_color_table[a][0],
+                                                  angband_color_table[a][1],
+                                                  angband_color_table[a][2],
+                                                  angband_color_table[a][3]));
 
                                /* Prompt */
 #ifdef JP
                                Term_putstr(0, 14, -1, TERM_WHITE,
-                                           "¥³¥Þ¥ó¥É (n/N/k/K/r/R/g/G/b/B): ");
+                                           "¥³¥Þ¥ó¥É (n/N/k/K/r/R/g/G/b/B): ");
 #else
                                Term_putstr(0, 14, -1, TERM_WHITE,
-                                           "Command (n/N/k/K/r/R/g/G/b/B): ");
+                                           "Command (n/N/k/K/r/R/g/G/b/B): ");
 #endif
 
 
@@ -4511,10 +4731,10 @@ void do_cmd_version(void)
        /* Silly message */
 #ifdef JP
        msg_format("ÊѶòÈÚÅÜ(Hengband) %d.%d.%d",
-                   FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
+                   FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
 #else
        msg_format("You are playing Hengband %d.%d.%d.",
-                   FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
+                   FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
 #endif
 }
 
@@ -4699,9 +4919,6 @@ static cptr do_cmd_feeling_text_lucky[11] =
  */
 void do_cmd_feeling(void)
 {
-       /* Verify the feeling */
-       if (feeling > 10) feeling = 10;
-
        /* No useful feeling in quests */
        if (p_ptr->inside_quest && !random_quest_number(dun_level))
        {
@@ -4756,103 +4973,617 @@ void do_cmd_feeling(void)
        }
 
        /* Display the feeling */
-        if (turn - old_turn >= (150 - dun_level)*TURNS_PER_TICK || cheat_xtra)
-        {
-                if (p_ptr->muta3 & MUT3_GOOD_LUCK) msg_print(do_cmd_feeling_text_lucky[feeling]);
-                else {
-                                       if((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)){
-                                               msg_print(do_cmd_feeling_text_combat[feeling]);
-                                       }else
-                                               msg_print(do_cmd_feeling_text[feeling]);
-                               }
-        }
-        else
-        {
-                msg_print(do_cmd_feeling_text[0]);
-        }
+       if (p_ptr->muta3 & MUT3_GOOD_LUCK)
+               msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
+       else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
+                inventory[INVEN_BOW].name1 == ART_CRIMSON)
+               msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
+       else
+               msg_print(do_cmd_feeling_text[p_ptr->feeling]);
 }
 
 
 
-
+/*
+ * Description of each monster group.
+ */
+static cptr monster_group_text[] = 
+{
+#ifdef JP
+       "¥æ¥Ë¡¼¥¯",     /* "Uniques" */
+       "¾èÇϲÄǽ¤Ê¥â¥ó¥¹¥¿¡¼", /* "Riding" */
+       "¥¢¥ê",
+       "¥³¥¦¥â¥ê",
+       "¥à¥«¥Ç",
+       "¥É¥é¥´¥ó",
+       "ÌܶÌ",
+       "¥Í¥³",
+       "¥´¡¼¥ì¥à",
+       "ɸ½à¿Í´Ö·¿À¸Êª",
+       "¥Ù¥È¥Ù¥È",
+       "¥¼¥ê¡¼",
+       "¥³¥Ü¥ë¥É",
+       "¿åÀ³À¸Êª",
+       "¥â¥ë¥É",
+       "¥Ê¡¼¥¬",
+       "¥ª¡¼¥¯",
+       "¿Í´Ö",
+       "»Í­½Ã",
+       "¥Í¥º¥ß",
+       "¥¹¥±¥ë¥È¥ó",
+       "¥Ç¡¼¥â¥ó",
+       "¥Ü¥ë¥Æ¥Ã¥¯¥¹",
+       "¥¤¥â¥à¥·/Âç·²",
+       /* "unused", */
+       "¥¤¡¼¥¯",
+       "¥¾¥ó¥Ó/¥ß¥¤¥é",
+       "Å·»È",
+       "Ļ",
+       "¸¤",
+       /* "¸ÅÂå¥É¥é¥´¥ó/¥ï¥¤¥¢¡¼¥à", */
+       "¥¨¥ì¥á¥ó¥¿¥ë",
+       "¥È¥ó¥Ü",
+       "¥´¡¼¥¹¥È",
+       "»¨¼ï",
+       "º«Ãî",
+       "¥Ø¥Ó",
+       "¥­¥é¡¼¡¦¥Ó¡¼¥È¥ë",
+       "¥ê¥Ã¥Á",
+       "¿¼ó¤Îà¨ÃîÎà",
+       "Ææ¤ÎÀ¸Êª",
+       "¥ª¡¼¥¬",
+       "µðÂç¿Í´Ö·¿À¸Êª",
+       "¥¯¥¤¥ë¥¹¥ë¥°",
+       "à¨ÃîÎà/ξÀ¸Îà",
+       "ÃØéá/¥µ¥½¥ê/¥À¥Ë",
+       "¥È¥í¥ë",
+       /* "¾åµé¥Ç¡¼¥â¥ó", */
+       "¥Ð¥ó¥Ñ¥¤¥¢",
+       "¥ï¥¤¥È/¥ì¥¤¥¹/Åù",
+       "¥¾¡¼¥ó/¥¶¥ì¥ó/Åù",
+       "¥¤¥¨¥Æ¥£",
+       "¥Ï¥¦¥ó¥É",
+       "¥ß¥ß¥Ã¥¯",
+       "ÊÉ/¿¢Êª/µ¤ÂÎ",
+       "¤ª¤Ð¤±¥­¥Î¥³",
+       "µåÂÎ",
+       "¥×¥ì¥¤¥ä¡¼",
+#else
+       "Uniques",
+       "Ridable monsters",
+       "Ant",
+       "Bat",
+       "Centipede",
+       "Dragon",
+       "Floating Eye",
+       "Feline",
+       "Golem",
+       "Hobbit/Elf/Dwarf",
+       "Icky Thing",
+       "Jelly",
+       "Kobold",
+       "Aquatic monster",
+       "Mold",
+       "Naga",
+       "Orc",
+       "Person/Human",
+       "Quadruped",
+       "Rodent",
+       "Skeleton",
+       "Demon",
+       "Vortex",
+       "Worm/Worm-Mass",
+       /* "unused", */
+       "Yeek",
+       "Zombie/Mummy",
+       "Angel",
+       "Bird",
+       "Canine",
+       /* "Ancient Dragon/Wyrm", */
+       "Elemental",
+       "Dragon Fly",
+       "Ghost",
+       "Hybrid",
+       "Insect",
+       "Snake",
+       "Killer Beetle",
+       "Lich",
+       "Multi-Headed Reptile",
+       "Mystery Living",
+       "Ogre",
+       "Giant Humanoid",
+       "Quylthulg",
+       "Reptile/Amphibian",
+       "Spider/Scorpion/Tick",
+       "Troll",
+       /* "Major Demon", */
+       "Vampire",
+       "Wight/Wraith/etc",
+       "Xorn/Xaren/etc",
+       "Yeti",
+       "Zephyr Hound",
+       "Mimic",
+       "Wall/Plant/Gas",
+       "Mushroom patch",
+       "Ball",
+       "Player",
+#endif
+       NULL
+};
+
 
 /*
- * Encode the screen colors
+ * Symbols of monsters in each group. Note the "Uniques" group
+ * is handled differently.
  */
-static char hack[17] = "dwsorgbuDWvyRGBU";
+static cptr monster_group_char[] =
+{
+       (char *) -1L,
+       (char *) -2L,
+       "a",
+       "b",
+       "c",
+       "dD",
+       "e",
+       "f",
+       "g",
+       "h",
+       "i",
+       "j",
+       "k",
+       "l",
+       "m",
+       "n",
+       "o",
+       "pt",
+       "q",
+       "r",
+       "s",
+       "uU",
+       "v",
+       "w",
+       /* "x", */
+       "y",
+       "z",
+       "A",
+       "B",
+       "C",
+       /* "D", */
+       "E",
+       "F",
+       "G",
+       "H",
+       "I",
+       "J",
+       "K",
+       "L",
+       "M",
+       "N",
+       "O",
+       "P",
+       "Q",
+       "R",
+       "S",
+       "T",
+       /* "U", */
+       "V",
+       "W",
+       "X",
+       "Y",
+       "Z",
+       "!$&()+./=>?[\\]`{|~",
+       "#%",
+       ",",
+       "*",
+       "@",
+       NULL
+};
 
 
-static errr photo_fgets(FILE *fff, char *buf, huge n)
+/*
+ * hook function to sort monsters by level
+ */
+static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
 {
-       huge i = 0;
+       u16b *who = (u16b*)(u);
 
-       char *s;
+       int w1 = who[a];
+       int w2 = who[b];
 
-       char tmp[1024];
+       monster_race *r_ptr1 = &r_info[w1];
+       monster_race *r_ptr2 = &r_info[w2];
 
-       /* Read a line */
-       if (fgets(tmp, 1024, fff))
+       /* Unused */
+       (void)v;
+
+       if (r_ptr2->level > r_ptr1->level) return TRUE;
+       if (r_ptr1->level > r_ptr2->level) return FALSE;
+
+       if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
+       if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
+       return w1 <= w2;
+}
+
+/*
+ * Build a list of monster indexes in the given group. Return the number
+ * of monsters in the group.
+ *
+ * mode & 0x01 : check for non-empty group
+ * mode & 0x02 : visual operation only
+ */
+static int collect_monsters(int grp_cur, s16b mon_idx[], byte mode)
+{
+       int i, mon_cnt = 0;
+       int dummy_why;
+
+       /* Get a list of x_char in this group */
+       cptr group_char = monster_group_char[grp_cur];
+
+       /* XXX Hack -- Check if this is the "Uniques" group */
+       bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
+
+       /* XXX Hack -- Check if this is the "Riding" group */
+       bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
+
+       /* Check every race */
+       for (i = 0; i < max_r_idx; i++)
        {
-               /* Convert weirdness */
-               for (s = tmp; *s; s++)
+               /* Access the race */
+               monster_race *r_ptr = &r_info[i];
+
+               /* Skip empty race */
+               if (!r_ptr->name) continue ;
+
+               /* Require known monsters */
+               if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
+
+               if (grp_unique)
                {
-                       /* Handle newline */
-                       if (*s == '\n')
-                       {
-                               /* Terminate */
-                               buf[i] = '\0';
+                       if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
+               }
 
-                               /* Success */
-                               return (0);
-                       }
+               else if (grp_riding)
+               {
+                       if (!(r_ptr->flags7 & RF7_RIDING)) continue;
+               }
 
-                       /* Handle tabs */
-                       else if (*s == '\t')
-                       {
-                               /* Hack -- require room */
-                               if (i + 8 >= n) break;
+               else
+               {
+                       /* Check for race in the group */
+                       if (!my_strchr(group_char, r_ptr->d_char)) continue;
+               }
 
-                               /* Append a space */
-                               buf[i++] = ' ';
+               /* Add the race */
+               mon_idx[mon_cnt++] = i;
+
+               /* XXX Hack -- Just checking for non-empty group */
+               if (mode & 0x01) break;
+       }
+
+       /* Terminate the list */
+       mon_idx[mon_cnt] = -1;
+
+       /* Select the sort method */
+       ang_sort_comp = ang_sort_comp_monster_level;
+       ang_sort_swap = ang_sort_swap_hook;
+
+       /* Sort by monster level */
+       ang_sort(mon_idx, &dummy_why, mon_cnt);
+
+       /* Return the number of races */
+       return mon_cnt;
+}
 
-                               /* Append some more spaces */
-                               while (!(i % 8)) buf[i++] = ' ';
-                       }
 
+/*
+ * Description of each monster group.
+ */
+static cptr object_group_text[] = 
+{
 #ifdef JP
-                       else if (iskanji(*s))
+       "¥­¥Î¥³",       /* "Mushrooms" */
+       "Ìô",           /* "Potions" */
+       "Ìý¤Ä¤Ü",       /* "Flasks" */
+       "´¬Êª",         /* "Scrolls" */
+       "»ØÎØ",         /* "Rings" */
+       "¥¢¥ß¥å¥ì¥Ã¥È", /* "Amulets" */
+       "ū",           /* "Whistle" */
+       "¸÷¸»",         /* "Lanterns" */
+       "ËâË¡ËÀ",       /* "Wands" */
+       "¾ó",           /* "Staffs" */
+       "¥í¥Ã¥É",       /* "Rods" */
+       "¥«¡¼¥É",       /* "Cards" */
+       "¥­¥ã¥×¥Á¥ã¡¼¡¦¥Ü¡¼¥ë",
+       "ÍÓÈé»æ",       
+       "¤¯¤µ¤Ó",
+       "Ȣ",
+       "¿Í·Á",
+       "Áü",
+       "¥´¥ß",
+       "¶õ¤Î¥Ó¥ó",
+       "¹ü",
+       "Åá·õÎà",       /* "Swords" */
+       "Æß´ï",         /* "Blunt Weapons" */
+       "ĹÊÁÉð´ï",     /* "Polearms" */
+       "ºÎ·¡Æ»¶ñ",     /* "Diggers" */
+       "Èô¤ÓÆ»¶ñ",     /* "Bows" */
+       "ÃÆ",
+       "Ìð",
+       "¥Ü¥ë¥È",
+       "·ÚÁõ³»",       /* "Soft Armor" */
+       "½ÅÁõ³»",       /* "Hard Armor" */
+       "¥É¥é¥´¥ó³»",   /* "Dragon Armor" */
+       "½â",   /* "Shields" */
+       "¥¯¥í¡¼¥¯",     /* "Cloaks" */
+       "äƼê", /* "Gloves" */
+       "¥Ø¥ë¥á¥Ã¥È",   /* "Helms" */
+       "´§",   /* "Crowns" */
+       "¥Ö¡¼¥Ä",       /* "Boots" */
+       "ËâË¡½ñ",
+       "²¿¤«",
+#else
+       "Mushrooms",
+       "Potions",
+       "Flasks",
+       "Scrolls",
+       "Rings",
+       "Amulets",
+       "Whistle",
+       "Lanterns",
+       "Wands",
+       "Staves",
+       "Rods",
+       "Cards",
+       "Capture Balls",
+       "Parchments",
+       "Spikes",
+       "Boxs",
+       "Figurines",
+       "Statues",
+       "Junks",
+       "Bottles",
+       "Skeletons",
+       "Swords",
+       "Blunt Weapons",
+       "Polearms",
+       "Diggers",
+       "Bows",
+       "Shots",
+       "Arrows",
+       "Bolts",
+       "Soft Armor",
+       "Hard Armor",
+       "Dragon Armor",
+       "Shields",
+       "Cloaks",
+       "Gloves",
+       "Helms",
+       "Crowns",
+       "Boots",
+       "Spellbooks",
+       "Something",
+#endif
+       NULL
+};
+
+
+/*
+ * TVALs of items in each group
+ */
+static byte object_group_tval[] = 
+{
+       TV_FOOD,
+       TV_POTION,
+       TV_FLASK,
+       TV_SCROLL,
+       TV_RING,
+       TV_AMULET,
+       TV_WHISTLE,
+       TV_LITE,
+       TV_WAND,
+       TV_STAFF,
+       TV_ROD,
+       TV_CARD,
+       TV_CAPTURE,
+       TV_PARCHMENT,
+       TV_SPIKE,
+       TV_CHEST,
+       TV_FIGURINE,
+       TV_STATUE,
+       TV_JUNK,
+       TV_BOTTLE,
+       TV_SKELETON,
+       TV_SWORD,
+       TV_HAFTED,
+       TV_POLEARM,
+       TV_DIGGING,
+       TV_BOW,
+       TV_SHOT,
+       TV_ARROW,
+       TV_BOLT,
+       TV_SOFT_ARMOR,
+       TV_HARD_ARMOR,
+       TV_DRAG_ARMOR,
+       TV_SHIELD,
+       TV_CLOAK,
+       TV_GLOVES,
+       TV_HELM,
+       TV_CROWN,
+       TV_BOOTS,
+       TV_LIFE_BOOK, /* Hack -- all spellbooks */
+       0,
+       0,
+};
+
+
+/*
+ * Build a list of object indexes in the given group. Return the number
+ * of objects in the group.
+ *
+ * mode & 0x01 : check for non-empty group
+ * mode & 0x02 : visual operation only
+ */
+static int collect_objects(int grp_cur, int object_idx[], byte mode)
+{
+       int i, j, k, object_cnt = 0;
+
+       /* Get a list of x_char in this group */
+       byte group_tval = object_group_tval[grp_cur];
+
+       /* Check every object */
+       for (i = 0; i < max_k_idx; i++)
+       {
+               /* Access the object */
+               object_kind *k_ptr = &k_info[i];
+
+               /* Skip empty objects */
+               if (!k_ptr->name) continue;
+
+               if (mode & 0x02)
+               {
+                       /* Any objects will be displayed */
+               }
+               else
+               {
+                       if (!p_ptr->wizard)
                        {
-                               if (!s[1]) break;
-                               buf[i++] = *s++;
-                               buf[i++] = *s;
+                               /* Skip non-flavoured objects */
+                               if (!k_ptr->flavor) continue;
+
+                               /* Require objects ever seen */
+                               if (!k_ptr->aware) continue;
                        }
-# ifndef EUC
-       /* È¾³Ñ¤«¤Ê¤ËÂбþ */
-                       else if ((((int)*s & 0xff) > 0xa1) && (((int)*s & 0xff ) < 0xdf))
+
+                       /* Skip items with no distribution (special artifacts) */
+                       for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
+                       if (!k) continue;
+               }
+
+               /* Check for objects in the group */
+               if (TV_LIFE_BOOK == group_tval)
+               {
+                       /* Hack -- All spell books */
+                       if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HISSATSU_BOOK)
                        {
-                               buf[i++] = *s;
-                               if (i >= n) break;
+                               /* Add the object */
+                               object_idx[object_cnt++] = i;
                        }
-# endif
-#endif
-                       /* Handle printables */
-                       else
-                       {
-                               /* Copy */
-                               buf[i++] = *s;
+                       else continue;
+               }
+               else if (k_ptr->tval == group_tval)
+               {
+                       /* Add the object */
+                       object_idx[object_cnt++] = i;
+               }
+               else continue;
 
-                               /* Check length */
-                               if (i >= n) break;
-                       }
+               /* XXX Hack -- Just checking for non-empty group */
+               if (mode & 0x01) break;
+       }
+
+       /* Terminate the list */
+       object_idx[object_cnt] = -1;
+
+       /* Return the number of objects */
+       return object_cnt;
+}
+
+
+/*
+ * Description of each feature group.
+ */
+static cptr feature_group_text[] = 
+{
+       "terrains",
+       NULL
+};
+
+
+/*
+ * Build a list of feature indexes in the given group. Return the number
+ * of features in the group.
+ *
+ * mode & 0x01 : check for non-empty group
+ */
+static int collect_features(int grp_cur, int *feat_idx, byte mode)
+{
+       int i, feat_cnt = 0;
+
+       /* Unused;  There is a single group. */
+       (void)grp_cur;
+
+       /* Check every feature */
+       for (i = 0; i < max_f_idx; i++)
+       {
+               /* Access the index */
+               feature_type *f_ptr = &f_info[i];
+
+               /* Skip empty index */
+               if (!f_ptr->name) continue;
+
+               /* Skip mimiccing features */
+               if (f_ptr->mimic != i) continue;
+
+               /* Add the index */
+               feat_idx[feat_cnt++] = i;
+
+               /* XXX Hack -- Just checking for non-empty group */
+               if (mode & 0x01) break;
+       }
+
+       /* Terminate the list */
+       feat_idx[feat_cnt] = -1;
+
+       /* Return the number of races */
+       return feat_cnt;
+}
+
+
+#if 0
+/*
+ * Build a list of monster indexes in the given group. Return the number
+ * of monsters in the group.
+ */
+static int collect_artifacts(int grp_cur, int object_idx[])
+{
+       int i, object_cnt = 0;
+
+       /* Get a list of x_char in this group */
+       byte group_tval = object_group_tval[grp_cur];
+
+       /* Check every object */
+       for (i = 0; i < max_a_idx; i++)
+       {
+               /* Access the artifact */
+               artifact_type *a_ptr = &a_info[i];
+
+               /* Skip empty artifacts */
+               if (!a_ptr->name) continue;
+
+               /* Skip "uncreated" artifacts */
+               if (!a_ptr->cur_num) continue;
+
+               /* Check for race in the group */
+               if (a_ptr->tval == group_tval)
+               {
+                       /* Add the race */
+                       object_idx[object_cnt++] = i;
                }
        }
 
-       /* Nothing */
-       buf[0] = '\0';
+       /* Terminate the list */
+       object_idx[object_cnt] = 0;
 
-       /* Failure */
-       return (1);
+       /* Return the number of races */
+       return object_cnt;
 }
+#endif /* 0 */
+
+
+/*
+ * Encode the screen colors
+ */
+static char hack[17] = "dwsorgbuDWvyRGBU";
 
 
 /*
@@ -4875,9 +5606,6 @@ void do_cmd_load_screen(void)
 
        Term_get_size(&wid, &hgt);
 
-       /* Hack -- drop permissions */
-       safe_setuid_drop();
-
        /* Build the filename */
        path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
 
@@ -4904,32 +5632,46 @@ void do_cmd_load_screen(void)
 
 
        /* Load the screen */
-       for (y = 0; okay && (y < hgt); y++)
+       for (y = 0; okay; y++)
        {
-               /* Get a line of data */
-               if (photo_fgets(fff, buf, 1024)) okay = FALSE;
+               /* Get a line of data including control code */
+               if (!fgets(buf, 1024, fff)) okay = FALSE;
+
+               /* Get the blank line */
+               if (buf[0] == '\n' || buf[0] == '\0') break;
+
+               /* Ignore too large screen image */
+               if (y >= hgt) continue;
 
                /* Show each row */
                for (x = 0; x < wid - 1; x++)
                {
+                       /* End of line */
+                       if (buf[x] == '\n' || buf[x] == '\0') break;
+
                        /* Put the attr/char */
                        Term_draw(x, y, TERM_WHITE, buf[x]);
                }
        }
 
-       /* Get the blank line */
-       if (my_fgets(fff, buf, sizeof(buf))) okay = FALSE;
-
-
        /* Dump the screen */
-       for (y = 0; okay && (y < hgt); y++)
+       for (y = 0; okay; y++)
        {
-               /* Get a line of data */
-               if (photo_fgets(fff, buf, 1024)) okay = FALSE;
+               /* Get a line of data including control code */
+               if (!fgets(buf, 1024, fff)) okay = FALSE;
+
+               /* Get the blank line */
+               if (buf[0] == '\n' || buf[0] == '\0') break;
+
+               /* Ignore too large screen image */
+               if (y >= hgt) continue;
 
                /* Dump each row */
                for (x = 0; x < wid - 1; x++)
                {
+                       /* End of line */
+                       if (buf[x] == '\n' || buf[x] == '\0') break;
+
                        /* Get the attr/char */
                        (void)(Term_what(x, y, &a, &c));
 
@@ -4946,16 +5688,9 @@ void do_cmd_load_screen(void)
        }
 
 
-       /* Get the blank line */
-       if (my_fgets(fff, buf, sizeof(buf))) okay = FALSE;
-
-
        /* Close it */
        my_fclose(fff);
 
-       /* Hack -- grab permissions */
-       safe_setuid_grab();
-               
 
        /* Message */
 #ifdef JP
@@ -4982,215 +5717,124 @@ cptr inven_res_label =
  "                               AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv";
 #endif
 
-/* XTRA HACK RESLIST */
-static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, 
-                                      int *j, byte tval, char *where)
-{
-  char o_name[MAX_NLEN];
-  u32b flgs[TR_FLAG_SIZE];
-
-  if (!o_ptr->k_idx)return;
-  if (o_ptr->tval != tval)return;
 
-       /* 
-       * HACK:Ring of Lordly protection and Dragon shield/helm
-        * have random resistances.
-        */
-  if ( ((o_ptr->tval >= TV_BOW && o_ptr->tval<= TV_DRAG_ARMOR && o_ptr->name2)
-       || (o_ptr->tval == TV_RING && o_ptr->sval == SV_RING_LORDLY) 
-       || (o_ptr->tval == TV_SHIELD && o_ptr->sval == SV_DRAGON_SHIELD) 
-       || (o_ptr->tval == TV_HELM && o_ptr->sval == SV_DRAGON_HELM) 
-       || (o_ptr->tval == TV_GLOVES && o_ptr->sval == SV_SET_OF_DRAGON_GLOVES) 
-       || (o_ptr->tval == TV_BOOTS && o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE) 
-       || o_ptr->art_name || o_ptr->name1) && object_known_p(o_ptr))
-    {
-      int i = 0;
-      object_desc(o_name, o_ptr, TRUE, 0);
-
-      while ( o_name[i] && i < 26 ){
-#ifdef JP
-       if (iskanji(o_name[i])) i++;
-#endif
-       i++;
-      }
-      if(i<28) while(i<28){o_name[i]=' ';i++;}
-      o_name[i]=0;
-      
-      fprintf(fff,"%s %s", where, o_name);
-
-      if (!(o_ptr->ident & (IDENT_MENTAL))) 
-       {
 #ifdef JP
-         fprintf(fff, "-------ÉÔÌÀ--------------- -------ÉÔÌÀ---------\n");
+#define IM_FLAG_STR  "¡ö"
+#define HAS_FLAG_STR "¡Ü"
+#define NO_FLAG_STR  "¡¦"
 #else
-         fprintf(fff, "-------unknown------------ -------unknown------\n");
+#define IM_FLAG_STR  "* "
+#define HAS_FLAG_STR "+ "
+#define NO_FLAG_STR  ". "
 #endif
-       }
-      else {
-       object_flags_known(o_ptr, flgs);
-      
-#ifdef JP
-       if (have_flag(flgs, TR_IM_ACID)) fprintf(fff,"¡ö");
-       else if (have_flag(flgs, TR_RES_ACID)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
 
-       if (have_flag(flgs, TR_IM_ELEC)) fprintf(fff,"¡ö");
-       else if (have_flag(flgs, TR_RES_ELEC)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
+#define print_im_or_res_flag(IM, RES) \
+{ \
+       fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
+             (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
+}
 
-       if (have_flag(flgs, TR_IM_FIRE)) fprintf(fff,"¡ö");
-       else if (have_flag(flgs, TR_RES_FIRE)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
+#define print_flag(TR) \
+{ \
+       fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
+}
 
-       if (have_flag(flgs, TR_IM_COLD)) fprintf(fff,"¡ö");
-       else if (have_flag(flgs, TR_RES_COLD)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_POIS)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_LITE)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_DARK)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_SHARDS)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_SOUND)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_NETHER)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_NEXUS)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_CHAOS)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_DISEN)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       fprintf(fff," ");
-       
-       if (have_flag(flgs, TR_RES_BLIND)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_FEAR)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_RES_CONF)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_FREE_ACT)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_SEE_INVIS)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
-       
-       if (have_flag(flgs, TR_HOLD_LIFE)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
 
-       if (have_flag(flgs, TR_TELEPATHY)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
+/* XTRA HACK RESLIST */
+static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, byte tval, char *where)
+{
+       char o_name[MAX_NLEN];
+       u32b flgs[TR_FLAG_SIZE];
+
+       if (!o_ptr->k_idx) return;
+       if (o_ptr->tval != tval) return;
+
+       /* Identified items only */
+       if (!object_is_known(o_ptr)) return;
+
+       /*
+        * HACK:Ring of Lordly protection and Dragon equipment
+        * have random resistances.
+        */
+       if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
+           || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
+           || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
+           || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
+           || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
+           || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
+           || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
+           || object_is_artifact(o_ptr))
+       {
+               int i = 0;
+               object_desc(o_name, o_ptr, OD_NAME_ONLY);
 
-       if (have_flag(flgs, TR_SLOW_DIGEST)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
+               while (o_name[i] && (i < 26))
+               {
+#ifdef JP
+                       if (iskanji(o_name[i])) i++;
+#endif
+                       i++;
+               }
 
+               if (i < 28)
+               {
+                       while (i < 28)
+                       {
+                               o_name[i] = ' '; i++;
+                       }
+               }
+               o_name[i] = '\0';
 
-       if (have_flag(flgs, TR_REGEN)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
+               fprintf(fff, "%s %s", where, o_name);
 
-       if (have_flag(flgs, TR_FEATHER)) fprintf(fff,"¡Ü");
-       else fprintf(fff,"¡¦");
+               if (!(o_ptr->ident & (IDENT_MENTAL)))
+               {
+#ifdef JP
+                       fputs("-------ÉÔÌÀ--------------- -------ÉÔÌÀ---------\n", fff);
 #else
-       if (have_flag(flgs, TR_IM_ACID)) fprintf(fff,"* ");
-       else if (have_flag(flgs, TR_RES_ACID)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-
-       if (have_flag(flgs, TR_IM_ELEC)) fprintf(fff,"* ");
-       else if (have_flag(flgs, TR_RES_ELEC)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-
-       if (have_flag(flgs, TR_IM_FIRE)) fprintf(fff,"* ");
-       else if (have_flag(flgs, TR_RES_FIRE)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-
-       if (have_flag(flgs, TR_IM_COLD)) fprintf(fff,"* ");
-       else if (have_flag(flgs, TR_RES_COLD)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_POIS)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_LITE)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_DARK)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_SHARDS)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_SOUND)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_NETHER)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_NEXUS)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_CHAOS)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_DISEN)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       fprintf(fff," ");
-       
-       if (have_flag(flgs, TR_RES_BLIND)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_FEAR)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_RES_CONF)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_FREE_ACT)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_SEE_INVIS)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-       
-       if (have_flag(flgs, TR_HOLD_LIFE)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-
-       if (have_flag(flgs, TR_TELEPATHY)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-
-       if (have_flag(flgs, TR_SLOW_DIGEST)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-
-
-       if (have_flag(flgs, TR_REGEN)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-
-       if (have_flag(flgs, TR_FEATHER)) fprintf(fff,"+ ");
-       else fprintf(fff,". ");
-#endif 
-       fprintf(fff,"\n");
-      }
-      (*j)++;
-      if(*j==9)
-       { 
-         *j=0;
-         fprintf(fff,"%s\n", inven_res_label);
+                       fputs("-------unknown------------ -------unknown------\n", fff);
+#endif
+               }
+               else
+               {
+                       object_flags_known(o_ptr, flgs);
+
+                       print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
+                       print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
+                       print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
+                       print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
+                       print_flag(TR_RES_POIS);
+                       print_flag(TR_RES_LITE);
+                       print_flag(TR_RES_DARK);
+                       print_flag(TR_RES_SHARDS);
+                       print_flag(TR_RES_SOUND);
+                       print_flag(TR_RES_NETHER);
+                       print_flag(TR_RES_NEXUS);
+                       print_flag(TR_RES_CHAOS);
+                       print_flag(TR_RES_DISEN);
+
+                       fputs(" ", fff);
+
+                       print_flag(TR_RES_BLIND);
+                       print_flag(TR_RES_FEAR);
+                       print_flag(TR_RES_CONF);
+                       print_flag(TR_FREE_ACT);
+                       print_flag(TR_SEE_INVIS);
+                       print_flag(TR_HOLD_LIFE);
+                       print_flag(TR_TELEPATHY);
+                       print_flag(TR_SLOW_DIGEST);
+                       print_flag(TR_REGEN);
+                       print_flag(TR_LEVITATION);
+
+                       fputc('\n', fff);
+               }
+               (*j)++;
+               if (*j == 9)
+               {
+                       *j = 0;
+                       fprintf(fff, "%s\n", inven_res_label);
+               }
        }
-    }
 }
 
 /*
@@ -5198,80 +5842,74 @@ static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr,
  */
 static void do_cmd_knowledge_inven(void)
 {
-
        FILE *fff;
 
        char file_name[1024];
+
        store_type  *st_ptr;
-       object_type *o_ptr;
 
        byte tval;
-       int i=0;
-        int j=0;
+       int i = 0;
+       int j = 0;
 
        char  where[32];
 
        /* Open a new file */
        fff = my_fopen_temp(file_name, 1024);
-       if (!fff) {
+       if (!fff)
+       {
 #ifdef JP
            msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
 #else
-           msg_format("Failed to create temporally file %s.", file_name);
+           msg_format("Failed to create temporary file %s.", file_name);
 #endif
            msg_print(NULL);
            return;
        }
-       fprintf(fff,"%s\n",inven_res_label);
+       fprintf(fff, "%s\n", inven_res_label);
 
-        for (tval=TV_BOW; tval <= TV_RING; tval++){
+       for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
+       {
+               if (j != 0)
+               {
+                       for (; j < 9; j++) fputc('\n', fff);
+                       j = 0;
+                       fprintf(fff, "%s\n", inven_res_label);
+               }
 
-          if (j!=0) {
-              for (;j<9;j++) fprintf(fff, "\n");
-              j=0;
-             fprintf(fff,"%s\n",inven_res_label);              
-         }
-         
 #ifdef JP
-         strcpy(where, "Áõ");
+               strcpy(where, "Áõ");
 #else
-         strcpy(where, "E ");
+               strcpy(where, "E ");
 #endif
-         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
-           {
-             o_ptr = &inventory[i];
-             do_cmd_knowledge_inven_aux(fff, o_ptr, &j, tval, where);
-           }
-         
+               for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
+               {
+                       do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
+               }
+
 #ifdef JP
-         strcpy(where, "»ý");
+               strcpy(where, "»ý");
 #else
-         strcpy(where, "I ");
+               strcpy(where, "I ");
 #endif
-         for (i = 0; i < INVEN_PACK; i++)
-           {
-             o_ptr = &inventory[i];
-             do_cmd_knowledge_inven_aux(fff, o_ptr, &j, tval, where);
-           }
-         
-         
-         /* Print all homes in the different towns */
-         st_ptr = &town[1].store[STORE_HOME];
+               for (i = 0; i < INVEN_PACK; i++)
+               {
+                       do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
+               }
+
+               st_ptr = &town[1].store[STORE_HOME];
 #ifdef JP
-         strcpy(where, "²È");
+               strcpy(where, "²È");
 #else
-         strcpy(where, "H ");
+               strcpy(where, "H ");
 #endif
-             
-         /* Dump all available items */
-         for (i = 0; i < st_ptr->stock_num; i++)
-           {
-             o_ptr = &st_ptr->stock[i];
-             do_cmd_knowledge_inven_aux(fff, o_ptr, &j, tval, where);
-           }
+
+               for (i = 0; i < st_ptr->stock_num; i++)
+               {
+                       do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
+               }
        }
-         
+
        /* Close the file */
        my_fclose(fff);
 
@@ -5470,13 +6108,7 @@ static void do_cmd_save_screen_html(void)
 
        msg_print(NULL);
 
-       /* Hack -- drop permissions */
-       safe_setuid_drop();
-
        do_cmd_save_screen_html_aux(buf, 1);
-
-       /* Hack -- grab permissions */
-       safe_setuid_grab();
 }
 
 
@@ -5555,10 +6187,6 @@ void do_cmd_save_screen(void)
 
                char buf[1024];
 
-
-               /* Hack -- drop permissions */
-               safe_setuid_drop();
-
                /* Build the filename */
                path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
 
@@ -5571,8 +6199,6 @@ void do_cmd_save_screen(void)
                /* Oops */
                if (!fff)
                {
-                       /* Hack -- grab permissions */
-                       safe_setuid_grab();
 #ifdef JP
                        msg_format("¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó¤Ç¤·¤¿¡£", buf);
 #else
@@ -5638,9 +6264,6 @@ void do_cmd_save_screen(void)
                /* Close it */
                my_fclose(fff);
 
-               /* Hack -- grab permissions */
-               safe_setuid_grab();
-
                /* Message */
 #ifdef JP
        msg_print("²èÌÌ(µ­Ç°»£±Æ)¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤Þ¤·¤¿¡£");
@@ -5686,7 +6309,6 @@ static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
 
        int z1, z2;
 
-
        /* Sort by total kills */
        if (*why >= 3)
        {
@@ -5743,6 +6365,9 @@ static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
 
        u16b holder;
 
+       /* Unused */
+       (void)v;
+
        /* Swap */
        holder = who[a];
        who[a] = who[b];
@@ -5825,10 +6450,10 @@ static void do_cmd_knowledge_artifacts(void)
                                next_o_idx = o_ptr->next_o_idx;
 
                                /* Ignore non-artifacts */
-                               if (!artifact_p(o_ptr)) continue;
+                               if (!object_is_fixed_artifact(o_ptr)) continue;
 
                                /* Ignore known items */
-                               if (object_known_p(o_ptr)) continue;
+                               if (object_is_known(o_ptr)) continue;
 
                                /* Note the artifact */
                                okay[o_ptr->name1] = FALSE;
@@ -5845,10 +6470,10 @@ static void do_cmd_knowledge_artifacts(void)
                if (!o_ptr->k_idx) continue;
 
                /* Ignore non-artifacts */
-               if (!artifact_p(o_ptr)) continue;
+               if (!object_is_fixed_artifact(o_ptr)) continue;
 
                /* Ignore known items */
-               if (object_known_p(o_ptr)) continue;
+               if (object_is_known(o_ptr)) continue;
 
                /* Note the artifact */
                okay[o_ptr->name1] = FALSE;
@@ -5859,12 +6484,12 @@ static void do_cmd_knowledge_artifacts(void)
                if (okay[k]) who[n++] = k;
        }
 
-        /* Select the sort method */
-        ang_sort_comp = ang_sort_art_comp;
-        ang_sort_swap = ang_sort_art_swap;
+       /* Select the sort method */
+       ang_sort_comp = ang_sort_art_comp;
+       ang_sort_swap = ang_sort_art_swap;
 
-        /* Sort the array by dungeon depth of monsters */
-        ang_sort(who, &why, n);
+       /* Sort the array by dungeon depth of monsters */
+       ang_sort(who, &why, n);
 
        /* Scan the artifacts */
        for (k = 0; k < n; k++)
@@ -5873,7 +6498,7 @@ static void do_cmd_knowledge_artifacts(void)
 
                /* Paranoia */
 #ifdef JP
-strcpy(base_name, "̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à");
+               strcpy(base_name, "̤ÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à");
 #else
                strcpy(base_name, "Unknown Artifact");
 #endif
@@ -5897,8 +6522,11 @@ strcpy(base_name, "̤
                        /* Make it an artifact */
                        q_ptr->name1 = (byte)who[k];
 
+                       /* Display as if known */
+                       q_ptr->ident |= IDENT_STORE;
+
                        /* Describe the artifact */
-                       object_desc_store(base_name, q_ptr, FALSE, 0);
+                       object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
                }
 
                /* Hack -- Build the artifact name */
@@ -5970,12 +6598,12 @@ static void do_cmd_knowledge_uniques(void)
                if (r_ptr->name) who[n++] = i;
        }
 
-        /* Select the sort method */
-        ang_sort_comp = ang_sort_comp_hook;
-        ang_sort_swap = ang_sort_swap_hook;
+       /* Select the sort method */
+       ang_sort_comp = ang_sort_comp_hook;
+       ang_sort_swap = ang_sort_swap_hook;
 
-        /* Sort the array by dungeon depth of monsters */
-        ang_sort(who, &why, n);
+       /* Sort the array by dungeon depth of monsters */
+       ang_sort(who, &why, n);
 
        /* Scan the monster races */
        for (k = 0; k < n; k++)
@@ -5995,10 +6623,10 @@ static void do_cmd_knowledge_uniques(void)
                                /* Print a message */
 #ifdef JP
                                fprintf(fff, "     %s¤Ï¤Þ¤ÀÀ¸¤­¤Æ¤¤¤ë¡£\n",
-                                       (r_name + r_ptr->name));
+                                       (r_name + r_ptr->name));
 #else
                                fprintf(fff, "     %s is alive\n",
-                                       (r_name + r_ptr->name));
+                                       (r_name + r_ptr->name));
 #endif
 
                        }
@@ -6025,103 +6653,11 @@ static void do_cmd_knowledge_uniques(void)
 
 
 /*
- * Display dead uniques
+ * Display weapon-exp
  */
-static void do_cmd_knowledge_uniques_dead(void)
+static void do_cmd_knowledge_weapon_exp(void)
 {
-       int i, k, n = 0;
-       u16b why = 2;
-       s16b *who;
-
-       FILE *fff;
-
-       char file_name[1024];
-
-       /* Open a new file */
-       fff = my_fopen_temp(file_name, 1024);
-
-       if (!fff) {
-#ifdef JP
-           msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
-#else
-           msg_format("Failed to create temporary file %s.", file_name);
-#endif
-           msg_print(NULL);
-           return;
-       }
-
-       /* Allocate the "who" array */
-       C_MAKE(who, max_r_idx, s16b);
-
-       /* Scan the monsters */
-       for (i = 1; i < max_r_idx; i++)
-       {
-               monster_race *r_ptr = &r_info[i];
-
-               /* Use that monster */
-               if (r_ptr->name) who[n++] = i;
-       }
-
-        /* Select the sort method */
-        ang_sort_comp = ang_sort_comp_hook;
-        ang_sort_swap = ang_sort_swap_hook;
-
-        /* Sort the array by dungeon depth of monsters */
-        ang_sort(who, &why, n);
-
-       /* Scan the monster races */
-       for (k = 0; k < n; k++)
-       {
-               monster_race *r_ptr = &r_info[who[k]];
-
-               /* Only print Uniques */
-               if (r_ptr->flags1 & (RF1_UNIQUE))
-               {
-                       bool dead = (r_ptr->max_num == 0);
-
-                       if (!dead) continue;
-
-                       /* Only display "known" uniques */
-                       if (dead || cheat_know || r_ptr->r_sights)
-                       {
-                               /* Print a message */
-#ifdef JP
-                               fprintf(fff, "     %s¤Ï´û¤Ë»à¤ó¤Ç¤¤¤ë¡£\n",
-                                       (r_name + r_ptr->name));
-#else
-                               fprintf(fff, "     %s is dead\n",
-                                       (r_name + r_ptr->name));
-#endif
-
-                       }
-               }
-       }
-
-       /* Free the "who" array */
-       C_KILL(who, max_r_idx, s16b);
-
-       /* Close the file */
-       my_fclose(fff);
-
-       /* Display the file contents */
-#ifdef JP
-       show_file(TRUE, file_name, "Åݤ·¤¿¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼", 0, 0);
-#else
-       show_file(TRUE, file_name, "Dead Uniques", 0, 0);
-#endif
-
-
-       /* Remove the file */
-       fd_kill(file_name);
-}
-
-
-/*
- * Display weapon-exp
- */
-static void do_cmd_knowledge_weapon_exp(void)
-{
-       int i,j, num, shougou;
+       int i, j, num, weapon_exp;
 
        FILE *fff;
 
@@ -6140,7 +6676,7 @@ static void do_cmd_knowledge_weapon_exp(void)
            return;
        }
 
-       for(i = 0; i < 5; i++)
+       for (i = 0; i < 5; i++)
        {
                for (num = 0; num < 64; num++)
                {
@@ -6148,22 +6684,18 @@ static void do_cmd_knowledge_weapon_exp(void)
                        {
                                object_kind *k_ptr = &k_info[j];
 
-                               if ((k_ptr->tval == TV_SWORD-i) && (k_ptr->sval == num))
+                               if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
                                {
-                                       if((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON)) continue;
+                                       if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON)) continue;
 
-                                       if(p_ptr->weapon_exp[4-i][num]<4000) shougou=0;
-                                       else if(p_ptr->weapon_exp[4-i][num]<6000) shougou=1;
-                                       else if(p_ptr->weapon_exp[4-i][num]<7000) shougou=2;
-                                       else if(p_ptr->weapon_exp[4-i][num]<8000) shougou=3;
-                                       else shougou=4;
+                                       weapon_exp = p_ptr->weapon_exp[4 - i][num];
                                        strip_name(tmp, j);
-                                       fprintf(fff,"%-25s ",tmp);
-                                       if (p_ptr->weapon_exp[4-i][num] >= s_info[p_ptr->pclass].w_max[4-i][num]) fprintf(fff,"!");
-                                       else fprintf(fff," ");
-                                       fprintf(fff,"%s",shougou_moji[shougou]);
-                                       if (cheat_xtra) fprintf(fff," %d",p_ptr->weapon_exp[4-i][num]);
-                                       fprintf(fff,"\n");
+                                       fprintf(fff, "%-25s ", tmp);
+                                       if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
+                                       else fprintf(fff, " ");
+                                       fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
+                                       if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
+                                       fprintf(fff, "\n");
                                        break;
                                }
                        }
@@ -6191,7 +6723,7 @@ static void do_cmd_knowledge_weapon_exp(void)
  */
 static void do_cmd_knowledge_spell_exp(void)
 {
-       int i=0, shougou;
+       int i = 0, spell_exp, exp_level;
 
        FILE *fff;
        magic_type *s_ptr;
@@ -6210,12 +6742,12 @@ static void do_cmd_knowledge_spell_exp(void)
            return;
        }
 
-       if(p_ptr->realm1 != REALM_NONE)
+       if (p_ptr->realm1 != REALM_NONE)
        {
 #ifdef JP
-               fprintf(fff,"%s¤ÎËâË¡½ñ\n",realm_names[p_ptr->realm1]);
+               fprintf(fff, "%s¤ÎËâË¡½ñ\n", realm_names[p_ptr->realm1]);
 #else
-               fprintf(fff,"%s Spellbook\n",realm_names[p_ptr->realm1]);
+               fprintf(fff, "%s Spellbook\n", realm_names[p_ptr->realm1]);
 #endif
                for (i = 0; i < 32; i++)
                {
@@ -6227,29 +6759,30 @@ static void do_cmd_knowledge_spell_exp(void)
                        {
                                s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
                        }
-                       if(s_ptr->slevel == 99) continue;
-                       if(p_ptr->spell_exp[i]<900) shougou=0;
-                       else if(p_ptr->spell_exp[i]<1200) shougou=1;
-                       else if(p_ptr->spell_exp[i]<1400) shougou=2;
-                       else if(p_ptr->spell_exp[i]<1600) shougou=3;
-                       else shougou=4;
-                       fprintf(fff,"%-25s ",spell_names[technic2magic(p_ptr->realm1)-1][i]);
+                       if (s_ptr->slevel >= 99) continue;
+                       spell_exp = p_ptr->spell_exp[i];
+                       exp_level = spell_exp_level(spell_exp);
+                       fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
                        if (p_ptr->realm1 == REALM_HISSATSU)
-                               fprintf(fff,"[--]");
+                               fprintf(fff, "[--]");
                        else
                        {
-                               if (shougou == 4) fprintf(fff,"!");
-                               else fprintf(fff," ");
-                               fprintf(fff,"%s",shougou_moji[shougou]);
+                               if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
+                               else fprintf(fff, " ");
+                               fprintf(fff, "%s", exp_level_str[exp_level]);
                        }
-                       if (cheat_xtra) fprintf(fff," %d",p_ptr->spell_exp[i]);
-                       fprintf(fff,"\n");
+                       if (cheat_xtra) fprintf(fff, " %d", spell_exp);
+                       fprintf(fff, "\n");
                }
        }
 
-       if(p_ptr->realm2 != REALM_NONE)
+       if (p_ptr->realm2 != REALM_NONE)
        {
-               fprintf(fff,"\n%s Spellbook\n",realm_names[p_ptr->realm2]);
+#ifdef JP
+               fprintf(fff, "%s¤ÎËâË¡½ñ\n", realm_names[p_ptr->realm2]);
+#else
+               fprintf(fff, "\n%s Spellbook\n", realm_names[p_ptr->realm2]);
+#endif
                for (i = 0; i < 32; i++)
                {
                        if (!is_magic(p_ptr->realm1))
@@ -6260,18 +6793,16 @@ static void do_cmd_knowledge_spell_exp(void)
                        {
                                s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
                        }
-                       if(s_ptr->slevel == 99) continue;
-
-                       if(p_ptr->spell_exp[i+32]<900) shougou=0;
-                       else if(p_ptr->spell_exp[i+32]<1200) shougou=1;
-                       else if(p_ptr->spell_exp[i+32]<1400) shougou=2;
-                       else shougou=3;
-                       fprintf(fff,"%-25s ",spell_names[technic2magic(p_ptr->realm2)-1][i]);
-                       if (shougou == 3) fprintf(fff,"!");
-                       else fprintf(fff," ");
-                       fprintf(fff,"%s",shougou_moji[shougou]);
-                       if (cheat_xtra) fprintf(fff," %d",p_ptr->spell_exp[i+32]);
-                       fprintf(fff,"\n");
+                       if (s_ptr->slevel >= 99) continue;
+
+                       spell_exp = p_ptr->spell_exp[i + 32];
+                       exp_level = spell_exp_level(spell_exp);
+                       fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
+                       if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
+                       else fprintf(fff, " ");
+                       fprintf(fff, "%s", exp_level_str[exp_level]);
+                       if (cheat_xtra) fprintf(fff, " %d", spell_exp);
+                       fprintf(fff, "\n");
                }
        }
 
@@ -6296,7 +6827,7 @@ static void do_cmd_knowledge_spell_exp(void)
  */
 static void do_cmd_knowledge_skill_exp(void)
 {
-       int i=0, shougou;
+       int i = 0, skill_exp;
 
        FILE *fff;
 
@@ -6321,28 +6852,13 @@ static void do_cmd_knowledge_skill_exp(void)
 
        for (i = 0; i < 3; i++)
        {
-               if(i == GINOU_RIDING)
-               {
-                       if(p_ptr->skill_exp[i]<500) shougou=0;
-                       else if(p_ptr->skill_exp[i]<2000) shougou=1;
-                       else if(p_ptr->skill_exp[i]<5000) shougou=2;
-                       else if(p_ptr->skill_exp[i]<8000) shougou=3;
-                       else shougou=4;
-               }
-               else
-               {
-                       if(p_ptr->skill_exp[i]<4000) shougou=0;
-                       else if(p_ptr->skill_exp[i]<6000) shougou=1;
-                       else if(p_ptr->skill_exp[i]<7000) shougou=2;
-                       else if(p_ptr->skill_exp[i]<8000) shougou=3;
-                       else shougou=4;
-               }
-               fprintf(fff,"%-20s ",skill_name[i]);
-               if (p_ptr->skill_exp[i] == s_info[p_ptr->pclass].s_max[i]) fprintf(fff,"!");
-               else fprintf(fff," ");
-               fprintf(fff,"%s",shougou_moji[shougou]);
-               if (cheat_xtra) fprintf(fff," %d",p_ptr->skill_exp[i]);
-               fprintf(fff,"\n");
+               skill_exp = p_ptr->skill_exp[i];
+               fprintf(fff, "%-20s ", skill_name[i]);
+               if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
+               else fprintf(fff, " ");
+               fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
+               if (cheat_xtra) fprintf(fff, " %d", skill_exp);
+               fprintf(fff, "\n");
        }
 
        /* Close the file */
@@ -6368,25 +6884,25 @@ void plural_aux(char *Name)
 {
        int NameLen = strlen(Name);
 
-       if (strstr(Name, "Disembodied hand"))
+       if (my_strstr(Name, "Disembodied hand"))
        {
                strcpy(Name, "Disembodied hands that strangled people");
        }
-       else if (strstr(Name, "Colour out of space"))
+       else if (my_strstr(Name, "Colour out of space"))
        {
                strcpy(Name, "Colours out of space");
        }
-       else if (strstr(Name, "stairway to hell"))
+       else if (my_strstr(Name, "stairway to hell"))
        {
                strcpy(Name, "stairways to hell");
        }
-       else if (strstr(Name, "Dweller on the threshold"))
+       else if (my_strstr(Name, "Dweller on the threshold"))
        {
                strcpy(Name, "Dwellers on the threshold");
        }
-       else if (strstr(Name, " of "))
+       else if (my_strstr(Name, " of "))
        {
-               cptr aider = strstr(Name, " of ");
+               cptr aider = my_strstr(Name, " of ");
                char dummy[80];
                int i = 0;
                cptr ctr = Name;
@@ -6410,7 +6926,7 @@ void plural_aux(char *Name)
                strcpy(&(dummy[i+1]), aider);
                strcpy(Name, dummy);
        }
-       else if (strstr(Name, "coins"))
+       else if (my_strstr(Name, "coins"))
        {
                char dummy[80];
                strcpy(dummy, "piles of ");
@@ -6418,7 +6934,7 @@ void plural_aux(char *Name)
                strcpy(Name, dummy);
                return;
        }
-       else if (strstr(Name, "Manes"))
+       else if (my_strstr(Name, "Manes"))
        {
                return;
        }
@@ -6471,7 +6987,7 @@ void plural_aux(char *Name)
                strcpy(&(Name[NameLen - 2]), "lves");
        }
        else if (suffix(Name, "ch") ||
-                suffix(Name, "sh") ||
+                suffix(Name, "sh") ||
                         suffix(Name, "nx") ||
                         suffix(Name, "s") ||
                         suffix(Name, "o"))
@@ -6492,6 +7008,7 @@ static void do_cmd_knowledge_pets(void)
        int             i;
        FILE            *fff;
        monster_type    *m_ptr;
+       char            pet_name[80];
        int             t_friends = 0;
        int             show_upkeep = 0;
        char            file_name[1024];
@@ -6512,28 +7029,18 @@ static void do_cmd_knowledge_pets(void)
        /* Process the monsters (backwards) */
        for (i = m_max - 1; i >= 1; i--)
        {
-               monster_race *r_ptr;
                /* Access the monster */
                m_ptr = &m_list[i];
 
                /* Ignore "dead" monsters */
                if (!m_ptr->r_idx) continue;
-               r_ptr = &r_info[m_ptr->r_idx];
 
                /* Calculate "upkeep" for pets */
                if (is_pet(m_ptr))
                {
-                       char pet_name[80];
                        t_friends++;
-                       monster_desc(pet_name, m_ptr, 0x88);
-                       fprintf(fff, "%s (%s)", pet_name, look_mon_desc(i));
-                       if (p_ptr->riding == i)
-#ifdef JP
-                               fprintf(fff, " ¾èÇÏÃæ");
-#else
-                               fprintf(fff, " Riding");
-#endif
-                       fprintf(fff, "\n");
+                       monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
+                       fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
                }
        }
 
@@ -6545,7 +7052,7 @@ static void do_cmd_knowledge_pets(void)
        fprintf(fff, " °Ý»ý¥³¥¹¥È: %d%% MP\n", show_upkeep);
 #else
        fprintf(fff, "   Total: %d pet%s.\n",
-               t_friends, (t_friends == 1 ? "" : "s"));
+               t_friends, (t_friends == 1 ? "" : "s"));
        fprintf(fff, "   Upkeep: %d%% mana.\n", show_upkeep);
 #endif
 
@@ -6556,7 +7063,7 @@ static void do_cmd_knowledge_pets(void)
 
        /* Display the file contents */
 #ifdef JP
-show_file(TRUE, file_name, "¸½ºß¤Î¥Ú¥Ã¥È", 0, 0);
+       show_file(TRUE, file_name, "¸½ºß¤Î¥Ú¥Ã¥È", 0, 0);
 #else
        show_file(TRUE, file_name, "Current Pets", 0, 0);
 #endif
@@ -6663,12 +7170,12 @@ static void do_cmd_knowledge_kill_count(void)
                if (r_ptr->name) who[n++] = i;
        }
 
-        /* Select the sort method */
-        ang_sort_comp = ang_sort_comp_hook;
-        ang_sort_swap = ang_sort_swap_hook;
+       /* Select the sort method */
+       ang_sort_comp = ang_sort_comp_hook;
+       ang_sort_swap = ang_sort_swap_hook;
 
-        /* Sort the array by dungeon depth of monsters */
-        ang_sort(who, &why, n);
+       /* Sort the array by dungeon depth of monsters */
+       ang_sort(who, &why, n);
 
        /* Scan the monster races */
        for (k = 0; k < n; k++)
@@ -6694,15 +7201,15 @@ static void do_cmd_knowledge_kill_count(void)
                        if (This > 0)
                        {
 #ifdef JP
-/* p,t¤Ï¿Í¤È¿ô¤¨¤ë by ita*/
-if(strchr("pt",r_ptr->d_char))
-fprintf(fff, "     %3d ¿Í¤Î %s\n", This, r_name + r_ptr->name);
-else
-fprintf(fff, "     %3d É¤¤Î %s\n", This, r_name + r_ptr->name);
+                               /* p,t¤Ï¿Í¤È¿ô¤¨¤ë by ita*/
+                               if(my_strchr("pt",r_ptr->d_char))
+                                       fprintf(fff, "     %3d ¿Í¤Î %s\n", This, r_name + r_ptr->name);
+                               else
+                                       fprintf(fff, "     %3d É¤¤Î %s\n", This, r_name + r_ptr->name);
 #else
                                if (This < 2)
                                {
-                                       if (strstr(r_name + r_ptr->name, "coins"))
+                                       if (my_strstr(r_name + r_ptr->name, "coins"))
                                        {
                                                fprintf(fff, "     1 pile of %s\n", (r_name + r_ptr->name));
                                        }
@@ -6731,7 +7238,7 @@ fprintf(fff, "     %3d ɤ
        fprintf(fff,"    ¹ç·×: %lu É¤¤òÅݤ·¤¿¡£\n", Total);
 #else
        fprintf(fff,"   Total: %lu creature%s killed.\n",
-               Total, (Total == 1 ? "" : "s"));
+               Total, (Total == 1 ? "" : "s"));
 #endif
 
 
@@ -6743,7 +7250,7 @@ fprintf(fff, "     %3d ɤ
 
        /* Display the file contents */
 #ifdef JP
-show_file(TRUE, file_name, "Åݤ·¤¿Å¨¤Î¿ô", 0, 0);
+       show_file(TRUE, file_name, "Åݤ·¤¿Å¨¤Î¿ô", 0, 0);
 #else
        show_file(TRUE, file_name, "Kill Count", 0, 0);
 #endif
@@ -6755,79 +7262,1506 @@ show_file(TRUE, file_name, "
 
 
 /*
- * Display known objects
+ * Display the object groups.
  */
-static void do_cmd_knowledge_objects(void)
+static void display_group_list(int col, int row, int wid, int per_page,
+       int grp_idx[], cptr group_text[], int grp_cur, int grp_top)
 {
-       int k;
+       int i;
 
-       FILE *fff;
+       /* Display lines until done */
+       for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
+       {
+               /* Get the group index */
+               int grp = grp_idx[grp_top + i];
 
-       char o_name[MAX_NLEN];
+               /* Choose a color */
+               byte attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
 
-       char file_name[1024];
+               /* Erase the entire line */
+               Term_erase(col, row + i, wid);
 
+               /* Display the group label */
+               c_put_str(attr, group_text[grp], row + i, col);
+       }
+}
 
-       /* Open a new file */
-       fff = my_fopen_temp(file_name, 1024);
-       if (!fff) {
-#ifdef JP
-           msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
-#else
-           msg_format("Failed to create temporary file %s.", file_name);
-#endif
-           msg_print(NULL);
-           return;
+
+/* 
+ * Move the cursor in a browser window 
+ */
+static void browser_cursor(char ch, int *column, int *grp_cur, int grp_cnt, 
+                                                  int *list_cur, int list_cnt)
+{
+       int d;
+       int col = *column;
+       int grp = *grp_cur;
+       int list = *list_cur;
+
+       /* Extract direction */
+       if (ch == ' ')
+       {
+               /* Hack -- scroll up full screen */
+               d = 3;
+       }
+       else if (ch == '-')
+       {
+               /* Hack -- scroll down full screen */
+               d = 9;
+       }
+       else
+       {
+               d = get_keymap_dir(ch);
+       }
+
+       if (!d) return;
+
+       /* Diagonals - hack */
+       if ((ddx[d] > 0) && ddy[d])
+       {
+               int browser_rows;
+               int wid, hgt;
+
+               /* Get size */
+               Term_get_size(&wid, &hgt);
+
+               browser_rows = hgt - 8;
+
+               /* Browse group list */
+               if (!col)
+               {
+                       int old_grp = grp;
+
+                       /* Move up or down */
+                       grp += ddy[d] * (browser_rows - 1);
+
+                       /* Verify */
+                       if (grp >= grp_cnt)     grp = grp_cnt - 1;
+                       if (grp < 0) grp = 0;
+                       if (grp != old_grp)     list = 0;
+               }
+
+               /* Browse sub-list list */
+               else
+               {
+                       /* Move up or down */
+                       list += ddy[d] * browser_rows;
+
+                       /* Verify */
+                       if (list >= list_cnt) list = list_cnt - 1;
+                       if (list < 0) list = 0;
+               }
+
+               (*grp_cur) = grp;
+               (*list_cur) = list;
+
+               return;
+       }
+
+       if (ddx[d])
+       {
+               col += ddx[d];
+               if (col < 0) col = 0;
+               if (col > 1) col = 1;
+
+               (*column) = col;
+
+               return;
+       }
+
+       /* Browse group list */
+       if (!col)
+       {
+               int old_grp = grp;
+
+               /* Move up or down */
+               grp += ddy[d];
+
+               /* Verify */
+               if (grp >= grp_cnt)     grp = grp_cnt - 1;
+               if (grp < 0) grp = 0;
+               if (grp != old_grp)     list = 0;
+       }
+
+       /* Browse sub-list list */
+       else
+       {
+               /* Move up or down */
+               list += ddy[d];
+
+               /* Verify */
+               if (list >= list_cnt) list = list_cnt - 1;
+               if (list < 0) list = 0;
+       }
+
+       (*grp_cur) = grp;
+       (*list_cur) = list;
+}
+
+
+/*
+ * Display visuals.
+ */
+static void display_visual_list(int col, int row, int height, int width, byte attr_top, byte char_left)
+{
+       int i, j;
+
+       /* Clear the display lines */
+       for (i = 0; i < height; i++)
+       {
+               Term_erase(col, row + i, width);
+       }
+
+       /* Bigtile mode uses double width */
+       if (use_bigtile) width /= 2;
+
+       /* Display lines until done */
+       for (i = 0; i < height; i++)
+       {
+               /* Display columns until done */
+               for (j = 0; j < width; j++)
+               {
+                       byte a;
+                       char c;
+                       int x = col + j;
+                       int y = row + i;
+                       int ia, ic;
+
+                       /* Bigtile mode uses double width */
+                       if (use_bigtile) x += j;
+
+                       ia = attr_top + i;
+                       ic = char_left + j;
+
+                       /* Ignore illegal characters */
+                       if (ia > 0x7f || ic > 0xff || ic < ' ' ||
+                           (!use_graphics && ic > 0x7f))
+                               continue;
+
+                       a = (byte)ia;
+                       c = (char)ic;
+
+                       /* Force correct code for both ASCII character and tile */
+                       if (c & 0x80) a |= 0x80;
+
+                       /* Display symbol */
+                       Term_queue_bigchar(x, y, a, c, 0, 0);
+               }
+       }
+}
+
+
+/*
+ * Place the cursor at the collect position for visual mode
+ */
+static void place_visual_list_cursor(int col, int row, byte a, byte c, byte attr_top, byte char_left)
+{
+       int i = (a & 0x7f) - attr_top;
+       int j = c - char_left;
+
+       int x = col + j;
+       int y = row + i;
+
+       /* Bigtile mode uses double width */
+       if (use_bigtile) x += j;
+
+       /* Place the cursor */
+       Term_gotoxy(x, y);
+}
+
+
+/*
+ *  Clipboard variables for copy&paste in visual mode
+ */
+static byte attr_idx = 0;
+static byte char_idx = 0;
+
+/* Hack -- for feature lighting */
+static byte attr_idx_feat[F_LIT_MAX];
+static byte char_idx_feat[F_LIT_MAX];
+
+/*
+ *  Do visual mode command -- Change symbols
+ */
+static bool visual_mode_command(char ch, bool *visual_list_ptr,
+                               int height, int width,
+                               byte *attr_top_ptr, byte *char_left_ptr,
+                               byte *cur_attr_ptr, byte *cur_char_ptr, bool *need_redraw)
+{
+       static byte attr_old = 0, char_old = 0;
+
+       switch (ch)
+       {
+       case ESCAPE:
+               if (*visual_list_ptr)
+               {
+                       /* Cancel change */
+                       *cur_attr_ptr = attr_old;
+                       *cur_char_ptr = char_old;
+                       *visual_list_ptr = FALSE;
+
+                       return TRUE;
+               }
+               break;
+
+       case '\n':
+       case '\r':
+               if (*visual_list_ptr)
+               {
+                       /* Accept change */
+                       *visual_list_ptr = FALSE;
+                       *need_redraw = TRUE;
+
+                       return TRUE;
+               }
+               break;
+
+       case 'V':
+       case 'v':
+               if (!*visual_list_ptr)
+               {
+                       *visual_list_ptr = TRUE;
+
+                       *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
+                       *char_left_ptr = MAX(0, *cur_char_ptr - 10);
+
+                       attr_old = *cur_attr_ptr;
+                       char_old = *cur_char_ptr;
+
+                       return TRUE;
+               }
+               break;
+
+       case 'C':
+       case 'c':
+               {
+                       int i;
+
+                       /* Set the visual */
+                       attr_idx = *cur_attr_ptr;
+                       char_idx = *cur_char_ptr;
+
+                       /* Hack -- for feature lighting */
+                       for (i = 0; i < F_LIT_MAX; i++)
+                       {
+                               attr_idx_feat[i] = 0;
+                               char_idx_feat[i] = 0;
+                       }
+               }
+               return TRUE;
+
+       case 'P':
+       case 'p':
+               if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow ATTR_DARK text */
+               {
+                       /* Set the char */
+                       *cur_attr_ptr = attr_idx;
+                       *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
+                       if (!*visual_list_ptr) *need_redraw = TRUE;
+               }
+
+               if (char_idx)
+               {
+                       /* Set the char */
+                       *cur_char_ptr = char_idx;
+                       *char_left_ptr = MAX(0, *cur_char_ptr - 10);
+                       if (!*visual_list_ptr) *need_redraw = TRUE;
+               }
+
+               return TRUE;
+
+       default:
+               if (*visual_list_ptr)
+               {
+                       int eff_width;
+                       int d = get_keymap_dir(ch);
+                       byte a = (*cur_attr_ptr & 0x7f);
+                       byte c = *cur_char_ptr;
+
+                       if (use_bigtile) eff_width = width / 2;
+                       else eff_width = width;
+
+                       /* Restrict direction */
+                       if ((a == 0) && (ddy[d] < 0)) d = 0;
+                       if ((c == 0) && (ddx[d] < 0)) d = 0;
+                       if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
+                       if ((c == 0xff) && (ddx[d] > 0)) d = 0;
+
+                       a += ddy[d];
+                       c += ddx[d];
+
+                       /* Force correct code for both ASCII character and tile */
+                       if (c & 0x80) a |= 0x80;
+
+                       /* Set the visual */
+                       *cur_attr_ptr = a;
+                       *cur_char_ptr = c;
+
+
+                       /* Move the frame */
+                       if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
+                       if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
+                       if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
+                       if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
+                       return TRUE;
+               }
+               break;
        }
 
-       /* Scan the object kinds */
-       for (k = 1; k < max_k_idx; k++)
+       /* Visual mode command is not used */
+       return FALSE;
+}
+
+
+/*
+ * Display the monsters in a group.
+ */
+static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
+       int mon_cur, int mon_top, bool visual_only)
+{
+       int i;
+
+       /* Display lines until done */
+       for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
        {
-               object_kind *k_ptr = &k_info[k];
+               byte attr;
+
+               /* Get the race index */
+               int r_idx = mon_idx[mon_top + i] ;
+
+               /* Access the race */
+               monster_race *r_ptr = &r_info[r_idx];
+
+               /* Choose a color */
+               attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
+
+               /* Display the name */
+               c_prt(attr, (r_name + r_ptr->name), row + i, col);
+
+               /* Hack -- visual_list mode */
+               if (per_page == 1)
+               {
+                       c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
+               }
+               if (p_ptr->wizard || visual_only)
+               {
+                       c_prt(attr, format("%d", r_idx), row + i, 62);
+               }
+
+               /* Erase chars before overwritten by the race letter */
+               Term_erase(69, row + i, 255);
+
+               /* Display symbol */
+               Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
+
+               if (!visual_only)
+               {
+                       /* Display kills */
+                       if (!(r_ptr->flags1 & RF1_UNIQUE)) put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
+#ifdef JP
+                       else c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE), (r_ptr->max_num == 0 ? "»àË´" : "À¸Â¸"), row + i, 74);
+#else
+                       else c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE), (r_ptr->max_num == 0 ? " dead" : "alive"), row + i, 73);
+#endif
+               }
+       }
+
+       /* Clear remaining lines */
+       for (; i < per_page; i++)
+       {
+               Term_erase(col, row + i, 255);
+       }
+}
+
+
+/*
+ * Display known monsters.
+ */
+static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, int direct_r_idx)
+{
+       int i, len, max;
+       int grp_cur, grp_top, old_grp_cur;
+       int mon_cur, mon_top;
+       int grp_cnt, grp_idx[100];
+       int mon_cnt;
+       s16b *mon_idx;
+
+       int column = 0;
+       bool flag;
+       bool redraw;
+
+       bool visual_list = FALSE;
+       byte attr_top = 0, char_left = 0;
+
+       int browser_rows;
+       int wid, hgt;
+
+       byte mode;
+
+       /* Get size */
+       Term_get_size(&wid, &hgt);
+
+       browser_rows = hgt - 8;
+
+       /* Allocate the "mon_idx" array */
+       C_MAKE(mon_idx, max_r_idx, s16b);
+
+       max = 0;
+       grp_cnt = 0;
+
+       if (direct_r_idx < 0)
+       {
+               mode = visual_only ? 0x03 : 0x01;
+
+               /* Check every group */
+               for (i = 0; monster_group_text[i] != NULL; i++)
+               {
+                       /* Measure the label */
+                       len = strlen(monster_group_text[i]);
+
+                       /* Save the maximum length */
+                       if (len > max) max = len;
+
+                       /* See if any monsters are known */
+                       if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
+                       {
+                               /* Build a list of groups with known monsters */
+                               grp_idx[grp_cnt++] = i;
+                       }
+               }
+
+               mon_cnt = 0;
+       }
+       else
+       {
+               mon_idx[0] = direct_r_idx;
+               mon_cnt = 1;
+
+               /* Terminate the list */
+               mon_idx[1] = -1;
+
+               (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
+                       &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
+       }
+
+       /* Terminate the list */
+       grp_idx[grp_cnt] = -1;
+
+       old_grp_cur = -1;
+       grp_cur = grp_top = 0;
+       mon_cur = mon_top = 0;
+
+       flag = FALSE;
+       redraw = TRUE;
+
+       mode = visual_only ? 0x02 : 0x00;
+
+       while (!flag)
+       {
+               char ch;
+               monster_race *r_ptr;
+
+               if (redraw)
+               {
+                       clear_from(0);
+
+#ifdef JP
+                       prt(format("%s - ¥â¥ó¥¹¥¿¡¼", !visual_only ? "Ãμ±" : "ɽ¼¨"), 2, 0);
+                       if (direct_r_idx < 0) prt("¥°¥ë¡¼¥×", 4, 0);
+                       prt("̾Á°", 4, max + 3);
+                       if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
+                       prt("ʸ»ú", 4, 67);
+                       if (!visual_only) prt("»¦³²¿ô", 4, 72);
+#else
+                       prt(format("%s - monsters", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
+                       if (direct_r_idx < 0) prt("Group", 4, 0);
+                       prt("Name", 4, max + 3);
+                       if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
+                       prt("Sym  ", 4, 67);
+                       if (!visual_only) prt(" Kills", 4, 72);
+#endif
+
+                       for (i = 0; i < 78; i++)
+                       {
+                               Term_putch(i, 5, TERM_WHITE, '=');
+                       }
+
+                       if (direct_r_idx < 0)
+                       {
+                               for (i = 0; i < browser_rows; i++)
+                               {
+                                       Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
+                               }
+                       }
+
+                       redraw = FALSE;
+               }
+
+               if (direct_r_idx < 0)
+               {
+                       /* Scroll group list */
+                       if (grp_cur < grp_top) grp_top = grp_cur;
+                       if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
+
+                       /* Display a list of monster groups */
+                       display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
+
+                       if (old_grp_cur != grp_cur)
+                       {
+                               old_grp_cur = grp_cur;
+
+                               /* Get a list of monsters in the current group */
+                               mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
+                       }
+
+                       /* Scroll monster list */
+                       while (mon_cur < mon_top)
+                               mon_top = MAX(0, mon_top - browser_rows/2);
+                       while (mon_cur >= mon_top + browser_rows)
+                               mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
+               }
+
+               if (!visual_list)
+               {
+                       /* Display a list of monsters in the current group */
+                       display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
+               }
+               else
+               {
+                       mon_top = mon_cur;
+
+                       /* Display a monster name */
+                       display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
+
+                       /* Display visual list below first monster */
+                       display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
+               }
+
+               /* Prompt */
+#ifdef JP
+               prt(format("<Êý¸þ>%s%s%s, ESC",
+                       (!visual_list && !visual_only) ? ", 'r'¤Ç»×¤¤½Ð¤ò¸«¤ë" : "",
+                       visual_list ? ", ENTER¤Ç·èÄê" : ", 'v'¤Ç¥·¥ó¥Ü¥ëÊѹ¹",
+                       (attr_idx || char_idx) ? ", 'c', 'p'¤Ç¥Ú¡¼¥¹¥È" : ", 'c'¤Ç¥³¥Ô¡¼"),
+                       hgt - 1, 0);
+#else
+               prt(format("<dir>%s%s%s, ESC",
+                       (!visual_list && !visual_only) ? ", 'r' to recall" : "",
+                       visual_list ? ", ENTER to accept" : ", 'v' for visuals",
+                       (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
+                       hgt - 1, 0);
+#endif
+
+               /* Get the current monster */
+               r_ptr = &r_info[mon_idx[mon_cur]];
+
+               if (!visual_only)
+               {
+                       /* Mega Hack -- track this monster race */
+                       if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
+
+                       /* Hack -- handle stuff */
+                       handle_stuff();
+               }
+
+               if (visual_list)
+               {
+                       place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
+               }
+               else if (!column)
+               {
+                       Term_gotoxy(0, 6 + (grp_cur - grp_top));
+               }
+               else
+               {
+                       Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
+               }
+
+               ch = inkey();
+
+               /* Do visual mode command if needed */
+               if (visual_mode_command(ch, &visual_list, browser_rows-1, wid - (max + 3), &attr_top, &char_left, &r_ptr->x_attr, &r_ptr->x_char, need_redraw))
+               {
+                       if (direct_r_idx >= 0)
+                       {
+                               switch (ch)
+                               {
+                               case '\n':
+                               case '\r':
+                               case ESCAPE:
+                                       flag = TRUE;
+                                       break;
+                               }
+                       }
+                       continue;
+               }
+
+               switch (ch)
+               {
+                       case ESCAPE:
+                       {
+                               flag = TRUE;
+                               break;
+                       }
+
+                       case 'R':
+                       case 'r':
+                       {
+                               /* Recall on screen */
+                               if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
+                               {
+                                       screen_roff(mon_idx[mon_cur], 0);
+
+                                       (void)inkey();
+
+                                       redraw = TRUE;
+                               }
+                               break;
+                       }
+
+                       default:
+                       {
+                               /* Move the cursor */
+                               browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
+
+                               break;
+                       }
+               }
+       }
+
+       /* Free the "mon_idx" array */
+       C_KILL(mon_idx, max_r_idx, s16b);
+}
+
+
+/*
+ * Display the objects in a group.
+ */
+static void display_object_list(int col, int row, int per_page, int object_idx[],
+       int object_cur, int object_top, bool visual_only)
+{
+       int i;
+
+       /* Display lines until done */
+       for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
+       {
+               char o_name[80];
+               byte a, c;
+               object_kind *flavor_k_ptr;
+
+               /* Get the object index */
+               int k_idx = object_idx[object_top + i];
+
+               /* Access the object */
+               object_kind *k_ptr = &k_info[k_idx];
+
+               /* Choose a color */
+               byte attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
+               byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
+
+
+               if (k_ptr->flavor)
+               {
+                       /* Appearance of this object is shuffled */
+                       flavor_k_ptr = &k_info[k_ptr->flavor];
+               }
+               else
+               {
+                       /* Appearance of this object is very normal */
+                       flavor_k_ptr = k_ptr;
+               }
+
+
+
+               attr = ((i + object_top == object_cur) ? cursor : attr);
+
+               if (!k_ptr->flavor || k_ptr->aware)
+               {
+                       /* Tidy name */
+                       strip_name(o_name, k_idx);
+               }
+               else
+               {
+                       /* Flavor name */
+                       strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
+               }
+
+               /* Display the name */
+               c_prt(attr, o_name, row + i, col);
+
+               /* Hack -- visual_list mode */
+               if (per_page == 1)
+               {
+                       c_prt(attr, format("%02x/%02x", flavor_k_ptr->x_attr, flavor_k_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 64 : 68);
+               }
+               if (p_ptr->wizard || visual_only)
+               {
+                       c_prt(attr, format("%d", k_idx), row + i, 70);
+               }
+
+               a = flavor_k_ptr->x_attr;
+               c = flavor_k_ptr->x_char;
+
+               /* Display symbol */
+               Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
+       }
+
+       /* Clear remaining lines */
+       for (; i < per_page; i++)
+       {
+               Term_erase(col, row + i, 255);
+       }
+}
+
+/*
+ * Describe fake object
+ */
+static void desc_obj_fake(int k_idx)
+{
+       object_type *o_ptr;
+       object_type object_type_body;
+
+       /* Get local object */
+       o_ptr = &object_type_body;
+
+       /* Wipe the object */
+       object_wipe(o_ptr);
+
+       /* Create the artifact */
+       object_prep(o_ptr, k_idx);
+
+       /* It's fully know */
+       o_ptr->ident |= IDENT_KNOWN;
+
+       /* Track the object */
+       /* object_actual_track(o_ptr); */
+
+       /* Hack - mark as fake */
+       /* term_obj_real = FALSE; */
+
+       /* Hack -- Handle stuff */
+       handle_stuff();
+
+       if (!screen_object(o_ptr, FALSE))
+       {
+#ifdef JP
+               msg_print("ÆäËÊѤï¤Ã¤¿¤È¤³¤í¤Ï¤Ê¤¤¤è¤¦¤À¡£");
+#else
+               msg_print("You see nothing special.");
+#endif
+               msg_print(NULL);
+       }
+}
+
+
+
+/*
+ * Display known objects
+ */
+static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, int direct_k_idx)
+{
+       int i, len, max;
+       int grp_cur, grp_top, old_grp_cur;
+       int object_old, object_cur, object_top;
+       int grp_cnt, grp_idx[100];
+       int object_cnt;
+       int *object_idx;
+
+       int column = 0;
+       bool flag;
+       bool redraw;
+
+       bool visual_list = FALSE;
+       byte attr_top = 0, char_left = 0;
+
+       int browser_rows;
+       int wid, hgt;
+
+       byte mode;
+
+       /* Get size */
+       Term_get_size(&wid, &hgt);
+
+       browser_rows = hgt - 8;
+
+       /* Allocate the "object_idx" array */
+       C_MAKE(object_idx, max_k_idx, int);
+
+       max = 0;
+       grp_cnt = 0;
+
+       if (direct_k_idx < 0)
+       {
+               mode = visual_only ? 0x03 : 0x01;
+
+               /* Check every group */
+               for (i = 0; object_group_text[i] != NULL; i++)
+               {
+                       /* Measure the label */
+                       len = strlen(object_group_text[i]);
+
+                       /* Save the maximum length */
+                       if (len > max) max = len;
+
+                       /* See if any monsters are known */
+                       if (collect_objects(i, object_idx, mode))
+                       {
+                               /* Build a list of groups with known monsters */
+                               grp_idx[grp_cnt++] = i;
+                       }
+               }
+
+               object_old = -1;
+               object_cnt = 0;
+       }
+       else
+       {
+               object_kind *k_ptr = &k_info[direct_k_idx];
+               object_kind *flavor_k_ptr;
+
+               if (k_ptr->flavor)
+               {
+                       /* Appearance of this object is shuffled */
+                       flavor_k_ptr = &k_info[k_ptr->flavor];
+               }
+               else
+               {
+                       /* Appearance of this object is very normal */
+                       flavor_k_ptr = k_ptr;
+               }
+
+               object_idx[0] = direct_k_idx;
+               object_old = direct_k_idx;
+               object_cnt = 1;
+
+               /* Terminate the list */
+               object_idx[1] = -1;
+
+               (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
+                       &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
+       }
+
+       /* Terminate the list */
+       grp_idx[grp_cnt] = -1;
+
+       old_grp_cur = -1;
+       grp_cur = grp_top = 0;
+       object_cur = object_top = 0;
+
+       flag = FALSE;
+       redraw = TRUE;
+
+       mode = visual_only ? 0x02 : 0x00;
+
+       while (!flag)
+       {
+               char ch;
+               object_kind *k_ptr, *flavor_k_ptr;
+
+               if (redraw)
+               {
+                       clear_from(0);
+
+#ifdef JP
+                       prt(format("%s - ¥¢¥¤¥Æ¥à", !visual_only ? "Ãμ±" : "ɽ¼¨"), 2, 0);
+                       if (direct_k_idx < 0) prt("¥°¥ë¡¼¥×", 4, 0);
+                       prt("̾Á°", 4, max + 3);
+                       if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
+                       prt("ʸ»ú", 4, 74);
+#else
+                       prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
+                       if (direct_k_idx < 0) prt("Group", 4, 0);
+                       prt("Name", 4, max + 3);
+                       if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
+                       prt("Sym", 4, 75);
+#endif
+
+                       for (i = 0; i < 78; i++)
+                       {
+                               Term_putch(i, 5, TERM_WHITE, '=');
+                       }
+
+                       if (direct_k_idx < 0)
+                       {
+                               for (i = 0; i < browser_rows; i++)
+                               {
+                                       Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
+                               }
+                       }
+
+                       redraw = FALSE;
+               }
+
+               if (direct_k_idx < 0)
+               {
+                       /* Scroll group list */
+                       if (grp_cur < grp_top) grp_top = grp_cur;
+                       if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
+
+                       /* Display a list of object groups */
+                       display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
+
+                       if (old_grp_cur != grp_cur)
+                       {
+                               old_grp_cur = grp_cur;
+
+                               /* Get a list of objects in the current group */
+                               object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
+                       }
+
+                       /* Scroll object list */
+                       while (object_cur < object_top)
+                               object_top = MAX(0, object_top - browser_rows/2);
+                       while (object_cur >= object_top + browser_rows)
+                               object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
+               }
+
+               if (!visual_list)
+               {
+                       /* Display a list of objects in the current group */
+                       display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
+               }
+               else
+               {
+                       object_top = object_cur;
+
+                       /* Display a list of objects in the current group */
+                       display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
+
+                       /* Display visual list below first object */
+                       display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
+               }
+
+               /* Get the current object */
+               k_ptr = &k_info[object_idx[object_cur]];
+
+               if (k_ptr->flavor)
+               {
+                       /* Appearance of this object is shuffled */
+                       flavor_k_ptr = &k_info[k_ptr->flavor];
+               }
+               else
+               {
+                       /* Appearance of this object is very normal */
+                       flavor_k_ptr = k_ptr;
+               }
+
+               /* Prompt */
+#ifdef JP
+               prt(format("<Êý¸þ>%s%s%s, ESC",
+                       (!visual_list && !visual_only) ? ", 'r'¤Ç¾ÜºÙ¤ò¸«¤ë" : "",
+                       visual_list ? ", ENTER¤Ç·èÄê" : ", 'v'¤Ç¥·¥ó¥Ü¥ëÊѹ¹",
+                       (attr_idx || char_idx) ? ", 'c', 'p'¤Ç¥Ú¡¼¥¹¥È" : ", 'c'¤Ç¥³¥Ô¡¼"),
+                       hgt - 1, 0);
+#else
+               prt(format("<dir>%s%s%s, ESC",
+                       (!visual_list && !visual_only) ? ", 'r' to recall" : "",
+                       visual_list ? ", ENTER to accept" : ", 'v' for visuals",
+                       (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
+                       hgt - 1, 0);
+#endif
+
+               if (!visual_only)
+               {
+                       /* Mega Hack -- track this object */
+                       if (object_cnt) object_kind_track(object_idx[object_cur]);
+
+                       /* The "current" object changed */
+                       if (object_old != object_idx[object_cur])
+                       {
+                               /* Hack -- handle stuff */
+                               handle_stuff();
+
+                               /* Remember the "current" object */
+                               object_old = object_idx[object_cur];
+                       }
+               }
+
+               if (visual_list)
+               {
+                       place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
+               }
+               else if (!column)
+               {
+                       Term_gotoxy(0, 6 + (grp_cur - grp_top));
+               }
+               else
+               {
+                       Term_gotoxy(max + 3, 6 + (object_cur - object_top));
+               }
+
+               ch = inkey();
+
+               /* Do visual mode command if needed */
+               if (visual_mode_command(ch, &visual_list, browser_rows-1, wid - (max + 3), &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw))
+               {
+                       if (direct_k_idx >= 0)
+                       {
+                               switch (ch)
+                               {
+                               case '\n':
+                               case '\r':
+                               case ESCAPE:
+                                       flag = TRUE;
+                                       break;
+                               }
+                       }
+                       continue;
+               }
+
+               switch (ch)
+               {
+                       case ESCAPE:
+                       {
+                               flag = TRUE;
+                               break;
+                       }
+
+                       case 'R':
+                       case 'r':
+                       {
+                               /* Recall on screen */
+                               if (!visual_list && !visual_only && (grp_cnt > 0))
+                               {
+                                       desc_obj_fake(object_idx[object_cur]);
+                                       redraw = TRUE;
+                               }
+                               break;
+                       }
+
+                       default:
+                       {
+                               /* Move the cursor */
+                               browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
+                               break;
+                       }
+               }
+       }
+
+       /* Free the "object_idx" array */
+       C_KILL(object_idx, max_k_idx, int);
+}
+
+
+/*
+ * Display the features in a group.
+ */
+static void display_feature_list(int col, int row, int per_page, int *feat_idx,
+       int feat_cur, int feat_top, bool visual_only, int lighting_level)
+{
+       int lit_col[F_LIT_MAX], i, j;
+       int f_idx_col = use_bigtile ? 62 : 64;
+
+       /* Correct columns 1 and 4 */
+       lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
+       for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
+               lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
+
+       /* Display lines until done */
+       for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
+       {
+               byte attr;
+
+               /* Get the index */
+               int f_idx = feat_idx[feat_top + i];
+
+               /* Access the index */
+               feature_type *f_ptr = &f_info[f_idx];
+
+               int row_i = row + i;
+
+               /* Choose a color */
+               attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
+
+               /* Display the name */
+               c_prt(attr, f_name + f_ptr->name, row_i, col);
+
+               /* Hack -- visual_list mode */
+               if (per_page == 1)
+               {
+                       /* Display lighting level */
+                       c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
+
+                       c_prt(attr, format("%02x/%02x", f_ptr->x_attr[lighting_level], f_ptr->x_char[lighting_level]), row_i, f_idx_col - ((p_ptr->wizard || visual_only) ? 6 : 2));
+               }
+               if (p_ptr->wizard || visual_only)
+               {
+                       c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
+               }
+
+               /* Display symbol */
+               Term_queue_bigchar(lit_col[F_LIT_STANDARD], row_i, f_ptr->x_attr[F_LIT_STANDARD], f_ptr->x_char[F_LIT_STANDARD], 0, 0);
+
+               Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
+               for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
+               {
+                       Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
+               }
+               Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
+
+               /* Mega-hack -- Use non-standard colour */
+               for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
+               {
+                       Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
+               }
+       }
+
+       /* Clear remaining lines */
+       for (; i < per_page; i++)
+       {
+               Term_erase(col, row + i, 255);
+       }
+}
+
+
+/*
+ * Interact with feature visuals.
+ */
+static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, int direct_f_idx, int *lighting_level)
+{
+       int i, len, max;
+       int grp_cur, grp_top, old_grp_cur;
+       int feat_cur, feat_top;
+       int grp_cnt, grp_idx[100];
+       int feat_cnt;
+       int *feat_idx;
+
+       int column = 0;
+       bool flag;
+       bool redraw;
+
+       bool visual_list = FALSE;
+       byte attr_top = 0, char_left = 0;
+
+       int browser_rows;
+       int wid, hgt;
+
+       byte attr_old[F_LIT_MAX];
+       byte char_old[F_LIT_MAX];
+       byte *cur_attr_ptr, *cur_char_ptr;
+
+       C_WIPE(attr_old, F_LIT_MAX, byte);
+       C_WIPE(char_old, F_LIT_MAX, byte);
+
+       /* Get size */
+       Term_get_size(&wid, &hgt);
+
+       browser_rows = hgt - 8;
+
+       /* Allocate the "feat_idx" array */
+       C_MAKE(feat_idx, max_f_idx, int);
+
+       max = 0;
+       grp_cnt = 0;
+
+       if (direct_f_idx < 0)
+       {
+               /* Check every group */
+               for (i = 0; feature_group_text[i] != NULL; i++)
+               {
+                       /* Measure the label */
+                       len = strlen(feature_group_text[i]);
+
+                       /* Save the maximum length */
+                       if (len > max) max = len;
+
+                       /* See if any features are known */
+                       if (collect_features(i, feat_idx, 0x01))
+                       {
+                               /* Build a list of groups with known features */
+                               grp_idx[grp_cnt++] = i;
+                       }
+               }
+
+               feat_cnt = 0;
+       }
+       else
+       {
+               feature_type *f_ptr = &f_info[direct_f_idx];
+
+               feat_idx[0] = direct_f_idx;
+               feat_cnt = 1;
+
+               /* Terminate the list */
+               feat_idx[1] = -1;
+
+               (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
+                       &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
+
+               for (i = 0; i < F_LIT_MAX; i++)
+               {
+                       attr_old[i] = f_ptr->x_attr[i];
+                       char_old[i] = f_ptr->x_char[i];
+               }
+       }
+
+       /* Terminate the list */
+       grp_idx[grp_cnt] = -1;
+
+       old_grp_cur = -1;
+       grp_cur = grp_top = 0;
+       feat_cur = feat_top = 0;
+
+       flag = FALSE;
+       redraw = TRUE;
+
+       while (!flag)
+       {
+               char ch;
+               feature_type *f_ptr;
+
+               if (redraw)
+               {
+                       clear_from(0);
+
+#ifdef JP
+                       prt("ɽ¼¨ - ÃÏ·Á", 2, 0);
+                       if (direct_f_idx < 0) prt("¥°¥ë¡¼¥×", 4, 0);
+                       prt("̾Á°", 4, max + 3);
+                       if (use_bigtile)
+                       {
+                               if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
+                               prt("ʸ»ú ( l/ d)", 4, 66);
+                       }
+                       else
+                       {
+                               if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
+                               prt("ʸ»ú (l/d)", 4, 68);
+                       }
+#else
+                       prt("Visuals - features", 2, 0);
+                       if (direct_f_idx < 0) prt("Group", 4, 0);
+                       prt("Name", 4, max + 3);
+                       if (use_bigtile)
+                       {
+                               if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
+                               prt("Sym ( l/ d)", 4, 67);
+                       }
+                       else
+                       {
+                               if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
+                               prt("Sym (l/d)", 4, 69);
+                       }
+#endif
+
+                       for (i = 0; i < 78; i++)
+                       {
+                               Term_putch(i, 5, TERM_WHITE, '=');
+                       }
+
+                       if (direct_f_idx < 0)
+                       {
+                               for (i = 0; i < browser_rows; i++)
+                               {
+                                       Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
+                               }
+                       }
+
+                       redraw = FALSE;
+               }
+
+               if (direct_f_idx < 0)
+               {
+                       /* Scroll group list */
+                       if (grp_cur < grp_top) grp_top = grp_cur;
+                       if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
+
+                       /* Display a list of feature groups */
+                       display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
+
+                       if (old_grp_cur != grp_cur)
+                       {
+                               old_grp_cur = grp_cur;
+
+                               /* Get a list of features in the current group */
+                               feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
+                       }
+
+                       /* Scroll feature list */
+                       while (feat_cur < feat_top)
+                               feat_top = MAX(0, feat_top - browser_rows/2);
+                       while (feat_cur >= feat_top + browser_rows)
+                               feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
+               }
+
+               if (!visual_list)
+               {
+                       /* Display a list of features in the current group */
+                       display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
+               }
+               else
+               {
+                       feat_top = feat_cur;
+
+                       /* Display a list of features in the current group */
+                       display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
+
+                       /* Display visual list below first object */
+                       display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
+               }
+
+               /* Prompt */
+#ifdef JP
+               prt(format("<Êý¸þ>%s, 'd'¤Çɸ½à¸÷¸»¸ú²Ì%s, ESC",
+                       visual_list ? ", ENTER¤Ç·èÄê, 'a'¤ÇÂоÝÌÀÅÙÊѹ¹" : ", 'v'¤Ç¥·¥ó¥Ü¥ëÊѹ¹",
+                       (attr_idx || char_idx) ? ", 'c', 'p'¤Ç¥Ú¡¼¥¹¥È" : ", 'c'¤Ç¥³¥Ô¡¼"),
+                       hgt - 1, 0);
+#else
+               prt(format("<dir>%s, 'd' for default lighting%s, ESC",
+                       visual_list ? ", ENTER to accept, 'a' for lighting level" : ", 'v' for visuals",
+                       (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
+                       hgt - 1, 0);
+#endif
+
+               /* Get the current feature */
+               f_ptr = &f_info[feat_idx[feat_cur]];
+               cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
+               cur_char_ptr = &f_ptr->x_char[*lighting_level];
+
+               if (visual_list)
+               {
+                       place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
+               }
+               else if (!column)
+               {
+                       Term_gotoxy(0, 6 + (grp_cur - grp_top));
+               }
+               else
+               {
+                       Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
+               }
+
+               ch = inkey();
+
+               if (visual_list && ((ch == 'A') || (ch == 'a')))
+               {
+                       int prev_lighting_level = *lighting_level;
+
+                       if (ch == 'A')
+                       {
+                               if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
+                               else (*lighting_level)--;
+                       }
+                       else
+                       {
+                               if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
+                               else (*lighting_level)++;
+                       }
+
+                       if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
+                               attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
+
+                       if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
+                               char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
+
+                       continue;
+               }
+
+               else if ((ch == 'D') || (ch == 'd'))
+               {
+                       byte prev_x_attr = f_ptr->x_attr[*lighting_level];
+                       byte prev_x_char = f_ptr->x_char[*lighting_level];
+
+                       apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
+
+                       if (visual_list)
+                       {
+                               if (prev_x_attr != f_ptr->x_attr[*lighting_level])
+                                        attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
+
+                               if (prev_x_char != f_ptr->x_char[*lighting_level])
+                                       char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
+                       }
+                       else *need_redraw = TRUE;
 
-               /* Hack -- skip artifacts */
-               if (k_ptr->gen_flags & (TRG_INSTA_ART)) continue;
+                       continue;
+               }
 
-               /* List known flavored objects */
-               if (k_ptr->flavor && k_ptr->aware)
+               /* Do visual mode command if needed */
+               else if (visual_mode_command(ch, &visual_list, browser_rows-1, wid - (max + 3), &attr_top, &char_left, cur_attr_ptr, cur_char_ptr, need_redraw))
                {
-                       object_type *i_ptr;
-                       object_type object_type_body;
+                       switch (ch)
+                       {
+                       /* Restore previous visual settings */
+                       case ESCAPE:
+                               for (i = 0; i < F_LIT_MAX; i++)
+                               {
+                                       f_ptr->x_attr[i] = attr_old[i];
+                                       f_ptr->x_char[i] = char_old[i];
+                               }
 
-                       /* Get local object */
-                       i_ptr = &object_type_body;
+                               /* Fall through */
 
-                       /* Create fake object */
-                       object_prep(i_ptr, k);
+                       case '\n':
+                       case '\r':
+                               if (direct_f_idx >= 0) flag = TRUE;
+                               else *lighting_level = F_LIT_STANDARD;
+                               break;
 
-                       /* Describe the object */
-                       object_desc_store(o_name, i_ptr, FALSE, 0);
+                       /* Preserve current visual settings */
+                       case 'V':
+                       case 'v':
+                               for (i = 0; i < F_LIT_MAX; i++)
+                               {
+                                       attr_old[i] = f_ptr->x_attr[i];
+                                       char_old[i] = f_ptr->x_char[i];
+                               }
+                               *lighting_level = F_LIT_STANDARD;
+                               break;
 
-                       /* Print a message */
-                       fprintf(fff, "     %s\n", o_name);
-               }
-       }
+                       case 'C':
+                       case 'c':
+                               if (!visual_list)
+                               {
+                                       for (i = 0; i < F_LIT_MAX; i++)
+                                       {
+                                               attr_idx_feat[i] = f_ptr->x_attr[i];
+                                               char_idx_feat[i] = f_ptr->x_char[i];
+                                       }
+                               }
+                               break;
 
-       /* Close the file */
-       my_fclose(fff);
+                       case 'P':
+                       case 'p':
+                               if (!visual_list)
+                               {
+                                       /* Allow ATTR_DARK text */
+                                       for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
+                                       {
+                                               if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
+                                               if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
+                                       }
+                               }
+                               break;
+                       }
+                       continue;
+               }
 
-       /* Display the file contents */
-#ifdef JP
-       show_file(TRUE, file_name, "´ûÃΤΥ¢¥¤¥Æ¥à", 0, 0);
-#else
-       show_file(TRUE, file_name, "Known Objects", 0, 0);
-#endif
+               switch (ch)
+               {
+                       case ESCAPE:
+                       {
+                               flag = TRUE;
+                               break;
+                       }
 
+                       default:
+                       {
+                               /* Move the cursor */
+                               browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
+                               break;
+                       }
+               }
+       }
 
-       /* Remove the file */
-       fd_kill(file_name);
+       /* Free the "feat_idx" array */
+       C_KILL(feat_idx, max_f_idx, int);
 }
 
 
 /*
-* List virtues & status
-*
-*/
+ * List wanted monsters
+ */
 static void do_cmd_knowledge_kubi(void)
 {
        int i;
@@ -6850,6 +8784,8 @@ static void do_cmd_knowledge_kubi(void)
        
        if (fff)
        {
+               bool listed = FALSE;
+
 #ifdef JP
                fprintf(fff, "º£Æü¤Î¥¿¡¼¥²¥Ã¥È : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "ÉÔÌÀ"));
                fprintf(fff, "\n");
@@ -6859,17 +8795,25 @@ static void do_cmd_knowledge_kubi(void)
                fprintf(fff, "\n");
                fprintf(fff, "List of wanted monsters\n");
 #endif
+               fprintf(fff, "----------------------------------------------\n");
+
                for (i = 0; i < MAX_KUBI; i++)
                {
-                       fprintf(fff,"%-40s ---- ",r_name + r_info[(kubi_r_idx[i] > 10000 ? kubi_r_idx[i] - 10000 : kubi_r_idx[i])].name);
-                       if (kubi_r_idx[i] > 10000)
+                       if (kubi_r_idx[i] <= 10000)
+                       {
+                               fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
+
+                               listed = TRUE;
+                       }
+               }
+
+               if (!listed)
+               {
 #ifdef JP
-                               fprintf(fff, "ºÑ\n");
+                       fprintf(fff,"\n%s\n", "¾Þ¶â¼ó¤Ï¤â¤¦»Ä¤Ã¤Æ¤¤¤Þ¤»¤ó¡£");
 #else
-                               fprintf(fff, "done\n");
+                       fprintf(fff,"\n%s\n", "There is no more wanted monster.");
 #endif
-                       else
-                               fprintf(fff, "$%d\n", 300 * (r_info[kubi_r_idx[i]].level + 1));
                }
        }
        
@@ -6878,7 +8822,7 @@ static void do_cmd_knowledge_kubi(void)
        
        /* Display the file contents */
 #ifdef JP
-show_file(TRUE, file_name, "¾Þ¶â¼ó¤Î°ìÍ÷", 0, 0);
+       show_file(TRUE, file_name, "¾Þ¶â¼ó¤Î°ìÍ÷", 0, 0);
 #else
        show_file(TRUE, file_name, "Wanted monsters", 0, 0);
 #endif
@@ -6889,9 +8833,8 @@ show_file(TRUE, file_name, "
 }
 
 /*
-* List virtues & status
-*
-*/
+ * List virtues & status
+ */
 static void do_cmd_knowledge_virtues(void)
 {
        FILE *fff;
@@ -6926,7 +8869,7 @@ static void do_cmd_knowledge_virtues(void)
        
        /* Display the file contents */
 #ifdef JP
-show_file(TRUE, file_name, "Ȭ¤Ä¤ÎÆÁ", 0, 0);
+       show_file(TRUE, file_name, "Ȭ¤Ä¤ÎÆÁ", 0, 0);
 #else
        show_file(TRUE, file_name, "Virtues", 0, 0);
 #endif
@@ -6986,7 +8929,7 @@ static void do_cmd_knowledge_dungeon(void)
        
        /* Display the file contents */
 #ifdef JP
-show_file(TRUE, file_name, "º£¤Þ¤Ç¤ËÆþ¤Ã¤¿¥À¥ó¥¸¥ç¥ó", 0, 0);
+       show_file(TRUE, file_name, "º£¤Þ¤Ç¤ËÆþ¤Ã¤¿¥À¥ó¥¸¥ç¥ó", 0, 0);
 #else
        show_file(TRUE, file_name, "Dungeon", 0, 0);
 #endif
@@ -7026,13 +8969,13 @@ static void do_cmd_knowledge_stat(void)
                        ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
 
 #ifdef JP
-if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "¸½ºß¤ÎÂÎÎÏ¥é¥ó¥¯ : %d/100\n\n", percent);
-else fprintf(fff, "¸½ºß¤ÎÂÎÎÏ¥é¥ó¥¯ : ???\n\n");
-fprintf(fff, "ǽÎϤκÇÂçÃÍ\n\n");
+               if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "¸½ºß¤ÎÂÎÎÏ¥é¥ó¥¯ : %d/100\n\n", percent);
+               else fprintf(fff, "¸½ºß¤ÎÂÎÎÏ¥é¥ó¥¯ : ???\n\n");
+               fprintf(fff, "ǽÎϤκÇÂçÃÍ\n\n");
 #else
                if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
                else fprintf(fff, "Your current Life Rating is ???.\n\n");
-fprintf(fff, "Limits of maximum stats\n\n");
+               fprintf(fff, "Limits of maximum stats\n\n");
 #endif
                for (v_nr = 0; v_nr < 6; v_nr++)
                {
@@ -7048,7 +8991,7 @@ fprintf(fff, "Limits of maximum stats\n\n");
        
        /* Display the file contents */
 #ifdef JP
-show_file(TRUE, file_name, "¼«Ê¬¤Ë´Ø¤¹¤ë¾ðÊó", 0, 0);
+       show_file(TRUE, file_name, "¼«Ê¬¤Ë´Ø¤¹¤ë¾ðÊó", 0, 0);
 #else
        show_file(TRUE, file_name, "HP-rate & Max stat", 0, 0);
 #endif
@@ -7058,13 +9001,12 @@ show_file(TRUE, file_name, "
        fd_kill(file_name);
 }
 
+
 /*
- * Print quest status of all active quests
+ * Print all active quests
  */
-static void do_cmd_knowledge_quests(void)
+static void do_cmd_knowledge_quests_current(FILE *fff)
 {
-       FILE *fff;
-       char file_name[1024];
        char tmp_str[120];
        char rand_tmp_str[120] = "\0";
        char name[80];
@@ -7073,18 +9015,6 @@ static void do_cmd_knowledge_quests(void)
        int rand_level = 100;
        int total = 0;
 
-       /* Open a new file */
-       fff = my_fopen_temp(file_name, 1024);
-       if (!fff) {
-#ifdef JP
-           msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
-#else
-           msg_format("Failed to create temporary file %s.", file_name);
-#endif
-           msg_print(NULL);
-           return;
-       }
-
 #ifdef JP
        fprintf(fff, "¡Ô¿ë¹ÔÃæ¤Î¥¯¥¨¥¹¥È¡Õ\n");
 #else
@@ -7093,33 +9023,28 @@ static void do_cmd_knowledge_quests(void)
 
        for (i = 1; i < max_quests; i++)
        {
-               if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_COMPLETED)
+               if ((quest[i].status == QUEST_STATUS_TAKEN) || (quest[i].status == QUEST_STATUS_COMPLETED))
                {
-                       int old_quest;
+                       /* Set the quest number temporary */
+                       int old_quest = p_ptr->inside_quest;
                        int j;
 
                        /* Clear the text */
-                       for (j = 0; j < 10; j++)
-                       {
-                               quest_text[j][0] = '\0';
-                       }
-
+                       for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
                        quest_text_line = 0;
 
-                       /* Set the quest number temporary */
-                       old_quest = p_ptr->inside_quest;
                        p_ptr->inside_quest = i;
 
                        /* Get the quest text */
                        init_flags = INIT_SHOW_TEXT;
 
-                       process_dungeon_file("q_info_j.txt", 0, 0, 0, 0);
+                       process_dungeon_file("q_info.txt", 0, 0, 0, 0);
 
                        /* Reset the old quest number */
                        p_ptr->inside_quest = old_quest;
 
-                        /* No info from "silent" quests */
-                        if (quest[i].flags & QUEST_FLAG_SILENT) continue;
+                       /* No info from "silent" quests */
+                       if (quest[i].flags & QUEST_FLAG_SILENT) continue;
 
                        total++;
 
@@ -7129,17 +9054,21 @@ static void do_cmd_knowledge_quests(void)
 
                                if (quest[i].status == QUEST_STATUS_TAKEN)
                                {
-                                       if (quest[i].type == QUEST_TYPE_KILL_LEVEL || quest[i].type == QUEST_TYPE_KILL_ANY_LEVEL)
+                                       switch (quest[i].type)
                                        {
+                                       case QUEST_TYPE_KILL_LEVEL:
+                                       case QUEST_TYPE_KILL_ANY_LEVEL:
                                                r_ptr = &r_info[quest[i].r_idx];
                                                strcpy(name, r_name + r_ptr->name);
                                                if (quest[i].max_num > 1)
                                                {
 #ifdef JP
-                                                       sprintf(note," - %d ÂΤÎ%s¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)",quest[i].max_num, name, quest[i].max_num-quest[i].cur_num);
+                                                       sprintf(note," - %d ÂΤÎ%s¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)",
+                                                               quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
 #else
                                                        plural_aux(name);
-                                                       sprintf(note," - kill %d %s, have killed %d.",quest[i].max_num, name, quest[i].cur_num);
+                                                       sprintf(note," - kill %d %s, have killed %d.",
+                                                               quest[i].max_num, name, quest[i].cur_num);
 #endif
                                                }
                                                else
@@ -7148,58 +9077,63 @@ static void do_cmd_knowledge_quests(void)
 #else
                                                        sprintf(note," - kill %s.",name);
 #endif
-                                       }
-                                       else if (quest[i].type == QUEST_TYPE_KILL_NUMBER)
-                                       {
-#ifdef JP
-                                               sprintf(note," - %d ÂΤΥâ¥ó¥¹¥¿¡¼¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)",quest[i].max_num, quest[i].max_num-quest[i].cur_num);
-#else
-                                               sprintf(note," - Kill %d monsters, have killed %d.",quest[i].max_num, quest[i].cur_num);
-#endif
-                                       }
-                                       else if (quest[i].type == QUEST_TYPE_FIND_ARTIFACT)
-                                       {
+                                               break;
+
+                                       case QUEST_TYPE_FIND_ARTIFACT:
                                                strcpy(name, a_name + a_info[quest[i].k_idx].name);
 #ifdef JP
                                                sprintf(note," - %s¤ò¸«¤Ä¤±½Ð¤¹¡£", name);
 #else
                                                sprintf(note," - Find out %s.", name);
 #endif
-                                       }
-                                       else if (quest[i].type == QUEST_TYPE_FIND_EXIT)
+                                               break;
+
+                                       case QUEST_TYPE_FIND_EXIT:
 #ifdef JP
                                                sprintf(note," - Ãµº÷¤¹¤ë¡£");
 #else
                                                sprintf(note," - Search.");
 #endif
-                                       else if (quest[i].type == QUEST_TYPE_KILL_ALL)
+                                               break;
+
+                                       case QUEST_TYPE_KILL_NUMBER:
+#ifdef JP
+                                               sprintf(note," - %d ÂΤΥâ¥ó¥¹¥¿¡¼¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)",
+                                                       quest[i].max_num, quest[i].max_num - quest[i].cur_num);
+#else
+                                               sprintf(note," - Kill %d monsters, have killed %d.",
+                                                       quest[i].max_num, quest[i].cur_num);
+#endif
+                                               break;
+
+                                       case QUEST_TYPE_KILL_ALL:
 #ifdef JP
                                                sprintf(note," - Á´¤Æ¤Î¥â¥ó¥¹¥¿¡¼¤òÅݤ¹¡£");
 #else
                                                sprintf(note," - Kill all monsters.");
 #endif
+                                               break;
+                                       }
                                }
 
                                /* Print the quest info */
 #ifdef JP
-                               sprintf(tmp_str, "%s (´í¸±ÅÙ:%d³¬ÁêÅö)%s\n",
+                               sprintf(tmp_str, "  %s (´í¸±ÅÙ:%d³¬ÁêÅö)%s\n",
+                                       quest[i].name, quest[i].level, note);
 #else
-                               sprintf(tmp_str, "%s (Danger level: %d)%s\n",
-#endif
-
+                               sprintf(tmp_str, "  %s (Danger level: %d)%s\n",
                                        quest[i].name, quest[i].level, note);
+#endif
 
                                fprintf(fff, tmp_str);
 
                                if (quest[i].status == QUEST_STATUS_COMPLETED)
                                {
 #ifdef JP
-                                       sprintf(tmp_str, "  ¥¯¥¨¥¹¥ÈãÀ® - ¤Þ¤ÀÊó½·¤ò¼õ¤±¤È¤Ã¤Æ¤Ê¤¤¡£\n");
+                                       sprintf(tmp_str, "    ¥¯¥¨¥¹¥ÈãÀ® - ¤Þ¤ÀÊó½·¤ò¼õ¤±¤È¤Ã¤Æ¤Ê¤¤¡£\n");
 #else
-                                       sprintf(tmp_str, "  Quest Completed - Unrewarded\n");
+                                       sprintf(tmp_str, "    Quest Completed - Unrewarded\n");
 #endif
-
-
                                        fprintf(fff, tmp_str);
                                }
                                else
@@ -7208,13 +9142,12 @@ static void do_cmd_knowledge_quests(void)
 
                                        while (quest_text[j][0] && j < 10)
                                        {
-                                               fprintf(fff, "  %s\n", quest_text[j]);
+                                               fprintf(fff, "    %s\n", quest_text[j]);
                                                j++;
                                        }
                                }
                        }
-                       else if ((quest[i].type == QUEST_TYPE_RANDOM) &&
-                                (quest[i].level < rand_level))
+                       else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
                        {
                                /* New random */
                                rand_level = quest[i].level;
@@ -7228,27 +9161,26 @@ static void do_cmd_knowledge_quests(void)
                                        if (quest[i].max_num > 1)
                                        {
 #ifdef JP
-sprintf(rand_tmp_str,"%s (%d ³¬) - %d ÂΤÎ%s¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)\n",
-       quest[i].name, quest[i].level,
-       quest[i].max_num, name, quest[i].max_num-quest[i].cur_num);
+                                               sprintf(rand_tmp_str,"  %s (%d ³¬) - %d ÂΤÎ%s¤òÅݤ¹¡£(¤¢¤È %d ÂÎ)\n",
+                                                       quest[i].name, quest[i].level,
+                                                       quest[i].max_num, name, quest[i].max_num - quest[i].cur_num);
 #else
                                                plural_aux(name);
 
-                                               sprintf(rand_tmp_str,"%s (Dungeon level: %d)\n  Kill %d %s, have killed %d.\n",
+                                               sprintf(rand_tmp_str,"  %s (Dungeon level: %d)\n  Kill %d %s, have killed %d.\n",
                                                        quest[i].name, quest[i].level,
                                                        quest[i].max_num, name, quest[i].cur_num);
 #endif
-
                                        }
                                        else
                                        {
 #ifdef JP
-sprintf(rand_tmp_str,"%s (%d ³¬) - %s¤òÅݤ¹¡£\n",
+                                               sprintf(rand_tmp_str,"  %s (%d ³¬) - %s¤òÅݤ¹¡£\n",
+                                                       quest[i].name, quest[i].level, name);
 #else
-                                               sprintf(rand_tmp_str,"%s (Dungeon level: %d)\n  Kill %s.\n",
-#endif
-
+                                               sprintf(rand_tmp_str,"  %s (Dungeon level: %d)\n  Kill %s.\n",
                                                        quest[i].name, quest[i].level, name);
+#endif
                                        }
                                }
                        }
@@ -7259,162 +9191,193 @@ sprintf(rand_tmp_str,"%s (%d 
        if (rand_tmp_str[0]) fprintf(fff, rand_tmp_str);
 
 #ifdef JP
-       if (!total) fprintf(fff, "¤Ê¤·\n");
+       if (!total) fprintf(fff, "  ¤Ê¤·\n");
 #else
-       if (!total) fprintf(fff, "Nothing.\n");
+       if (!total) fprintf(fff, "  Nothing.\n");
 #endif
+}
+
+
+/*
+ * Print all finished quests
+ */
+void do_cmd_knowledge_quests_completed(FILE *fff, int quest_num[])
+{
+       char tmp_str[120];
+       int i;
+       int total = 0;
 
 #ifdef JP
-       fprintf(fff, "\n¡ÔãÀ®¤·¤¿¥¯¥¨¥¹¥È¡Õ\n");
+       fprintf(fff, "¡ÔãÀ®¤·¤¿¥¯¥¨¥¹¥È¡Õ\n");
 #else
-       fprintf(fff, "\n< Completed Quest >\n");
+       fprintf(fff, "< Completed Quest >\n");
 #endif
-       total = 0;
        for (i = 1; i < max_quests; i++)
        {
-               if (quest[i].status == QUEST_STATUS_FINISHED)
+               int q_idx = quest_num[i];
+
+               if (quest[q_idx].status == QUEST_STATUS_FINISHED)
                {
-                       if (i < MIN_RANDOM_QUEST)
+                       if (is_fixed_quest_idx(q_idx))
                        {
-                                int old_quest;
-
                                /* Set the quest number temporary */
-                               old_quest = p_ptr->inside_quest;
-                               p_ptr->inside_quest = i;
+                               int old_quest = p_ptr->inside_quest;
+
+                               p_ptr->inside_quest = q_idx;
 
                                /* Get the quest */
                                init_flags = INIT_ASSIGN;
 
-                               process_dungeon_file("q_info_j.txt", 0, 0, 0, 0);
+                               process_dungeon_file("q_info.txt", 0, 0, 0, 0);
 
                                /* Reset the old quest number */
                                p_ptr->inside_quest = old_quest;
 
-                                /* No info from "silent" quests */
-                                if (quest[i].flags & QUEST_FLAG_SILENT) continue;
+                               /* No info from "silent" quests */
+                               if (quest[q_idx].flags & QUEST_FLAG_SILENT) continue;
                        }
 
                        total++;
 
-                       if ((i >= MIN_RANDOM_QUEST) && quest[i].r_idx)
+                       if (!is_fixed_quest_idx(q_idx) && quest[q_idx].r_idx)
                        {
                                /* Print the quest info */
 
-                                if (quest[i].complev == 0)
-                                {
-                                        sprintf(tmp_str, 
+                               if (quest[q_idx].complev == 0)
+                               {
+                                       sprintf(tmp_str,
 #ifdef JP
-                                                "%s (%d³¬) - ÉÔÀᄀ\n",
+                                               "  %-40s (%3d³¬)            -   ÉÔÀᄀ\n",
 #else
-                                                "%s (Dungeon level: %d) - (Cancelled)\n",
+                                               "  %-40s (Dungeon level: %3d) - (Cancelled)\n",
 #endif
-                                                r_name+r_info[quest[i].r_idx].name,
-                                                quest[i].level);
-                                }
-                                else
-                                {
-                                        sprintf(tmp_str, 
+                                               r_name+r_info[quest[q_idx].r_idx].name,
+                                               quest[q_idx].level);
+                               }
+                               else
+                               {
+                                       sprintf(tmp_str,
 #ifdef JP
-                                                "%s (%d³¬) - ¥ì¥Ù¥ë%d\n",
+                                               "  %-40s (%3d³¬)            - ¥ì¥Ù¥ë%2d\n",
 #else
-                                                "%s (Dungeon level: %d) - level %d\n",
+                                               "  %-40s (Dungeon level: %3d) - level %2d\n",
 #endif
-                                                r_name+r_info[quest[i].r_idx].name,
-                                                quest[i].level,
-                                                quest[i].complev);
-                                }
+                                               r_name+r_info[quest[q_idx].r_idx].name,
+                                               quest[q_idx].level,
+                                               quest[q_idx].complev);
+                               }
                        }
                        else
                        {
                                /* Print the quest info */
 #ifdef JP
-                               sprintf(tmp_str, "%s (´í¸±ÅÙ:%d³¬ÁêÅö) - ¥ì¥Ù¥ë%d\n",
+                               sprintf(tmp_str, "  %-40s (´í¸±ÅÙ:%3d³¬ÁêÅö) - ¥ì¥Ù¥ë%2d\n",
+                                       quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
 #else
-                               sprintf(tmp_str, "%s (Danger level: %d) - level %d\n",
+                               sprintf(tmp_str, "  %-40s (Danger  level: %3d) - level %2d\n",
+                                       quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
 #endif
-
-                                       quest[i].name, quest[i].level, quest[i].complev);
                        }
 
                        fprintf(fff, tmp_str);
                }
        }
 #ifdef JP
-       if (!total) fprintf(fff, "¤Ê¤·\n");
+       if (!total) fprintf(fff, "  ¤Ê¤·\n");
 #else
-       if (!total) fprintf(fff, "Nothing.\n");
+       if (!total) fprintf(fff, "  Nothing.\n");
 #endif
+}
+
+
+/*
+ * Print all failed quests
+ */
+void do_cmd_knowledge_quests_failed(FILE *fff, int quest_num[])
+{
+       char tmp_str[120];
+       int i;
+       int total = 0;
 
 #ifdef JP
-       fprintf(fff, "\n¡Ô¼ºÇÔ¤·¤¿¥¯¥¨¥¹¥È¡Õ\n");
+       fprintf(fff, "¡Ô¼ºÇÔ¤·¤¿¥¯¥¨¥¹¥È¡Õ\n");
 #else
-       fprintf(fff, "\n< Failed Quest >\n");
+       fprintf(fff, "< Failed Quest >\n");
 #endif
-       total = 0;
        for (i = 1; i < max_quests; i++)
        {
-               if ((quest[i].status == QUEST_STATUS_FAILED_DONE) || (quest[i].status == QUEST_STATUS_FAILED))
+               int q_idx = quest_num[i];
+
+               if ((quest[q_idx].status == QUEST_STATUS_FAILED_DONE) || (quest[q_idx].status == QUEST_STATUS_FAILED))
                {
-                       if (i < MIN_RANDOM_QUEST)
+                       if (is_fixed_quest_idx(q_idx))
                        {
-                                int old_quest;
-
                                /* Set the quest number temporary */
-                               old_quest = p_ptr->inside_quest;
-                               p_ptr->inside_quest = i;
+                               int old_quest = p_ptr->inside_quest;
+
+                               p_ptr->inside_quest = q_idx;
 
                                /* Get the quest text */
                                init_flags = INIT_ASSIGN;
 
-                               process_dungeon_file("q_info_j.txt", 0, 0, 0, 0);
+                               process_dungeon_file("q_info.txt", 0, 0, 0, 0);
 
                                /* Reset the old quest number */
                                p_ptr->inside_quest = old_quest;
 
-                                /* No info from "silent" quests */
-                                if (quest[i].flags & QUEST_FLAG_SILENT) continue;
+                               /* No info from "silent" quests */
+                               if (quest[q_idx].flags & QUEST_FLAG_SILENT) continue;
                        }
 
                        total++;
 
-                       if ((i >= MIN_RANDOM_QUEST) && quest[i].r_idx)
+                       if (!is_fixed_quest_idx(q_idx) && quest[q_idx].r_idx)
                        {
                                /* Print the quest info */
 #ifdef JP
-                               sprintf(tmp_str, "%s (%d³¬) - ¥ì¥Ù¥ë%d\n",
+                               sprintf(tmp_str, "  %-40s (%3d³¬)            - ¥ì¥Ù¥ë%2d\n",
+                                       r_name+r_info[quest[q_idx].r_idx].name, quest[q_idx].level, quest[q_idx].complev);
 #else
-                               sprintf(tmp_str, "%s (Dungeon level: %d) - level %d\n",
+                               sprintf(tmp_str, "  %-40s (Dungeon level: %3d) - level %2d\n",
+                                       r_name+r_info[quest[q_idx].r_idx].name, quest[q_idx].level, quest[q_idx].complev);
 #endif
-
-                                       r_name+r_info[quest[i].r_idx].name, quest[i].level, quest[i].complev);
                        }
                        else
                        {
                                /* Print the quest info */
 #ifdef JP
-                               sprintf(tmp_str, "%s (´í¸±ÅÙ:%d³¬ÁêÅö) - ¥ì¥Ù¥ë%d\n",
+                               sprintf(tmp_str, "  %-40s (´í¸±ÅÙ:%3d³¬ÁêÅö) - ¥ì¥Ù¥ë%2d\n",
+                                       quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
 #else
-                               sprintf(tmp_str, "%s (Danger level: %d) - level %d\n",
+                               sprintf(tmp_str, "  %-40s (Danger  level: %3d) - level %2d\n",
+                                       quest[q_idx].name, quest[q_idx].level, quest[q_idx].complev);
 #endif
-
-                                       quest[i].name, quest[i].level, quest[i].complev);
                        }
                        fprintf(fff, tmp_str);
                }
        }
 #ifdef JP
-       if (!total) fprintf(fff, "¤Ê¤·\n");
+       if (!total) fprintf(fff, "  ¤Ê¤·\n");
 #else
-       if (!total) fprintf(fff, "Nothing.\n");
+       if (!total) fprintf(fff, "  Nothing.\n");
 #endif
+}
+
+
+/*
+ * Print all random quests
+ */
+static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
+{
+       char tmp_str[120];
+       int i;
+       int total = 0;
 
-       if (p_ptr->wizard) {
 #ifdef JP
-       fprintf(fff, "\n¡Ô»Ä¤ê¤Î¥é¥ó¥À¥à¥¯¥¨¥¹¥È¡Õ\n");
+       fprintf(fff, "¡Ô»Ä¤ê¤Î¥é¥ó¥À¥à¥¯¥¨¥¹¥È¡Õ\n");
 #else
-       fprintf(fff, "\n< Remaining Random Quest >\n");
+       fprintf(fff, "< Remaining Random Quest >\n");
 #endif
-       total = 0;
        for (i = 1; i < max_quests; i++)
        {
                /* No info from "silent" quests */
@@ -7426,21 +9389,94 @@ sprintf(rand_tmp_str,"%s (%d 
 
                        /* Print the quest info */
 #ifdef JP
-                       sprintf(tmp_str, "%s (%d³¬, %s)\n",
+                       sprintf(tmp_str, "  %s (%d³¬, %s)\n",
+                               quest[i].name, quest[i].level, r_name+r_info[quest[i].r_idx].name);
 #else
-                       sprintf(tmp_str, "%s (%d, %s)\n",
-#endif
-
+                       sprintf(tmp_str, "  %s (%d, %s)\n",
                                quest[i].name, quest[i].level, r_name+r_info[quest[i].r_idx].name);
+#endif
                        fprintf(fff, tmp_str);
                }
        }
 #ifdef JP
-       if (!total) fprintf(fff, "¤Ê¤·\n");
+       if (!total) fprintf(fff, "  ¤Ê¤·\n");
+#else
+       if (!total) fprintf(fff, "  Nothing.\n");
+#endif
+}
+
+
+bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
+{
+       int *q_num = (int *)u;
+       quest_type *qa = &quest[q_num[a]];
+       quest_type *qb = &quest[q_num[b]];
+
+       /* Unused */
+       (void)v;
+
+       if (qa->complev < qb->complev) return TRUE;
+       if (qa->complev > qb->complev) return FALSE;
+       if (qa->level <= qb->level) return TRUE;
+       return FALSE;
+}
+
+void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
+{
+       int *q_num = (int *)u;
+       int tmp;
+
+       /* Unused */
+       (void)v;
+
+       tmp = q_num[a];
+       q_num[a] = q_num[b];
+       q_num[b] = tmp;
+}
+
+
+/*
+ * Print quest status of all active quests
+ */
+static void do_cmd_knowledge_quests(void)
+{
+       FILE *fff;
+       char file_name[1024];
+       int *quest_num, dummy, i;
+
+       /* Open a new file */
+       fff = my_fopen_temp(file_name, 1024);
+       if (!fff)
+       {
+#ifdef JP
+           msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
 #else
-       if (!total) fprintf(fff, "Nothing.\n");
+           msg_format("Failed to create temporary file %s.", file_name);
 #endif
-       }       
+           msg_print(NULL);
+           return;
+       }
+
+       /* Allocate Memory */
+       C_MAKE(quest_num, max_quests, int);
+
+       /* Sort by compete level */
+       for (i = 1; i < max_quests; i++) quest_num[i] = i;
+       ang_sort_comp = ang_sort_comp_quest_num;
+       ang_sort_swap = ang_sort_swap_quest_num;
+       ang_sort(quest_num, &dummy, max_quests);
+
+       /* Dump Quest Information */
+       do_cmd_knowledge_quests_current(fff);
+       fputc('\n', fff);
+       do_cmd_knowledge_quests_completed(fff, quest_num);
+       fputc('\n', fff);
+       do_cmd_knowledge_quests_failed(fff, quest_num);
+       if (p_ptr->wizard)
+       {
+               fputc('\n', fff);
+               do_cmd_knowledge_quests_wiz_random(fff);
+       }
 
        /* Close the file */
        my_fclose(fff);
@@ -7452,41 +9488,41 @@ sprintf(rand_tmp_str,"%s (%d 
        show_file(TRUE, file_name, "Quest status", 0, 0);
 #endif
 
-
        /* Remove the file */
        fd_kill(file_name);
-}
 
+       /* Free Memory */
+       C_KILL(quest_num, max_quests, int);
+}
 
 
 /*
-* List my home
-*
-*/
+ * List my home
+ */
 static void do_cmd_knowledge_home(void)
 {
        FILE *fff;
-       
-       int i, x;
+
+       int i;
        char file_name[1024];
        store_type  *st_ptr;
        char o_name[MAX_NLEN];
        cptr            paren = ")";
 
-       process_dungeon_file("w_info_j.txt", 0, 0, max_wild_y, max_wild_x);
+       process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
 
        /* Open a new file */
        fff = my_fopen_temp(file_name, 1024);
        if (!fff) {
 #ifdef JP
-           msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
+               msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
 #else
-           msg_format("Failed to create temporary file %s.", file_name);
+               msg_format("Failed to create temporary file %s.", file_name);
 #endif
-           msg_print(NULL);
-           return;
+               msg_print(NULL);
+               return;
        }
-       
+
        if (fff)
        {
                /* Print all homes in the different towns */
@@ -7495,20 +9531,22 @@ static void do_cmd_knowledge_home(void)
                /* Home -- if anything there */
                if (st_ptr->stock_num)
                {
+#ifdef JP
+                       int x = 1;
+#endif
                        /* Header with name of the town */
 #ifdef JP
                        fprintf(fff, "  [ ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à ]\n");
 #else
                        fprintf(fff, "  [Home Inventory]\n");
 #endif
-                               x = 1;
 
                        /* Dump all available items */
                        for (i = 0; i < st_ptr->stock_num; i++)
                        {
 #ifdef JP
-                               if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
-                               object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
+                               if ((i % 12) == 0) fprintf(fff, "\n ( %d ¥Ú¡¼¥¸ )\n", x++);
+                               object_desc(o_name, &st_ptr->stock[i], 0);
                                if (strlen(o_name) <= 80-3)
                                {
                                        fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
@@ -7525,7 +9563,7 @@ static void do_cmd_knowledge_home(void)
                                        fprintf(fff, "   %.77s\n", o_name+n);
                                }
 #else
-                               object_desc(o_name, &st_ptr->stock[i], TRUE, 3);
+                               object_desc(o_name, &st_ptr->stock[i], 0);
                                fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
 #endif
 
@@ -7535,18 +9573,18 @@ static void do_cmd_knowledge_home(void)
                        fprintf(fff, "\n\n");
                }
        }
-       
+
        /* Close the file */
        my_fclose(fff);
-       
+
        /* Display the file contents */
 #ifdef JP
-show_file(TRUE, file_name, "²æ¤¬²È¤Î¥¢¥¤¥Æ¥à", 0, 0);
+       show_file(TRUE, file_name, "²æ¤¬²È¤Î¥¢¥¤¥Æ¥à", 0, 0);
 #else
        show_file(TRUE, file_name, "Home Inventory", 0, 0);
 #endif
 
-       
+
        /* Remove the file */
        fd_kill(file_name);
 }
@@ -7620,7 +9658,7 @@ static void do_cmd_knowledge_autopick(void)
                        tmp = "Pickup";
 #endif
                }
-               else if (act & DO_QUERY_AUTOPICK)
+               else /* if (act & DO_QUERY_AUTOPICK) */ /* Obvious */
                {
 #ifdef JP
                        tmp = "³Îǧ";
@@ -7658,16 +9696,21 @@ static void do_cmd_knowledge_autopick(void)
  */
 void do_cmd_knowledge(void)
 {
-       int i,p=0;
+       int i, p = 0;
+       bool need_redraw = FALSE;
+
        /* File type is "TEXT" */
        FILE_TYPE(FILE_TYPE_TEXT);
+
        /* Save the screen */
        screen_save();
+
        /* Interact until done */
        while (1)
        {
                /* Clear screen */
                Term_clear();
+
                /* Ask for a choice */
 #ifdef JP
                prt(format("%d/2 ¥Ú¡¼¥¸", (p+1)), 2, 65);
@@ -7679,17 +9722,21 @@ void do_cmd_knowledge(void)
 
                /* Give some choices */
 #ifdef JP
-               if (p == 0) {
+               if (p == 0)
+               {
                        prt("(1) ´ûÃΤÎÅÁÀâ¤Î¥¢¥¤¥Æ¥à                 ¤Î°ìÍ÷", 6, 5);
                        prt("(2) ´ûÃΤΥ¢¥¤¥Æ¥à                       ¤Î°ìÍ÷", 7, 5);
                        prt("(3) ´ûÃΤÎÀ¸¤­¤Æ¤¤¤ë¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼ ¤Î°ìÍ÷", 8, 5);
-                       prt("(4) Åݤ·¤¿¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼           ¤Î°ìÍ÷", 9, 5);
+                       prt("(4) ´ûÃΤΥâ¥ó¥¹¥¿¡¼                     ¤Î°ìÍ÷", 9, 5);
                        prt("(5) Åݤ·¤¿Å¨¤Î¿ô                         ¤Î°ìÍ÷", 10, 5);
-                       prt("(6) ¾Þ¶â¼ó                               ¤Î°ìÍ÷", 11, 5);
+                       if (!vanilla_town) prt("(6) ¾Þ¶â¼ó                               ¤Î°ìÍ÷", 11, 5);
                        prt("(7) ¸½ºß¤Î¥Ú¥Ã¥È                         ¤Î°ìÍ÷", 12, 5);
                        prt("(8) ²æ¤¬²È¤Î¥¢¥¤¥Æ¥à                     ¤Î°ìÍ÷", 13, 5);
                        prt("(9) *´ÕÄê*ºÑ¤ßÁõÈ÷¤ÎÂÑÀ­                 ¤Î°ìÍ÷", 14, 5);
-               } else {
+                       prt("(0) ÃÏ·Á¤Îɽ¼¨Ê¸»ú/¥¿¥¤¥ë                ¤Î°ìÍ÷", 15, 5);
+               }
+               else
+               {
                        prt("(a) ¼«Ê¬¤Ë´Ø¤¹¤ë¾ðÊó                     ¤Î°ìÍ÷", 6, 5);
                        prt("(b) ÆÍÁ³ÊÑ°Û                             ¤Î°ìÍ÷", 7, 5);
                        prt("(c) Éð´ï¤Î·Ð¸³ÃÍ                         ¤Î°ìÍ÷", 8, 5);
@@ -7701,17 +9748,21 @@ void do_cmd_knowledge(void)
                        prt("(i) ¸½ºß¤Î¼«Æ°½¦¤¤/Ç˲õÀßÄê              ¤Î°ìÍ÷", 14, 5);
                }
 #else
-               if (p == 0) {
+               if (p == 0)
+               {
                        prt("(1) Display known artifacts", 6, 5);
                        prt("(2) Display known objects", 7, 5);
                        prt("(3) Display remaining uniques", 8, 5);
-                       prt("(4) Display dead uniques", 9, 5);
+                       prt("(4) Display known monster", 9, 5);
                        prt("(5) Display kill count", 10, 5);
-                       prt("(6) Display wanted monsters", 11, 5);
+                       if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
                        prt("(7) Display current pets", 12, 5);
                        prt("(8) Display home inventory", 13, 5);
                        prt("(9) Display *identified* equip.", 14, 5);
-               } else {
+                       prt("(0) Display terrain symbols.", 15, 5);
+               }
+               else
+               {
                        prt("(a) Display about yourself", 6, 5);
                        prt("(b) Display mutations", 7, 5);
                        prt("(c) Display weapon proficiency", 8, 5);
@@ -7725,13 +9776,13 @@ void do_cmd_knowledge(void)
 #endif
                /* Prompt */
 #ifdef JP
-               prt("-³¤¯-", 16, 8);
+               prt("-³¤¯-", 17, 8);
                prt("ESC) È´¤±¤ë", 21, 1);
                prt("SPACE) ¼¡¥Ú¡¼¥¸", 21, 30);
                /*prt("-) Á°¥Ú¡¼¥¸", 21, 60);*/
                prt("¥³¥Þ¥ó¥É:", 20, 0);
 #else
-               prt("-more-", 16, 8);
+               prt("-more-", 17, 8);
                prt("ESC) Exit menu", 21, 1);
                prt("SPACE) Next page", 21, 30);
                /*prt("-) Previous page", 21, 60);*/
@@ -7740,6 +9791,7 @@ void do_cmd_knowledge(void)
 
                /* Prompt */
                i = inkey();
+
                /* Done */
                if (i == ESCAPE) break;
                switch (i)
@@ -7752,19 +9804,19 @@ void do_cmd_knowledge(void)
                        do_cmd_knowledge_artifacts();
                        break;
                case '2': /* Objects */
-                       do_cmd_knowledge_objects();
+                       do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
                        break;
                case '3': /* Uniques */
                        do_cmd_knowledge_uniques();
                        break;
-               case '4': /* Uniques */
-                       do_cmd_knowledge_uniques_dead();
+               case '4': /* Monsters */
+                       do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
                        break;
                case '5': /* Kill count  */
                        do_cmd_knowledge_kill_count();
                        break;
                case '6': /* wanted */
-                       do_cmd_knowledge_kubi();
+                       if (!vanilla_town) do_cmd_knowledge_kubi();
                        break;
                case '7': /* Pets */
                        do_cmd_knowledge_pets();
@@ -7775,6 +9827,12 @@ void do_cmd_knowledge(void)
                case '9': /* Resist list */
                        do_cmd_knowledge_inven();
                        break;
+               case '0': /* Feature list */
+                       {
+                               int lighting_level = F_LIT_STANDARD;
+                               do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
+                       }
+                       break;
                /* Next page */
                case 'a': /* Max stat */
                        do_cmd_knowledge_stat();
@@ -7806,11 +9864,15 @@ void do_cmd_knowledge(void)
                default: /* Unknown option */
                        bell();
                }
+
                /* Flush messages */
                msg_print(NULL);
        }
+
        /* Restore the screen */
        screen_load();
+
+       if (need_redraw) do_cmd_redraw();
 }
 
 
@@ -7855,7 +9917,7 @@ void do_cmd_time(void)
        num = 0;
 
 #ifdef JP
-strcpy(desc, "ÊѤʻþ¹ï¤À¡£");
+       strcpy(desc, "ÊѤʻþ¹ï¤À¡£");
 #else
        strcpy(desc, "It is a strange time.");
 #endif
@@ -7863,33 +9925,35 @@ strcpy(desc, "
 
        /* Message */
 #ifdef JP
-msg_format("%d ÆüÌÜ,»þ¹ï¤Ï%d:%02d %s¤Ç¤¹¡£",
+       msg_format("%d ÆüÌÜ,»þ¹ï¤Ï%d:%02d %s¤Ç¤¹¡£",
+                  day, (hour % 12 == 0) ? 12 : (hour % 12),
+                  min, (hour < 12) ? "AM" : "PM");
 #else
        msg_format("This is day %d. The time is %d:%02d %s.",
+                  day, (hour % 12 == 0) ? 12 : (hour % 12),
+                  min, (hour < 12) ? "AM" : "PM");
 #endif
 
-                                 day, (hour % 12 == 0) ? 12 : (hour % 12),
-                                 min, (hour < 12) ? "AM" : "PM");
 
        /* Find the path */
        if (!randint0(10) || p_ptr->image)
-               {
+       {
 #ifdef JP
                path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timefun_j.txt");
 #else
                path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timefun.txt");
 #endif
 
-               }
-               else
-               {
+       }
+       else
+       {
 #ifdef JP
                path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timenorm_j.txt");
 #else
                path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, "timenorm.txt");
 #endif
 
-               }
+       }
 
        /* Open this file */
        fff = my_fopen(buf, "rt");