/*
 *  File:       view.cc
 *  Summary:    Misc function used to render the dungeon.
 *  Written by: Linley Henzell
 *
 *  Change History (most recent first):
 *
 *   <10>     29 Jul 00  JDJ    show_map iterates horizontally to 79 instead of 80.
 *                              item no longer indexes past the end of environ::grid.
 *   <9>      19 Jun 00  GDL    Complete rewrite of LOS code
 *   <8>      11/23/99   LRH    Added colour-coded play-screen map & clean_map
 *                                                              init options
 *   <7>      9/29/99    BCR    Removed first argument from draw_border
 *   <6>      9/11/99    LRH    Added calls to overmap functions
 *   <5>      6/22/99    BWR    Fixed and improved the stealth
 *   <4>      5/20/99    BWR    show_map colours all portals,
 *                              exits from subdungeons now
 *                              look like up stairs.
 *   <3>      5/09/99    JDJ    show_map draws shops in yellow.
 *   <2>      5/09/99    JDJ    show_map accepts '\r' along with '.'.
 *   <1>      -/--/--    LRH    Created
 */

#include "AppHdr.h"
#include "view.h"

#include <string.h>

#ifdef DOS
#include <conio.h>
#endif

#include "externs.h"

#include "debug.h"
#include "insult.h"
#include "macro.h"
#include "monstuff.h"
#include "mon-util.h"
#include "overmap.h"
#include "player.h"
#include "skills2.h"
#include "stuff.h"
#include "spells4.h"
#include "travel.h"

#ifdef WINDOWS
#include "winclass.h"
#endif

unsigned char your_sign;        // accessed as extern in transfor.cc and acr.cc
unsigned char your_colour;      // accessed as extern in transfor.cc and acr.cc

FixedArray < unsigned int, 20, 19 > show_backup;

#ifdef USE_TILE
#include "tiles.h"
#endif

#ifdef WINDOWS
extern WinClass    *win_main;
#endif

unsigned char show_green;
extern int stealth;             // defined in acr.cc
extern FixedVector<char, 10>  Visible_Statue;        // defined in acr.cc

// char colour_code_map(unsigned char map_value);
char colour_code_map( int x, int y );

unsigned char (*mapch) (unsigned char);
unsigned char (*mapch2) (unsigned char);
unsigned char mapchar(unsigned char ldfk);
unsigned char mapchar2(unsigned char ldfk);
unsigned char mapchar3(unsigned char ldfk);
unsigned char mapchar4(unsigned char ldfk);
unsigned char mapchar5(unsigned char ldfk);
unsigned char mapchar6(unsigned char ldfk);
void cloud_grid(void);
void monster_grid(bool do_updates);

//---------------------------------------------------------------
//
// get_number_of_lines
//
// Made this a function instead of a #define.  This should help
// considering the fact that the curses version is a macro
// (curses tends to be implemented with a large number of
// preprocessor macros, which can wreak havoc with things
// like the C++ string class, so we want to isolate that
// away to keep portability up).
//
// Other OSes might want to hook into reading system environment
// variables or player set options to determine the screen size
// (see the Options and SysEnv structures, as well as initfile.cc).
//
// This might be better to move to the lib*.cc files, but we
// don't really have a standard API defined for them, or the
// all important libdos.cc.  It would be a good idea to eventually
// head that way. -- bwr
//
//---------------------------------------------------------------
int get_number_of_lines(void)
{
#ifdef USE_TILE
    return (get_number_of_lines_tile());
#elif defined(LINUX)
    return (get_number_of_lines_from_curses());
#elif defined(MAC)
    return (MAC_NUMBER_OF_LINES);
#else
    return (25);
#endif
}

#ifdef JP
#ifdef LINUX
// VT100 フォントの特殊文字を使用
static unsigned char ascii_to_zenkaku[2*256+1] ="\
　！”＃＄％＆’（）＊＋，−．／\
０１２３４５６７８９：；＜＝＞？\
＠ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯ\
ＰＱＲＳＴＵＶＷＸＹＺ［＼］＾＿\
‘ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏ\
ｐｑｒｓｔｕｖｗｘｙｚ｛｜｝〜\002\002\
回《・Π∩●□≡》※\002\002\002\002\002\002巛‰";

#else /* LINUX */

static unsigned char ascii_to_zenkaku[2*256+1] ="\
　！”＃＄％＆’（）＊＋，−．／\
０１２３４５６７８９：；＜＝＞？\
＠ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯ\
ＰＱＲＳＴＵＶＷＸＹＺ［＼］＾＿\
‘ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏ\
ｐｑｒｓｔｕｖｗｘｙｚ｛｜｝〜＃\
回《・Π∩●□≡》※＃＃＃巛‰";
#endif /* JP */

/*
 0 1 2 3 4 5 6 7 8 9 A B C D E F
128:回閉じたドア 129:《特殊階段 130:・床          131:Π祭壇
132:∩入口       133:● 噴水    134:□ 開いたドア 135:≡ 水
136:》特殊階段   137:※蜂の巣   138:＃石の壁      139:＃金属の壁
140:＃水晶の壁   141:巛 溶岩    142:‰死体
*/
#endif

// Convert special char(>=127) back to normal char for the
//  'X' command
#ifdef LINUX
//VT100 フォント特殊文字を使用
// 001=ダイヤ型 002=メッシュ四角 037=中央ドット
static unsigned char special_to_ascii[128] =
  "\002+<\037_\\\001'{>\002\002\002\002{% ";
#else /* LINUX */
static unsigned char special_to_ascii[128] ="#+<._\\}'{>####{% ";
#endif

//---------------------------------------------------------------
//
// get_zenkaku_symbol
//
// Returns zenkaku character index and color for everything
//
//
//---------------------------------------------------------------
void get_zenkaku_symbol(unsigned int object, unsigned short *ch,
                           unsigned short *color)
{
    ASSERT(color != NULL);
    ASSERT(ch != NULL);

    switch (object)
    {
    case DNGN_UNSEEN:
        *ch = 0;
        break;

    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
        *color = env.rock_colour;
        *ch = 127;
        break;                  // remember earth elementals

    // stone in the realm of Zot is coloured the same as rock
    case DNGN_STONE_WALL:
        *color = (player_in_branch( BRANCH_HALL_OF_ZOT ) ? env.rock_colour
                                                         : LIGHTGREY);
        *ch = 138;
        break;

    case DNGN_CLOSED_DOOR:
        *ch = 128;
        break;

    case DNGN_METAL_WALL:
        *ch = 139;
        *color = CYAN;
        break;

    case DNGN_SECRET_DOOR:
        *ch = 127;
        *color = env.rock_colour;
        break;

    case DNGN_GREEN_CRYSTAL_WALL:
        *ch = 140;
        *color = GREEN;
        break;

    case DNGN_ORCISH_IDOL:
        *ch = '8';
        *color = DARKGREY;
        break;

    case DNGN_WAX_WALL:
        *ch = 137;
        *color = YELLOW;
        break;                  // wax wall
        /* Anything added here must also be added to the PLAIN_TERMINAL
           viewwindow2 below */

    case DNGN_SILVER_STATUE:
        *ch = '8';
        *color = WHITE;
        Visible_Statue[ STATUE_SILVER ] = 1;
        break;

    case DNGN_GRANITE_STATUE:
        *ch = '8';
        *color = LIGHTGREY;
        break;

    case DNGN_ORANGE_CRYSTAL_STATUE:
        *ch = '8';
        *color = LIGHTRED;
        Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 1;
        break;

    case DNGN_LAVA:
        *ch = 141;
        *color = RED;
        break;

    case DNGN_DEEP_WATER:
        *ch = 135;          // this wavy thing also used for water elemental
        *color = BLUE;
        break;

    case DNGN_SHALLOW_WATER:
        *ch = 135;          // this wavy thing also used for water elemental
        *color = CYAN;
        break;

    case DNGN_FLOOR:
        *color = env.floor_colour;
        *ch = 130;
        break;

    case DNGN_ENTER_HELL:
        *ch = 136;
        *color = RED;
        seen_other_thing(object);
        break;

    case DNGN_OPEN_DOOR:
        *ch = 134;
        break;

    case DNGN_BRANCH_STAIRS:
        *ch = 136;
        *color = BROWN;
        break;

    case DNGN_TRAP_MECHANICAL:
        *color = LIGHTCYAN;
        *ch = 94;
        break;

    case DNGN_TRAP_MAGICAL:
        *color = MAGENTA;
        *ch = 94;
        break;

    case DNGN_TRAP_III:
        *color = LIGHTGREY;
        *ch = 94;
        break;

    case DNGN_UNDISCOVERED_TRAP:
        *ch = 130;
        *color = env.floor_colour;
        break;

    case DNGN_ENTER_SHOP:
        *ch = 132;
        *color = YELLOW;

        seen_other_thing(object);
        break;
    // if I change anything above here, must also change magic mapping!

    case DNGN_ENTER_LABYRINTH:
      *ch = 132;
        *color = LIGHTGREY;
        seen_other_thing(object);
        break;

    // not sure why we have "odd" here, but "ladders" are special in
    // that they all lead to the first staircase of the next level
    // (and returning from there will take you somewhere different)
    // ... that's why they're brown... it's a warning -- bwr
    case DNGN_ROCK_STAIRS_DOWN:
        *color = BROWN;         // ladder    // odd {dlb}
    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
        *ch = '>';
        break;

    case DNGN_ROCK_STAIRS_UP:
        *color = BROWN;         // ladder    // odd {dlb}
    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
        *ch = '<';
        break;

    case DNGN_ENTER_DIS:
        *color = CYAN;
        *ch = 132;
        break;

    case DNGN_ENTER_GEHENNA:
        *color = RED;
        *ch = 132;
        break;

    case DNGN_ENTER_COCYTUS:
        *color = LIGHTCYAN;
        *ch = 132;
        break;

    case DNGN_ENTER_TARTARUS:
        *color = DARKGREY;
        *ch = 132;
        break;

    case DNGN_ENTER_ABYSS:
        *color = random2(16);
        *ch = 132;
        seen_other_thing(object);
        break;

    case DNGN_EXIT_ABYSS:
        *color = random2(16);
        *ch = 132;
        break;

    case DNGN_STONE_ARCH:
        *color = LIGHTGREY;
        *ch = 132;
        break;

    case DNGN_ENTER_PANDEMONIUM:
        *color = LIGHTBLUE;
        *ch = 132;
        seen_other_thing(object);
        break;

    case DNGN_EXIT_PANDEMONIUM:
        *color = LIGHTBLUE;
        *ch = 132;
        break;

    case DNGN_TRANSIT_PANDEMONIUM:
        *color = LIGHTGREEN;
        *ch = 132;
        break;

    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        *color = YELLOW;
        *ch = 136;
        seen_staircase(object);
        break;

    case DNGN_ENTER_ZOT:
        *color = MAGENTA;
        *ch = 132;
        seen_staircase(object);
        break;

    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        *color = YELLOW;
        *ch = 129; //《
        break;

    case DNGN_RETURN_FROM_ZOT:
        *color = MAGENTA;
        *ch = 132;
        break;

    case DNGN_ALTAR_ZIN:
        *color = WHITE;
        *ch = 131;
        seen_altar(GOD_ZIN);
        break;

    case DNGN_ALTAR_SHINING_ONE:
        *color = YELLOW;
        *ch = 131;
        seen_altar(GOD_SHINING_ONE);
        break;

    case DNGN_ALTAR_KIKUBAAQUDGHA:
        *color = DARKGREY;
        *ch = 131;
        seen_altar(GOD_KIKUBAAQUDGHA);
        break;

    case DNGN_ALTAR_YREDELEMNUL:
        *color = ((one_chance_in(3)) ? RED : DARKGREY);
        *ch = 131;
        seen_altar(GOD_YREDELEMNUL);
        break;

    case DNGN_ALTAR_XOM:
        *color = random_colour();
        *ch = 131;
        seen_altar(GOD_XOM);
        break;

    case DNGN_ALTAR_VEHUMET:
        *color = LIGHTBLUE;
        if (one_chance_in(3))
            *color = LIGHTMAGENTA;
        if (one_chance_in(3))
            *color = LIGHTRED;
        *ch = 131;
        seen_altar(GOD_VEHUMET);
        break;

    case DNGN_ALTAR_OKAWARU:
        *color = CYAN;
        *ch = 131;
        seen_altar(GOD_OKAWARU);
        break;

    case DNGN_ALTAR_MAKHLEB:
        *color = RED;
        if (one_chance_in(3))
            *color = LIGHTRED;
        if (one_chance_in(3))
            *color = YELLOW;
        *ch = 131;
        seen_altar(GOD_MAKHLEB);
        break;

    case DNGN_ALTAR_SIF_MUNA:
        *color = BLUE;
        *ch = 131;
        seen_altar(GOD_SIF_MUNA);
        break;

    case DNGN_ALTAR_TROG:
        *color = RED;
        *ch = 131;
        seen_altar(GOD_TROG);
        break;

    case DNGN_ALTAR_NEMELEX_XOBEH:
        *color = LIGHTMAGENTA;
        *ch = 131;
        seen_altar(GOD_NEMELEX_XOBEH);
        break;

    case DNGN_ALTAR_ELYVILON:
        *color = LIGHTGREY;
        *ch = 131;
        seen_altar(GOD_ELYVILON);
        break;

    case DNGN_BLUE_FOUNTAIN:
        *color = BLUE;
        *ch = 133;
        break;

    case DNGN_SPARKLING_FOUNTAIN:
        *color = LIGHTBLUE;
        *ch = 133;
        break;

    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_PERMADRY_FOUNTAIN:
        *color = LIGHTGREY;
        *ch = 133;
        break;

    case 256:
        *ch = '0';
        break;

    case 257:
        *color = CYAN;
        *ch = '~';
        break;                  /* Invis creature walking through water */

    case 258:
        *ch = ')';
        break;                  // weapon )

    case 259:
        *ch = '[';
        break;                  // armour [

    case 260:
        *ch = '/';
        break;                  // wands, etc.

    case 261:
        *ch = '%';
        break;                  // food

    case 262:
        *ch = '+';
        break;                  // books +

    case 263:
        *ch = '?';
        break;                  // scroll ?

    case 264:
        *ch = '=';
        break;                  // ring = etc

    case 265:
        *ch = '!';
        break;                  // potions !

    case 266:
        *ch = '(';
        break;                  // stones

    case 267:
        *ch = '+';
        break;                  // book +

    case 268:
        *ch = '%';
        break;                  // corpses part 1

    case 269:
        *ch = '\\';
        break;                  // magical staves

    case 270:
        *ch = '}';
        break;                  // gems

    case 271:
        *ch = 142; //'%';
        break;                  // don't know ?

    case 272:
        *ch = '$';
        break;                  // $ gold

    case 273:
        *ch = '"';
        break;                  // amulet

    default:
        *ch = ((object >= 297) ? mons_char(object - 297) : object);
        break;
    }
}                               // end get_zenkaku_symbol

//---------------------------------------------------------------
//
// get_ibm_symbol
//
// Returns the DOS character code and color for everything drawn
// with the IBM graphics option.
//
//---------------------------------------------------------------
static void get_ibm_symbol(unsigned int object, unsigned short *ch,
                           unsigned short *color)
{
    ASSERT(color != NULL);
    ASSERT(ch != NULL);

    switch (object)
    {
    case DNGN_UNSEEN:
        *ch = 0;
        break;

    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
        *color = env.rock_colour;
        *ch = 177;
        break;                  // remember earth elementals

    // stone in the realm of Zot is coloured the same as rock
    case DNGN_STONE_WALL:
        *color = (player_in_branch( BRANCH_HALL_OF_ZOT ) ? env.rock_colour
                                                         : LIGHTGREY);
        *ch = 177;
        break;

    case DNGN_CLOSED_DOOR:
        *ch = 254;
        break;

    case DNGN_METAL_WALL:
        *ch = 177;
        *color = CYAN;
        break;

    case DNGN_SECRET_DOOR:
        *ch = 177;
        *color = env.rock_colour;
        break;

    case DNGN_GREEN_CRYSTAL_WALL:
        *ch = 177;
        *color = GREEN;
        break;

    case DNGN_ORCISH_IDOL:
        *ch = '8';
        *color = DARKGREY;
        break;

    case DNGN_WAX_WALL:
        *ch = 177;
        *color = YELLOW;
        break;                  // wax wall
        /* Anything added here must also be added to the PLAIN_TERMINAL
           viewwindow2 below */

    case DNGN_SILVER_STATUE:
        *ch = '8';
        *color = WHITE;
        Visible_Statue[ STATUE_SILVER ] = 1;
        break;

    case DNGN_GRANITE_STATUE:
        *ch = '8';
        *color = LIGHTGREY;
        break;

    case DNGN_ORANGE_CRYSTAL_STATUE:
        *ch = '8';
        *color = LIGHTRED;
        Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 1;
        break;

    case DNGN_LAVA:
        *ch = 247;
        *color = RED;
        break;

    case DNGN_DEEP_WATER:
        *ch = 247;          // this wavy thing also used for water elemental
        *color = BLUE;
        break;

    case DNGN_SHALLOW_WATER:
        *ch = 247;          // this wavy thing also used for water elemental
        *color = CYAN;
        break;

    case DNGN_FLOOR:
        *color = env.floor_colour;
        *ch = 249;
        break;

    case DNGN_ENTER_HELL:
        *ch = 239;
        *color = RED;
        seen_other_thing(object);
        break;

    case DNGN_OPEN_DOOR:
        *ch = 39;
        break;

    case DNGN_BRANCH_STAIRS:
        *ch = 240;
        *color = BROWN;
        break;

    case DNGN_TRAP_MECHANICAL:
        *color = LIGHTCYAN;
        *ch = 94;
        break;

    case DNGN_TRAP_MAGICAL:
        *color = MAGENTA;
        *ch = 94;
        break;

    case DNGN_TRAP_III:
        *color = LIGHTGREY;
        *ch = 94;
        break;

    case DNGN_UNDISCOVERED_TRAP:
        *ch = 249;
        *color = env.floor_colour;
        break;

    case DNGN_ENTER_SHOP:
        *ch = 239;
        *color = YELLOW;

        seen_other_thing(object);
        break;
    // if I change anything above here, must also change magic mapping!

    case DNGN_ENTER_LABYRINTH:
        *ch = 239;
        *color = LIGHTGREY;
        seen_other_thing(object);
        break;

    // not sure why we have "odd" here, but "ladders" are special in
    // that they all lead to the first staircase of the next level
    // (and returning from there will take you somewhere different)
    // ... that's why they're brown... it's a warning -- bwr
    case DNGN_ROCK_STAIRS_DOWN:
        *color = BROWN;         // ladder    // odd {dlb}
    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
        *ch = '>';
        break;

    case DNGN_ROCK_STAIRS_UP:
        *color = BROWN;         // ladder    // odd {dlb}
    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
        *ch = '<';
        break;

    case DNGN_ENTER_DIS:
        *color = CYAN;
        *ch = 239;
        break;

    case DNGN_ENTER_GEHENNA:
        *color = RED;
        *ch = 239;
        break;

    case DNGN_ENTER_COCYTUS:
        *color = LIGHTCYAN;
        *ch = 239;
        break;

    case DNGN_ENTER_TARTARUS:
        *color = DARKGREY;
        *ch = 239;
        break;

    case DNGN_ENTER_ABYSS:
        *color = random2(16);
        *ch = 239;
        seen_other_thing(object);
        break;

    case DNGN_EXIT_ABYSS:
        *color = random2(16);
        *ch = 239;
        break;

    case DNGN_STONE_ARCH:
        *color = LIGHTGREY;
        *ch = 239;
        break;

    case DNGN_ENTER_PANDEMONIUM:
        *color = LIGHTBLUE;
        *ch = 239;
        seen_other_thing(object);
        break;

    case DNGN_EXIT_PANDEMONIUM:
        *color = LIGHTBLUE;
        *ch = 239;
        break;

    case DNGN_TRANSIT_PANDEMONIUM:
        *color = LIGHTGREEN;
        *ch = 239;
        break;

    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        *color = YELLOW;
        *ch = '>';
        seen_staircase(object);
        break;

    case DNGN_ENTER_ZOT:
        *color = MAGENTA;
        *ch = 239;
        seen_staircase(object);
        break;

    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        *color = YELLOW;
        *ch = '<';
        break;

    case DNGN_RETURN_FROM_ZOT:
        *color = MAGENTA;
        *ch = 239;
        break;

    case DNGN_ALTAR_ZIN:
        *color = WHITE;
        *ch = 220;
        seen_altar(GOD_ZIN);
        break;

    case DNGN_ALTAR_SHINING_ONE:
        *color = YELLOW;
        *ch = 220;
        seen_altar(GOD_SHINING_ONE);
        break;

    case DNGN_ALTAR_KIKUBAAQUDGHA:
        *color = DARKGREY;
        *ch = 220;
        seen_altar(GOD_KIKUBAAQUDGHA);
        break;

    case DNGN_ALTAR_YREDELEMNUL:
        *color = ((one_chance_in(3)) ? RED : DARKGREY);
        *ch = 220;
        seen_altar(GOD_YREDELEMNUL);
        break;

    case DNGN_ALTAR_XOM:
        *color = random_colour();
        *ch = 220;
        seen_altar(GOD_XOM);
        break;

    case DNGN_ALTAR_VEHUMET:
        *color = LIGHTBLUE;
        if (one_chance_in(3))
            *color = LIGHTMAGENTA;
        if (one_chance_in(3))
            *color = LIGHTRED;
        *ch = 220;
        seen_altar(GOD_VEHUMET);
        break;

    case DNGN_ALTAR_OKAWARU:
        *color = CYAN;
        *ch = 220;
        seen_altar(GOD_OKAWARU);
        break;

    case DNGN_ALTAR_MAKHLEB:
        *color = RED;
        if (one_chance_in(3))
            *color = LIGHTRED;
        if (one_chance_in(3))
            *color = YELLOW;
        *ch = 220;
        seen_altar(GOD_MAKHLEB);
        break;

    case DNGN_ALTAR_SIF_MUNA:
        *color = BLUE;
        *ch = 220;
        seen_altar(GOD_SIF_MUNA);
        break;

    case DNGN_ALTAR_TROG:
        *color = RED;
        *ch = 220;
        seen_altar(GOD_TROG);
        break;

    case DNGN_ALTAR_NEMELEX_XOBEH:
        *color = LIGHTMAGENTA;
        *ch = 220;
        seen_altar(GOD_NEMELEX_XOBEH);
        break;

    case DNGN_ALTAR_ELYVILON:
        *color = LIGHTGREY;
        *ch = 220;
        seen_altar(GOD_ELYVILON);
        break;

    case DNGN_BLUE_FOUNTAIN:
        *color = BLUE;
        *ch = 159;
        break;

    case DNGN_SPARKLING_FOUNTAIN:
        *color = LIGHTBLUE;
        *ch = 159;
        break;

    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_PERMADRY_FOUNTAIN:
        *color = LIGHTGREY;
        *ch = 159;
        break;

    case 256:
        *ch = '0';
        break;

    case 257:
        *color = CYAN;
        *ch = '~';
        break;                  /* Invis creature walking through water */

    case 258:
        *ch = ')';
        break;                  // weapon )

    case 259:
        *ch = '[';
        break;                  // armour [

    case 260:
        *ch = '/';
        break;                  // wands, etc.

    case 261:
        *ch = '%';
        break;                  // food

    case 262:
        *ch = '+';
        break;                  // books +

    case 263:
        *ch = '?';
        break;                  // scroll ?

    case 264:
        *ch = '=';
        break;                  // ring = etc

    case 265:
        *ch = '!';
        break;                  // potions !

    case 266:
        *ch = '(';
        break;                  // stones

    case 267:
        *ch = '+';
        break;                  // book +

    case 268:
        *ch = '%';
        break;                  // corpses part 1

    case 269:
        *ch = '\\';
        break;                  // magical staves

    case 270:
        *ch = '}';
        break;                  // gems

    case 271:
        *ch = '%';
        break;                  // don't know ?

    case 272:
        *ch = '$';
        break;                  // $ gold

    case 273:
        *ch = '"';
        break;                  // amulet

    default:
        *ch = ((object >= 297) ? mons_char(object - 297) : object);
        break;
    }
}                               // end get_ibm_symbol()

//---------------------------------------------------------------
//
// viewwindow2
//
// Draws the main window using the extended IBM character set.
//
// This function should not interfer with the game condition,
// unless do_updates is set (ie.  stealth checks for visible
// monsters).
//
//---------------------------------------------------------------
void viewwindow2(char draw_it, bool do_updates)
{
    const long BUFFER_SIZE = 1550;
#ifdef DOS_TERM
    // DOS functions like gettext() and puttext() can only
    // work with arrays of characters, not shorts.
    FixedVector < unsigned char, BUFFER_SIZE > buffy;   //[800]; //392];
#else
    FixedVector < unsigned short, BUFFER_SIZE > buffy;   //[800]; //392];
#endif

    unsigned short ch, color;

//  Must be zero-cleared before losight
    losight(env.show, grd, you.x_pos, you.y_pos);

    int count_x, count_y;

    for (count_x = 0; count_x < 18; count_x++)
    {
        for (count_y = 0; count_y < 18; count_y++)
        {
            // Zero clear env.show before losight
            //env.show[count_x][count_y] = 0;
            env.show_col[count_x][count_y] = LIGHTGREY;
            show_backup[count_x][count_y] = 0;
        }
    }

    losight(env.show, grd, you.x_pos, you.y_pos);

    item();
    cloud_grid();
    monster_grid(do_updates);
    int bufcount = 0;

    if (draw_it == 1)
    {
        _setcursortype(_NOCURSOR);
        for (count_y = you.y_pos - 8; count_y < you.y_pos + 9; count_y++)
        {
            bufcount += 16;

            for (count_x = you.x_pos - 8; count_x < you.x_pos + 9; count_x++)
            {
                // may be overriden by the code below
                color = env.show_col[ count_x - you.x_pos + 9 ]
                                    [ count_y - you.y_pos + 9 ];

                unsigned int object = env.show[ count_x - you.x_pos + 9 ]
                                              [ count_y - you.y_pos + 9 ];

                get_ibm_symbol(object, &ch, &color);

                if (count_x == you.x_pos && count_y == you.y_pos)
                {
                    ch = your_sign;

                    if (player_is_swimming())
                    {
                        color = (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
                                    ? BLUE : CYAN;
                    }
                    else
                    {
                        color = your_colour;
                    }
                }

                ASSERT(bufcount + 1 < BUFFER_SIZE);
                buffy[bufcount] = ch;
                buffy[bufcount + 1] = color;

                bufcount += 2;
            }

            bufcount += 16;
        }

        if (you.level_type != LEVEL_LABYRINTH && you.level_type != LEVEL_ABYSS)
        {
            bufcount = 0;

            for (count_y = 0; count_y < 17; count_y++)
            {
                bufcount += 16;

                for (count_x = 0; count_x < 17; count_x++)
                {
                    ASSERT(bufcount < BUFFER_SIZE);

                    int mapx = count_x + you.x_pos - 9;
                    int mapy = count_y + you.y_pos - 9;
                    if (buffy[bufcount] != 0 && mapx >= 0 && mapx < GXM
                            && mapy >= 0 && mapy < GYM)
                    {
                        env.map[ mapx ][ mapy ] = buffy[bufcount];
                    }

                    if (Options.clean_map == 1
                        && show_backup[count_x + 1][count_y + 1] != 0)
                    {
                        get_ibm_symbol(show_backup[count_x + 1][count_y + 1],
                                       &ch, &color);
                        if (mapx >= 0 && mapx < GXM
                                && mapy >= 0 && mapy < GYM)
                        env.map[ count_x + you.x_pos - 9 ]
                               [ count_y + you.y_pos - 9 ] = ch;
                    }
                    bufcount += 2;
                }
                bufcount += 16;
            }
        }

        bufcount = 0;
        for (count_y = 0; count_y < 17; count_y++)
        {
            for (count_x = 0; count_x < 33; count_x++)
            {
                if (count_x + you.x_pos - 17 < 3
                    || count_y + you.y_pos - 9 < 3
                    || count_x + you.x_pos - 14 > 77
                    || count_y + you.y_pos - 9 > 67)
                {
                    ASSERT(bufcount < BUFFER_SIZE);
                    buffy[bufcount] = 0;
                    bufcount++;
                    buffy[bufcount] = 0;
                    bufcount++;
                    continue;
                }

                if (count_x >= 8 && count_x <= 24 && count_y >= 0
                    && count_y <= 16 && buffy[bufcount] != 0)
                {
                    bufcount += 2;
                    continue;
                }

                ASSERT(bufcount + 1 < BUFFER_SIZE);

                buffy[bufcount] = env.map[ count_x + you.x_pos - 17 ]
                                         [ count_y + you.y_pos - 9 ];

                buffy[bufcount + 1] = DARKGREY;

                if (Options.colour_map)
                {
                    if (env.map[ count_x + you.x_pos - 16 ]
                               [ count_y + you.y_pos - 8 ] != 0)
                    {
                        buffy[bufcount + 1]
                                = colour_code_map( count_x + you.x_pos - 17,
                                                   count_y + you.y_pos - 9 );
                    }
                }
                bufcount += 2;
            }
        }

        if (you.berserker)
        {
            for (count_x = 1; count_x < 1400; count_x += 2)
            {
                if (buffy[count_x] != DARKGREY)
                    buffy[count_x] = RED;
            }
        }

        if (show_green != BLACK)
        {
            for (count_x = 1; count_x < 1400; count_x += 2)
            {
                if (buffy[count_x] != DARKGREY)
                    buffy[count_x] = show_green;
            }

            show_green = BLACK;

            if (you.special_wield == SPWLD_SHADOW)
                show_green = DARKGREY;
        }

#ifdef DOS_TERM
        puttext(2, 1, 34, 17, buffy.buffer());
#endif

#ifdef PLAIN_TERM
        gotoxy(2, 1);
        bufcount = 0;

        // following lines are purely optional.
        // if used,  players will 'jump' move.
        // Resting will be a LOT faster too.
        if (you.running == 0 || (you.running < 0 && Options.travel_delay > -1))
        {
            for (count_x = 0; count_x < 1120; count_x += 2)
            {                   // 1056
                ch = buffy[count_x];
                color = buffy[count_x + 1];
//                ASSERT(color < 16);
                ASSERT(ch < 255);

#ifdef JP
                if (Options.use_zenkaku)
                {
                    if ((count_x % 66) >=16 && (count_x % 66)<=48)
                    {
                            textcolor(color);
                            writeWChar( &ascii_to_zenkaku[(ch-' ')*2] );
                    }
                    if (count_x % 66 == 64 && count_x > 0)
                        gotoxy(2, wherey() + 1);
                }
                else
#endif
                {
                    textcolor(color);
                    if (ch>=127) ch = special_to_ascii[ch-127];
                    putch(ch);
                    if (count_x % 66 == 64 && count_x > 0)
                        gotoxy(2, wherey() + 1);
                }
           }
           // remember to comment out the line below if you comment out jump move.
        }
        _setcursortype(_NORMALCURSOR);
#endif
    }
}                               // end viewwindow2()

char colour_code_map( int x, int y )
{
    // XXX: Yes, the map array and the grid array are off by one. -- bwr
    const int map_value = env.map[x][y];
    const int grid_value = grd[x + 1][y + 1];

    // XXX: Yeah, this is ugly, but until we have stored layers in the
    // map we can't tell if we've seen a square, detected it, or just
    // detected the item or monster on top... giving colour here will
    // result in detect creature/item detecting features like stairs. -- bwr
    if (map_value != mapch2( grid_value ))
        return (DARKGREY);

    switch (grid_value)
    {
    case DNGN_TRAP_MECHANICAL:
        return (LIGHTCYAN);

    case DNGN_TRAP_MAGICAL:
    case DNGN_TRAP_III:
        return (MAGENTA);

    case DNGN_ENTER_SHOP:
        return (YELLOW);

    case DNGN_ENTER_DIS:
        return (CYAN);

    case DNGN_ENTER_HELL:
    case DNGN_ENTER_GEHENNA:
        return (RED);

    case DNGN_ENTER_COCYTUS:
        return (LIGHTCYAN);

    case DNGN_ENTER_ABYSS:
        return random2(16);     // so it can be black - is this right? {dlb}

    case DNGN_ENTER_LABYRINTH:
    case DNGN_STONE_ARCH:
        return (LIGHTGREY);

    case DNGN_ENTER_PANDEMONIUM:
        return (LIGHTBLUE);

    case DNGN_EXIT_PANDEMONIUM:
        // Exit pandemonium gates won't show up on the map as light blue
        // unless the character has the "gate to pandemonium" demonspawn
        // mutation.  This is so that the player can't quickly use a
        // crystal ball to find their way out.  -- bwr
        return (you.mutation[MUT_PANDEMONIUM] ? LIGHTBLUE : LIGHTGREEN);

    case DNGN_TRANSIT_PANDEMONIUM:
        return (LIGHTGREEN);

    case DNGN_ENTER_ZOT:
    case DNGN_RETURN_FROM_ZOT:
        return (MAGENTA);

    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
    case DNGN_ROCK_STAIRS_DOWN:
        return (RED);

    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
    case DNGN_ROCK_STAIRS_UP:
        return (GREEN);

    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        return (YELLOW);  //return (LIGHTRED);

    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        return (YELLOW);  //return (LIGHTBLUE);

    default:
        break;
    }

    return (DARKGREY);
}


void monster_grid(bool do_updates)
{
    struct monsters *monster = 0;       // NULL {dlb}

    for (int s = 0; s < MAX_MONSTERS; s++)
    {
        monster = &menv[s];

        if (monster->type != -1 && mons_near(monster))
        {
            if (do_updates
                && (monster->behaviour == BEH_SLEEP
                     || monster->behaviour == BEH_WANDER)
                && check_awaken(s))
            {
                behaviour_event( monster, ME_ALERT, MHITYOU );

                if (you.turn_is_over == 1
                    && mons_shouts(monster->type) > 0
                    && random2(30) >= you.skills[SK_STEALTH])
                {
                    int noise_level = 8;

                    if (!mons_friendly(monster)
                        && (!silenced(you.x_pos, you.y_pos)
                            && !silenced(monster->x, monster->y)))
                    {
                        if (mons_is_demon( monster->type ) && coinflip())
                        {
                            if (monster->type == MONS_IMP
                                || monster->type == MONS_WHITE_IMP
                                || monster->type == MONS_SHADOW_IMP)
                            {
                                imp_taunt( monster );
                            }
                            else
                            {
                                demon_taunt( monster );
                            }
                        }
                        else
                        {
                            int the_shout = mons_shouts(monster->type);

#ifdef JP
                            strcpy(info, "あなたは");
                            switch (the_shout)
                            {
                            case S_SILENT:
                            default:
                                strcat(info, "バグの蠢きを耳にした！");
                                break;
                            case S_SHOUT:
                                strcat(info, "叫び声を耳にした！");
                                break;
                            case S_BARK:
                                strcat(info, "吠え声を耳にした！");
                                break;
                            case S_SHOUT2:
                                strcat(info, "二つの叫びを耳にした！");
                                noise_level = 12;
                                break;
                            case S_ROAR:
                                strcat(info, "咆哮を耳にした！");
                                noise_level = 12;
                                break;
                            case S_SCREAM:
                                strcat(info, "おぞましい金切り声を耳にした！");
                                break;
                            case S_BELLOW:
                                strcat(info, "唸り声を耳にした！");
                                break;
                            case S_SCREECH:
                                strcat(info, "金切り声を耳にした！");
                                break;
                            case S_BUZZ:
                                strcat(info, "剣呑なブンブンいう音を耳にした。");
                                break;
                            case S_MOAN:
                                strcat(info, "身も凍るような呻き声を耳にした。");
                                break;
                            case S_WHINE:
                                strcat(info,
                                       "癇に障る甲高い唸りを耳にした。");
                                break;
                            case S_CROAK:
                                if (coinflip())
                                    strcat(info, "やかましくゲコゲコ鳴く声を耳にした！");
                                else
                                    strcat(info, "ゲコゲコ鳴く声を耳にした。");
                                break;
                            case S_GROWL:
                                strcat(info, "険悪な唸り声を耳にした！");
                                break;
                            case S_HISS:
                                strcat(info, "険悪なシューという音を耳にした！");
                                noise_level = 4;  // not very loud -- bwr
                                break;
                            }
#else
                            strcpy(info, "You hear ");
                            switch (the_shout)
                            {
                            case S_SILENT:
                            default:
                                strcat(info, "buggy behaviour!");
                                break;
                            case S_SHOUT:
                                strcat(info, "a shout!");
                                break;
                            case S_BARK:
                                strcat(info, "a bark!");
                                break;
                            case S_SHOUT2:
                                strcat(info, "two shouts!");
                                noise_level = 12;
                                break;
                            case S_ROAR:
                                strcat(info, "a roar!");
                                noise_level = 12;
                                break;
                            case S_SCREAM:
                                strcat(info, "a hideous shriek!");
                                break;
                            case S_BELLOW:
                                strcat(info, "a bellow!");
                                break;
                            case S_SCREECH:
                                strcat(info, "a screech!");
                                break;
                            case S_BUZZ:
                                strcat(info, "an angry buzzing noise.");
                                break;
                            case S_MOAN:
                                strcat(info, "a chilling moan.");
                                break;
                            case S_WHINE:
                                strcat(info,
                                       "an irritating high-pitched whine.");
                                break;
                            case S_CROAK:
                                if (coinflip())
                                    strcat(info, "a loud, deep croak!");
                                else
                                    strcat(info, "a croak.");
                                break;
                            case S_GROWL:
                                strcat(info, "an angry growl!");
                                break;
                            case S_HISS:
                                strcat(info, "an angry hiss!");
                                noise_level = 4;  // not very loud -- bwr
                                break;
                            }
#endif

                            mpr(info);
                        }
                    }

                    noisy( noise_level, monster->x, monster->y );
                }
            }

            if (!player_monster_visible( monster ))
            {
                // ripple effect?
                if (grd[monster->x][monster->y] == DNGN_SHALLOW_WATER
                    && !mons_flies(monster))
                {
                    show_backup[ monster->x - you.x_pos + 9 ]
                               [ monster->y - you.y_pos + 9]
                       = env.show[ monster->x - you.x_pos + 9 ]
                                 [ monster->y - you.y_pos + 9 ];
                    env.show[monster->x - you.x_pos + 9]
                            [monster->y - you.y_pos + 9] = 257;
                }
                continue;
            }
            else if (!mons_friendly( monster )
                     && !mons_is_mimic( monster->type )
                     && !mons_flag( monster->type, M_NO_EXP_GAIN )
                     && you.running != 0)
            {
                // Friendly monsters, mimics, or harmless monsters
                // don't disturb the player's running/resting.
                //
                // Doing it this way causes players in run mode 2
                // to move one square, and in mode 1 to stop.  This
                // means that the character will run one square if
                // a monster is in sight... we automatically jump
                // to zero if we're resting.  -- bwr
                if (you.run_x == 0 && you.run_y == 0)
                    you.running = 0;
                else if (you.running > 0)
                    you.running--;
                else
                    you.running = 0;
            }

#ifdef USE_TILE
            if (Options.use_tile)
                tile_place_monster(monster->x - you.x_pos + 9,
                                   monster->y - you.y_pos + 9, s);
#endif
            // mimics are always left on map
            if (!mons_is_mimic( monster->type ))
            {
                show_backup[monster->x - you.x_pos + 9]
                           [monster->y - you.y_pos + 9]
                       = env.show[monster->x - you.x_pos + 9]
                                 [monster->y - you.y_pos + 9];
            }

            env.show[monster->x - you.x_pos + 9]
                    [monster->y - you.y_pos + 9] = monster->type + 297;

            env.show_col[monster->x - you.x_pos + 9]
                        [monster->y - you.y_pos + 9]
                = ((mcolour[monster->type] == BLACK)
                        ? monster->number : mcolour[monster->type]);
#ifdef USE_COLOUR_OPTS
#if defined(JP) && (defined(WIN32CONSOLE) || defined(USE_X11) || defined(USE_TILE))
            //WIN用の仲間モンスター強調表示コード
            if ( (mons_friendly(monster) == true)&&(Options.friend_brand == CHATTR_REVERSE) )
            {
                unsigned short cul_mon_col;
                cul_mon_col = env.show_col[monster->x - you.x_pos + 9][monster->y - you.y_pos + 9];
                //BLACK or LIGHTGREY or DARKGREY or rock_colour
                if ( (cul_mon_col == 0)
                  || (cul_mon_col == 7)
                  || (cul_mon_col == 8)
                  || ( (cul_mon_col == env.rock_colour)
                     &&(you.level_type != LEVEL_LABYRINTH) ) )
                    {
                    //if (monster==LIGHTGREY)&&(rock==LIGHTGREY)    LABYRINTH=LIGHTGREY
                    if ( (env.rock_colour == 7) || (you.level_type == LEVEL_LABYRINTH) )
                      cul_mon_col += 15*16;
                    //if (rock!=LIGHTGREY)
                    else if (cul_mon_col == 7)
                      cul_mon_col = 8 + cul_mon_col*16;
                    else
                      cul_mon_col +=  7*16;
                    }
                else
                    cul_mon_col = cul_mon_col*16;
            env.show_col[monster->x - you.x_pos + 9][monster->y - you.y_pos + 9] = cul_mon_col;
            }
#else
            if (mons_friendly(monster))
            {
                env.show_col[monster->x - you.x_pos + 9]
                            [monster->y - you.y_pos + 9]
                    |= COLFLAG_FRIENDLY_MONSTER;
            }
#endif
#endif
        }                       // end "if (monster->type != -1 && mons_ner)"
    }                           // end "for s"
}                               // end monster_grid()


bool check_awaken(int mons_aw)
{
    int mons_perc = 0;
    struct monsters *monster = &menv[mons_aw];
    const int mon_holy = mons_holiness( monster->type );

    // berserkers aren't really concerned about stealth
    if (you.berserker)
        return (true);

    // Repel undead is a holy aura, to which evil creatures are sensitive.
    // Note that even though demons aren't affected by repel undead, they
    // do sense this type of divine aura. -- bwr
    if (you.duration[DUR_REPEL_UNDEAD]
        && (mon_holy == MH_UNDEAD || mon_holy == MH_DEMONIC))
    {
        return (true);
    }

    // I assume that creatures who can see invisible are very perceptive
    mons_perc = 10 + (mons_intel(monster->type) * 4) + monster->hit_dice
                   + mons_see_invis(monster) * 5;

    // critters that are wandering still have MHITYOU as their foe are
    // still actively on guard for the player,  even if they can't see
    // him.  Give them a large bonus (handle_behaviour() will nuke 'foe'
    // after a while,  removing this bonus.
    if (monster->behaviour == BEH_WANDER && monster->foe == MHITYOU)
        mons_perc += 15;

    if (!mons_player_visible(monster))
        mons_perc -= 75;

    if (monster->behaviour == BEH_SLEEP)
    {
        if (mon_holy == MH_NATURAL)
        {
            // monster is "hibernating"... reduce chance of waking
            if (mons_has_ench( monster, ENCH_SLEEP_WARY ))
                mons_perc -= 10;
        }
        else // unnatural creature
        {
            // Unnatural monsters don't actually "sleep", they just
            // haven't noticed an intruder yet... we'll assume that
            // they're diligently on guard.
            mons_perc += 10;
        }
    }

    // glowing with magical contamination isn't very stealthy
    if (you.magic_contamination > 10)
        mons_perc += you.magic_contamination - 10;

    if (mons_perc < 0)
        mons_perc = 0;

    return (random2(stealth) <= mons_perc);
}                               // end check_awaken()


void item()
{
    char count_x, count_y;

    for (count_y = (you.y_pos - 8); (count_y < you.y_pos + 9); count_y++)
    {
        for (count_x = (you.x_pos - 8); (count_x < you.x_pos + 9); count_x++)
        {
            if (count_x >= 0 && count_x < GXM && count_y >= 0 && count_y < GYM)
            {
                if (igrd[count_x][count_y] != NON_ITEM)
                {
                    if (env.show[count_x - you.x_pos + 9]
                                [count_y - you.y_pos + 9] != 0)
                    {
                        if (grd[count_x][count_y] == DNGN_SHALLOW_WATER)
                        {
                            env.show_col[count_x - you.x_pos + 9]
                                        [count_y - you.y_pos + 9] = CYAN;
                        }
                        else
                        {
                            env.show_col[count_x - you.x_pos + 9]
                                        [count_y - you.y_pos + 9]
                                    = mitm[igrd[count_x][count_y]].colour;
                        }

#ifdef USE_TILE
                        if (Options.use_tile)
                            tile_place_item(count_x - you.x_pos + 9,
                                            count_y - you.y_pos + 9,
                        igrd[count_x][count_y]);
#endif

                        switch (mitm[igrd[count_x][count_y]].base_type)
                        {
                        case OBJ_ORBS:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 256;
                            break;
                            // need + 6 because show is 0 - 12, not -6 - +6
                        case OBJ_WEAPONS:
                        case OBJ_MISSILES:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 258;
                            break;
                        case OBJ_ARMOUR:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 259;
                            break;
                        case OBJ_WANDS:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 260;
                            break;
                        case OBJ_FOOD:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 261;
                            break;
                        case OBJ_UNKNOWN_I:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 262;
                            break;
                        case OBJ_SCROLLS:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 263;
                            break;

                        case OBJ_JEWELLERY:
                            if (mitm[igrd[count_x][count_y]].sub_type >= AMU_RAGE)
                            {
                                env.show[count_x - you.x_pos + 9]
                                        [count_y - you.y_pos + 9] = 273;
                            }
                            else
                            {
                                env.show[count_x - you.x_pos + 9]
                                        [count_y - you.y_pos + 9] = 264;
                            }
                            break;

                        case OBJ_POTIONS:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 265;
                            break;
                        case OBJ_UNKNOWN_II:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 266;
                            break;
                        case OBJ_BOOKS:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 267;
                            break;
                        case OBJ_STAVES:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 269;
                            break;
                        case OBJ_MISCELLANY:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 270;
                            break;
                        case OBJ_CORPSES:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 271;
                            break;

                        case OBJ_GOLD:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = 272;

                            env.show_col[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = YELLOW;
                            break;

                        default:
                            env.show[count_x - you.x_pos + 9]
                                    [count_y - you.y_pos + 9] = '8';
                            break;
                        }
                    }
                }
            }
        }                       // end of "for count_y, count_x"
    }
}                               // end item()


void cloud_grid(void)
{
    int mnc = 0;

    // btw, this is also the 'default' color {dlb}
    unsigned char which_color = LIGHTGREY;

    for (int s = 0; s < MAX_CLOUDS; s++)
    {
        // can anyone explain this??? {dlb}
        // its an optimization to avoid looking past the last cloud -bwr
        if (mnc > env.cloud_no)
            break;

        if (env.cloud[s].type != CLOUD_NONE)
        {
            mnc++;

            if (see_grid(env.cloud[s].x, env.cloud[s].y))
            {
                show_backup[env.cloud[s].x - you.x_pos + 9]
                           [env.cloud[s].y - you.y_pos + 9]
                       = env.show[env.cloud[s].x - you.x_pos + 9]
                                 [env.cloud[s].y - you.y_pos + 9];

                env.show[env.cloud[s].x - you.x_pos + 9]
                        [env.cloud[s].y - you.y_pos + 9] = '#';
#ifdef USE_TILE
        if (Options.use_tile)
                    tile_place_cloud(env.cloud[s].x - you.x_pos + 9,
                                     env.cloud[s].y - you.y_pos + 9,
                                     env.cloud[s].type,  env.cloud[s].decay);
#endif
                switch (env.cloud[s].type)
                {
                case CLOUD_FIRE:
                case CLOUD_FIRE_MON:
                    if (env.cloud[s].decay <= 20)
                        which_color = RED;
                    else if (env.cloud[s].decay <= 40)
                        which_color = LIGHTRED;
                    else if (one_chance_in(4))
                        which_color = RED;
                    else if (one_chance_in(4))
                        which_color = LIGHTRED;
                    else
                        which_color = YELLOW;
                    break;

                case CLOUD_STINK:
                case CLOUD_STINK_MON:
                    which_color = GREEN;
                    break;

                case CLOUD_COLD:
                case CLOUD_COLD_MON:
                    if (env.cloud[s].decay <= 20)
                        which_color = BLUE;
                    else if (env.cloud[s].decay <= 40)
                        which_color = LIGHTBLUE;
                    else if (one_chance_in(4))
                        which_color = BLUE;
                    else if (one_chance_in(4))
                        which_color = LIGHTBLUE;
                    else
                        which_color = WHITE;
                    break;

                case CLOUD_POISON:
                case CLOUD_POISON_MON:
                    which_color = (one_chance_in(3) ? LIGHTGREEN : GREEN);
                    break;

                case CLOUD_BLUE_SMOKE:
                case CLOUD_BLUE_SMOKE_MON:
                    which_color = LIGHTBLUE;
                    break;

                case CLOUD_PURP_SMOKE:
                case CLOUD_PURP_SMOKE_MON:
                    which_color = MAGENTA;
                    break;

                case CLOUD_MIASMA:
                case CLOUD_MIASMA_MON:
                case CLOUD_BLACK_SMOKE:
                case CLOUD_BLACK_SMOKE_MON:
                    which_color = DARKGREY;
                    break;

                default:
                    which_color = LIGHTGREY;
                    break;
                }

                env.show_col[env.cloud[s].x - you.x_pos + 9]
                            [env.cloud[s].y - you.y_pos + 9] = which_color;
            }
        }                       // end 'if != CLOUD_NONE'
    }                           // end 'for s' loop
}                               // end cloud_grid()


void noisy( int loudness, int nois_x, int nois_y )
{
    int p;
    struct monsters *monster = 0;       // NULL {dlb}

    if (silenced( nois_x, nois_y ))
        return;

    int dist = loudness * loudness;

    for (p = 0; p < MAX_MONSTERS; p++)
    {
        monster = &menv[p];

        if (monster->type < 0)
            continue;

        if (distance(monster->x, monster->y, nois_x, nois_y) <= dist
            && !silenced(monster->x, monster->y))
        {
            // If the noise came from the character, any nearby monster
            // will be jumping on top of them.
            if (nois_x == you.x_pos && nois_y == you.y_pos)
                behaviour_event( monster, ME_ALERT, MHITYOU );
            else
                behaviour_event( monster, ME_DISTURB, MHITNOT, nois_x, nois_y );
        }
    }
}                               // end noisy()

/* ========================================================================
 *                           brand new LOS code
 * ========================================================================
 * The new LOS works via a new (I think) shadow casting algorithm,
 * plus an esthetic tweak for more pleasing corner illumination.  More
 * detail can be had by contacting its author,  Gordon Lipford.          */

#define MAX_LIGHT_RADIUS    20
#define CIRC_MAX            32000
#define BIG_SHADOW          32000

// the following two constants represent the 'middle' of the sh array.
// since the current shown area is 19x19,  centering the view at (9,9)
// means it will be exactly centered.
// This is done to accomodate possible future changes in viewable screen
// area - simply change sh_xo and sh_yo to the new view center.

const int sh_xo = 9;            // X and Y origins for the sh array
const int sh_yo = 9;

// the Cell class,  used in the shadow-casting LOS algorithm
class Cell
{

public:
    int up_count;
    int up_max;
    int low_count;
    int low_max;
    bool lit;
    bool lit_delay;
    bool visible;               // for blockers only
    void init();
    bool reachedLower();
    bool reachedUpper();

    Cell()
    {
        init();
    };
};

void Cell::init()
{
    up_count = 0;
    up_max = 0;
    low_count = 0;
    low_max = 0;
    lit = true;
    visible = true;
    lit_delay = false;
}

bool Cell::reachedLower()
{
    // integer math: a 'step' has a value of 10
    // see if we're within a half step of the max.  VERY important
    // to use 'half step' or else things look really stupid.
    if (low_max != 0 && low_count + 5 >= low_max && low_count - 5 < low_max)
        return true;

    return false;
}

bool Cell::reachedUpper()
{
    // see if we're within a half step of the max.  VERY important
    // to use 'half step' or else things look really stupid.
    if (up_max != 0 && up_count + 5 >= up_max && up_count - 5 < up_max)
        return true;

    return false;
}

// the cell array
static FixedVector < Cell, MAX_LIGHT_RADIUS + 1 > cells;

// the 'circle' array.  For any given row,  we won't check higher than
// this given cell.
static FixedVector < int, MAX_LIGHT_RADIUS + 1 > circle;

// current light radius
static int LR = 0;

// View constant
const int view = 2;             // 1=widest LOS .. 5=narrowest

// initialize LOS code for a given light radius
extern void setLOSRadius(int newLR)
{
    int i, j;

    // sanity check - also allows multiple calls w/out performance loss
    if (LR == newLR)
        return;

    LR = newLR;
    // cells should already be initted.  calculate the circle array.

    // note that rows 0 and 1 will always go to infinity.
    circle[0] = circle[1] = CIRC_MAX;

    // for the rest,  simply calculate max height based on light rad.
    for (i = 2; i <= LR; i++)
    {
        // check top
        if (2 * i * i <= LR * LR)
        {
            circle[i] = CIRC_MAX;
            continue;
        }

        for (j = i - 1; j >= 0; j--)
        {
            // check that Distance (I^2 + J^2) is no more than (R+0.5)^2
            // this rounding allows for *much* better looking circles.
            if (i * i + j * j <= LR * LR + LR)
            {
                circle[i] = j;
                break;
            }
        }
    }
}

static int calcUpper(int bX, int bY)
{
    // got a blocker at row bX,  cell bY.  do all values
    // and scale by a factor of 10 for the integer math.
    int upper;

    upper = (10 * (10 * bX - view)) / (10 * bY + view);
    if (upper < 10)             // upper bound for blocker on diagonal
        upper = 10;

    return upper;
}

static int calcLower(int bX, int bY)
{
    // got a blocker at row bX,  cell bY.  do all values
    // and scale by a factor of 10 for the integer math.

    if (bY == 0)
        return BIG_SHADOW;

    return (10 * (10 * bX + view)) / (10 * bY - view);
}

// for easy x,y octant translation
static int xxcomp[8] = { 1, 0, 0, -1, -1, 0, 0, 1 };
static int xycomp[8] = { 0, 1, -1, 0, 0, -1, 1, 0 };
static int yxcomp[8] = { 0, 1, 1, 0, 0, -1, -1, 0 };
static int yycomp[8] = { 1, 0, 0, 1, -1, 0, 0, -1 };

static void los_octant(int o, FixedArray < unsigned int, 19, 19 > &sh,
                       FixedArray < unsigned char, 80, 70 > &gr, int x_p,
                       int y_p)
{
    int row, cell, top, south;
    int tx, ty;                 // translated x, y deltas for this octant
    unsigned char gv;           // grid value
    bool row_dark, all_dark;
    bool blocker, vis_corner;
    int up_inc, low_inc;

    // leave [0,0] alone,  because the old LOS code seems to.

    // init cell[0].  this is the only one that needs clearing.
    cells[0].init();
    all_dark = false;
    vis_corner = false;

    // loop through each row
    for (row = 1; row <= LR; row++)
    {
        row_dark = true;

        // loop through each cell,  up to the max allowed by circle[]
        top = circle[row];
        if (top > row)
            top = row;

        for (cell = 0; cell <= top; cell++)
        {
            // translate X,Y co'ord + bounds check
            tx = row * xxcomp[o] + cell * xycomp[o];
            ty = row * yxcomp[o] + cell * yycomp[o];

            if (x_p + tx < 0 || x_p + tx > 79 || y_p + ty < 0 || y_p + ty > 69)
                continue;

            // check for all_dark - we've finished the octant but
            // have yet to fill in '0' for the rest of the sight grid
            if (all_dark == true)
            {
                sh[sh_xo + tx][sh_yo + ty] = 0;
                continue;
            }

            // get grid value.. see if it blocks LOS
            gv = gr[x_p + tx][y_p + ty];
            blocker = (gv < MINSEE);

            // init some other variables
            up_inc = 10;
            low_inc = 10;
            south = cell - 1;

            // STEP 1 - inherit values from immediate West, if possible
            if (cell < row)
            {
                // check for delayed lighting
                if (cells[cell].lit_delay)
                {
                    if (!blocker)
                    {           // blockers don't light up with lit_delay.
                        if (cells[south].lit)
                        {
                            if (cells[south].low_max != 0)
                            {
                                cells[cell].lit = false;
                                // steal lower values
                                cells[cell].low_max = cells[south].low_max;
                                cells[cell].low_count = cells[south].low_count;
                                cells[south].low_count = 0;
                                cells[south].low_max = 0;
                                low_inc = 0;    // avoid double-inc.
                            }
                            else
                                cells[cell].lit = true;
                        }
                    }
                    cells[cell].lit_delay = false;
                }
            }
            else
            {
                // initialize new cell.
                cells[cell].init();
            }

            // STEP 2 - check for blocker
            // a dark blocker in shadow's edge will be visible
            if (blocker)
            {
                if (cells[cell].lit || (cell != 0 && cells[south].lit)
                    || vis_corner)
                {
                    // hack: make 'corners' visible
                    vis_corner = cells[cell].lit;

                    cells[cell].lit = false;
                    cells[cell].visible = true;

                    int upper = calcUpper(row, cell);
                    int lower = calcLower(row, cell);

                    if (upper < cells[cell].up_max || cells[cell].up_max == 0)
                    {
                        // new upper shadow
                        cells[cell].up_max = upper;
                        cells[cell].up_count = 0;
                        up_inc = 0;
                    }

                    if (lower > cells[cell].low_max || cells[cell].low_max == 0)
                    {
                        // new lower shadow
                        cells[cell].low_max = lower;
                        cells[cell].low_count = -10;
                        low_inc = 0;
                        if (lower <= 30)        // somewhat arbitrary
                            cells[cell].lit_delay = true;
                        // set dark_delay if lower > 20?? how to decide?
                    }
                }
                else
                {
                    cells[cell].visible = false;
                }
            }
            else
            {
                cells[cell].visible = false;    // special flags for blockers
            }

            // STEP 3 - add increments to upper, lower counts
            cells[cell].up_count += up_inc;
            cells[cell].low_count += low_inc;

            // STEP 4 - check south for dark
            if (south >= 0)
                if (cells[south].reachedUpper() == true)
                {
                    if (cells[cell].reachedUpper() == false)
                    {
                        cells[cell].up_max = cells[south].up_max;
                        cells[cell].up_count = cells[south].up_count;
                        cells[cell].up_count -= cells[south].up_max;
                    }
                    cells[cell].lit = false;
                    cells[cell].visible = false;
                }

            // STEP 5 - nuke lower if south lower
            if (south >= 0)
            {
                if (cells[south].reachedLower())
                {
                    cells[cell].low_max = cells[south].low_max;
                    cells[cell].low_count = cells[south].low_count;
                    cells[cell].low_count -= cells[south].low_max;
                    cells[south].low_count = cells[south].low_max = 0;
                }

                if (cells[south].low_max != 0
                    || (cells[south].lit == false
                        && cells[south].low_max == 0))
                {
                    cells[cell].low_count = cells[cell].low_max + 10;
                }
            }

            // STEP 6 - light up if we've reached lower bound
            if (cells[cell].reachedLower() == true)
                cells[cell].lit = true;

            // now place appropriate value in sh
            if (cells[cell].lit == true
                || (blocker == true && cells[cell].visible == true))
            {
                sh[sh_xo + tx][sh_yo + ty] = gv;
            }
            else
                sh[sh_xo + tx][sh_yo + ty] = 0;

            if (cells[cell].lit == true)
                row_dark = false;
        }                       // end for - cells

        vis_corner = false;     // don't carry over to next row. :)
        if (row_dark == true)
            all_dark = true;
    }                           // end for - rows
}

void losight(FixedArray < unsigned int, 19, 19 > &sh,
             FixedArray < unsigned char, 80, 70 > &gr, int x_p, int y_p)
{
    int o;

    for (o = 0; o < 8; o++)
        los_octant(o, sh, gr, x_p, y_p);
}

void draw_border(void)
{
#ifdef USE_TILE
    mpr_on( MODE_STAT );
#endif
    clrscr();

    //おまじない
    gotoxy(40, 1);
    cprintf(" ");

    redraw_skill( you.your_name, player_title() );
#ifdef USE_TILE
    mpr_on( MODE_STAT );
#endif
    gotoxy(40, 2);
    cprintf( "%s %s", species_name( you.species, you.experience_level ),
                     (you.wizard ? "*WIZARD*" : "" ) );
#ifdef JP
    gotoxy(40,  3); cprintf("ＨＰ:");
    gotoxy(40,  4); cprintf("ＭＰ:");
    gotoxy(40,  5); cprintf("ＡＣ:");
    gotoxy(40,  6); cprintf("ＥＶ:");
    gotoxy(40,  7); cprintf("腕力:");
    gotoxy(40,  8); cprintf("知力:");
    gotoxy(40,  9); cprintf("器用:");
    gotoxy(40, 10); cprintf("所持金:");
    gotoxy(40, 11); cprintf("経験値:");
    gotoxy(40, 12); cprintf("現在地:");
#else
    gotoxy(40,  3); cprintf("HP:");
    gotoxy(40,  4); cprintf("Magic:");
    gotoxy(40,  5); cprintf("AC:");
    gotoxy(40,  6); cprintf("EV:");
    gotoxy(40,  7); cprintf("Str:");
    gotoxy(40,  8); cprintf("Int:");
    gotoxy(40,  9); cprintf("Dex:");
    gotoxy(40, 10); cprintf("Gold:");
    gotoxy(40, 11); cprintf("Experience:");
    gotoxy(40, 12); cprintf("Level");
#endif

#ifdef USE_TILE
    mpr_on( MODE_CRT );
#endif
}                               // end draw_border()

// Determines if the given feature is present at (x, y) in _grid_ coordinates.
// If you have map coords, add (1, 1) to get grid coords.
// Use one of
// 1. '<' and '>' to look for stairs
// 2. '\t' or '\\' for shops, portals.
// 3. '^' for traps
// 4. '_' for altars
// 5. Anything else will look for the exact same character in the level map.

static bool is_feature(int feature, int x, int y) {
    char envfeat = env.map[x - 1][y - 1];
    if (!envfeat)
        return false;

    // 'grid' can fit in an unsigned char, but making this a short shuts up
    // warnings about out-of-range case values.
    short grid = grd[x][y];

    switch (feature) {
    case '_':
        switch (grid) {
        case DNGN_ALTAR_ZIN:
        case DNGN_ALTAR_SHINING_ONE:
        case DNGN_ALTAR_KIKUBAAQUDGHA:
        case DNGN_ALTAR_YREDELEMNUL:
        case DNGN_ALTAR_XOM:
        case DNGN_ALTAR_VEHUMET:
        case DNGN_ALTAR_OKAWARU:
        case DNGN_ALTAR_MAKHLEB:
        case DNGN_ALTAR_SIF_MUNA:
        case DNGN_ALTAR_TROG:
        case DNGN_ALTAR_NEMELEX_XOBEH:
        case DNGN_ALTAR_ELYVILON:
            return true;
        default:
            return false;
        }
    case '\t':
    case '\\':
        switch (grid) {
        case DNGN_ENTER_HELL:
        case DNGN_ENTER_LABYRINTH:
        case DNGN_ENTER_SHOP:
        case DNGN_ENTER_DIS:
        case DNGN_ENTER_GEHENNA:
        case DNGN_ENTER_COCYTUS:
        case DNGN_ENTER_TARTARUS:
        case DNGN_ENTER_ABYSS:
        case DNGN_EXIT_ABYSS:
        case DNGN_STONE_ARCH:
        case DNGN_ENTER_PANDEMONIUM:
        case DNGN_EXIT_PANDEMONIUM:
        case DNGN_TRANSIT_PANDEMONIUM:
        case DNGN_ENTER_ZOT:
        case DNGN_RETURN_FROM_ZOT:
            return true;
        default:
            return false;
        }
    case '<':
        switch (grid) {
        case DNGN_ROCK_STAIRS_UP:
        case DNGN_STONE_STAIRS_UP_I:
        case DNGN_STONE_STAIRS_UP_II:
        case DNGN_STONE_STAIRS_UP_III:
        case DNGN_RETURN_FROM_ORCISH_MINES:
        case DNGN_RETURN_FROM_HIVE:
        case DNGN_RETURN_FROM_LAIR:
        case DNGN_RETURN_FROM_SLIME_PITS:
        case DNGN_RETURN_FROM_VAULTS:
        case DNGN_RETURN_FROM_CRYPT:
        case DNGN_RETURN_FROM_HALL_OF_BLADES:
        case DNGN_RETURN_FROM_TEMPLE:
        case DNGN_RETURN_FROM_SNAKE_PIT:
        case DNGN_RETURN_FROM_ELVEN_HALLS:
        case DNGN_RETURN_FROM_TOMB:
        case DNGN_RETURN_FROM_SWAMP:
            return true;
        default:
            return false;
        }
    case '>':
        switch (grid) {
        case DNGN_ROCK_STAIRS_DOWN:
        case DNGN_STONE_STAIRS_DOWN_I:
        case DNGN_STONE_STAIRS_DOWN_II:
        case DNGN_STONE_STAIRS_DOWN_III:
        case DNGN_ENTER_ORCISH_MINES:
        case DNGN_ENTER_HIVE:
        case DNGN_ENTER_LAIR:
        case DNGN_ENTER_SLIME_PITS:
        case DNGN_ENTER_VAULTS:
        case DNGN_ENTER_CRYPT:
        case DNGN_ENTER_HALL_OF_BLADES:
        case DNGN_ENTER_TEMPLE:
        case DNGN_ENTER_SNAKE_PIT:
        case DNGN_ENTER_ELVEN_HALLS:
        case DNGN_ENTER_TOMB:
        case DNGN_ENTER_SWAMP:
            return true;
        default:
            return false;
        }
    case '^':
        switch (grid) {
        case DNGN_TRAP_MECHANICAL:
        case DNGN_TRAP_MAGICAL:
        case DNGN_TRAP_III:
            return true;
        default:
            return false;
        }
    default:
        return envfeat == feature;
    }
}

static int find_feature(unsigned char feature, int curs_x, int curs_y,
                         int start_x, int start_y, int anchor_x, int anchor_y,
                         int ignore_count, char *move_x, char *move_y) {
    int cx = anchor_x,
        cy = anchor_y;

    int firstx = -1, firsty = -1;
    int matchcount = 0;

    // Find the first occurrence of feature 'feature', spiralling around (x,y)
    int maxradius = GXM > GYM? GXM : GYM;
    for (int radius = 1; radius < maxradius; ++radius) {
        for (int axis = -2; axis < 2; ++axis) {
            int rad = radius - (axis < 0);
            for (int var = -rad; var <= rad; ++var) {
                int dx = radius, dy = var;
                if (axis % 2)
                    dx = -dx;
                if (axis < 0) {
                    int temp = dx;
                    dx = dy;
                    dy = temp;
                }

                int x = cx + dx, y = cy + dy;
                if (x < 0 || y < 0 || x >= GXM || y >= GYM) continue;
                if (is_feature(feature, x + 1, y + 1)) {
                    ++matchcount;
                    if (!ignore_count--) {
                        // We want to cursor to (x,y)
                        *move_x = x - (start_x + curs_x - 1);
                        *move_y = y - (start_y + curs_y - 1);
                        return matchcount;
                    }
                    else if (firstx == -1) {
                        firstx = x;
                        firsty = y;
                    }
                }
            }
        }
    }

    // We found something, but ignored it because of an ignorecount
    if (firstx != -1) {
        *move_x = firstx - (start_x + curs_x - 1);
        *move_y = firsty - (start_y + curs_y - 1);
        return 1;
    }
    return 0;
}

void find_features(const std::vector<coord_def>& features,
        unsigned char feature, std::vector<coord_def> *found) {
    for (unsigned feat = 0; feat < features.size(); ++feat) {
        const coord_def& coord = features[feat];
        if (is_feature(feature, coord.x, coord.y))
            found->push_back(coord);
    }
}

static int find_feature( const std::vector<coord_def>& features,
                         unsigned char feature, int curs_x, int curs_y,
                         int start_x, int start_y,
                         int ignore_count, char *move_x, char *move_y) {
    int firstx = -1, firsty = -1;
    int matchcount = 0;

    for (unsigned feat = 0; feat < features.size(); ++feat) {
        const coord_def& coord = features[feat];

        if (is_feature(feature, coord.x, coord.y)) {
            ++matchcount;
            if (!ignore_count--) {
                // We want to cursor to (x,y)
                *move_x = coord.x - (start_x + curs_x);
                *move_y = coord.y - (start_y + curs_y);
                return matchcount;
            }
            else if (firstx == -1) {
                firstx = coord.x;
                firsty = coord.y;
            }
        }
    }

    // We found something, but ignored it because of an ignorecount
    if (firstx != -1) {
        *move_x = firstx - (start_x + curs_x);
        *move_y = firsty - (start_y + curs_y);
        return 1;
    }
    return 0;
}

// show_map() now centers the known map along x or y.  This prevents
// the player from getting "artificial" location clues by using the
// map to see how close to the end they are.  They'll need to explore
// to get that.  This function is still a mess, though. -- bwr
void show_map( FixedVector<int, 2> &spec_place )
{
    int i, j;

    int bufcount2 = 0;

    char move_x = 0;
    char move_y = 0;
    int  getty = 0;

#ifdef DOS_TERM
    char buffer[4800];
#endif

#ifdef USE_TILE
    if (Options.use_tile)
    {
        set_keyin_mode(KEYIN_MODE_MAP);
    }
#endif

    //ハイライトする文字
    static int wanted_char = -1;

    // Vector to track all features we can travel to, in order of distance.
    std::vector<coord_def> features;
    if (!spec_place[0]) {
        // find_travel_pos defined in acr.cc
        extern void find_travel_pos(int youx, int youy,
                char *move_x, char *move_y,
                std::vector<coord_def>* coords);
        find_travel_pos(you.x_pos, you.y_pos, NULL, NULL, &features);
        // Sort features into the order the player is likely to be interested in.
        arrange_features(features);
    }

    // buffer2[GYM * GXM * 2] segfaults my box {dlb}

    // char buffer2[GYM * GXM * 2]; から変更
    unsigned char buffer2[GYM * GXM * 2];

    char min_x = 80, max_x = 0, min_y = 0, max_y = 0;
    bool found_y = false;

    const int num_lines = get_number_of_lines();
    const int half_screen = num_lines / 2 - 1;


    for (j = 0; j < GYM; j++)
    {
        for (i = 0; i < GXM; i++)
        {
            if (env.map[i][j])
            {
                if (!found_y)
                {
                    found_y = true;
                    min_y = j;
                }

                max_y = j;

                if (i < min_x)
                    min_x = i;

                if (i > max_x)
                    max_x = i;
            }
        }
    }

    const int map_lines = max_y - min_y + 1;

    const int start_x = min_x + (max_x - min_x + 1) / 2 - 40; // no x scrolling
    int start_y;                                              // y does scroll

    int screen_y = you.y_pos;

    // if close to top of known map, put min_y on top
    // else if close to bottom of known map, put max_y on bottom.
    //
    // The num_lines comparisons are done to keep things neat, by
    // keeping things at the top of the screen.  By shifting an
    // additional one in the num_lines > map_lines case, we can
    // keep the top line clear... which makes things look a whole
    // lot better for small maps.
    if (num_lines > map_lines)
        screen_y = min_y + half_screen - 1;
    else if (num_lines == map_lines || screen_y - half_screen < min_y)
        screen_y = min_y + half_screen;
    else if (screen_y + half_screen > max_y)
        screen_y = max_y - half_screen;

    int curs_x = you.x_pos - start_x;
    int curs_y = you.y_pos - screen_y + half_screen;
    int search_feat = 0, search_found = 0, anchor_x = -1, anchor_y = -1;

#ifdef DOS_TERM
    gettext(1, 1, 80, 25, buffer);
    window(1, 1, 80, 25);
#endif

    clrscr();
    textcolor(DARKGREY);

    //lanbel
    put_screen:
    bufcount2 = 0;

    _setcursortype(_NOCURSOR);

#ifdef PLAIN_TERM
    gotoxy(1, 1);
#endif

    start_y = screen_y - half_screen;

    for (j = 0; j < num_lines; j++)
    {
        for (i = 0; i < 80; i++)
        {
            unsigned char colour = DARKGREY;
            if (start_y + j >= 65 || start_y + j <= 3
                || start_x + i < 0 || start_x + i >= GXM - 1)
            {
                buffer2[bufcount2 + 1] = DARKGREY;
                buffer2[bufcount2] = 0;
                bufcount2 += 2;

#if defined(DOS_TERM) || defined(USE_TILE)
                continue;
#endif

#if defined(PLAIN_TERM) && !defined(USE_TILE)
                goto print_it;
#endif
            }

            colour = colour_code_map(start_x + i, start_y + j);

            if (!spec_place[0]) {
                // If we can travel to this square, and this is a good old
                // DARKGREY square, change it to BLUE instead

                // point_distance[][] is declared in acr.cc
                extern short point_distance[GXM][GYM];
                if (Options.travel_colour && colour == DARKGREY)
                {
                    short dist = point_distance[start_x + i + 1]
                                               [start_y + j + 1];
                    if (dist > 0)
                        colour = BLUE;
                    else if (dist < 0)
                        colour = CYAN;
                }
            }

            if (start_x + i + 1 == you.x_pos && start_y + j + 1 == you.y_pos)
                colour = WHITE;

            //chに文字コードを格納
            unsigned char ch;
            ch = env.map[start_x + i][start_y + j];

            if (Options.use_cake)
            {
                //全体マップでのトウフ
                if (ch == 42)  //'*'
                    colour = ( BLUE )<<4 | ( BLUE );
                if (ch == 127 || ch == 137 || ch == 138 || ch == 139 || ch == 140) //'#'
                    colour = ( DARKGREY )<<4 | ( DARKGREY );
            }
//日本語版ではアイテムの類を明るく表示
#if 1 //JP
            if (ch == wanted_char) colour = WHITE;

            if ( (ch == 33)||(ch == 34)||(ch == 36)||(ch == 37)||(ch == 40)
               ||(ch == 41)||(ch == 43)||(ch == 47)||(ch == 48)||(ch == 58)
               ||(ch == 61)||(ch == 63)||(ch == 88)||(ch == 91)||(ch == 92)
               ||(ch == 93)||(ch == 125) )
              colour = LIGHTGREY;
#endif
#ifdef USE_TILE
            if (i + 1 == curs_x && j + 1 == curs_y)
                if (ch == 42 || ch == 127 || ch == 137 || ch == 138 || ch == 139 || ch == 140)
                    colour =( WHITE )<<4 | ( WHITE );
                else
                    colour = ( WHITE )<<4 | ( BLACK );
#endif

            if (ch >= 127) ch = special_to_ascii[ch - 127];
            buffer2[bufcount2] = ch;

            buffer2[bufcount2 + 1] = colour;
            bufcount2 += 2;

#if defined(PLAIN_TERM) && !defined(USE_TILE)

          print_it:
            // avoid line wrap
            if (i == 79)
                continue;

            // newline
            if (i == 0 && j > 0)
                gotoxy( 1, j + 1 );

            if (colour & 0xf0)
                textcolor_cake( colour & 0x0f);
            else
                textcolor( colour );

            if (ch >= 127)
                ch= special_to_ascii[ch - 127];

            putch(ch);

#if defined(LINUX) && !defined(USE_X11)
            if (Options.use_cake) textbackground(BLACK);
#endif

#endif // PLAINTERM || ! USE_TILE
        }
    }

#if defined(DOS_TERM) || defined(USE_TILE)
    puttext(1, 1, 80, 25, buffer2);
#endif

    _setcursortype(_NORMALCURSOR);

    gotoxy(curs_x, curs_y);

    gettything:
    getty = getch();
#ifdef USE_TILE
    if (getty == CMD_MOUSE_WHEEL_UP)
        getty = '-';
    if (getty == CMD_MOUSE_WHEEL_DOWN)
        getty = '+';
#endif

    if (spec_place[0] == 0 && getty != 0 && getty != '+' && getty != '-'
        && getty != 'h' && getty != 'j' && getty != 'k' && getty != 'l'
        && getty != 'y' && getty != 'u' && getty != 'b' && getty != 'n'
#if defined(LINUX)||defined(WIN32CONSOLE)||defined(WINDOWS)
        && getty != 'H' && getty != 'J' && getty != 'K' && getty != 'L'
        && getty != 'Y' && getty != 'U' && getty != 'B' && getty != 'N'
#endif
        // Keystrokes to initiate travel
        && getty != ',' && getty != '.'

        // Keystrokes for jumping to features
        && getty != '<' && getty != '>' && getty != '@' && getty != '\t'
        && getty != '^' && getty != '_'
        && (getty < '0' || getty > '9')
        && getty != '/')

    {
        goto putty;
    }

    if (spec_place[0] == 1 && getty != 0 && getty != '+' && getty != '-'
        && getty != 'h' && getty != 'j' && getty != 'k' && getty != 'l'
        && getty != 'y' && getty != 'u' && getty != 'b' && getty != 'n'
#ifdef LINUX
        && getty != 'H' && getty != 'J' && getty != 'K' && getty != 'L'
        && getty != 'Y' && getty != 'U' && getty != 'B' && getty != 'N'
#endif
        // Keystroke for searching
        && getty != '/'
        && getty != '.' && getty != 'S' && (getty < '0' || getty > '9')
        // Keystrokes for jumping to features
        && getty != '<' && getty != '>' && getty != '@' && getty != '\t'
        && getty != '^' && getty != '_')
    {
        goto gettything;
    }

    if (getty == 0)
        getty = getch();

    switch (getty)
    {
    case 'b':
    case '1':
        move_x = -1;
        move_y = 1;
        break;

    case 'j':
    case '2':
        move_y = 1;
        move_x = 0;
        break;

    case 'u':
    case '9':
        move_x = 1;
        move_y = -1;
        break;

    case 'k':
    case '8':
        move_y = -1;
        move_x = 0;
        break;

    case 'y':
    case '7':
        move_y = -1;
        move_x = -1;
        break;

    case 'h':
    case '4':
        move_x = -1;
        move_y = 0;
        break;

    case 'n':
    case '3':
        move_y = 1;
        move_x = 1;
        break;

    case 'l':
    case '6':
        move_x = 1;
        move_y = 0;
        break;

#if !defined(LINUX)&&!defined(WIN32CONSOLE)&&!defined(WINDOWS)
        // This is old DOS keypad support
    case 'H':
        move_y = -1;
        move_x = 0;
        break;
    case 'P':
        move_y = 1;
        move_x = 0;
        break;
    case 'K':
        move_x = -1;
        move_y = 0;
        break;
    case 'M':
        move_x = 1;
        move_y = 0;
        break;
    case 'O':
        move_x = -1;
        move_y = 1;
        break;
    case 'I':
        move_x = 1;
        move_y = -1;
        break;
    case 'G':
        move_y = -1;
        move_x = -1;
        break;
    case 'Q':
        move_y = 1;
        move_x = 1;
        break;

#else

    case 'B':
        move_x = -10;
        move_y = 10;
        break;

    case 'J':
        move_y = 10;
        move_x = 0;
        break;

    case 'U':
        move_x = 10;
        move_y = -10;
        break;

    case 'K':
        move_y = -10;
        move_x = 0;
        break;

    case 'Y':
        move_y = -10;
        move_x = -10;
        break;

    case 'H':
        move_x = -10;
        move_y = 0;
        break;

    case 'N':
        move_y = 10;
        move_x = 10;
        break;

    case 'L':
        move_x = 10;
        move_y = 0;
        break;

#endif

    case '+':
        move_y = 10;
        move_x = 0;
        break;
    case '-':
        move_y = -10;
        move_x = 0;
        break;
    case '<':
    case '>':
    case '@':
    case '\t':
    case '^':
    case '_':
        move_x = 0;
        move_y = 0;
        if (anchor_x == -1) {
            anchor_x = start_x + curs_x - 1;
            anchor_y = start_y + curs_y - 1;
        }
        if (search_feat != getty) {
            search_feat         = getty;
            search_found        = 0;
        }
        if (!spec_place[0])
            search_found = find_feature(features, getty, curs_x, curs_y,
                                        start_x, start_y,
                                        search_found, &move_x, &move_y);
        else
            search_found = find_feature(getty, curs_x, curs_y,
                                        start_x, start_y,
                                        anchor_x, anchor_y,
                                        search_found, &move_x, &move_y);
        break;
    case '.':
    case '\r':
    case 'S':
    case ',':
    case ';':
        spec_place[0] = start_x + curs_x;
        spec_place[1] = start_y + curs_y;
        goto putty;

    case '/':
        gotoxy(1, 1);
        textcolor (LIGHTGRAY);
        cprintf("Press a letter to hilight:");
        wanted_char = getch();
        break;

    default:
        move_x = 0;
        move_y = 0;
        break;
    }

    if (curs_x + move_x < 1 || curs_x + move_x > 80)
        move_x = 0;

    curs_x += move_x;

    if (num_lines < map_lines)
    {
        // Scrolling only happens when we don't have a large enough
        // display to show the known map.
        if (getty == '-' || getty == '+')
        {
            if (getty == '-')
                screen_y -= 10;

            if (screen_y <= min_y + half_screen)
                screen_y = min_y + half_screen;

            if (getty == '+')
                screen_y += 10;

            if (screen_y >= max_y - half_screen)
                screen_y = max_y - half_screen;

            goto put_screen;
        }

        if (curs_y + move_y < 1)
        {
            // screen_y += (curs_y + move_y) - 1;
            screen_y += move_y;

            if (screen_y < min_y + half_screen) {
                move_y   = screen_y - (min_y + half_screen);
                screen_y = min_y + half_screen;
            }
            else
                move_y = 0;
        }

        if (curs_y + move_y > num_lines - 1)
        {
            // screen_y += (curs_y + move_y) - num_lines + 1;
            screen_y += move_y;

            if (screen_y > max_y - half_screen) {
                move_y   = screen_y - (max_y - half_screen);
                screen_y = max_y - half_screen;
            }
            else
                move_y = 0;
        }
    }

    if (curs_y + move_y < 1 || curs_y + move_y > num_lines)
        move_y = 0;

    curs_y += move_y;
    goto put_screen;

    putty:

#ifdef DOS_TERM
    puttext(1, 1, 80, 25, buffer);
#endif

#ifdef USE_TILE
        if (Options.use_tile)
        {
            set_keyin_mode(KEYIN_MODE_NONE);
        }
#endif

    return;
}                               // end show_map()

void magic_mapping(int map_radius, int proportion)
{
    int i, j, k, l, empty_count;

    if (map_radius > 50)
        map_radius = 50;

    for (i = you.x_pos - map_radius; i < you.x_pos + map_radius; i++)
    {
        for (j = you.y_pos - map_radius; j < you.y_pos + map_radius; j++)
        {
            if (random2(100) > proportion)
                continue;       // note that proportion can be over 100

            if (i < 5 || j < 5 || i > (GXM - 5) || j > (GYM - 5))
                continue;

            if (env.map[i][j] == mapch2(grd[i + 1][j + 1]))
                continue;

            empty_count = 8;

            if (grd[i][j] < DNGN_LAVA && grd[i][j] != DNGN_CLOSED_DOOR)
            {
                for (k = 0; k < 3; k++)
                {
                    for (l = 0; l < 3; l++)
                    {
                        if (k == 1 && l == 1)
                            continue;

                        if (grd[i + k][j + l] <= 60
                            && grd[i + k][j + l] != DNGN_CLOSED_DOOR)
                        {
                            empty_count--;
                        }
                    }
                }
            }

            if (empty_count > 0)
                env.map[i][j] = mapch(grd[i + 1][j + 1]);
        }
    }
#ifdef USE_TILE
    init_gmap();
#endif
}                               // end magic_mapping()


/* mapchars 3 & 4 are for non-ibm char sets */
unsigned char mapchar(unsigned char ldfk)
{
    unsigned char showed = 0;

    switch (ldfk)
    {
    case DNGN_UNSEEN:
        showed = 0;
        break;

    case DNGN_SECRET_DOOR:
    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
    case DNGN_STONE_WALL:
    case DNGN_METAL_WALL:
    case DNGN_GREEN_CRYSTAL_WALL:
    case DNGN_WAX_WALL:
        showed = 176;
        break;

    case DNGN_CLOSED_DOOR:
        showed = 206;
        break;

    case 20:                    // orcish idol
    case 24:                    // ???
    case 25:                    // ???
    case DNGN_SILVER_STATUE:
    case DNGN_GRANITE_STATUE:
    case DNGN_ORANGE_CRYSTAL_STATUE:
        showed = '8';
        break;

    case DNGN_LAVA_X:
    case DNGN_WATER_X:
    case DNGN_LAVA:
    case DNGN_DEEP_WATER:
    case DNGN_SHALLOW_WATER:
        showed = 247;
        break;

    case DNGN_FLOOR:
    case DNGN_UNDISCOVERED_TRAP:
        showed = 250;
        break;

        //case 68: showed = '>'; break; // < (60)

    case DNGN_OPEN_DOOR:
        showed = 39;
        break;

        //case 72: showed = '<'; break;

    case DNGN_TRAP_MECHANICAL:
    case DNGN_TRAP_MAGICAL:
    case DNGN_TRAP_III:
        showed = '^';
        break;

    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
    case DNGN_ROCK_STAIRS_DOWN:
    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        showed = '>';
        break;

    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
    case DNGN_ROCK_STAIRS_UP:
    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        showed = '<';
        break;

    case DNGN_ENTER_HELL:
    case DNGN_ENTER_LABYRINTH:
    case DNGN_ENTER_SHOP:
    case DNGN_ENTER_DIS:
    case DNGN_ENTER_GEHENNA:
    case DNGN_ENTER_COCYTUS:
    case DNGN_ENTER_TARTARUS:
    case DNGN_ENTER_ABYSS:
    case DNGN_EXIT_ABYSS:
    case DNGN_STONE_ARCH:
    case DNGN_ENTER_PANDEMONIUM:
    case DNGN_EXIT_PANDEMONIUM:
    case DNGN_TRANSIT_PANDEMONIUM:
    case DNGN_ENTER_ZOT:
    case DNGN_RETURN_FROM_ZOT:
        showed = 239;
        break;

    case DNGN_ALTAR_ZIN:
    case DNGN_ALTAR_SHINING_ONE:
    case DNGN_ALTAR_KIKUBAAQUDGHA:
    case DNGN_ALTAR_YREDELEMNUL:
    case DNGN_ALTAR_XOM:
    case DNGN_ALTAR_VEHUMET:
    case DNGN_ALTAR_OKAWARU:
    case DNGN_ALTAR_MAKHLEB:
    case DNGN_ALTAR_SIF_MUNA:
    case DNGN_ALTAR_TROG:
    case DNGN_ALTAR_NEMELEX_XOBEH:
    case DNGN_ALTAR_ELYVILON:
        showed = 220;
        break;

    case DNGN_BLUE_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_SPARKLING_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_DRY_FOUNTAIN_III:
    case DNGN_DRY_FOUNTAIN_IV:
    case DNGN_DRY_FOUNTAIN_V:
    case DNGN_DRY_FOUNTAIN_VI:
    case DNGN_DRY_FOUNTAIN_VII:
    case DNGN_DRY_FOUNTAIN_VIII:
    case DNGN_PERMADRY_FOUNTAIN:
        showed = 159;
        break;

    default:
        showed = 0;
        break;
    }

    return showed;
}


unsigned char mapchar2(unsigned char ldfk)
{
    unsigned char showed = 0;

    switch (ldfk)
    {
    case DNGN_UNSEEN:
        showed = 0;
        break;

    case DNGN_SECRET_DOOR:
    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
    case DNGN_STONE_WALL:
    case DNGN_METAL_WALL:
    case DNGN_GREEN_CRYSTAL_WALL:
    case DNGN_WAX_WALL:
        showed = 177;
        break;

    case DNGN_CLOSED_DOOR:
        showed = 254;
        break;

    //case DNGN_LAVA_X: showed = 247; break;     // deprecated? {dlb}
    //case DNGN_WATER_X: showed = 247; break;    // deprecated? {dlb}

    case 20:                    // orcish idol
    case 24:                    // ???
    case 25:                    // ???
    case DNGN_SILVER_STATUE:
    case DNGN_GRANITE_STATUE:
    case DNGN_ORANGE_CRYSTAL_STATUE:
        showed = '8';
        break;

    case DNGN_LAVA:
    case DNGN_DEEP_WATER:
    case DNGN_SHALLOW_WATER:
        showed = 247;
        break;

    case DNGN_FLOOR:
    case DNGN_UNDISCOVERED_TRAP:
        showed = 249;
        break;

    case 68:
        showed = '>';
        break;                  // <

    case DNGN_OPEN_DOOR:
        showed = 39;
        break;

    case 72:
        showed = '<';
        break;                  // <

    case DNGN_TRAP_MECHANICAL:
    case DNGN_TRAP_MAGICAL:
    case DNGN_TRAP_III:
        showed = '^';
        break;

    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
    case DNGN_ROCK_STAIRS_DOWN:
    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        showed = '>';
        break;

    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
    case DNGN_ROCK_STAIRS_UP:
    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        showed = '<';
        break;

    case DNGN_ENTER_HELL:
    case DNGN_ENTER_LABYRINTH:
    case DNGN_ENTER_SHOP:
    case DNGN_ENTER_DIS:
    case DNGN_ENTER_GEHENNA:
    case DNGN_ENTER_COCYTUS:
    case DNGN_ENTER_TARTARUS:
    case DNGN_ENTER_ABYSS:
    case DNGN_EXIT_ABYSS:
    case DNGN_STONE_ARCH:
    case DNGN_ENTER_PANDEMONIUM:
    case DNGN_EXIT_PANDEMONIUM:
    case DNGN_TRANSIT_PANDEMONIUM:
    case DNGN_ENTER_ZOT:
    case DNGN_RETURN_FROM_ZOT:
        showed = 239;
        break;

    case DNGN_ALTAR_ZIN:
    case DNGN_ALTAR_SHINING_ONE:
    case DNGN_ALTAR_KIKUBAAQUDGHA:
    case DNGN_ALTAR_YREDELEMNUL:
    case DNGN_ALTAR_XOM:
    case DNGN_ALTAR_VEHUMET:
    case DNGN_ALTAR_OKAWARU:
    case DNGN_ALTAR_MAKHLEB:
    case DNGN_ALTAR_SIF_MUNA:
    case DNGN_ALTAR_TROG:
    case DNGN_ALTAR_NEMELEX_XOBEH:
    case DNGN_ALTAR_ELYVILON:
        showed = 220;
        break;

    case DNGN_BLUE_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_SPARKLING_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_DRY_FOUNTAIN_III:
    case DNGN_DRY_FOUNTAIN_IV:
    case DNGN_DRY_FOUNTAIN_V:
    case DNGN_DRY_FOUNTAIN_VI:
    case DNGN_DRY_FOUNTAIN_VII:
    case DNGN_DRY_FOUNTAIN_VIII:
    case DNGN_PERMADRY_FOUNTAIN:
        showed = 159;
        break;
    default:
        showed = 0;
        break;
    }

    return showed;
}


// realize that this is simply a repackaged version of
// stuff::see_grid() -- make certain they correlate {dlb}:
bool mons_near(struct monsters *monster, unsigned int foe)
{
    // early out -- no foe!
    if (foe == MHITNOT)
        return (false);

    if (foe == MHITYOU)
    {
        if (monster->x > you.x_pos - 9 && monster->x < you.x_pos + 9
            && monster->y > you.y_pos - 9 && monster->y < you.y_pos + 9)
        {
            if (env.show[monster->x - you.x_pos + 9][monster->y - you.y_pos + 9])
                return (true);
        }
        return (false);
    }

    // must be a monster
    struct monsters *myFoe = &menv[foe];
    if (myFoe->type >= 0)
    {
        if (monster->x > myFoe->x - 9 && monster->x < myFoe->x + 9
            && monster->y > myFoe->y - 9 && monster->y < myFoe->y + 9)
        {
            return (true);
        }
    }

    return (false);
}                               // end mons_near()


//---------------------------------------------------------------
//
// get_non_ibm_symbol
//
// Returns the character code and color for everything drawn
// without the IBM graphics option.
//
//---------------------------------------------------------------
void get_non_ibm_symbol(unsigned int object, unsigned short *ch,
                               unsigned short *color)
{
    ASSERT(color != NULL);
    ASSERT(ch != NULL);

    switch (object)
    {

    case DNGN_UNSEEN:
        *ch = 0;
        break;

    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
        *color = env.rock_colour;
        *ch = '#';
        break;

    case DNGN_STONE_WALL:
        if (player_in_branch( BRANCH_HALL_OF_ZOT ))
            *color = env.rock_colour;
        else
            *color = LIGHTGREY;
        *ch = '#';
        break;

    case DNGN_CLOSED_DOOR:
        *ch = '+';
        break;

    case DNGN_METAL_WALL:
        *ch = '#';
        *color = CYAN;
        break;

    case DNGN_SECRET_DOOR:
        *ch = '#';
        *color = env.rock_colour;
        break;

    case DNGN_GREEN_CRYSTAL_WALL:
        *ch = '#';
        *color = GREEN;
        break;

    case DNGN_ORCISH_IDOL:
        *ch = '8';
        *color = DARKGREY;
        break;

    case DNGN_WAX_WALL:
        *ch = '#';
        *color = YELLOW;
        break;

    case DNGN_SILVER_STATUE:
        *ch = '8';
        *color = WHITE;
        Visible_Statue[ STATUE_SILVER ] = 1;
        break;

    case DNGN_GRANITE_STATUE:
        *ch = '8';
        *color = LIGHTGREY;
        break;

    case DNGN_ORANGE_CRYSTAL_STATUE:
        *ch = '8';
        *color = LIGHTRED;
        Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 1;
        break;

    case DNGN_LAVA:
        *ch = '{';
        *color = RED;
        break;

    case DNGN_DEEP_WATER:
        *ch = '{';
        // this wavy thing also used for water elemental
        // note that some monsters which use IBM graphics aren't set
        // for this function - too tricky for now.
        *color = BLUE;
        break;

    case DNGN_SHALLOW_WATER:
        *color = CYAN;
        *ch = '{';
        break;

    case DNGN_FLOOR:
        *color = env.floor_colour;
        *ch = '.';
        break;

    case DNGN_ENTER_HELL:
        *color = RED;
        *ch = '\\';
        seen_other_thing(DNGN_ENTER_HELL);
        break;

    case DNGN_OPEN_DOOR:
        *ch = '\'';
        break;

    case DNGN_BRANCH_STAIRS:
        *color = BROWN;
        *ch = '>';
        break;

    case DNGN_TRAP_MECHANICAL:
        *color = 11;
        *ch = '^';
        break;

    case DNGN_TRAP_MAGICAL:
        *color = MAGENTA;
        *ch = '^';
        break;

    case DNGN_TRAP_III:
        *color = LIGHTGREY;
        *ch = '^';
        break;

    case DNGN_UNDISCOVERED_TRAP:
        *color = env.floor_colour;
        *ch = '.';
        break;

    case DNGN_ENTER_SHOP:
        *color = YELLOW;
        *ch = '\\';
        seen_other_thing(DNGN_ENTER_SHOP);
        break;
// if I change anything above here, must also change magic mapping!

    case DNGN_ENTER_LABYRINTH:
        *color = LIGHTGREY;
        *ch = '\\';
        seen_other_thing(DNGN_ENTER_LABYRINTH);
        break;

    case DNGN_ROCK_STAIRS_DOWN:
        *color = BROWN;         // ladder
    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
        *ch = '>';
        break;

    case DNGN_ROCK_STAIRS_UP:
        *color = BROWN;         // ladder
    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
        *ch = '<';
        break;

    case DNGN_ENTER_DIS:
        *color = CYAN;
        *ch = '\\';
        break;

    case DNGN_ENTER_GEHENNA:
        *color = RED;
        *ch = '\\';
        break;

    case DNGN_ENTER_COCYTUS:
        *color = LIGHTCYAN;
        *ch = '\\';
        break;

    case DNGN_ENTER_TARTARUS:
        *color = DARKGREY;
        *ch = '\\';
        break;

    case DNGN_ENTER_ABYSS:
        *color = random2(16);
        *ch = '\\';
        seen_other_thing(DNGN_ENTER_ABYSS);
        break;

    case DNGN_EXIT_ABYSS:
        *color = random2(16);
        *ch = '\\';
        break;

    case DNGN_STONE_ARCH:
        *color = LIGHTGREY;
        *ch = '\\';
        break;

    case DNGN_ENTER_PANDEMONIUM:
        *color = LIGHTBLUE;
        *ch = '\\';
        seen_other_thing(DNGN_ENTER_PANDEMONIUM);
        break;

    case DNGN_EXIT_PANDEMONIUM:
        *color = LIGHTBLUE;
        *ch = '\\';
        break;

    case DNGN_TRANSIT_PANDEMONIUM:
        *color = LIGHTGREEN;
        *ch = '\\';
        break;                  // gate to other part of pandemonium

    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        *color = YELLOW;
        *ch = '>';
        seen_staircase(object);
        break;

    case DNGN_ENTER_ZOT:
        *color = MAGENTA;
        *ch = '\\';
        seen_staircase(object);
        break;

    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        *color = YELLOW;
        *ch = '<';
        break;

    case DNGN_RETURN_FROM_ZOT:
        *color = MAGENTA;
        *ch = '\\';
        break;

    case DNGN_ALTAR_ZIN:
        *color = WHITE;
        *ch = '_';
        seen_altar(GOD_ZIN);
        break;

    case DNGN_ALTAR_SHINING_ONE:
        *color = YELLOW;
        *ch = '_';
        seen_altar(GOD_SHINING_ONE);
        break;

    case DNGN_ALTAR_KIKUBAAQUDGHA:
        *color = DARKGREY;
        *ch = '_';
        seen_altar(GOD_KIKUBAAQUDGHA);
        break;

    case DNGN_ALTAR_YREDELEMNUL:
        *color = DARKGREY;
        if (one_chance_in(3))
            *color = RED;
        *ch = '_';
        seen_altar(GOD_YREDELEMNUL);
        break;

    case DNGN_ALTAR_XOM:
        *color = random_colour();
        *ch = '_';
        seen_altar(GOD_XOM);
        break;

    case DNGN_ALTAR_VEHUMET:
        *color = LIGHTBLUE;
        if (one_chance_in(3))
            *color = LIGHTMAGENTA;
        if (one_chance_in(3))
            *color = LIGHTRED;
        *ch = '_';
        seen_altar(GOD_VEHUMET);
        break;

    case DNGN_ALTAR_OKAWARU:
        *color = CYAN;
        *ch = '_';
        seen_altar(GOD_OKAWARU);
        break;

    case DNGN_ALTAR_MAKHLEB:
        *color = RED;
        if (one_chance_in(3))
            *color = LIGHTRED;
        if (one_chance_in(3))
            *color = YELLOW;
        *ch = '_';
        seen_altar(GOD_MAKHLEB);
        break;

    case DNGN_ALTAR_SIF_MUNA:
        *color = BLUE;
        *ch = '_';
        seen_altar(GOD_SIF_MUNA);
        break;

    case DNGN_ALTAR_TROG:
        *color = RED;
        *ch = '_';
        seen_altar(GOD_TROG);
        break;

    case DNGN_ALTAR_NEMELEX_XOBEH:
        *color = LIGHTMAGENTA;
        *ch = '_';
        seen_altar(GOD_NEMELEX_XOBEH);
        break;

    case DNGN_ALTAR_ELYVILON:
        *color = LIGHTGREY;
        *ch = '_';
        seen_altar(GOD_ELYVILON);
        break;

    case DNGN_BLUE_FOUNTAIN:
        *color = BLUE;
        *ch = '}';
        break;

    case DNGN_SPARKLING_FOUNTAIN:
        *color = LIGHTBLUE;
        *ch = '}';
        break;

    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_PERMADRY_FOUNTAIN:
        *color = LIGHTGREY;
        *ch = '}';
        break;

    case 256:
        *ch = '0';
        break;

    case 257:
        *color = CYAN;
        *ch = '~';
        break;                  /* Invis creature walking through water */

    case 258:
        *ch = ')';
        break;                  // weapon )

    case 259:
        *ch = '[';
        break;                  // armour [

    case 260:
        *ch = '/';
        break;                  // wands, etc.

    case 261:
        *ch = '%';
        break;                  // food

    case 262:
        *ch = '+';
        break;                  // books +

    case 263:
        *ch = '?';
        break;                  // scroll ?

    case 264:
        *ch = '=';
        break;                  // ring = etc

    case 265:
        *ch = '!';
        break;                  // potions !

    case 266:
        *ch = '(';
        break;                  // stones

    case 267:
        *ch = ':';
        break;                  // book +

    case 268:
        *ch = '%';
        break;                  // corpses part 1

    case 269:
        *ch = '|';
        break;                  // magical staves

    case 270:
        *ch = '}';
        break;                  // gems

    case 271:
        *ch = '%';
        break;                  // don't know ?

    case 272:
        *ch = '$';
        break;                  // $ gold

    case 273:
        *ch = '"';
        break;                  // amulet

    default:
        int mnr = object;
        *ch = ((mnr >= 297) ? mons_char(mnr - 297) : object);   // yeah
        break;
    }
}

/*
   This is the viewwindow function for computers without IBM graphic displays.
   It is activated by a command line argument, which sets a function pointer.
 */
//!!!!
void viewwindow3(char draw_it, bool do_updates)
{
#ifdef WINDOWS
    _setcursortype(0);
#endif
    int bufcount = 0;
    FixedVector < unsigned short, 1500 > buffy;  //[800]; //392];

    unsigned short ch, color;

    int count_x, count_y;

//  Must be zero-cleared before losight
    for (count_x = 0; count_x < 18; count_x++)
    {
        for (count_y = 0; count_y < 18; count_y++)
        {
            // Zero clear env.show before losight
            env.show[count_x][count_y] = 0;
        }
    }

    losight(env.show, grd, you.x_pos, you.y_pos);

    for (count_x = 0; count_x < 18; count_x++)
    {
        for (count_y = 0; count_y < 18; count_y++)
        {
            env.show_col[count_x][count_y] = LIGHTGREY;
            show_backup[count_x][count_y] = 0;
        }
    }

    item();
    cloud_grid();
    monster_grid(do_updates);
    bufcount = 0;

    if (draw_it == 1)
    {
        _setcursortype(_NOCURSOR);
        for (count_y = (you.y_pos - 8); (count_y < you.y_pos + 9); count_y++)
        {
            int y0 = count_y - you.y_pos + 9;
            bufcount += 16;

            for (count_x = (you.x_pos - 8); (count_x < you.x_pos + 9); count_x++)
            {
                int x0 = count_x - you.x_pos + 9;
                color = env.show_col[x0][y0];

                if (count_x == you.x_pos && count_y == you.y_pos)
                {
                    ch = your_sign;
                    if (player_is_swimming())
                    {
                        color = (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
                                    ? BLUE : CYAN;
                    }
                    else
                    {
                        color = your_colour;
                    }
                }
                else
                {
                    unsigned int object = env.show[x0][y0];

                    // Always get zenkaku
                    get_zenkaku_symbol(object, &ch, &color);
                }
                buffy[bufcount] = ch;   //showed;
                buffy[bufcount + 1] = color;
                bufcount += 2;
            }

            bufcount += 16;
        }

        bufcount = 0;

        if (you.level_type != LEVEL_LABYRINTH
            && you.level_type != LEVEL_ABYSS)
        {
            for (count_y = 0; count_y < 17; count_y++)
            {
                int y0 = count_y + you.y_pos - 9;

                bufcount += 16;
                for (count_x = 0; count_x < 17; count_x++)
                {
                    int x0 = count_x + you.x_pos - 9;

                    if ((buffy[bufcount] != 0) && (x0 >= 0) && (y0 >= 0)
                && (x0 < GXM) && (y0 < GYM))
                    {
                        env.map[x0][y0] = buffy[bufcount];
#ifdef USE_TILE
                        update_gmap(x0, y0, buffy[bufcount]);
#endif
                    }

                    if (Options.clean_map == 1
                        && show_backup[count_x + 1][count_y + 1] != 0
                        && x0 >= 0 && y0 >= 0 && x0< GXM && y0 < GYM)
                    {
                        get_zenkaku_symbol( show_backup[count_x + 1]
                                                       [count_y + 1],
                                                       &ch, &color );
                        env.map[x0][y0] = ch;
                    }
                    bufcount += 2;
                }
                bufcount += 16;
            }
        }

        bufcount = 0;

//Handle unseen grids

        for (count_y = 0; count_y < 17; count_y++)
        {
            for (count_x = 0; count_x < 33; count_x++)
            {
                if (count_x + you.x_pos - 17 < 3
                    || count_y + you.y_pos - 9 < 3
                    || count_x + you.x_pos - 14 > (GXM - 3)
                    || count_y + you.y_pos - 9 > (GYM - 3))
                {
                    buffy[bufcount] = 0;
                    bufcount++;
                    buffy[bufcount] = 0;
                    bufcount++;
                    continue;
                }

                if (count_x >= 8 && count_x <= 24 && count_y >= 0
                    && count_y <= 16 && buffy[bufcount] != 0)
                {
                    bufcount += 2;
                    continue;
                }
                buffy[bufcount] = env.map[count_x + you.x_pos - 17]
                                         [count_y + you.y_pos -  9];
                buffy[bufcount + 1] = DARKGREY;

                if (Options.colour_map)
                {
                    if (env.map[count_x + you.x_pos - 16]
                               [count_y + you.y_pos - 8] != 0)
                    {
                        buffy[bufcount + 1]
                        = colour_code_map( count_x + you.x_pos - 17,
                                           count_y + you.y_pos - 9 );
                    }
                }

                bufcount += 2;
            }
        }

        if (you.berserker)
        {
            for (count_x = 1; count_x < 1400; count_x += 2)
            {
                if (buffy[count_x] != DARKGREY)
                    buffy[count_x] = RED;
#ifdef JP
                //バーサークの周辺色は暗い赤にする
                if (buffy[count_x] != DARKGREY)
                    buffy[count_x] = 4;
#endif
            }
        }

        if (show_green != BLACK)
        {
            for (count_x = 1; count_x < 1400; count_x += 2)
            {
                if (buffy[count_x] != DARKGREY)
                    buffy[count_x] = show_green;
            }

            show_green = ((you.special_wield == SPWLD_SHADOW) ? DARKGREY
                                                              : BLACK);
        }

#ifdef DOS_TERM
        puttext(2, 1, 34, 17, buffy.buffer());
#endif

#ifdef PLAIN_TERM
        {

        gotoxy(2, 1);
        bufcount = 0;

        // this line is purely optional
        if (you.running == 0 ||
            ((Options.travel_delay > -1) && (you.run_x !=0 || you.run_y !=0)))
        {
#ifdef USE_TILE
            extern void display_gmap();
            display_gmap();
#endif
            for (count_x = 0; count_x < 1120; count_x += 2)     // 1056
            {
  #ifdef JP
              if (Options.use_zenkaku)
              {
                if ((count_x % 66) >=16 && (count_x % 66)<=50)
                {
                    unsigned char ch=buffy[count_x];

                    if(ch < 32) ch = 32;

                    if (Options.use_cake)
                    {
                        if (ch == 127 || ch == 137 || ch == 138 || ch == 139 || ch == 140)
                            textcolor_cake( buffy[count_x + 1] );
                        else if ( (ch == '*') && ( buffy[count_x + 1] == DARKGREY ) )
                            textcolor_cake(BLUE);
                        else
                            textcolor(buffy[count_x + 1]);
                    }
                    else
                        textcolor(buffy[count_x + 1]);
                    writeWChar( &ascii_to_zenkaku[(ch-' ')*2] );
                }
              }
              else //zenkaku
  #endif
              {
                unsigned char ch = buffy[count_x];

                if (Options.use_cake)
                {
                  if (ch == 127 || ch == 137 || ch == 138 || ch == 139 || ch == 140)
                      textcolor_cake( buffy[count_x + 1] );
                  else if ( (ch == '*') && ( buffy[count_x + 1] == DARKGREY ) )
                      textcolor_cake(BLUE);
                  else
                      textcolor(buffy[count_x + 1]);
                }
                else
                    textcolor(buffy[count_x + 1]);

                if(ch >= 127) ch = special_to_ascii[ch - 127];
                putch(ch);
              }
  #if defined(LINUX) && !defined(USE_X11)
              textbackground(BLACK);
  #endif

              if (count_x % 66 == 64 && count_x > 0)
                  gotoxy(2, wherey() + 1);
            }
        }
    }
#endif //PLAIN_TERM

        _setcursortype(_NORMALCURSOR);

    }                           // end of (if brek...)
}                               // end viewwindow3()


unsigned char mapchar3(unsigned char ldfk)
{
    unsigned char showed = 0;

    switch (ldfk)
    {
    case DNGN_UNSEEN:
        showed = 0;
        break;

    case DNGN_SECRET_DOOR:
    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
    case DNGN_STONE_WALL:
    case DNGN_METAL_WALL:
    case DNGN_GREEN_CRYSTAL_WALL:
    case DNGN_WAX_WALL:
        showed = '*';
        break;

    case DNGN_CLOSED_DOOR:
        showed = '+';
        break;

    case 20:                    // orcish idol
    case 24:                    // ???
    case 25:                    // ???
    case DNGN_SILVER_STATUE:
    case DNGN_GRANITE_STATUE:
    case DNGN_ORANGE_CRYSTAL_STATUE:
        showed = '8';
        break;

    case DNGN_LAVA_X:
    case DNGN_WATER_X:
    case DNGN_LAVA:
    case DNGN_DEEP_WATER:
    case DNGN_SHALLOW_WATER:
        showed = '{';
        break;

    case DNGN_FLOOR:
    case DNGN_UNDISCOVERED_TRAP:
        showed = ',';
        break;

    //case 68: showed = '>'; break; // < (60)

    case DNGN_OPEN_DOOR:
        showed = 39;
        break;                  // open door

    //case 72: showed = '<'; break;

    case DNGN_TRAP_MECHANICAL:
    case DNGN_TRAP_MAGICAL:
    case DNGN_TRAP_III:
        showed = '^';
        break;

    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
    case DNGN_ROCK_STAIRS_DOWN:
    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        showed = '>';
        break;

    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
    case DNGN_ROCK_STAIRS_UP:
    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        showed = '<';
        break;

    case DNGN_ENTER_HELL:
    case DNGN_ENTER_LABYRINTH:
    case DNGN_ENTER_SHOP:
    case DNGN_ENTER_DIS:
    case DNGN_ENTER_GEHENNA:
    case DNGN_ENTER_COCYTUS:
    case DNGN_ENTER_TARTARUS:
    case DNGN_ENTER_ABYSS:
    case DNGN_EXIT_ABYSS:
    case DNGN_STONE_ARCH:
    case DNGN_ENTER_PANDEMONIUM:
    case DNGN_EXIT_PANDEMONIUM:
    case DNGN_TRANSIT_PANDEMONIUM:
    case DNGN_ENTER_ZOT:
    case DNGN_RETURN_FROM_ZOT:
        showed = '\\';
        break;

    case DNGN_ALTAR_ZIN:
    case DNGN_ALTAR_SHINING_ONE:
    case DNGN_ALTAR_KIKUBAAQUDGHA:
    case DNGN_ALTAR_YREDELEMNUL:
    case DNGN_ALTAR_XOM:
    case DNGN_ALTAR_VEHUMET:
    case DNGN_ALTAR_OKAWARU:
    case DNGN_ALTAR_MAKHLEB:
    case DNGN_ALTAR_SIF_MUNA:
    case DNGN_ALTAR_TROG:
    case DNGN_ALTAR_NEMELEX_XOBEH:
    case DNGN_ALTAR_ELYVILON:
        showed = '_';
        break;

    case DNGN_BLUE_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_SPARKLING_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_DRY_FOUNTAIN_III:
    case DNGN_DRY_FOUNTAIN_IV:
    case DNGN_DRY_FOUNTAIN_V:
    case DNGN_DRY_FOUNTAIN_VI:
    case DNGN_DRY_FOUNTAIN_VII:
    case DNGN_DRY_FOUNTAIN_VIII:
    case DNGN_PERMADRY_FOUNTAIN:
        showed = '}';
        break;

    default:
        showed = 0;
        break;
    }

    return showed;
}


unsigned char mapchar4(unsigned char ldfk)
{
    unsigned char showed = 0;

    switch (ldfk)
    {
    case DNGN_UNSEEN:
        showed = 0;
        break;

    case DNGN_CLOSED_DOOR:
        showed = '+';
        break;

    case DNGN_SECRET_DOOR:
    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
    case DNGN_STONE_WALL:
    case DNGN_METAL_WALL:
    case DNGN_GREEN_CRYSTAL_WALL:
    case DNGN_WAX_WALL:
        showed = '#';
        break;

    case 20:                    // orcish idol
    case 24:                    // ???
    case 25:                    // ???
    case DNGN_SILVER_STATUE:
    case DNGN_GRANITE_STATUE:
    case DNGN_ORANGE_CRYSTAL_STATUE:
        showed = '8';
        break;

    case DNGN_LAVA_X:
    case DNGN_WATER_X:
    case DNGN_LAVA:
    case DNGN_DEEP_WATER:
    case DNGN_SHALLOW_WATER:
        showed = '{';
        break;

    case DNGN_FLOOR:
    case DNGN_UNDISCOVERED_TRAP:
        showed = '.';
        break;

    case 68:
        showed = '>';           // <
        break;

    case DNGN_OPEN_DOOR:
        showed = 39;
        break;

    case 72:
        showed = '<';
        break;

    case DNGN_TRAP_MECHANICAL:
    case DNGN_TRAP_MAGICAL:
    case DNGN_TRAP_III:
        showed = '^';
        break;

    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
    case DNGN_ROCK_STAIRS_DOWN:
    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        showed = '>';
        break;

    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
    case DNGN_ROCK_STAIRS_UP:
    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        showed = '<';
        break;

    case DNGN_ENTER_HELL:
    case DNGN_ENTER_LABYRINTH:
    case DNGN_ENTER_SHOP:
    case DNGN_ENTER_DIS:
    case DNGN_ENTER_GEHENNA:
    case DNGN_ENTER_COCYTUS:
    case DNGN_ENTER_TARTARUS:
    case DNGN_ENTER_ABYSS:
    case DNGN_EXIT_ABYSS:
    case DNGN_STONE_ARCH:
    case DNGN_ENTER_PANDEMONIUM:
    case DNGN_EXIT_PANDEMONIUM:
    case DNGN_TRANSIT_PANDEMONIUM:
    case DNGN_ENTER_ZOT:
    case DNGN_RETURN_FROM_ZOT:
        showed = '\\';
        break;

    case DNGN_ALTAR_ZIN:
    case DNGN_ALTAR_SHINING_ONE:
    case DNGN_ALTAR_KIKUBAAQUDGHA:
    case DNGN_ALTAR_YREDELEMNUL:
    case DNGN_ALTAR_XOM:
    case DNGN_ALTAR_VEHUMET:
    case DNGN_ALTAR_OKAWARU:
    case DNGN_ALTAR_MAKHLEB:
    case DNGN_ALTAR_SIF_MUNA:
    case DNGN_ALTAR_TROG:
    case DNGN_ALTAR_NEMELEX_XOBEH:
    case DNGN_ALTAR_ELYVILON:
        showed = '_';
        break;

    case DNGN_BLUE_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_SPARKLING_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_DRY_FOUNTAIN_III:
    case DNGN_DRY_FOUNTAIN_IV:
    case DNGN_DRY_FOUNTAIN_V:
    case DNGN_DRY_FOUNTAIN_VI:
    case DNGN_DRY_FOUNTAIN_VII:
    case DNGN_DRY_FOUNTAIN_VIII:
    case DNGN_PERMADRY_FOUNTAIN:
        showed = '}';
        break;

    default:
        showed = 0;
        break;
    }

    return showed;
}


// for ZENKAKU MAP
unsigned char mapchar5(unsigned char ldfk)
{
    unsigned char showed = 0;

    switch (ldfk)
    {
    case DNGN_UNSEEN:
        showed = 0;
        break;

    case DNGN_SECRET_DOOR:
    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
    case DNGN_STONE_WALL:
    case DNGN_METAL_WALL:
    case DNGN_GREEN_CRYSTAL_WALL:
    case DNGN_WAX_WALL:
        showed = '*';
        break;

    case DNGN_CLOSED_DOOR:
        showed = 128;
        break;

    case 20:                    // orcish idol
    case 24:                    // ???
    case 25:                    // ???
    case DNGN_SILVER_STATUE:
    case DNGN_GRANITE_STATUE:
    case DNGN_ORANGE_CRYSTAL_STATUE:
        showed = '8';
        break;

    case DNGN_LAVA_X:
    case DNGN_LAVA:
        showed = 141;
        break;

    case DNGN_WATER_X:
    case DNGN_DEEP_WATER:
    case DNGN_SHALLOW_WATER:
        showed = 135;
        break;

    case DNGN_FLOOR:
    case DNGN_UNDISCOVERED_TRAP:
        showed = ','; // was = 39;
        break;

    //case 68: showed = '>'; break; // < (60)

    case DNGN_OPEN_DOOR:
        showed = 134;
        break;                  // open door

    //case 72: showed = '<'; break;

    case DNGN_TRAP_MECHANICAL:
    case DNGN_TRAP_MAGICAL:
    case DNGN_TRAP_III:
        showed = '^';
        break;

    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
    case DNGN_ROCK_STAIRS_DOWN:
        showed = '>';
        break;

    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        showed = 136; // "》"
        break;

    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
    case DNGN_ROCK_STAIRS_UP:
        showed = '<';
        break;

    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        showed = 129; // "《"
        break;

    case DNGN_ENTER_HELL:
    case DNGN_ENTER_LABYRINTH:
    case DNGN_ENTER_SHOP:
    case DNGN_ENTER_DIS:
    case DNGN_ENTER_GEHENNA:
    case DNGN_ENTER_COCYTUS:
    case DNGN_ENTER_TARTARUS:
    case DNGN_ENTER_ABYSS:
    case DNGN_EXIT_ABYSS:
    case DNGN_STONE_ARCH:
    case DNGN_ENTER_PANDEMONIUM:
    case DNGN_EXIT_PANDEMONIUM:
    case DNGN_TRANSIT_PANDEMONIUM:
    case DNGN_ENTER_ZOT:
    case DNGN_RETURN_FROM_ZOT:
        showed = 132;
        break;

    case DNGN_ALTAR_ZIN:
    case DNGN_ALTAR_SHINING_ONE:
    case DNGN_ALTAR_KIKUBAAQUDGHA:
    case DNGN_ALTAR_YREDELEMNUL:
    case DNGN_ALTAR_XOM:
    case DNGN_ALTAR_VEHUMET:
    case DNGN_ALTAR_OKAWARU:
    case DNGN_ALTAR_MAKHLEB:
    case DNGN_ALTAR_SIF_MUNA:
    case DNGN_ALTAR_TROG:
    case DNGN_ALTAR_NEMELEX_XOBEH:
    case DNGN_ALTAR_ELYVILON:
        showed = 131;
        break;

    case DNGN_BLUE_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_SPARKLING_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_DRY_FOUNTAIN_III:
    case DNGN_DRY_FOUNTAIN_IV:
    case DNGN_DRY_FOUNTAIN_V:
    case DNGN_DRY_FOUNTAIN_VI:
    case DNGN_DRY_FOUNTAIN_VII:
    case DNGN_DRY_FOUNTAIN_VIII:
    case DNGN_PERMADRY_FOUNTAIN:
        showed = 133;
        break;

    default:
        showed = 0;
        break;
    }

    return showed;
}

// for ZENKAKU MAP
unsigned char mapchar6(unsigned char ldfk)
{
    unsigned char showed = 0;

    switch (ldfk)
    {
    case DNGN_UNSEEN:
        showed = 0;
        break;

    case DNGN_CLOSED_DOOR:
        showed = 128;
        break;

    case DNGN_SECRET_DOOR:
    case DNGN_ROCK_WALL:
    case DNGN_PERMAROCK_WALL:
    case DNGN_STONE_WALL:
    case DNGN_METAL_WALL:
    case DNGN_GREEN_CRYSTAL_WALL:
    case DNGN_WAX_WALL:
        showed = 127;
        break;

    case 20:                    // orcish idol
    case 24:                    // ???
    case 25:                    // ???
    case DNGN_SILVER_STATUE:
    case DNGN_GRANITE_STATUE:
    case DNGN_ORANGE_CRYSTAL_STATUE:
        showed = 130;
        break;

    case DNGN_LAVA_X:
    case DNGN_LAVA:
        showed = 141;
        break;

    case DNGN_WATER_X:
    case DNGN_DEEP_WATER:
    case DNGN_SHALLOW_WATER:
        showed = 135;
        break;

    case DNGN_FLOOR:
    case DNGN_UNDISCOVERED_TRAP:
        showed = 130;
        break;

    case 68:
        showed = '>';           // <
        break;

    case DNGN_OPEN_DOOR:
        showed = 134;
        break;

    case 72:
        showed = '<';
        break;

    case DNGN_TRAP_MECHANICAL:
    case DNGN_TRAP_MAGICAL:
    case DNGN_TRAP_III:
        showed = '^';
        break;

    case DNGN_STONE_STAIRS_DOWN_I:
    case DNGN_STONE_STAIRS_DOWN_II:
    case DNGN_STONE_STAIRS_DOWN_III:
    case DNGN_ROCK_STAIRS_DOWN:
        showed = '>';
        break;

    case DNGN_ENTER_ORCISH_MINES:
    case DNGN_ENTER_HIVE:
    case DNGN_ENTER_LAIR:
    case DNGN_ENTER_SLIME_PITS:
    case DNGN_ENTER_VAULTS:
    case DNGN_ENTER_CRYPT:
    case DNGN_ENTER_HALL_OF_BLADES:
    case DNGN_ENTER_TEMPLE:
    case DNGN_ENTER_SNAKE_PIT:
    case DNGN_ENTER_ELVEN_HALLS:
    case DNGN_ENTER_TOMB:
    case DNGN_ENTER_SWAMP:
    case 123:
    case 124:
    case 125:
    case 126:
        showed = 136; // 》
        break;

    case DNGN_STONE_STAIRS_UP_I:
    case DNGN_STONE_STAIRS_UP_II:
    case DNGN_STONE_STAIRS_UP_III:
    case DNGN_ROCK_STAIRS_UP:
        showed = '<';
        break;

    case DNGN_RETURN_FROM_ORCISH_MINES:
    case DNGN_RETURN_FROM_HIVE:
    case DNGN_RETURN_FROM_LAIR:
    case DNGN_RETURN_FROM_SLIME_PITS:
    case DNGN_RETURN_FROM_VAULTS:
    case DNGN_RETURN_FROM_CRYPT:
    case DNGN_RETURN_FROM_HALL_OF_BLADES:
    case DNGN_RETURN_FROM_TEMPLE:
    case DNGN_RETURN_FROM_SNAKE_PIT:
    case DNGN_RETURN_FROM_ELVEN_HALLS:
    case DNGN_RETURN_FROM_TOMB:
    case DNGN_RETURN_FROM_SWAMP:
    case 143:
    case 144:
    case 145:
    case 146:
        showed = 129; //《
        break;

    case DNGN_ENTER_HELL:
    case DNGN_ENTER_LABYRINTH:
    case DNGN_ENTER_SHOP:
    case DNGN_ENTER_DIS:
    case DNGN_ENTER_GEHENNA:
    case DNGN_ENTER_COCYTUS:
    case DNGN_ENTER_TARTARUS:
    case DNGN_ENTER_ABYSS:
    case DNGN_EXIT_ABYSS:
    case DNGN_STONE_ARCH:
    case DNGN_ENTER_PANDEMONIUM:
    case DNGN_EXIT_PANDEMONIUM:
    case DNGN_TRANSIT_PANDEMONIUM:
    case DNGN_ENTER_ZOT:
    case DNGN_RETURN_FROM_ZOT:
        showed = 132;
        break;

    case DNGN_ALTAR_ZIN:
    case DNGN_ALTAR_SHINING_ONE:
    case DNGN_ALTAR_KIKUBAAQUDGHA:
    case DNGN_ALTAR_YREDELEMNUL:
    case DNGN_ALTAR_XOM:
    case DNGN_ALTAR_VEHUMET:
    case DNGN_ALTAR_OKAWARU:
    case DNGN_ALTAR_MAKHLEB:
    case DNGN_ALTAR_SIF_MUNA:
    case DNGN_ALTAR_TROG:
    case DNGN_ALTAR_NEMELEX_XOBEH:
    case DNGN_ALTAR_ELYVILON:
        showed = 131;
        break;

    case DNGN_BLUE_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_I:
    case DNGN_SPARKLING_FOUNTAIN:
    case DNGN_DRY_FOUNTAIN_II:
    case DNGN_DRY_FOUNTAIN_III:
    case DNGN_DRY_FOUNTAIN_IV:
    case DNGN_DRY_FOUNTAIN_V:
    case DNGN_DRY_FOUNTAIN_VI:
    case DNGN_DRY_FOUNTAIN_VII:
    case DNGN_DRY_FOUNTAIN_VIII:
    case DNGN_PERMADRY_FOUNTAIN:
        showed = 133;
        break;

    default:
        showed = 0;
        break;
    }

    return showed;
}
