by setting UNICODE_GLYPHS=y in makefile.unix).
Removed the (1,1) offset between map and grid. Both map and grid are now in sync.
Store object indexes instead of raw characters in env.map so that players can change charsets and have the display update immediately.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1552 c06c8d41-db1a-0410-9941-cceddc491573
PL6I2CMSTHY5ZHWVMIQE5YTM5S5VPKBNZM6QJVHZSSKOJGIJ5W4AC
JI3OY2BNOZWJ5RQGQJTIJ2X2NUURL6YI2L5OVUAL3CSNEWAQW6VQC
2D77G7XIIDVS2RUE33YH2NAPSXNLXKXXN3RP2TKPLWRXTEAVSZ3QC
R5Q2OJMXNVK5RPXIKLTHHAOP67XOBB44AZKKZ2TOI3USPL6HACXAC
XRZPPYWPWUOM4SFNI6BHKH2UKJQNLKOV6Y7XIEPEZXE5QYRT26PAC
Y2VKZYSQXLYYQNB6OSQP44IYLT2M56SE2ZW2MHOAZUODKCVDHEAQC
LLKV4OYGEDB4GVJS5JVBZP5JQFW7VMPZ2CBRSITJ5XCFS3QNWIBQC
DKGRBWIZWKTE74OTWDMFVGOMHMU5LUNO5S5RMBOTEB2SFMFPFCWQC
OSRZEPPGBIMSZBWIVBTZTTIMV6TEUGVZRZ5AI2ZJW7CVZZQBUIMQC
EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
X3RDT655FEYO6XEVPIUAPEPJZAFE55KZBH2AZOLK3NGHINMVIGFQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
7NDXS36TE7QVXTXJWMYSVG5UHCCLPIO4VL6NXFGTDK3ZNKE3A2IAC
TZ643KHSE5CUPXFSQ7VYVOCM5MTQ7F4SENEYQX2RNFHGHLQVS3RQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
TJISAZK5RWKXIIC5UTQNY4KT3UX3ASGBUQQNWZ7ZDULPRYFRZXQQC
D27U7RT2C77NEUBP6JCSQJ2DRCJVHOXUO2PFZ45VFYMEVMKI4TSAC
5ASC3STDYCNLZFEBN6UTMUCGDETHBR2OCBZCF5VIAZ5RRWLOTDYQC
SJHCL6QB52L4OCU5GT3UN7ZIRKL5NENRHOS2DU2SOG7QSVNXSZPQC
RC6L3CIBLJEH4GWRFD7UQNGI6PZT74FRUVOYHSAN2XCC74NZUASQC
XSO7MOLH5QDXYJW2NDFGNTHBEPF2QYEN5BLNOONV6I7NE4U4XFUAC
OT53X5ORPLBVG4SRIM5PTQ5ERZLZELB7ZKR6ZKDKVOD7IJR6VDOQC
AXQJOPTECRU3ECV3ICDUR6SGBIOIZT5HIOSJ77MRLF5ECGOITMDQC
AJJ6D6JRV6ZAZOAUHYUM2IQG42V6PBALOD4KEMNKSVVAOJXAUCPQC
YHSVOROKPYS33Y4RYZRVZTE3G5LXOFX52HEDNLV6HIXOJYNOKH3QC
KCHX2F3JFEWOZT3WMJVZAAQUU2QSZ5Q7RDCD7WUJ7VE65J52JFUQC
KTNZIWQ7HRC2YKQEQ5SAM3UOYJPJY5JGWKMFGALBPRDZUJSFH2YQC
R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC
Q5SFQO7ANODRI6OXKHPFQ4QWKGQ367S64DPURQW2TWK7ANTYO4NQC
JR2RAQ523LOWNDYJNK6AZVKI6WVMI622PIV72XWOVZYPXPUKSQWAC
6GJYM7D3VKAKCIHAOEZW5XPE7KIJZXJCYZYMHVJAECV5QZWGQAUAC
OUFJSYTIBMN6DSI7A77NJP5S6QDIXALXI2B6OKDPOXEQ5SCDC6MAC
6HQB2N6N75R2RGKJFWRUN7WAC2PNGWQFXTII5DTRLTHZ2BOTMTVAC
3YK4G4IQBXW63HPGU5WRTV6L2FCMKAK4DOTCHFK2FNSB5B3Y3PVQC
GSQ72ULBSL6WBJZUB3GJKAPQDXZIQV7B2TDBA5OP2WVGHVJMCQFQC
IPXXB4VRVZWOU5DKQ5ZTD37LS3QNK2R6APNZUO672YEEJT6OFAYQC
547JREUJXTZNYVGHNNAET5F5O5JYYGNTDQB6ABZNT7YX5EY64OHAC
NJDPIHOREOTAZJXOMZA5QA4TBADDWLFZ25NVAIFDQ7BUBVUWCEEAC
QKGDOYIYKE6B36ION5O2DRW65DWWPZMYNWJVH7LJJ7FPGGM2MYAQC
MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC
SH6NU4H5TG4O7CRXRHZ7MDHABZLWWXQ77NJDBHI7KCVHXHQYK46QC
KR655YT3I3U5DMN5NS3FPUGMDNT4BI56K3SFF2FNJ77C45NFKL5AC
YRY2TC3VHOYE47M23UJGUWDGF7H7WGU7WLWI4SUNM4EDNTGUPHGAC
TOKBONNNPTP2CIEHMMR4QAJZTXYETS55OGGDA6FY6NIMNDYMWJDAC
GCIZIUXO5TYROKDUYB3HAY7H7MRDTJNM7HR7DGSH7KXDIZC2LCDAC
UPJVSMMMHGRDUIJG4MZX6IBLQ4ODBF5Z3PF3RHDYTSAEOCVDZM5AC
V4WGXVERZ34B7CEINV4D3ZYEKKT2TUIUYTOX5FSOX6B26U3DPVLQC
4XGOVPFCU6KZIYHKWCHUTZY6G5S326DKBG3UREPR34Q4TSDD3TAAC
SW3RLYFNRT3IJBK6LYKHKP2J2YDU7SXQWAJZX7U6S7ICYW43OMNQC
UURAYLSSITZLQR56MCWFPIWMECU7F3USMA2UPJAO4IPIY5WVKP5QC
3JOOHBLF6D4362LD2TQGKYB5JVTNX34DD7DPXVJL5E2K2QN2EFLQC
YAAJ6PTN6QUSWE52URI5AENOGD366FIHOIFUOXFUJLVZYE4OG6HQC
TJRYL3NXPW5IUGEV3YOC7JYWEXCZDBFPLT4AUG4P227WVKVB72ZAC
NQMXQ6OQVUSC7Y7F7IL252QW4A5JED224EECNHWAM4ZZYVNY745AC
IHIJSWVOONSTA2WCHKW3YKBLETUQECFVBVLMET5SGQZ4C6U3GCUQC
EHSY6DVGUMI6C67WKET3GDJVLWJWGYBYQONNDK5JVT7BCTHBEZVAC
RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC
XPCGZBHHSL6MB3ORMUJI64BAERU6AZTIY6RK56BBW7SNB3IK24IAC
HXOYKQF6JLOELDE27O66U3Q7J6CP2YPRF42VSJD4LPTV7PZNT6PQC
#define MAP_MAGIC_MAPPED_FLAG 0x0100
#define MAP_SEEN_FLAG 0x0200
#define MAP_CHANGED_FLAG 0x0400
#define MAP_DETECTED_MONSTER 0x0800
#define MAP_DETECTED_ITEM 0x1000
#define MAP_GRID_KNOWN 0xFF00
#define MAP_CHARACTER_MASK 0x00ff
#define MAP_MAGIC_MAPPED_FLAG 0x01
#define MAP_SEEN_FLAG 0x02
#define MAP_CHANGED_FLAG 0x04
#define MAP_DETECTED_MONSTER 0x08
#define MAP_DETECTED_ITEM 0x10
#define MAP_GRID_KNOWN 0xFF
unsigned map_cell::glyph() const
{
if (!object)
return (' ');
return get_symbol(object, NULL, !(flags & MAP_SEEN_FLAG));
}
bool map_cell::known() const
{
return (object && (flags & (MAP_SEEN_FLAG | MAP_MAGIC_MAPPED_FLAG)));
}
bool map_cell::seen() const
{
return (object && (flags & MAP_SEEN_FLAG));
}
inline void set_envmap_item(int x, int y, bool isitem)
{
if (isitem)
env.map_col[x - 1][y - 1].flags |= MC_ITEM;
else
env.map_col[x - 1][y - 1].flags &= ~MC_ITEM;
}
inline void set_envmap_mons(int x, int y, bool ismons)
{
if (ismons)
env.map_col[x - 1][y - 1].flags |= MC_MONS;
else
env.map_col[x - 1][y - 1].flags &= ~MC_MONS;
}
const int colmask = *colour & COLFLAG_MASK;
// Don't clobber with BLACK, because the colour should be already set.
if (Feature[object].colour != BLACK)
*colour = Feature[object].colour | colmask;
if (colour)
{
const int colmask = *colour & COLFLAG_MASK;
// Don't clobber with BLACK, because the colour should be
// already set.
if (Feature[object].colour != BLACK)
*colour = Feature[object].colour | colmask;
}
// XXX: Yes, the map array and the grid array are off by one. -- bwr
const int grid_value = grd[x + 1][y + 1];
const int grid_value = grd[x][y];
colour = colour_code_map(c.x, c.y,
Options.item_colour,
travel_mode && Options.travel_colour);
buffer2[bufcount2 + 1] = colour;
buffer2[bufcount2] = (unsigned char) env.map(c);
buffer2[bufcount2 + 1] = colour;
buffer2[bufcount2] = env.map(c).glyph();
if (c.x + 1 == you.x_pos && c.y + 1 == you.y_pos)
{
// [dshaligram] Draw the @ symbol on the level-map. It's no
// longer saved into the env.map, so we need to draw it
// directly.
buffer2[bufcount2 + 1] = WHITE;
buffer2[bufcount2] = you.symbol;
}
if (c == you.pos())
{
// [dshaligram] Draw the @ symbol on the level-map. It's no
// longer saved into the env.map, so we need to draw it
// directly.
buffer2[bufcount2 + 1] = WHITE;
buffer2[bufcount2] = you.symbol;
}
// If we've a waypoint on the current square, *and* the
// square is a normal floor square with nothing on it,
// show the waypoint number.
if (Options.show_waypoints)
{
// XXX: This is a horrible hack.
screen_buffer_t &bc = buffer2[bufcount2];
const coord_def gridc = c + coord_def(1, 1);
unsigned char ch = is_waypoint(gridc.x, gridc.y);
if (ch && (bc == get_sightmap_char(DNGN_FLOOR) ||
bc == get_magicmap_char(DNGN_FLOOR)))
bc = ch;
// If we've a waypoint on the current square, *and* the
// square is a normal floor square with nothing on it,
// show the waypoint number.
if (Options.show_waypoints)
{
// XXX: This is a horrible hack.
screen_buffer_t &bc = buffer2[bufcount2];
unsigned char ch = is_waypoint(c.x, c.y);
if (ch && (bc == get_sightmap_char(DNGN_FLOOR) ||
bc == get_magicmap_char(DNGN_FLOOR)))
bc = ch;
}
if (is_feature('>',gx,gy))
learned_something_new(TUT_SEEN_STAIRS,gx,gy);
else if (is_feature('_',gx,gy))
learned_something_new(TUT_SEEN_ALTAR,gx,gy);
else if (grd[gx][gy] == DNGN_CLOSED_DOOR
&& see_grid( gx, gy ))
learned_something_new(TUT_SEEN_DOOR,gx,gy);
else if (grd[gx][gy] == DNGN_ENTER_SHOP
&& see_grid( gx, gy ))
learned_something_new(TUT_SEEN_SHOP,gx,gy);
if (is_feature('>', gc.x, gc.y))
learned_something_new(TUT_SEEN_STAIRS, gc.x, gc.y);
else if (is_feature('_', gc.x, gc.y))
learned_something_new(TUT_SEEN_ALTAR, gc.x, gc.y);
else if (grd(gc) == DNGN_CLOSED_DOOR
&& see_grid( gc.x, gc.y ))
learned_something_new(TUT_SEEN_DOOR, gc.x, gc.y);
else if (grd(gc) == DNGN_ENTER_SHOP
&& see_grid( gc.x, gc.y ))
learned_something_new(TUT_SEEN_SHOP, gc.x, gc.y);
const int ex = gx - you.x_pos + 9;
const int ey = gy - you.y_pos + 9;
int object = env.show[ex][ey];
unsigned short colour = env.show_col[ex][ey];
unsigned short ch;
get_symbol( gx, gy, object, &ch, &colour );
int object = env.show(ep);
unsigned short colour = env.show_col(ep);
unsigned ch;
get_symbol( gc.x, gc.y, object, &ch, &colour );
set_envmap_glyph( gx, gy, ch, colour, object );
set_terrain_seen( gx, gy );
set_envmap_detected_mons(gx, gy, false);
set_envmap_detected_item(gx, gy, false);
set_envmap_glyph( gc.x, gc.y, object, colour );
set_terrain_seen( gc.x, gc.y );
set_envmap_detected_mons(gc.x, gc.y, false);
set_envmap_detected_item(gc.x, gc.y, false);
// Note: env.show is set for grids in LoS
// get env coords
const int ex = gx - you.x_pos + 9;
const int ey = gy - you.y_pos + 9;
int object = env.show[ex][ey];
unsigned short colour = env.show_col[ex][ey];
unsigned short ch;
int object = env.show(ep);
unsigned short colour = env.show_col(ep);
unsigned ch;
set_envmap_glyph( gx, gy, ch, colour, object );
set_terrain_seen( gx, gy );
set_envmap_detected_mons(gx, gy, false);
set_envmap_detected_item(gx, gy, false);
set_envmap_glyph( gc.x, gc.y, object, colour );
set_terrain_seen( gc.x, gc.y );
set_envmap_detected_mons(gc.x, gc.y, false);
set_envmap_detected_item(gc.x, gc.y, false);
get_symbol( gx, gy,
Show_Backup[ex][ey], &ch, &colour );
set_envmap_glyph( gx, gy, ch, colour,
Show_Backup[ex][ey] );
get_symbol( gc.x, gc.y,
Show_Backup(ep), &ch, &colour );
set_envmap_glyph( gc.x, gc.y, Show_Backup(ep),
colour );
return (is_player_mapped( env.map[grid_x - 1][grid_y - 1] ));
}
// Determines whether the player has seen this square, given the user-visible
// character.
//
// The player is assumed to have seen the square if:
// a. The square is mapped (the env map char is not zero)
// b. The square was *not* magic-mapped.
//
// FIXME: There's better ways of doing this with the new view.cc.
bool is_player_mapped(unsigned char envch)
{
// Note that we're relying here on mapch(DNGN_FLOOR) != mapch2(DNGN_FLOOR)
// and that no *other* dungeon feature renders as mapch(DNGN_FLOOR).
// The check for a ~ is to ensure explore stops for items turned up by
// detect items.
return envch && envch != get_magicmap_char(DNGN_FLOOR) && envch != '~';
return (is_terrain_seen(grid_x, grid_y));
marshallShort(th, env.map[count_x][count_y]);
marshallShort(th, env.map_col[count_x][count_y].colour);
marshallShort(th, env.map_col[count_x][count_y].flags);
marshallShort(th, env.map[count_x][count_y].object);
marshallShort(th, env.map[count_x][count_y].colour);
marshallShort(th, env.map[count_x][count_y].flags);
if ((env.map[i][j] & 0xFF) == 201) // what is this??
env.map[i][j] = (env.map[i][j] & 0xFF00U) | 239;
env.map_col[i][j].colour = unmarshallShort(th);
env.map_col[i][j].flags = unmarshallShort(th);
env.map[i][j].object = unmarshallShort(th);
env.map[i][j].colour = unmarshallShort(th);
env.map[i][j].flags = unmarshallShort(th);
static unsigned oldch, oldmangledch;
static int faked_x = -1, faked_y;
#ifdef UNICODE_GLYPHS
typedef cchar_t char_info;
inline bool operator == (const cchar_t &a, const cchar_t &b)
{
return (a.attr == b.attr && *a.chars == *b.chars);
}
inline char_info character_at(int y, int x)
{
cchar_t c;
mvin_wch(y, x, &c);
return (c);
}
inline bool valid_char(const cchar_t &c)
{
return *c.chars;
}
inline void write_char_at(int y, int x, const cchar_t &ch)
{
move(y, x);
add_wchnstr(&ch, 1);
}
static void flip_colour(cchar_t &ch)
{
const unsigned colour = (ch.attr & A_COLOR);
const int pair = PAIR_NUMBER(colour);
const unsigned c = mvinch(y - 1, x - 1);
const int ch = c & A_CHARTEXT;
const unsigned colour = c & A_COLOR;
const int pair = PAIR_NUMBER(colour);
const int newpair = (fg * 8 + bg);
ch.attr = COLOR_PAIR(newpair);
}
#else // ! UNICODE_GLYPHS
typedef unsigned char_info;
#define character_at(y,x) mvinch(y,x)
#define valid_char(x) (x)
#define write_char_at(y,x,c) mvaddch(y, x, c)
faked_x = x - 1;
faked_y = y - 1;
oldch = c;
#define char_info_character(c) ((c) & A_CHARTEXT)
#define char_info_colour(c) ((c) & A_COLOR)
static void flip_colour(unsigned &ch)
{
const unsigned colour = char_info_colour(ch);
const int pair = PAIR_NUMBER(colour);
void fakecursorxy(int x, int y)
{
if (valid_char(oldch) && faked_x != -1
&& character_at(faked_y, faked_x) == oldmangledch)
{
if (faked_x != x - 1 || faked_y != y - 1)
write_char_at(faked_y, faked_x, oldch);
else
return;
}
char_info c = character_at(y - 1, x - 1);
oldch = c;
faked_x = x - 1;
faked_y = y - 1;
flip_colour(c);
write_char_at( y - 1, x - 1, oldmangledch = c);
#define VIEW_SX 1
#define VIEW_EX 33
#define VIEW_SY 1
#define VIEW_EY 17
#define VIEW_WIDTH (VIEW_EX - VIEW_SX + 1)
#define VIEW_HEIGHT (VIEW_EY - VIEW_SY + 1)
#define VIEW_Y_DIFF (((VIEW_EX - VIEW_SX + 1) - (VIEW_EY - VIEW_SY + 1)) / 2)
// View centre must be the same as LOS centre.
// VIEW_CX == 17
#define VIEW_CX ((VIEW_SX + VIEW_EX) / 2)
// VIEW_CY == 9
#define VIEW_CY ((VIEW_SY + VIEW_EY) / 2)
#define VIEW_MIN_WIDTH 33
#define VIEW_MIN_HEIGHT 17
for (i = 0; i < GXM; i++)
{
for (j = 0; j < GYM; j++)
{
env.map[i][j] = 0;
env.map_col[i][j].clear();
}
}
env.map.init(map_cell());
// Enable support for Unicode character glyphs. Note that this needs
// to be accompanied by changes to linker and compiler options and may
// not be available on all platforms. In most cases you want to set
// this option from your makefile, not directly in AppHdr.h (See
// INSTALL for more details.)
//
// #define UNICODE_GLYPHS
feature = rock wall { , , red } # shows rock walls in red
feature = metal wall {#} # use '#' for metal walls
* Colour rock walls red:
feature = rock wall { , , red }
* Use # for metal walls in all character sets:
feature = metal wall {#}
Symbols can be specified as with cset:
feature = metal wall {#}
feature = metal wall {35}
feature = metal wall {x23}
all do the same thing.
Unicode
-------
Modern Unixes may support Unicode terminals (particularly xterms). If
you have a terminal that can display Unicode characters, and an
ncurses library that can handle Unicode (libncursesw, and its devel
headers), you can build Crawl to display Unicode in the map: set
UNICODE_GLYPHS = y in makefile.unix.
NOTE: You may have libncursesw, but not have the header files; check
that you have the header files installed as well, or you'll get a lot
of errors. Crawl expects the ncursesw headers to be in
/usr/include/ncursesw.
After compiling Crawl with Unicode support, you still need to add the
line "char_set = unicode" in your .crawlrc to tell Crawl to use
Unicode.