git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3194 c06c8d41-db1a-0410-9941-cceddc491573
25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC
XKOGHLABEKWUF6G7NEX3EWCM6JX7UFUDTGFAZDRPQTW4FAHOA6WQC
4DEFHDNO2GUBYL4EGYEAR2IP3KBDXRU7UL7L4P7HEZY2UNR6IYJAC
WNQLH6VJ5DIPNQJUSUQBEKGNOZYCVWU5BYP4W6WQZBRMSR7GLUUQC
3JKKL6VSKQHBBTKEBSADZVCNXZLL4S6KN2W7G2CY5OBOMMUTIWXQC
62QFUV3PSEEXKEFGARMAYALNWY6KJVLGWGKV7JIXRBE37AMC64FQC
WL5WZXFJ6TONUQRSHUY4GQ5USU47ILWNN5X2JDQZO4CRJJZSRQIAC
ZGZVOMRXLVC42FV67RBTLBOZWFYRL4UHL54A365BR76OUIYRWQXAC
QOYITYZZM3BXITPZGSQGAVUM4T5H6ZL4QYRG5H5W7PSELOF2PO2QC
2UUCC7V3WQ5KBHJS4MTKZ5OIELYJHSTUVRPYGPWIQ5JS6D7YIK4AC
IXLNOTBJGHKESBCTME6QAR6XVWFNCHYGMS62V62ZJEA7VLQHXO2QC
YL3SLEMOESF2QDGYWH5ATHN46PODT57GQUKYHWDAV4HFC5AR6OHQC
A5H6EHZ5L5Z3BW2MIEJSDZMGTUQIJT6HSQXJVFBN5ZR55SGNNQNQC
UZ5623MOLKBTGBSRBJ4OBOEI4IEZSPV3NCV2DRMUZ3CHHJQVHIIAC
UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC
PL6I2CMSTHY5ZHWVMIQE5YTM5S5VPKBNZM6QJVHZSSKOJGIJ5W4AC
D27U7RT2C77NEUBP6JCSQJ2DRCJVHOXUO2PFZ45VFYMEVMKI4TSAC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
RC6L3CIBLJEH4GWRFD7UQNGI6PZT74FRUVOYHSAN2XCC74NZUASQC
WT66JDIRTLLP37SHTV4GI3V64JFJ4D25LNRLGCHFG6CLEFKJ3QGQC
X3RDT655FEYO6XEVPIUAPEPJZAFE55KZBH2AZOLK3NGHINMVIGFQC
EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC
ZBPZZ5A7AB2VFZKQ2UJXVDGUK22OCZJCEN2RWTGDGK3VXFCCDKVAC
ASFH3NFXSJ6AWVLIBJNTIC35HCOSHY42YQG2ELGPEYAULZUIRRRQC
TAHSTXR7ROOMDFUSBUU4ZAIEWQLAS5CIRCTARLD4Q2BGNLSL7E5QC
AJJ6D6JRV6ZAZOAUHYUM2IQG42V6PBALOD4KEMNKSVVAOJXAUCPQC
UPJVSMMMHGRDUIJG4MZX6IBLQ4ODBF5Z3PF3RHDYTSAEOCVDZM5AC
IIN7AVA6JYRBXH6ZYRR7BY7TV6PW7ANAQ2A3PD55FKBKKQFEEF2AC
FSD7GIK3YLZXWLEH37BU6KV3IUCFGXPQL6IZ7H65YWNRBEKDBX5AC
AMFTO4UE74UYQBU3R2EYUU6BJ7SC4O4NOAFICRTLMT3MIFRQ6AKAC
QZW5TK33G53OGU6YMFHW5UF25KJJTR6ATTSWXMFJ2D5FE52XRYMAC
FWVE7KM7BGEZUFQVM7H7UFGM3QMMPT7QHLNXSP62HG3SMBIPZBSQC
AUXVWXWIFSTWFA6VZXN2FMG7FQEKRZVV6MD32VQQ7J2RKCXHAVGAC
WG6O475IOLZFMUQSLVR2KHM7XTBF5HH276L2KDGF7UOSESDOAILQC
OUFJSYTIBMN6DSI7A77NJP5S6QDIXALXI2B6OKDPOXEQ5SCDC6MAC
6GJYM7D3VKAKCIHAOEZW5XPE7KIJZXJCYZYMHVJAECV5QZWGQAUAC
RCU52DRCPWJVQ6HME4QR6V6EVQWTBKZTPWDI47UGUDAUBPOO5YNAC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
5ASC3STDYCNLZFEBN6UTMUCGDETHBR2OCBZCF5VIAZ5RRWLOTDYQC
22RFWMSJGG26Z2MQEEXGKVTFSTLREHQIG46WYOTMDRKI5YVMRNVAC
4VV5V2ZLRNS6TDMQR7ZAE5INGFZAGNLJ5GXFMMX5JJWZEJSLFS7QC
SH6NU4H5TG4O7CRXRHZ7MDHABZLWWXQ77NJDBHI7KCVHXHQYK46QC
5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC
TV3ZC6WOZKSQQJQN26JIVKCHK6UK7WMDBYZDUYRWEAZ4JB4YVNAAC
YIIILIV4ZPRIPWWT4GL7YWSJCUVH6RJJLXV4XIHY6SF3H7Y3EAYAC
74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC
LIBWXPN6HLJAIGEFJYLOL4HLIUD236U3WM5QPHIZ3DSB4CCUJERAC
YWYXUCZKGNIAWAUKUESIPFCAL5HZOKOEWHUEUW7X4DMAX2HG2FSAC
SCNVGV5WCDZK5OAJBYCAGSINHGIDANF3WXQCM5JVITL2I6RWMLMAC
CIPVRZGLOZHCERK6YPOBV3P2E4IAB4H6D5EHLRQE2O5E4P4VCBUAC
2NCKGJDDPPGP2NXYYPEPVRJIIWEP6M7HE6WYMQN3UNNN3C2JIRFQC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
UB73UGG2GEG6AL4T76UILFLTELH4Z5WN54UROLJD6RDR3JG77CXAC
JYCMD6WMNHXA53K4LLKVTNX6PLRLU25F6J2TYMPQXM2ENAE66NIAC
6HQB2N6N75R2RGKJFWRUN7WAC2PNGWQFXTII5DTRLTHZ2BOTMTVAC
4XGOVPFCU6KZIYHKWCHUTZY6G5S326DKBG3UREPR34Q4TSDD3TAAC
YQ5IYBHW2ICYKOC2M6CI5BNOZKST3DIMMZRQN72LUQCHDAPVYQCQC
LAMIVDKY7LO5ONX5Z273ZCCEA5UBENOJD5VWNE4AK2EXGFED6BFQC
2GV6OW7P54FXZ5OD2NUMX7MLXH424LYAFMOAUQ2UGSOLKLYDBJGAC
OFAVQUIGMKBKXMEMRMNPHJK75RNXJVN3OYWNBKCT6EUUAG6U23DAC
JM7UAK777RAVDAVLQLEOBRTGNW2B47S5G55XITJXO243IUNZHVYQC
EEZCC5GUYHETFQV4KSZJSJ6BTTWZHKS7RXQ25XQ6ODGKLDD4XFRAC
LP3U7LC6QK6TCMLAYTRGZ2CDZAHPM6VWDT6NPE5ET4WBBZVHBDXQC
6NF5UR6BR6OBG62NDZPT3OMKYDT2MJ4AEF6QD4QUKWHNW2ZHAK2AC
ZA7XPDPN44QXOAE5UKRQKMCJCC4IOFTW24CWRFIBKNJBCS7MRR5AC
BWAQ3FHBBM6G3K3KYP75CRTR343RDQZJRYX5ZGYUEXYBAC3APDLAC
2VOD7XONHR3G2JGZGXOPHNR2AN7WUQZFR5KJH5ZY4P4G67H3RCSQC
BW3XFNOS6LDAQLHOZ6RXARCMKCY5JVLVDSXDSSAX4DSYM3FANQBAC
D77K7ISUWRLGNSQGYH5P2KEJZCNYQHDZC5AMLSKTXVBIRNG6F5KQC
3SQXLWND3FXMHEEEGTSRKNIAGQL2BDWZDSU6P7HTMCJJYQZXTY4AC
SW3RLYFNRT3IJBK6LYKHKP2J2YDU7SXQWAJZX7U6S7ICYW43OMNQC
7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC
TZ643KHSE5CUPXFSQ7VYVOCM5MTQ7F4SENEYQX2RNFHGHLQVS3RQC
HSRRNAU5UAYC6B6IQWGJPFROMZBTJICPCH6DJVZDHDTAGOQ6IOYAC
NQMXQ6OQVUSC7Y7F7IL252QW4A5JED224EECNHWAM4ZZYVNY745AC
NLSZ4SHFD6LN6AWB3HLLKQTCKQW55ZHEW3YM7XRAVAKIPD3C3Q3AC
EAQJ2VSSFA3MKDR7ELP7M5VHTHGN2DCBPPZHXRAXDRKKAX2R6SHQC
YAAJ6PTN6QUSWE52URI5AENOGD366FIHOIFUOXFUJLVZYE4OG6HQC
VD4KDTGHVKCN35AWREYB4TEOUMCTW7SAUPAMTMF5ABC7VBHVKP4AC
CRX4RG35C3DH57NIXCW4CG4X7SBMSX7TAJR2BAFQ4LQKCLYUNANQC
ESWIM76FGJL4QFLSHU6AC4D74PT7OPLQ7ZCJYWLZS5UCBAJDXYHAC
X2FMEN4E345XD26Z2X7JMJ7VGHOGCGIELMHQRE2ITLVNQACP3NOQC
Z6XF4AIERIW4U4AR3HU2ILYFZ54IK4K4ORQ6JKCEWRO5LZODWDDAC
SYXSZQICCRNKCSZ4HDO24JIE5HBVMWFWLXXM26MS3OKB37PJOAVQC
VEOWM6UDFNWRAXP5YUO7XBH4ZALAJXCWRA4IRDITXJ3QWH42CTWAC
2BTN774TDEFKS7L23YNEDQJSLSUWWKXPC5GA73ZGKLCKDHVEWSJAC
W6IY6LF3MREPXC23AAKA2BJNUCJYCSOWY55DIWJWFLUEE2Y3LGNQC
ZHFUXYUHS6V47WK2NRH7OU6RX77NRKTXOZC3MND2GG7PEEWSGFTAC
DOZORMA366M4HB5JKSS27BMCR6ET7QNZNND2B7KV3NVEEPR5H7EAC
43ZTEB57FU7KE5EVMYWZONNVJBZCGF3JEAJZIY25LC4LGE65PG5QC
QNKMXCJSGRBEPE6ZNPEXU5EQIOME6EI4DECVC56GLOBCMGWWE6MQC
YZXHBEKWQPY4BTKG5FFGLP3AIRBQSTKQVLJJHWKQEA3HTN4UHDYQC
TOKBONNNPTP2CIEHMMR4QAJZTXYETS55OGGDA6FY6NIMNDYMWJDAC
YHSVOROKPYS33Y4RYZRVZTE3G5LXOFX52HEDNLV6HIXOJYNOKH3QC
MWHMD65QP6UKXO6Q4ZVEAMXY563AJ6KH7J6UEZOB5CRPPSRB762QC
5OVWAD2MGK2NT6Q546KW7HZHELVDBBRC2CQX6VZMZF2YVRC7CPVAC
XPCGZBHHSL6MB3ORMUJI64BAERU6AZTIY6RK56BBW7SNB3IK24IAC
EHSY6DVGUMI6C67WKET3GDJVLWJWGYBYQONNDK5JVT7BCTHBEZVAC
RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC
WQU4ORZR2C52JNRTH5DN4XKNLEC4Q4SUZ7MLO6MBU6SSL2YXLSOAC
Text:DngnX=19
Text:DngnY=17
Text:MapPx=4
Text:MsgX=73
Text:MsgY=10
Text:WindowTop=54
Text:WindowLeft=121
Text:FontName=8x13
Text:FontSize=19
Tile:DngnX=19
Tile:DngnY=17
Tile:MapPx=4
Tile:MsgX=73
Tile:MsgY=10
Tile:WindowTop=40
Tile:WindowLeft=193
Tile:FontName=8x13
Tile:FontSize=16
Iso:DngnX=17
Iso:DngnY=17
Iso:MapPx=1
Iso:MsgX=40
Iso:MsgY=8
Iso:WindowTop=10
Iso:WindowLeft=73
Iso:FontName=8x16
Iso:FontSize=24
gotoxy(xcol, 3); cprintf("HP:");
gotoxy(xcol, 4); cprintf("Magic:");
gotoxy(xcol, 5); cprintf("AC:");
gotoxy(xcol, 6); cprintf("EV:");
gotoxy(xcol, 7); cprintf("Str:");
gotoxy(xcol, 8); cprintf("Int:");
gotoxy(xcol, 9); cprintf("Dex:");
gotoxy(xcol, 10); cprintf("Gold:");
gotoxy(1, 3, GOTO_STAT); cprintf("HP:");
gotoxy(1, 4, GOTO_STAT); cprintf("Magic:");
gotoxy(1, 5, GOTO_STAT); cprintf("AC:");
gotoxy(1, 6, GOTO_STAT); cprintf("EV:");
gotoxy(1, 7, GOTO_STAT); cprintf("Str:");
gotoxy(1, 8, GOTO_STAT); cprintf("Int:");
gotoxy(1, 9, GOTO_STAT); cprintf("Dex:");
gotoxy(1, 10, GOTO_STAT); cprintf("Gold:");
{
#ifdef USE_TILE
// Note: Tile versions just center on the current cursor
// location. It silently ignores everything else going
// on in this function. --Enne
unsigned int cx = start_x + curs_x - 1;
unsigned int cy = start_y + curs_y - 1;
TileDrawMap(cx, cy);
GmapDisplay(cx, cy);
}
#else
#ifdef USE_TILE
unsigned short bg = env.tile_bk_bg[gc.x][gc.y];
unsigned short fg = env.tile_bk_fg[gc.x][gc.y];
if (bg == 0 && fg == 0)
{
bg = tileidx_unseen(get_envmap_char(gc.x,gc.y), gc);
env.tile_bk_bg[gc.x][gc.y] = bg;
}
tileb[bufcount] = fg;
tileb[bufcount+1] = bg | tile_unseen_flag(gc);
#endif
#ifdef USE_TILE
// We remove any references to mcache when
// writing to the background.
if (Options.clean_map)
{
env.tile_bk_fg[gc.x][gc.y] =
get_clean_map_idx(
env.tile_fg[ep.x-1][ep.y-1]);
}
else
{
env.tile_bk_fg[gc.x][gc.y] =
get_base_idx_from_mcache(
env.tile_fg[ep.x-1][ep.y-1]);
}
env.tile_bk_bg[gc.x][gc.y] =
env.tile_bg[ep.x-1][ep.y-1];
#endif
#ifdef USE_TILE
if(env.tile_bk_fg[gc.x][gc.y] != 0
|| env.tile_bk_bg[gc.x][gc.y] != 0)
{
tileb[bufcount] =
env.tile_bk_fg[gc.x][gc.y];
tileb[bufcount + 1] =
env.tile_bk_bg[gc.x][gc.y]
| tile_unseen_flag(gc);
}
else
{
tileb[bufcount] = 0;
tileb[bufcount + 1] =
tileidx_unseen(
get_envmap_char( gc.x, gc.y ), gc);
}
#endif
#ifdef USE_TILE
#include "tiledef.h"
#include "beam.h"
//*tile1.cc: get data from core part and drives tile drawing codes
//**convert in-game data to tile index
int tileidx(unsigned int object, int extra);
int tileidx_feature(int object);
int tileidx_player(int job);
int tileidx_unseen(int ch, const coord_def& gc);
int tileidx_item(const item_def &item);
int tileidx_item_throw(const item_def &item, int dx, int dy);
int tileidx_bolt(const bolt &bolt);
int tileidx_zap(int color);
int tile_idx_unseen_terrain(int x, int y, int what);
int tile_unseen_flag(const coord_def& gc);
#define simple_iso_tile(x) (x)
// Player tile related
void tilep_race_default(int race, int gender, int level, int *parts);
void tilep_job_default(int job, int gender, int *parts);
void tilep_calc_flags(int parts[], int flag[]);
void tilep_part_to_str(int number, char *buf);
int tilep_str_to_part(char *str);
void tilep_scan_parts(char *fbuf, int *parts);
void tilep_print_parts(char *fbuf, int *parts);
int tilep_equ_weapon(const item_def &item);
int tilep_equ_shield(const item_def &item);
int tilep_equ_armour(const item_def &item);
int tilep_equ_cloak(const item_def &item);
int tilep_equ_helm(const item_def &item);
int tilep_equ_gloves(const item_def &item);
int tilep_equ_boots(const item_def &item);
// Tile display related
void tile_draw_floor();
void tile_place_monster(int gx, int gy, int idx, bool foreground = true);
void tile_place_item(int x, int y, int idx);
void tile_place_item_bk(int gx, int gy, int idx);
void tile_place_tile_bk(int gx, int gy, int tileidx);
void tile_place_item_marker(int x, int y, int idx);
void tile_place_cloud(int x, int y, int type, int decay);
void tile_place_ray(const coord_def& gc);
void tile_draw_rays(bool resetCount);
void tile_clear_buf();
void tile_finish_dngn(short unsigned int *tileb, int cx, int cy);
void tile_draw_dungeon(short unsigned int *tileb);
// Tile Inventry display
void tile_draw_inv(int item_type = -1, int flag = -1);
// Multiple pickup
void tile_pick_menu();
int get_num_wall_flavors();
int get_num_floor_flavors();
int get_num_floor_special_flavors();
int get_wall_tile_idx();
int get_floor_tile_idx();
int get_floor_special_tile_idx();
void tile_init_flavor();
/**************************************/
/* tile2.cc image manipulation */
/**************************************/
// init them all
void TileInit();
void TileResizeScreen(int x, int y);
// display tile cursor, returns old cursor value there
int TileDrawCursor(int x, int y, int flag);
// display bolts
void TileDrawBolt(int x, int y, int fg);
// display dungeon: tileb = { fg(0,0),bg(0,0),fg(1,0),bg(1,0), ..
void TileDrawDungeon(short unsigned int *tileb);
// display memorized dungeon
void TileDrawFarDungeon(int cx, int cy);
// display map centered on grid coords
void TileDrawMap(int gx, int gy);
void LoadDungeonView(short unsigned int *tileb);
void StoreDungeonView(short unsigned int *tileb);
void TileNewLevel(bool first_time);
// display inventry
void TileDrawInvData(int n, int flag, int *tiles, int *num,
int *idx, int *iflags);
void TileDrawOneItem(int region, int i, char key, int idx,
int tile, int num, bool floor,
bool select, bool equip, bool tried, bool cursed);
void TileRedrawInv(int region);
void TileClearInv(int region);
void TileMoveInvCursor(int ix);
int TileInvIdx(int i);
// refresh player tile
void TilePlayerRefresh();
// edit player tile
void TilePlayerEdit();
// init player tile
void TilePlayerInit();
// init ghost tile
void TileGhostInit(struct ghost_demon &gs);
// init pandem demon tile (only in iso mode)
void TilePandemInit(struct ghost_demon &gs);
// edit pandem tile (debug)
void TileEditPandem();
// init id-ed item tiles
void TileInitItems();
// load wall tiles
void TileLoadWall(bool wizard);
//�^�C�g��
void TileDrawTitle();
// monster+weapon tile
void TileMcacheUnlock();
int TileMcacheFind(int mon_tile, int eq_tile, int draco = 0);
int get_base_idx_from_mcache(int tile_idx);
int get_clean_map_idx(int tile_idx);
/* Flags for drawing routines */
// MAY_STAB, FLAG_STAB, and FLAG_PET are mutually exclusive
#define TILE_FLAG_MAY_STAB 0xC000 // May stab brand is always fg
#define TILE_FLAG_STAB 0x8000 // Stab brand is always fg
#define TILE_FLAG_PET 0x4000 //pet is always fg
#define TILE_FLAG_NET 0x2000 //nets are always in fg
#define TILE_FLAG_FLYING 0x1000 //flying object is always fg
#define TILE_FLAG_S_UNDER 0x800 //fg
#define TILE_FLAG_CURSOR 0xc000 //cursor is always bg
#define TILE_FLAG_CURSOR1 0x8000 //cursor is always bg
#define TILE_FLAG_CURSOR2 0x4000 //cursor is always bg
#define TILE_FLAG_CURSOR3 0xc000 //cursor is always bg
#define TILE_FLAG_CURSOR0 0x0000 //cursor is always bg
#define TILE_FLAG_UNSEEN 0x2000 //unseen flag is set to bg
#define TILE_FLAG_MM_UNSEEN 0x1000
#define TILE_FLAG_RAY 0x800
#define TILE_FLAG_MASK 0x07ff
#define TILEI_FLAG_SELECT 0x100
#define TILEI_FLAG_TRIED 0x200
#define TILEI_FLAG_EQUIP 0x400
#define TILEI_FLAG_FLOOR 0x800
#define TILEI_FLAG_CURSE 0x1000
#define TILEI_FLAG_CURSOR 0x2000
#define TILEP_GENDER_MALE 0
#define TILEP_GENDER_FEMALE 1
#define TILEP_M_DEFAULT 0
#define TILEP_M_LOADING 1
#define TILEP_SHOW_EQUIP 0x1000
enum TilePlayerFlagCut
{
TILEP_FLAG_HIDE,
TILEP_FLAG_NORMAL,
TILEP_FLAG_CUT_CENTAUR,
TILEP_FLAG_CUT_NAGA
};
#ifdef TILEP_DEBUG
const char *get_ctg_name(int part);
int get_ctg_idx(char *name);
const char *get_parts_name(int part, int idx);
int get_parts_idx(int part, char *name);
#endif
// Dungeon view window size
#define TILE_DAT_XMAX 35
#define TILE_DAT_YMAX 35
// normal tile size in px
#define TILE_X 32
#define TILE_Y 32
// Unit size
// iso mode screen size
#define TILE_XMAX_ISO 24
#define TILE_YMAX_ISO 13
// iso tile size in px
#define TILE_X_EX_ISO 64
#define TILE_Y_EX_ISO 64
// iso mode unit grid size in px
#define TILE_UX_ISO (TILE_X_EX_ISO/2)
#define TILE_UY_ISO (TILE_X_EX_ISO/2)
// screen size in grids
#define TILE_XMAX_NORMAL 17
#define TILE_YMAX_NORMAL 17
// grid size in px
#define TILE_UX_NORMAL TILE_X
#define TILE_UY_NORMAL TILE_Y
#define TILEP_BOOTS_NAGA_BARDING (N_PART_BOOTS + 1)
#define TILEP_BOOTS_CENTAUR_BARDING (N_PART_BOOTS + 2)
#endif // USE_TILES
#ifdef USE_TILE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "AppHdr.h"
#include "describe.h"
#include "direct.h"
#include "dungeon.h"
#include "files.h"
#include "guic.h"
#include "itemprop.h"
#include "it_use2.h"
#include "stuff.h"
#include "tiles.h"
#include "tilecount-w2d.h"
#include "tiledef-p.h"
#include "transfor.h"
// normal tile count + iso tile count
#define TILE_TOTAL2 (TILE_TOTAL)
// normal tile count
#define TILE_NORMAL TILE_TOTAL
extern void TileDrawDungeonAux();
// Raw tile images
extern img_type TileImg;
extern img_type TileIsoImg;
extern img_type PlayerImg;
extern img_type WallImg;
extern img_type ScrBufImg;
extern WinClass *win_main;
// Regions
extern TileRegionClass *region_tile;
extern TextRegionClass *region_crt;
extern TextRegionClass *region_stat;
extern TextRegionClass *region_tip;
extern TextRegionClass *region_msg;
extern TileRegionClass *region_item;
extern TileRegionClass *region_item2;
#define ScrBufImg (region_tile->backbuf)
//Internal
static img_type DollCacheImg;
static void tile_draw_grid(int kind, int xx, int yy);
static void clear_tcache();
static void init_tcache();
static void init_tileflag();
static void register_tile_mask(int tile, int region, int *cp,
char *ms, bool smalltile = false);
static void tcache_compose_normal(int ix, int *fg, int *bg);
#if 1 // TILE_MON_EQUIP
static void mcache_init();
#endif
//Internal variables
bool force_redraw_tile;
bool force_redraw_inv = false;
static unsigned short int t1buf[TILE_DAT_XMAX+2][TILE_DAT_YMAX+2],
t2buf[TILE_DAT_XMAX+2][TILE_DAT_YMAX+2];
static short unsigned int tb_bk[TILE_DAT_YMAX*TILE_DAT_XMAX*2];
#define MAX_ITEMLIST 200
int itemlist[MAX_ITEMLIST];
int itemlist_num[MAX_ITEMLIST];
int itemlist_idx[MAX_ITEMLIST];
char itemlist_key[MAX_ITEMLIST];
int itemlist_iflag[MAX_ITEMLIST];
int itemlist_flag = -1;
int itemlist_n=0;
static int wall_flavors = 0;
static int floor_flavors = 0;
static int special_flavors = 0;
static int wall_tile_idx = 0;
static int floor_tile_idx = 0;
static int special_tile_idx = 0;
int get_num_wall_flavors()
{
return wall_flavors;
}
int get_num_floor_flavors()
{
return floor_flavors;
}
int get_num_floor_special_flavors()
{
return special_flavors;
}
int get_wall_tile_idx()
{
return wall_tile_idx;
}
int get_floor_tile_idx()
{
return floor_tile_idx;
}
int get_floor_special_tile_idx()
{
return special_tile_idx;
}
/******** Cache buffer for transparency operation *****/
static int tcache_kind;
#if 1 // ISO
#define TCACHE_KIND_ISO 2
#define TCACHE0_ISO 0
#define TCACHE1_ISO 1
#endif
#define TCACHE_KIND_NORMAL 1
#define TCACHE0_NORMAL 0
static int last_cursor = -1;
//Internal cache Image buffer
static img_type *tcache_image;
//Start of a pointer string
static int *tcache_head;
typedef struct tile_cache
{
unsigned int id[4];
int idx;
tile_cache *next;
tile_cache *prev;
} tile_cache;
// number of tile grids
static int tile_xmax;
static int tile_ymax;
static int max_tcache;
static int tc_hash;
// [kind * tc_hash][max_tcache]
static tile_cache **tcache;
// [kind][x*y]
static int **screen_tcach_idx;
#if 1 //ISO
/*
screen grid arrangement. (x,y,kind)
(0,0,B) (1,0,A) (2,0,B)
(0,0,A) (1,0,B) (2,0,A) ...
(0,1,B) (1,1,A) (2,1,B)
(0,1,A) (1,1,B) (2,1,A)
....
*/
const int tcache_wx_iso[TCACHE_KIND_ISO] = {TILE_X_EX_ISO/2, TILE_X_EX_ISO/2};
const int tcache_wy_iso[TCACHE_KIND_ISO] = {TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/4};
const int tcache_ox_iso[TCACHE_KIND_ISO] = {0,0};
const int tcache_oy_iso[TCACHE_KIND_ISO] = {0,TILE_Y_EX_ISO/4};
const int tcache_nlayer_iso[TCACHE_KIND_ISO] = {4,4};
#endif
const int tcache_wx_normal[TCACHE_KIND_NORMAL] = {TILE_X};
const int tcache_wy_normal[TCACHE_KIND_NORMAL] = {TILE_Y};
const int tcache_ox_normal[TCACHE_KIND_NORMAL] = {0};
const int tcache_oy_normal[TCACHE_KIND_NORMAL] = {0};
const int tcache_nlayer_normal[TCACHE_KIND_NORMAL] = {1};
unsigned char tile_flag[TILE_TOTAL2];
#define TFLAG_A 0x80
#define TFLAG_B 0x40
#define TFLAG_C 0x20
#define TFLAG_D 0x10
#define TFLAG_F 0x08
#define TFLAG_G 0x04
#define TFLAG_H 0x02
#define TFLAG_I 0x01
#define tile_check_blank(tile,region) \
if( (tile_flag[tile & TILE_FLAG_MASK]&(region))==0) (tile) &= ~TILE_FLAG_MASK;
#if 1 //ISO
#define TREGION_A_ISO 0
#define TREGION_B_ISO 1
#define TREGION_C_ISO 2
#define TREGION_D_ISO 3
#define TREGION_E_ISO 4
#define TREGION_F_ISO 5
#define TREGION_G_ISO 6
#define TREGION_H_ISO 7
/*
<-64->
AAEE |
BBFF 64
CCGG |
DDHH |
*/
const int region_sx_iso[8]=
{0, 0, 0, 0,
TILE_X_EX_ISO/2, TILE_X_EX_ISO/2, TILE_X_EX_ISO/2, TILE_X_EX_ISO/2};
const int region_sy_iso[8]=
{0, TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/2, (TILE_Y_EX_ISO*3)/4,
0, TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/2, (TILE_Y_EX_ISO*3)/4};
const int region_wx_iso[8]=
{TILE_X_EX_ISO/2, TILE_X_EX_ISO/2, TILE_X_EX_ISO/2, TILE_X_EX_ISO/2,
TILE_X_EX_ISO/2, TILE_X_EX_ISO/2, TILE_X_EX_ISO/2, TILE_X_EX_ISO/2};
const int region_wy_iso[8]=
{TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/4,
TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/4, TILE_Y_EX_ISO/4};
/* 32x32 �̏ꍇ �^�C����(sx,sy)����wx*wy �̗̈��� ox,oy ���炵�ăR�s�[ */
#ifdef ISO48
//�傫��BMP��48x48 �̏ꍇ
const int region_sx_small_iso[8]=
{0, 0, 0, 0,
TILE_X/2, TILE_X/2, TILE_X/2, TILE_X/2};
const int region_sy_small_iso[8]=
{0, 2, 14, 26, 0, 2, 14, 26};
const int region_wx_small_iso[8]=
{16,16,16,16, 16,16,16,16};
const int region_wy_small_iso[8]=
{2, 12, 12, 6, 2, 12, 12, 6};
const int region_ox_small_iso[8]=
{8,8,8, 8, 0, 0, 0, 0};
const int region_oy_small_iso[8]=
{14,0,0,0, 14,0,0,0};
#else
//�傫��BMP��64x64 �̏ꍇ
const int region_sx_small_iso[8]=
{0, 0, 0, 0,
TILE_X/2, TILE_X/2, TILE_X/2, TILE_X/2};
const int region_sy_small_iso[8]=
{0, 0, 8,24, 0, 0, 8,24};
const int region_wx_small_iso[8]={0,16,16,16, 0,16,16,16};
const int region_wy_small_iso[8]={0, 8,16, 8, 0, 8,16, 8};
const int region_ox_small_iso[8]={16,16,16, 16, 0, 0, 0, 0};
const int region_oy_small_iso[8]={0,8,0,0,0,8,0,0};
#endif
#endif // ISO
#define TREGION_0_NORMAL 0
const int region_sx_normal[1]={0};
const int region_sy_normal[1]={0};
const int region_wx_normal[1]={TILE_X};
const int region_wy_normal[1]={TILE_Y};
// ISO mode sink mask
static char *sink_mask;
/* BG tile priority */
static unsigned char tile_prio[TILE_TOTAL2];
#define PRIO_WALL 10
#define tile_is_wall(tile) (tile_prio[(tile)&TILE_FLAG_MASK]==PRIO_WALL)
/********* Image manipulation subroutines ****************/
img_type ImgLoadFileSimple(const char *name)
{
char fname[512];
#ifdef USE_X11
sprintf(fname,"tiles/%s.png", name);
std::string path = datafile_path(fname, true, true);
return ImgLoadFile(path.c_str());
#endif
#ifdef WIN32TILES
sprintf(fname,"tiles/%s.bmp", name);
std::string path = datafile_path(fname, true, true);
return ImgLoadFile(path.c_str());
#endif
}
// TileImg macro
void ImgCopyFromTileImg(int idx, img_type dest, int dx, int dy, int copy,
char *mask = NULL, bool hilite = false)
{
int sx = (idx % TILE_PER_ROW)*TILE_X;
int sy = (idx / TILE_PER_ROW)*TILE_Y;
if (hilite)
{
if (mask != NULL)
ImgCopyMaskedH(TileImg, sx, sy, TILE_X, TILE_Y,
dest, dx, dy, mask);
else
ImgCopyH(TileImg, sx, sy, TILE_X, TILE_Y, dest, dx, dy, copy);
}
else
{
if (mask != NULL)
ImgCopyMasked(TileImg, sx, sy, TILE_X, TILE_Y,
dest, dx, dy, mask);
else
ImgCopy(TileImg, sx, sy, TILE_X, TILE_Y, dest, dx, dy, copy);
}
}
void ImgCopyToTileImg(int idx, img_type src, int sx, int sy, int copy,
char *mask = NULL, bool hilite = false)
{
int dx = (idx % TILE_PER_ROW)*TILE_X;
int dy = (idx / TILE_PER_ROW)*TILE_Y;
if (hilite)
{
if (mask != NULL)
ImgCopyMaskedH(src, sx, sy, TILE_X, TILE_Y,
TileImg, dx, dy, mask);
else
ImgCopyH(src, sx, sy, TILE_X, TILE_Y, TileImg, dx, dy, copy);
}
else
{
if (mask != NULL)
ImgCopyMasked(src, sx, sy, TILE_X, TILE_Y,
TileImg, dx, dy, mask);
else
ImgCopy(src, sx, sy, TILE_X, TILE_Y, TileImg, dx, dy, copy);
}
}
void TileInit()
{
int x, y, k;
textcolor(WHITE);
TileImg = ImgLoadFileSimple("tile");
PlayerImg = ImgLoadFileSimple("player");
WallImg = ImgLoadFileSimple("wall2d");
if (!TileImg)
{
cprintf("Main tile not initialized\n");
getch();
end(-1);
}
ImgSetTransparentPix(TileImg);
if (ImgWidth(TileImg)!= TILE_X * TILE_PER_ROW ||
ImgHeight(TileImg) < TILE_Y*( (TILE_TOTAL + TILE_PER_ROW -1)/TILE_PER_ROW))
{
cprintf("Main tile size invalid\n");
getch();
end(-1);
}
if (!PlayerImg)
{
cprintf("Player tile not initialized\n");
getch();
end(-1);
}
if (ImgWidth(PlayerImg)!= TILE_X * TILEP_PER_ROW)
{
cprintf("Player tile size invalid\n");
getch();
end(-1);
}
if (!WallImg)
{
cprintf("wall2d tile not initialized\n");
getch();
end(-1);
}
tcache_kind = TCACHE_KIND_NORMAL;
tc_hash = 1;
tile_xmax = tile_dngn_x;
tile_ymax = tile_dngn_y;
max_tcache = 4*tile_xmax*tile_ymax;
screen_tcach_idx = (int **)malloc(sizeof(int *) * tcache_kind);
tcache = (tile_cache **)malloc(sizeof(tile_cache *)*tcache_kind);
tcache_head = (int *)malloc(sizeof(int)*tcache_kind*tc_hash);
for(k=0;k<tcache_kind;k++)
{
screen_tcach_idx[k]= (int *)malloc(sizeof(int)* tile_xmax * tile_ymax);
tcache[k] = (tile_cache *)malloc(sizeof(tile_cache)*max_tcache);
for(x=0;x<tile_xmax * tile_ymax;x++)
screen_tcach_idx[k][x] = -1;
}
sink_mask = (char *)malloc(TILE_X*TILE_Y);
init_tileflag();
init_tcache();
DollCacheImg = ImgCreateSimple(TILE_X, TILE_Y);
for(x=0;x<TILE_DAT_XMAX+2;x++){
for(y=0;y<TILE_DAT_YMAX+2;y++){
t1buf[x][y]=0;
t2buf[x][y]=simple_iso_tile(TILE_DNGN_UNSEEN)|TILE_FLAG_UNSEEN;
}}
force_redraw_tile = false;
#if 1 // TILE_MON_EQUIP
mcache_init();
#endif
for(x=0; x<MAX_ITEMLIST;x++)
{
itemlist[x]=itemlist_num[x]=itemlist_key[x]=itemlist_idx[x]=0;
}
}
void TileResizeScreen(int x0, int y0)
{
int k, x;
tile_xmax = x0;
tile_ymax = y0;
max_tcache = 4*tile_xmax*tile_ymax;
for(k=0;k<tcache_kind;k++)
{
free(screen_tcach_idx[k]);
screen_tcach_idx[k]= (int *)malloc(sizeof(int)* tile_xmax * tile_ymax);
free(tcache[k]);
tcache[k] = (tile_cache *)malloc(sizeof(tile_cache)*max_tcache);
for(x=0;x<tile_xmax * tile_ymax;x++)
{
screen_tcach_idx[k][x] = -1;
}
}
clear_tcache();
crawl_view.viewsz.x = tile_xmax;
crawl_view.viewsz.y = tile_ymax;
crawl_view.vbuf.size(crawl_view.viewsz);
}
/*** Investigate a region of specific tile whether it contains any
picture, or it is blank ***/
int init_tileflag_aux(int tile, int xs, int ys, int wx, int wy){
int x,y, sx,sy;
img_type src=TileImg;
ASSERT(tile<TILE_TOTAL2);
sx = tile % TILE_PER_ROW;
sx *= TILE_X;
sy = tile / TILE_PER_ROW;
sy *= TILE_Y;
for(x=xs;x<xs+wx;x++){
for(y=ys;y<ys+wy;y++){
if(!ImgIsTransparentAt(src, sx+x, sy+y))
return 1;
}}
return 0;
}
void init_tileflag(){
int tile, flag;
for(tile=0;tile<TILE_TOTAL2;tile++){
flag = 0;
tile_flag[tile]=flag;
tile_prio[tile]=0;
}
for(tile=0;tile<4;tile++)
{
tile_prio[simple_iso_tile(TILE_DNGN_LAVA)+tile]=2;
tile_prio[simple_iso_tile(TILE_DNGN_SHALLOW_WATER)+tile]=2;
tile_prio[simple_iso_tile(TILE_DNGN_DEEP_WATER)+tile]=3;
}
}
void clear_tcache(){
int i, k, h;
for(k=0;k<tcache_kind;k++)
{
tile_cache *tc = tcache[k];
// Decompose pointer string tcache[k] into tc_hash segments
for (h=0; h<tc_hash;h++)
{
int i_start = (max_tcache*h)/tc_hash;
int i_end = (max_tcache*(h+1))/tc_hash -1;
tcache_head[k*tc_hash + h] = i_start;
for(i=i_start;i<=i_end;i++)
{
tc[i].id[3] = tc[i].id[2] =
tc[i].id[1] = tc[i].id[0] = 0;
tc[i].idx = i;
if (i==i_start) tc[i].prev = NULL;
else tc[i].prev = &tc[i-1];
if (i==i_end) tc[i].next = NULL;
else tc[i].next = &tc[i+1];
}
}
}
}
void init_tcache(){
int k;
clear_tcache();
tcache_image = (img_type *)malloc(sizeof(img_type)*tcache_kind);
for(k=0;k<tcache_kind;k++)
{
int wx = tcache_wx_normal[k];
int wy = tcache_wy_normal[k];
tcache_image[k] = ImgCreateSimple(wx, max_tcache*wy);
}
}
// Move a cache to the top of pointer string
// to shorten the search time
void lift_tcache(int ix, int kind, int hash){
int kind_n_hash = kind * tc_hash + hash;
int head_old=tcache_head[kind_n_hash];
tile_cache *tc = tcache[kind];
tile_cache *p = tc[ix].prev;
tile_cache *n = tc[ix].next;
ASSERT(ix<max_tcache);
ASSERT(head_old<max_tcache);
ASSERT(kind<tcache_kind);
ASSERT(hash<tc_hash);
if(ix == head_old) return;
if(p!=NULL) p->next = n;
if(n!=NULL) n->prev = p;
tcache_head[kind_n_hash] = ix;
tc[head_old].prev = &tc[ix];
tc[ix].next = &tc[head_old];
}
// Find cached image of fg+bg
// If not found, compose and cache it
static int tcache_find_id_normal(int kind, int *fg, int *bg, int *is_new)
{
unsigned int id[4];
int i;
int hash = 0; // Don't use hash
int kind_n_hash = kind*tc_hash + hash;
int nlayer = tcache_nlayer_normal[kind];
tile_cache *tc = tcache[kind];
tile_cache *tc0 = &tc[tcache_head[kind_n_hash]];
#if DEBUG
int search_count =0;
#endif
*is_new=0;
for(i=0;i<nlayer;i++) id[i]= (fg[i]<<16)+bg[i]+1;
while(1){
tile_cache *next = tc0->next;
if(tc0->id[0] == id[0]) break;
if(tc0->id[0]==0 || next == NULL)
{
//end of used cache
*is_new = 1;
tcache_compose_normal(tc0->idx, fg, bg);
for(i=0;i<nlayer;i++) tc0->id[i] = id[i];
break;
}
tc0 = next;
#if DEBUG
search_count++;
#endif
}
lift_tcache(tc0->idx, kind, hash);
#if DEBUG
//DEBUGLOG("%d\n",search_count);
#endif
return tc0->idx;
}
/*** overlay a tile onto an exsisting image with transpalency operation */
void tcache_overlay(img_type img, int idx,
int tile, int region, int *copy, char *mask)
{
int x0, y0;
int sx= region_sx_normal[region];
int sy= region_sy_normal[region];
int wx= region_wx_normal[region];
int wy= region_wy_normal[region];
int ox=0;
int oy=0;
img_type src = TileImg;
int uy=wy;
tile &= TILE_FLAG_MASK;
x0 = (tile % TILE_PER_ROW)*TILE_X;
y0 = (tile / TILE_PER_ROW)*TILE_Y;
if (mask != NULL)
{
if(*copy ==2)
ImgCopyMaskedH(src, x0 + sx, y0 + sy, wx, wy,
img, ox, oy + idx*uy, mask);
else
ImgCopyMasked(src, x0 + sx, y0 + sy, wx, wy,
img, ox, oy + idx*uy, mask);
*copy = 0;
return;
}
// Hack: hilite rim color
else if(*copy ==2)
{
*copy=0;
ImgCopyH(src, x0 + sx, y0 + sy, wx, wy,
img, ox, oy + idx*uy, *copy);
return;
} else
{
ImgCopy(src, x0 + sx, y0 + sy, wx, wy,
img, ox, oy + idx*uy, *copy);
}
*copy = 0;
}
void tcache_overlay_player(img_type img, int dx, int dy,
int part, int idx, int ymax, int *copy)
{
int xs, ys;
int tidx = tilep_parts_start[part];
int nx = tilep_parts_nx[part];
int ny = tilep_parts_ny[part];
int ox = tilep_parts_ox[part];
int oy = tilep_parts_oy[part];
int wx = TILE_X/nx;
int wy = TILE_Y/ny;
if(!idx)return;
idx--;
tidx += idx/(nx*ny);
if (oy+wy > ymax) wy -= oy + wy - ymax;
if (wy<=0) return;
xs = (tidx % TILEP_PER_ROW)*TILE_X;
ys = (tidx / TILEP_PER_ROW)*TILE_Y;
xs += (idx % nx)*(TILE_X/nx);
ys += ((idx/nx) % ny)*(TILE_Y/ny);
ImgCopy(PlayerImg, xs, ys, wx, wy,
img, dx+ox, dy+oy, *copy);
*copy = 0;
}
/** overlay a tile onto an exsisting image with transpalency operation */
void register_tile_mask(int tile, int region, int *copy,
char *mask, bool smalltile)
{
int x0, y0, x, y;
int sx= region_sx_normal[region];
int sy= region_sy_normal[region];
int wx= region_wx_normal[region];
int wy= region_wy_normal[region];
int ox=0;
int oy=0;
img_type src = TileImg;
int ux=wx;
int uy=wy;
tile &= TILE_FLAG_MASK;
x0 = (tile % TILE_PER_ROW)*TILE_X;
y0 = (tile / TILE_PER_ROW)*TILE_Y;
if (*copy!=0) memset(mask, 0, ux*uy);
if (*copy == 2)
{
if (smalltile)
{
ux = wx;
}
for(x=0;x<wx;x++){
for(y=0;y<wy;y++){
if(! ImgIsTransparentAt(src, x0+sx+x, y0+sy+y))
mask[(y+oy)*ux+(x+ox)]=1;
}}
}
else
{
for(x=0;x<wx;x+=2){
for(y=0;y<wy;y+=2){
if(! ImgIsTransparentAt(src, x0+sx+x, y0+sy+y))
mask[(y+oy)*ux+(x+ox)]=1;
}}
}
*copy = 0;
}
void tile_draw_grid(int kind, int xx, int yy){
int fg[4],bg[4],ix, ix_old, is_new;
if (xx < 0 || yy < 0 || xx >= tile_xmax || yy>= tile_ymax) return;
fg[0] = t1buf[xx+1][yy+1];
bg[0] = t2buf[xx+1][yy+1];
ix_old = screen_tcach_idx[kind][xx+yy*tile_xmax];
ix = tcache_find_id_normal(kind, fg, bg, &is_new);
screen_tcach_idx[kind][xx+yy*tile_xmax]=ix;
if(is_new || ix!=ix_old || force_redraw_tile)
{
int x_dest = tcache_ox_normal[kind]+xx* TILE_UX_NORMAL;
int y_dest = tcache_oy_normal[kind]+yy* TILE_UY_NORMAL;
int wx = tcache_wx_normal[kind];
int wy = tcache_wy_normal[kind];
ImgCopy(tcache_image[kind],
0, ix*wy, wx, wy,
ScrBufImg, x_dest, y_dest, 1);
}
}
void update_single_grid(int x, int y)
{
int sx, sy, wx, wy;
tile_draw_grid(TCACHE0_NORMAL, x, y);
sx = x*TILE_UX_NORMAL;
sy = y*TILE_UY_NORMAL;
wx = TILE_UX_NORMAL;
wy = TILE_UY_NORMAL;
region_tile->redraw(sx, sy, sx+wx-1, sy+wy-1);
}
// Discard cache containing specific tile
void redraw_spx_tcache(int tile)
{
int kind, idx, layer, redraw;
int fg[4], bg[4];
for(kind = 0; kind < tcache_kind; kind++)
{
int nlayer = tcache_nlayer_normal[kind];
for(idx = 0; idx < max_tcache; idx++)
{
redraw = 0;
for(layer = 0; layer < nlayer; layer++)
{
fg[layer] = (tcache[kind][idx].id[layer]-1)>>16;
bg[layer] = (tcache[kind][idx].id[layer]-1)&0xffff;
if((fg[layer]&TILE_FLAG_MASK) == tile) redraw = 1;
if((bg[layer]&TILE_FLAG_MASK) == tile) redraw = 1;
}
if (redraw)
{
tcache_compose_normal(idx, fg, bg);
}
}
}
}
void get_bbg(int bg, int *new_bg, int *bbg)
{
int bg0 = bg & TILE_FLAG_MASK;
*bbg=simple_iso_tile(TILE_DNGN_FLOOR);
*new_bg= bg0;
if(bg0 == TILE_DNGN_UNSEEN ||
(bg0 >= TILE_DNGN_ROCK_WALL_OFS && bg0 < TILE_DNGN_WAX_WALL) ||
bg0 == 0)
*bbg = 0;
else
if( bg0 >= TILE_DNGN_FLOOR && bg0 <= TILE_DNGN_SHALLOW_WATER)
{
*bbg = bg;
*new_bg = 0;
}
}
int sink_mask_tile(int bg, int fg)
{
int bg0 = bg & TILE_FLAG_MASK;
if (fg == 0 || (fg & TILE_FLAG_FLYING)!=0) return 0;
/*
if ( bg0 == simple_iso_tile(TILE_DNGN_SHALLOW_WATER))
return TILE_MASK_SHALLOW_WATER;
if ( bg0 == simple_iso_tile(TILE_DNGN_DEEP_WATER))
return TILE_MASK_DEEP_WATER;
if ( bg0 >= simple_iso_tile(TILE_DNGN_LAVA) &&
bg0 <= simple_iso_tile(TILE_DNGN_LAVA)+3)
return TILE_MASK_LAVA;
*/
if ( bg0 >= simple_iso_tile(TILE_DNGN_LAVA) &&
bg0 <= simple_iso_tile(TILE_DNGN_SHALLOW_WATER) + 3)
{
int result = TILE_SINK_MASK;//simple_iso_tile(TILE_SINK_MASK);
if ((fg & TILE_FLAG_MASK) >= TILE_NORMAL)
result = simple_iso_tile(TILE_SINK_MASK);
//if ((fg & TILE_FLAG_MASK) >= TILE_NORMAL) result++;
return result;
}
return 0;
}
//normal
void tcache_compose_normal(int ix, int *fg, int *bg){
int bbg;
int new_bg;
int c=1;
int fg0=fg[0];
int bg0=bg[0];
int sink;
img_type tc_img = tcache_image[TCACHE0_NORMAL];
get_bbg(bg0, &new_bg, &bbg);
if(bbg) tcache_overlay(tc_img, ix, bbg, TREGION_0_NORMAL, &c, NULL);
if(new_bg) tcache_overlay(tc_img, ix, new_bg, TREGION_0_NORMAL, &c, NULL);
//Tile cursor
if(bg0&TILE_FLAG_CURSOR)
{
int type = ((bg0&TILE_FLAG_CURSOR) == TILE_FLAG_CURSOR1) ?
TILE_CURSOR : TILE_CURSOR2;
if ((bg0&TILE_FLAG_CURSOR) == TILE_FLAG_CURSOR3) type = TILE_CURSOR3;
tcache_overlay(tc_img, ix, type, TREGION_0_NORMAL, &c, NULL);
if (type != TILE_CURSOR3) c = 2;// Hilite
}
if (bg0 & TILE_FLAG_RAY)
tcache_overlay(tc_img, ix, TILE_RAY_MESH, TREGION_0_NORMAL, &c, NULL);
if(fg0)
{
sink = sink_mask_tile(bg0, fg0);
if (sink)
{
int flag=2;
register_tile_mask(sink, TREGION_0_NORMAL, &flag, sink_mask);
tcache_overlay(tc_img, ix, fg0, TREGION_0_NORMAL, &c, sink_mask);
}
else
tcache_overlay(tc_img, ix, fg0, TREGION_0_NORMAL, &c, NULL);
}
if (fg0 & TILE_FLAG_NET)
tcache_overlay(tc_img, ix, TILE_TRAP_NET, TREGION_0_NORMAL, &c, NULL);
if(fg0 & TILE_FLAG_S_UNDER)
tcache_overlay(tc_img, ix, TILE_SOMETHING_UNDER,
TREGION_0_NORMAL, &c, NULL);
//Pet mark
if((fg0&TILE_FLAG_MAY_STAB) == TILE_FLAG_PET)
tcache_overlay(tc_img, ix, TILE_HEART, TREGION_0_NORMAL, &c, NULL);
if((fg0&TILE_FLAG_MAY_STAB) == TILE_FLAG_STAB)
tcache_overlay(tc_img, ix, TILE_STAB_BRAND, TREGION_0_NORMAL, &c, NULL);
else if((fg0&TILE_FLAG_MAY_STAB) == TILE_FLAG_MAY_STAB)
tcache_overlay(tc_img, ix, TILE_MAY_STAB_BRAND, TREGION_0_NORMAL, &c,
NULL);
if(bg0&TILE_FLAG_UNSEEN)
tcache_overlay(tc_img, ix, TILE_MESH, TREGION_0_NORMAL, &c, NULL);
if(bg0&TILE_FLAG_MM_UNSEEN)
tcache_overlay(tc_img, ix, TILE_MAGIC_MAP_MESH, TREGION_0_NORMAL, &c, NULL);
}
// Tile cursor
int TileDrawCursor(int x, int y, int cflag)
{
int oldc = t2buf[x+1][y+1] & TILE_FLAG_CURSOR;
t2buf[x+1][y+1] &= ~ TILE_FLAG_CURSOR;
t2buf[x+1][y+1] |= cflag;
update_single_grid(x, y);
return oldc;
}
void TileDrawBolt(int x, int y, int fg){
t1buf[x+1][y+1]=fg | TILE_FLAG_FLYING;
update_single_grid(x, y);
}
void StoreDungeonView(short unsigned int *tileb)
{
int x, y;
int count = 0;
if (tileb == NULL)
tileb = tb_bk;
for(y=0;y<tile_dngn_y;y++){
for(x=0;x<tile_dngn_x;x++){
tileb[count] = t1buf[x+1][y+1];
count ++;
tileb[count] = t2buf[x+1][y+1];
count ++;
}}
}
void LoadDungeonView(short unsigned int *tileb)
{
int x, y;
int count = 0;
if (tileb == NULL)
tileb = tb_bk;
for(y=0;y<tile_dngn_y;y++)
{
for(x=0;x<tile_dngn_x;x++)
{
if(tileb[count]==tileb[count+1])
tileb[count]=0;
t1buf[x+1][y+1] = tileb[count];
count ++;
t2buf[x+1][y+1] = tileb[count];
count ++;
}
}
}
//Draw the tile screen once and for all
void TileDrawDungeon(short unsigned int *tileb)
{
int x, y, kind;
if(!TileImg)return;
LoadDungeonView(tileb);
extern int tile_cursor_x;
tile_cursor_x = -1;
for(kind=0;kind<tcache_kind;kind++)
{
for(x=0;x<tile_xmax;x++)
{
for(y=0;y<tile_ymax;y++)
{
tile_draw_grid(kind, x, y);
}
}
}
force_redraw_tile = false;
TileDrawDungeonAux();
region_tile->redraw();
}
void TileDrawFarDungeon(int cx, int cy)
{
short unsigned int tb[TILE_DAT_YMAX*TILE_DAT_XMAX*2];
int count = 0;
for(int y=0; y<tile_dngn_y; y++)
{
for(int x=0; x<tile_dngn_x; x++)
{
int fg;
int bg;
const coord_def gc(
cx + x - tile_dngn_x/2,
cy + y - tile_dngn_y/2 );
const coord_def ep = view2show(grid2view(gc));
// mini "viewwindow" routine
if (!map_bounds(gc))
{
fg = 0;
bg = TILE_DNGN_UNSEEN;
}
else if (!crawl_view.in_grid_los(gc) || !env.show(ep))
{
fg = env.tile_bk_fg[gc.x][gc.y];
bg = env.tile_bk_bg[gc.x][gc.y];
if (bg == 0)
bg |= TILE_DNGN_UNSEEN;
bg |= tile_unseen_flag(gc);
}
else
{
fg = env.tile_fg[ep.x-1][ep.y-1];
bg = env.tile_bg[ep.x-1][ep.y-1];
}
if (gc.x == cx && gc.y == cy)
bg |= TILE_FLAG_CURSOR1;
tb[count++]=fg;
tb[count++]=bg;
}
}
tile_finish_dngn(tb, cx, cy);
TileDrawDungeon(tb);
region_tile->redraw();
}
void TileDrawMap(int gx, int gy)
{
TileDrawFarDungeon(gx, gy);
}
// Load optional wall tile
static void TileLoadWallAux(int idx_src, int idx_dst, img_type wall)
{
int tile_per_row = ImgWidth(wall) / TILE_X;
int sx = idx_src % tile_per_row;
int sy = idx_src / tile_per_row;
sx *= TILE_X;
sy *= TILE_Y;
ImgCopyToTileImg(idx_dst, wall, sx, sy, 1);
}
void WallIdx(int &wall, int &floor, int &special)
{
special = -1;
if (you.level_type == LEVEL_PANDEMONIUM)
{
switch (mcolour[env.mons_alloc[8]])
{
case BLUE:
case LIGHTBLUE:
wall = IDX_WALL_ZOT_BLUE;
floor = IDX_FLOOR_ZOT_BLUE;
return;
case RED:
case LIGHTRED:
wall = IDX_WALL_ZOT_RED;
floor = IDX_FLOOR_ZOT_RED;
return;
case MAGENTA:
case LIGHTMAGENTA:
wall = IDX_WALL_ZOT_MAGENTA;
floor = IDX_FLOOR_ZOT_MAGENTA;
return;
case GREEN:
case LIGHTGREEN:
wall = IDX_WALL_ZOT_GREEN;
floor = IDX_FLOOR_ZOT_GREEN;
return;
case CYAN:
case LIGHTCYAN:
wall = IDX_WALL_ZOT_CYAN;
floor = IDX_FLOOR_ZOT_CYAN;
return;
case BROWN:
case YELLOW:
wall = IDX_WALL_ZOT_YELLOW;
floor = IDX_FLOOR_ZOT_YELLOW;
return;
case BLACK:
case WHITE:
default:
wall = IDX_WALL_ZOT_GRAY;
floor = IDX_FLOOR_ZOT_GRAY;
return;
}
}
else if (you.level_type == LEVEL_ABYSS)
{
wall = IDX_WALL_UNDEAD;
floor = IDX_FLOOR_UNDEAD;
return;
}
else if (you.level_type == LEVEL_LABYRINTH)
{
wall = IDX_WALL_UNDEAD;
floor = IDX_FLOOR_UNDEAD;
return;
}
else if (you.level_type == LEVEL_PORTAL_VAULT)
{
if (you.level_type_name == "bazaar")
{
// Bazaar tiles here lean towards grass and dirt to emphasize
// both the non-hostile and other-wordly aspects of the
// portal vaults (i.e. they aren't in the dungeon, necessarily.)
int colour = env.floor_colour;
switch (colour)
{
case BLUE:
wall = IDX_WALL_BAZAAR_GRAY;
floor = IDX_FLOOR_BAZAAR_GRASS;
special = IDX_FLOOR_BAZAAR_GRASS1_SPECIAL;
return;
case RED:
// Reds often have lava, which looks ridiculous
// next to grass or dirt, so we'll use existing
// floor and wall tiles here.
wall = IDX_WALL_ZOT_RED;
floor = IDX_FLOOR_VAULT;
special = IDX_FLOOR_BAZAAR_VAULT_SPECIAL;
return;
case LIGHTBLUE:
wall = IDX_WALL_HIVE;
floor = IDX_FLOOR_BAZAAR_GRASS;
special = IDX_FLOOR_BAZAAR_GRASS2_SPECIAL;
return;
case GREEN:
wall = IDX_WALL_BAZAAR_STONE;
floor = IDX_FLOOR_BAZAAR_GRASS;
special = IDX_FLOOR_BAZAAR_GRASS1_SPECIAL;
return;
case MAGENTA:
wall = IDX_WALL_BAZAAR_STONE;
floor = IDX_FLOOR_BAZAAR_DIRT;
special = IDX_FLOOR_BAZAAR_DIRT_SPECIAL;
return;
default:
wall = IDX_WALL_VAULT;
floor = IDX_FLOOR_VAULT;
special = IDX_FLOOR_BAZAAR_VAULT_SPECIAL;
return;
}
}
}
switch (you.where_are_you)
{
case BRANCH_MAIN_DUNGEON:
wall = IDX_WALL_NORMAL;
floor = IDX_FLOOR_NORMAL;
return;
case BRANCH_HIVE:
wall = IDX_WALL_HIVE;
floor = IDX_FLOOR_HIVE;
return;
case BRANCH_VAULTS:
wall = IDX_WALL_VAULT;
floor = IDX_FLOOR_VAULT;
return;
case BRANCH_ELVEN_HALLS:
case BRANCH_HALL_OF_BLADES:
case BRANCH_ECUMENICAL_TEMPLE:
wall = IDX_WALL_HALL;
floor = IDX_FLOOR_HALL;
return;
case BRANCH_TARTARUS:
case BRANCH_CRYPT:
case BRANCH_VESTIBULE_OF_HELL:
wall = IDX_WALL_UNDEAD;
floor = IDX_FLOOR_UNDEAD;
return;
case BRANCH_TOMB:
wall = IDX_WALL_TOMB;
floor = IDX_FLOOR_TOMB;
return;
case BRANCH_DIS:
wall = IDX_WALL_ZOT_CYAN;
floor = IDX_FLOOR_ZOT_CYAN;
return;
case BRANCH_GEHENNA:
case BRANCH_INFERNO:
case BRANCH_THE_PIT:
wall = IDX_WALL_ZOT_RED;
floor = IDX_FLOOR_ZOT_RED;
return;
case BRANCH_COCYTUS:
wall = IDX_WALL_ICE;
floor = IDX_FLOOR_ICE;
return;
case BRANCH_ORCISH_MINES:
wall = IDX_WALL_ORC;
floor = IDX_FLOOR_ORC;
return;
case BRANCH_LAIR:
wall = IDX_WALL_LAIR;
floor = IDX_FLOOR_LAIR;
return;
case BRANCH_SLIME_PITS:
wall = IDX_WALL_SLIME;
floor = IDX_FLOOR_SLIME;
return;
case BRANCH_SNAKE_PIT:
wall = IDX_WALL_SNAKE;
floor = IDX_FLOOR_SNAKE;
return;
case BRANCH_SWAMP:
wall = IDX_WALL_SWAMP;
floor = IDX_FLOOR_SWAMP;
return;
case BRANCH_SHOALS:
wall = IDX_WALL_SWAMP;
floor = IDX_FLOOR_SWAMP;
return;
case BRANCH_CAVERNS:
wall = IDX_WALL_ORC;
floor = IDX_FLOOR_ORC;
return;
case BRANCH_HALL_OF_ZOT:
if (you.your_level - you.branch_stairs[7] <= 1)
{
wall = IDX_WALL_ZOT_YELLOW;
floor = IDX_FLOOR_ZOT_YELLOW;
return;
}
switch (you.your_level - you.branch_stairs[7])
{
case 2:
wall = IDX_WALL_ZOT_GREEN;
floor = IDX_FLOOR_ZOT_GREEN;
return;
case 3:
wall = IDX_WALL_ZOT_CYAN;
floor = IDX_WALL_ZOT_CYAN;
return;
case 4:
wall = IDX_WALL_ZOT_BLUE;
floor = IDX_FLOOR_ZOT_GREEN;
return;
case 5:
default:
wall = IDX_WALL_ZOT_MAGENTA;
floor = IDX_FLOOR_ZOT_MAGENTA;
return;
}
case NUM_BRANCHES:
break;
// NOTE: there is no default case in this switch statement so that
// the compiler will issue a warning when new branches are created.
}
wall = IDX_WALL_NORMAL;
floor = IDX_FLOOR_NORMAL;
}
void TileLoadWall(bool wizard)
{
clear_tcache();
force_redraw_tile = true;
int wall_idx;
int floor_idx;
int special_idx;
WallIdx(wall_idx, floor_idx, special_idx);
// Number of flavors are generated automatically...
floor_tile_idx = TILE_DNGN_FLOOR;
floor_flavors = tile_W2D_count[floor_idx];
int offset = floor_tile_idx;
for (int i = 0; i < floor_flavors; i++)
{
int idx_src = tile_W2D_start[floor_idx] + i;
int idx_dst = offset++;
TileLoadWallAux(idx_src, idx_dst, WallImg);
}
wall_tile_idx = offset;
wall_flavors = tile_W2D_count[wall_idx];
for (int i = 0; i < wall_flavors; i++)
{
int idx_src = tile_W2D_start[wall_idx] + i;
int idx_dst = offset++;
TileLoadWallAux(idx_src, idx_dst, WallImg);
}
if (special_idx != -1)
{
special_tile_idx = offset;
special_flavors = tile_W2D_count[special_idx];
for (int i = 0; i < special_flavors; i++)
{
int idx_src = tile_W2D_start[special_idx] + i;
int idx_dst = offset++;
TileLoadWallAux(idx_src, idx_dst, WallImg);
}
}
else
{
special_flavors = 0;
}
}
#define DOLLS_MAX 11
#define PARTS_DISP_MAX 11
#define PARTS_ITEMS 12
#define TILEP_SELECT_DOLL 20
typedef struct dolls_data
{
int parts[TILEP_PARTS_TOTAL];
} dolls_data;
static dolls_data current_doll;
static int current_gender = 0;
static int current_parts[TILEP_PARTS_TOTAL];
static bool draw_doll(img_type img, dolls_data *doll, bool force_redraw = false, bool your_doll = true)
{
const int p_order[TILEP_PARTS_TOTAL]=
{
TILEP_PART_SHADOW,
TILEP_PART_DRCWING,
TILEP_PART_CLOAK,
TILEP_PART_BASE,
TILEP_PART_BOOTS,
TILEP_PART_LEG,
TILEP_PART_BODY,
TILEP_PART_ARM,
TILEP_PART_HAND1,
TILEP_PART_HAND2,
TILEP_PART_HAIR,
TILEP_PART_BEARD,
TILEP_PART_HELM,
TILEP_PART_DRCHEAD
};
int p_order2[TILEP_PARTS_TOTAL];
int i;
int flags[TILEP_PARTS_TOTAL];
int parts2[TILEP_PARTS_TOTAL];
int *parts = doll->parts;
int c=1;
bool changed = false;
int default_parts[TILEP_PARTS_TOTAL];
memset(default_parts, 0, sizeof(default_parts));
if (your_doll)
{
tilep_race_default(you.species, parts[TILEP_PART_BASE] % 2,
you.experience_level, default_parts);
if (default_parts[TILEP_PART_BASE] != parts[TILEP_PART_BASE])
force_redraw = true;
parts[TILEP_PART_BASE] = default_parts[TILEP_PART_BASE];
// TODO enne - make these configurable.
parts[TILEP_PART_DRCHEAD] = default_parts[TILEP_PART_DRCHEAD];
parts[TILEP_PART_DRCWING] = default_parts[TILEP_PART_DRCWING];
}
// convert TILEP_SHOW_EQUIP into real parts number
for(i = 0; i < TILEP_PARTS_TOTAL; i++)
{
parts2[i] = parts[i];
if (parts2[i] == TILEP_SHOW_EQUIP)
{
switch (i)
{
int item;
case TILEP_PART_HAND1:
item = you.equip[EQ_WEAPON];
if (you.attribute[ATTR_TRANSFORMATION] ==
TRAN_BLADE_HANDS)
{
parts2[i] = TILEP_HAND1_BLADEHAND;
}
else if (item == -1)
{
parts2[i] = 0;
}
else
{
parts2[i] = tilep_equ_weapon(you.inv[item]);
}
break;
case TILEP_PART_HAND2:
item = you.equip[EQ_SHIELD];
if (you.attribute[ATTR_TRANSFORMATION] ==
TRAN_BLADE_HANDS)
{
parts2[i] = TILEP_HAND2_BLADEHAND;
}
else if (item == -1)
{
parts2[i] = 0;
}
else
{
parts2[i] = tilep_equ_shield(you.inv[item]);
}
break;
case TILEP_PART_BODY:
item = you.equip[EQ_BODY_ARMOUR];
if (item == -1)
parts2[i] = 0;
else
parts2[i] = tilep_equ_armour(you.inv[item]);
break;
case TILEP_PART_CLOAK:
item = you.equip[EQ_CLOAK];
if (item == -1)
parts2[i] = 0;
else
parts2[i] = tilep_equ_cloak(you.inv[item]);
break;
case TILEP_PART_HELM:
item = you.equip[EQ_HELMET];
if (item == -1)
parts2[i] = 0;
else
parts2[i] = tilep_equ_helm(you.inv[item]);
if (parts2[i] == 0 && you.mutation[MUT_HORNS] > 0)
{
switch (you.mutation[MUT_HORNS])
{
case 1:
parts2[i] = TILEP_HELM_HORNS1;
break;
case 2:
parts2[i] = TILEP_HELM_HORNS2;
break;
case 3:
parts2[i] = TILEP_HELM_HORNS3;
break;
}
}
break;
case TILEP_PART_BOOTS:
item = you.equip[EQ_BOOTS];
if (item == -1)
parts2[i] = 0;
else
parts2[i] = tilep_equ_boots(you.inv[item]);
if (parts2[i] == 0 && you.mutation[MUT_HOOVES])
parts2[i] = TILEP_BOOTS_HOOVES;
break;
case TILEP_PART_ARM:
item = you.equip[EQ_GLOVES];
if (item == -1)
parts2[i] = 0;
else
parts2[i] = tilep_equ_gloves(you.inv[item]);
// There is player_has_claws() but it is not equivalent.
// Claws appear if they're big enough to not wear gloves
// or on races that have claws.
if (parts2[i] == 0 && (you.mutation[MUT_CLAWS] >= 3 ||
you.species == SP_TROLL || you.species == SP_GHOUL))
{
parts2[i] = TILEP_ARM_CLAWS;
}
break;
case TILEP_PART_HAIR:
case TILEP_PART_BEARD:
parts2[i] = default_parts[i];
break;
case TILEP_PART_LEG:
default:
parts2[i] = 0;
}
}
if (parts2[i] != current_parts[i])
changed = true;
current_parts[i] = parts2[i];
}
if (!changed && !force_redraw)
{
return false;
}
tilep_calc_flags(parts2, flags);
ImgClear(img);
// Hack: change overlay order of boots/skirts
for(i = 0; i < TILEP_PARTS_TOTAL; i++)
p_order2[i]=p_order[i];
// swap boot and leg-armor
if (parts2[TILEP_PART_LEG] < TILEP_LEG_SKIRT_OFS)
{
p_order2[5] = TILEP_PART_LEG;
p_order2[4] = TILEP_PART_BOOTS;
}
for(i = 0; i < TILEP_PARTS_TOTAL; i++)
{
int p = p_order2[i];
int ymax = TILE_Y;
if (flags[p]==TILEP_FLAG_CUT_CENTAUR) ymax=18;
if (flags[p]==TILEP_FLAG_CUT_NAGA) ymax=18;
if (parts2[p] && p == TILEP_PART_BOOTS &&
(parts2[p] == TILEP_BOOTS_NAGA_BARDING ||
parts2[p] == TILEP_BOOTS_CENTAUR_BARDING))
{
// Special case for barding. They should be in "boots" but because
// they're double-wide, they're stored in a different part. We just
// intercept it here before drawing.
char tile = parts2[p] == TILEP_BOOTS_NAGA_BARDING ?
TILEP_SHADOW_NAGA_BARDING : TILEP_SHADOW_CENTAUR_BARDING;
tcache_overlay_player(img, 0, 0, TILEP_PART_SHADOW, tile,
TILE_Y, &c);
}
else if(parts2[p] && flags[p])
{
tcache_overlay_player(img, 0, 0, p, parts2[p], ymax, &c);
}
}
return true;
}
static void load_doll_data(const char *fn, dolls_data *dolls, int max,
int *mode, int *cur)
{
char fbuf[1024];
int cur0 = 0;
int mode0 = TILEP_M_DEFAULT;
FILE *fp = NULL;
std::string dollsTxtString = datafile_path(fn, false, true);
const char *dollsTxt = dollsTxtString.c_str()[0] == 0 ?
"dolls.txt" : dollsTxtString.c_str();
if ( (fp = fopen(dollsTxt, "r")) == NULL )
{
// File doesn't exist. By default, use show equipment defaults.
// This will be saved out (if possible.)
for (int i = 0; i < max; i++)
{
// Don't take gender too seriously. -- Enne
tilep_race_default(you.species, coinflip() ? 1 : 0,
you.experience_level, dolls[i].parts);
dolls[i].parts[TILEP_PART_SHADOW] = 1;
dolls[i].parts[TILEP_PART_CLOAK] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_BOOTS] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_LEG] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_BODY] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_ARM] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_HAIR] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_BEARD] = TILEP_SHOW_EQUIP;
dolls[i].parts[TILEP_PART_HELM] = TILEP_SHOW_EQUIP;
}
}
else
{
memset(fbuf, 0, sizeof(fbuf));
if (fscanf(fp, "%s", fbuf) != EOF)
{
if (strcmp(fbuf, "MODE=LOADING") == 0)
mode0 = TILEP_M_LOADING;
}
if (fscanf(fp, "%s", fbuf) != EOF)
{
if (strncmp(fbuf, "NUM=", 4) == 0)
{
sscanf(fbuf, "NUM=%d",&cur0);
if ( (cur0 < 0)||(cur0 > 10) )
cur0 = 0;
}
}
if (max == 1)
{
for(int j = 0; j <= cur0; j++)
{
if (fscanf(fp, "%s", fbuf) != EOF)
{
tilep_scan_parts(fbuf, dolls[0].parts);
}
else
{
break;
}
}
}
else
{
for(int j = 0; j < max; j++)
{
if (fscanf(fp, "%s", fbuf) != EOF)
{
tilep_scan_parts(fbuf, dolls[j].parts);
}
else
{
break;
}
}
}
fclose(fp);
}
*mode = mode0;
*cur = cur0;
current_gender = dolls[cur0].parts[TILEP_PART_BASE] % 2;
}
void TilePlayerEdit()
{
const int p_lines[PARTS_ITEMS]=
{
TILEP_SELECT_DOLL,
TILEP_PART_BASE,
TILEP_PART_HELM,
TILEP_PART_HAIR,
TILEP_PART_BEARD,
TILEP_PART_HAND1,
TILEP_PART_HAND2,
TILEP_PART_ARM,
TILEP_PART_BODY,
TILEP_PART_LEG,
TILEP_PART_BOOTS,
TILEP_PART_CLOAK
};
const char *p_names[PARTS_ITEMS]=
{
" Index:",
" Gendr:",
" Helm :",
" Hair :",
" Beard:",
" Weapn:",
" Shild:",
" Glove:",
" Armor:",
" Legs :",
" Boots:",
" Cloak:"
};
const char *gender_name[2] ={
"Male",
"Fem "
};
#define display_parts_idx(part) \
{ \
gotoxy(10 , part + 1, GOTO_STAT); \
tilep_part_to_str(dolls[cur_doll].parts[ p_lines[part] ], ibuf);\
cprintf(ibuf);\
}
dolls_data dolls[DOLLS_MAX], undo_dolls[DOLLS_MAX];
int copy_doll[TILEP_PARTS_TOTAL];
//int parts[TILEP_PARTS_TOTAL];
int i, j, k, x, y, kin, done = 0;
int cur_doll = 0;
int pre_part = 0;
int cur_part = 0;
int mode = TILEP_M_DEFAULT;
int d = 0;
FILE *fp;
char fbuf[80], ibuf[8];
int tile_str, sx, sy;
img_type PartsImg = ImgCreateSimple(TILE_X * PARTS_DISP_MAX, TILE_Y * 1);
img_type DollsListImg = ImgCreateSimple( TILE_X * DOLLS_MAX, TILE_Y * 1);
ImgClear(ScrBufImg);
memset( copy_doll, 0, sizeof(dolls_data) );
tilep_race_default(you.species, current_gender,
you.experience_level, copy_doll);
for(j = 0; j < DOLLS_MAX; j++)
{
memset( dolls[j].parts, 0, sizeof(dolls_data) );
memset( undo_dolls[j].parts, 0, sizeof(dolls_data) );
tilep_race_default(you.species, current_gender, you.experience_level,
dolls[j].parts);
tilep_race_default(you.species, current_gender, you.experience_level,
undo_dolls[j].parts);
}
// load settings
load_doll_data("dolls.txt", dolls, DOLLS_MAX, &mode, &cur_doll);
for(j = 0; j < DOLLS_MAX; j++)
{
undo_dolls[j] = dolls[j];
}
clrscr();
gotoxy(1,1, GOTO_MSG);
mpr("Select Part : [j][k]or[up][down]");
mpr("Change Part/Page : [h][l]or[left][right]/[H][L]");
mpr("Class-Default : [CTRL]+[D]");
mpr("Toggle Equipment Mode : [*]");
mpr("Take off/Take off All : [t]/[CTRL]+[T]");
mpr("Copy/Paste/Undo : [CTRL]+[C]/[CTRL]+[V]/[CTRL]+[Z]");
mpr("Randomize : [CTRL]+[R]");
gotoxy(1, 8, GOTO_MSG);
cprintf("Toggle Startup mode : [m] (Current mode:%s)",
( (mode == TILEP_M_LOADING) ? "Load User's Settings":"Class Default" ));
for (j=0; j < PARTS_ITEMS; j++)
{
gotoxy(1, 1+j, GOTO_STAT);
cprintf(p_names[j]);
}
#define PARTS_Y (TILE_Y*11)
// draw strings "Dolls/Parts" into backbuffer
tile_str = TILE_TEXT_PARTS_E;
sx = (tile_str % TILE_PER_ROW)*TILE_X;
sy = (tile_str / TILE_PER_ROW)*TILE_Y;
ImgCopy(TileImg, sx, sy, TILE_X, TILE_Y/2,
ScrBufImg, (TILE_X * 3) - 8,(TILE_Y * 4) - 8-24, 0);
ImgCopy(TileImg, sx, sy+ TILE_Y/2, TILE_X, TILE_Y/2,
ScrBufImg, (TILE_X * 4) - 8,(TILE_Y * 4) - 8-24, 0);
tile_str = TILE_TEXT_DOLLS_E;
sx = (tile_str % TILE_PER_ROW)*TILE_X;
sy = (tile_str / TILE_PER_ROW)*TILE_Y;
ImgCopy(TileImg, sx, sy, TILE_X, TILE_Y/2,
ScrBufImg, (TILE_X * 3) - 8,PARTS_Y - 8 -24, 0);
ImgCopy(TileImg, sx, sy+ TILE_Y/2, TILE_X, TILE_Y/2,
ScrBufImg, (TILE_X * 4) - 8,PARTS_Y - 8 -24, 0);
ImgClear(DollsListImg);
for(j = 0; j < DOLLS_MAX; j++)
{
draw_doll(DollCacheImg, &dolls[j], true);
ImgCopy(DollCacheImg, 0, 0,
ImgWidth(DollCacheImg), ImgHeight(DollCacheImg),
DollsListImg, j * TILE_X, 0, 1);
}
done = 0;
while (!done)
{
static int inc = 1;
static int cur_inc = 1;
ImgClear(PartsImg);
region_tile->DrawPanel((TILE_X * 3) - 8, (TILE_Y * 4) - 8,
ImgWidth(PartsImg) + 16, ImgHeight(PartsImg) + 16);
region_tile->DrawPanel((TILE_X * 3) - 8, PARTS_Y - 8,
ImgWidth(DollsListImg) + 16, ImgHeight(DollsListImg) + 16);
region_tile->DrawPanel(8*TILE_X - 8, 8*TILE_Y - 8,
TILE_X + 16, TILE_Y + 16);
if (cur_part == 0)
{
// now selecting doll index
gotoxy(10 , 1, GOTO_STAT);
cprintf("%02d", cur_doll);
gotoxy(10 , 2, GOTO_STAT);
current_gender = dolls[cur_doll].parts[TILEP_PART_BASE] % 2;
cprintf("%s", gender_name[ current_gender ]);
for (i = 2; i<PARTS_ITEMS; i++)
{
gotoxy(10 , i + 1, GOTO_STAT);
tilep_part_to_str(dolls[cur_doll].parts[ p_lines[i] ], ibuf);
cprintf("%s / %03d", ibuf, tilep_parts_total[ p_lines[i] ]);
}
}
else
{
for(i = 0; i < PARTS_DISP_MAX; i++)
{
int index;
if (dolls[cur_doll].parts[ p_lines[cur_part] ]
== TILEP_SHOW_EQUIP)
index = 0;
else
index = i + dolls[cur_doll].parts[ p_lines[cur_part] ]
- (PARTS_DISP_MAX / 2);
if (index < 0)
index = index + tilep_parts_total[ p_lines[cur_part] ] + 1;
if (index > tilep_parts_total[ p_lines[cur_part] ])
index = index - tilep_parts_total[ p_lines[cur_part] ] - 1;
tcache_overlay_player(PartsImg, i * TILE_X, 0,
p_lines[cur_part], index, TILE_Y, &d);
}
ImgCopy(PartsImg, 0, 0, ImgWidth(PartsImg), ImgHeight(PartsImg),
ScrBufImg, 3 * TILE_X, 4 * TILE_Y, 0);
ImgCopyFromTileImg( TILE_CURSOR, ScrBufImg,
(3 + PARTS_DISP_MAX / 2) * TILE_X, 4 * TILE_Y, 0);
}
draw_doll(DollCacheImg, &dolls[cur_doll], true);
ImgCopy(DollCacheImg, 0, 0, TILE_X, TILE_Y,
DollsListImg, cur_doll*TILE_X, 0, 1);
ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1);
ImgCopyFromTileImg(TILE_PLAYER, ScrBufImg, 8*TILE_X, 8*TILE_Y, 0);
ImgCopy(DollsListImg, 0, 0,
ImgWidth(DollsListImg), ImgHeight(DollsListImg),
ScrBufImg, 3 * TILE_X, PARTS_Y, 0);
ImgCopyFromTileImg( TILE_CURSOR, ScrBufImg,
(3 + cur_doll) * TILE_X, PARTS_Y, 0);
region_tile->redraw();
gotoxy(10 , cur_part + 1, GOTO_STAT);
if (cur_part == 1)
{
current_gender = dolls[cur_doll].parts[p_lines[cur_part] ]%2;
cprintf("%s", gender_name[ current_gender ]);
}
else if (cur_part != 0)
{
tilep_part_to_str(dolls[cur_doll].parts[ p_lines[cur_part] ], ibuf);
cprintf("%s", ibuf);
}
gotoxy(1, pre_part + 1, GOTO_STAT);cprintf(" ");
gotoxy(1, cur_part + 1, GOTO_STAT);cprintf("->");
pre_part = cur_part;
/* Get a key */
kin = getch();
inc = cur_inc = 0;
/* Analyze the key */
switch (kin)
{
case 0x1B: //ESC
done = 1;
break;
case 'h':
inc = -1;
break;
case 'l':
inc = +1;
break;
case 'H':
inc = -PARTS_DISP_MAX;
break;
case 'L':
inc = +PARTS_DISP_MAX;
break;
case 'j':
{
if (cur_part < (PARTS_ITEMS-1) )
cur_part += 1;
else
cur_part = 0;
break;
}
case 'k':
{
if (cur_part > 0)
cur_part -= 1;
else
cur_part = (PARTS_ITEMS-1);
break;
}
case 'm':
{
if (mode == TILEP_M_LOADING)
mode = TILEP_M_DEFAULT;
else
mode = TILEP_M_LOADING;
gotoxy(1, 8, GOTO_MSG);
cprintf("Toggle Startup mode : [m] (Current mode:%s)",
( (mode == TILEP_M_LOADING) ? "Load User's Settings":"Class Default" ));
break;
}
case 't':
{
if (cur_part >= 2)
{
dolls[cur_doll].parts[ p_lines[cur_part] ] = 0;
display_parts_idx(cur_part);
}
break;
}
case CONTROL('D'):
{
tilep_job_default(you.char_class, current_gender,
dolls[cur_doll].parts);
for(i = 2; i < PARTS_ITEMS; i++)
{
display_parts_idx(i);
}
break;
}
case CONTROL('T'):
{
for(i = 2; i < PARTS_ITEMS; i++)
{
undo_dolls[cur_doll].parts[ p_lines[i] ] = dolls[cur_doll].parts[ p_lines[i] ];
dolls[cur_doll].parts[ p_lines[i] ] = 0;
display_parts_idx(i);
}
break;
}
case CONTROL('C'):
{
for(i = 2; i < PARTS_ITEMS; i++)
{
copy_doll[ p_lines[i] ] = dolls[cur_doll].parts[ p_lines[i] ];
}
break;
}
case CONTROL('V'):
{
for(i = 2; i < PARTS_ITEMS; i++)
{
undo_dolls[cur_doll].parts[ p_lines[i] ] = dolls[cur_doll].parts[ p_lines[i] ];
dolls[cur_doll].parts[ p_lines[i] ] = copy_doll[ p_lines[i] ];
display_parts_idx(i);
}
break;
}
case CONTROL('Z'):
{
for(i = 2; i < PARTS_ITEMS; i++)
{
dolls[cur_doll].parts[ p_lines[i] ] = undo_dolls[cur_doll].parts[ p_lines[i] ];
display_parts_idx(i);
}
break;
}
case CONTROL('R'):
{
for(i = 2; i < PARTS_ITEMS; i++)
{
undo_dolls[cur_doll].parts[ p_lines[i] ] = dolls[cur_doll].parts[ p_lines[i] ];
}
dolls[cur_doll].parts[TILEP_PART_CLOAK] =
one_chance_in(2) * ( random2(tilep_parts_total[ TILEP_PART_CLOAK ]) + 1);
dolls[cur_doll].parts[TILEP_PART_BOOTS] =
( random2(tilep_parts_total[ TILEP_PART_BOOTS ] + 1) );
dolls[cur_doll].parts[TILEP_PART_LEG] =
( random2(tilep_parts_total[ TILEP_PART_LEG ] + 1) );
dolls[cur_doll].parts[TILEP_PART_BODY] =
( random2(tilep_parts_total[ TILEP_PART_BODY ] + 1) );
dolls[cur_doll].parts[TILEP_PART_ARM] =
one_chance_in(2) * ( random2(tilep_parts_total[ TILEP_PART_ARM ]) + 1);
dolls[cur_doll].parts[TILEP_PART_HAND1] =
( random2(tilep_parts_total[ TILEP_PART_HAND1 ] + 1) );
dolls[cur_doll].parts[TILEP_PART_HAND2] =
one_chance_in(2) * ( random2(tilep_parts_total[ TILEP_PART_HAND2 ]) + 1);
dolls[cur_doll].parts[TILEP_PART_HAIR] =
( random2(tilep_parts_total[ TILEP_PART_HAIR ] + 1) );
dolls[cur_doll].parts[TILEP_PART_BEARD] =
( (dolls[cur_doll].parts[TILEP_PART_BASE] + 1) % 2) *
one_chance_in(4) * ( random2(tilep_parts_total[ TILEP_PART_BEARD ]) + 1 );
dolls[cur_doll].parts[TILEP_PART_HELM] =
one_chance_in(2) * ( random2(tilep_parts_total[ TILEP_PART_HELM ]) + 1 );
for(i = 2; i < PARTS_ITEMS; i++)
{
display_parts_idx(i);
}
break;
}
case '*':
{
int part = p_lines[cur_part];
int *target = &dolls[cur_doll].parts[part];
if (part == TILEP_PART_BASE)
continue;
if (*target == TILEP_SHOW_EQUIP)
*target = 0;
else
*target = TILEP_SHOW_EQUIP;
display_parts_idx(cur_part);
break;
}
#ifdef WIZARD
case '1':
dolls[cur_doll].parts[TILEP_PART_DRCHEAD]++;
dolls[cur_doll].parts[TILEP_PART_DRCHEAD] %=
tilep_parts_total[TILEP_PART_DRCHEAD] -1;
break;
case '2':
dolls[cur_doll].parts[TILEP_PART_DRCWING]++;
dolls[cur_doll].parts[TILEP_PART_DRCWING] %=
tilep_parts_total[TILEP_PART_DRCWING] -1;
break;
#endif
default:
{
}
}
if (inc != 0)
{
int *target = &dolls[cur_doll].parts[ p_lines[cur_part] ];
if (cur_part == 0)
{
if (inc > 0)
cur_doll++;
else
cur_doll--;
if (cur_doll < 0)
cur_doll = DOLLS_MAX -1;
else if (cur_doll == DOLLS_MAX)
cur_doll = 0;
}
else if (cur_part == 1)
{
if (*target % 2)
(*target)++;
else
(*target)--;
}
else
{
if (*target == TILEP_SHOW_EQUIP) continue;
(*target) += inc;
(*target) += tilep_parts_total[ p_lines[cur_part] ]+1;
(*target) %= tilep_parts_total[ p_lines[cur_part] ]+1;
}
}
delay(20);
}
current_doll = dolls[cur_doll];
draw_doll(DollCacheImg, ¤t_doll);
ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1);
std::string dollsTxtString = datafile_path("dolls.txt", false, true);
const char *dollsTxt = dollsTxtString.c_str()[0] == 0 ?
"dolls.txt" : dollsTxtString.c_str();
if ( (fp = fopen(dollsTxt, "w+")) == NULL )
{
}
else
{
fprintf(fp, "MODE=%s\n", ( (mode == TILEP_M_LOADING) ? "LOADING":"DEFAULT" ) );
fprintf(fp, "NUM=%02d\n", cur_doll);
for(j = 0; j < DOLLS_MAX; j++)
{
tilep_print_parts(fbuf, dolls[j].parts);
fprintf(fp, "%s\n", fbuf);
}
fclose(fp);
}
ImgDestroy(PartsImg);
ImgDestroy(DollsListImg);
ImgClear(ScrBufImg);
redraw_spx_tcache(TILE_PLAYER);
for(x=0;x<TILE_DAT_XMAX+2;x++){
for(y=0;y<TILE_DAT_YMAX+2;y++){
t1buf[x][y]=0;
t2buf[x][y]=simple_iso_tile(TILE_DNGN_UNSEEN)|TILE_FLAG_UNSEEN;
}}
for(k=0;k<tcache_kind;k++)
for(x=0;x<tile_xmax*tile_ymax;x++)
screen_tcach_idx[k][x] = -1;
clrscr();
redraw_screen();
}
void TilePlayerRefresh()
{
if (!draw_doll(DollCacheImg, ¤t_doll))
return; // Not changed
ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1);
redraw_spx_tcache(TILE_PLAYER);
force_redraw_tile = true;
const coord_def ep = grid2view(you.pos());
update_single_grid(ep.x-1, ep.y-1);
}
void TilePlayerInit()
{
int i;
int cur_doll = 0;
int mode = TILEP_M_DEFAULT;
dolls_data doll;
int gender = 0;
for(i = 0; i < TILEP_PARTS_TOTAL; i++)
doll.parts[i] = 0;
tilep_race_default(you.species, gender, you.experience_level, doll.parts);
tilep_job_default(you.char_class, gender, doll.parts);
load_doll_data("dolls.txt", &doll, 1, &mode, &cur_doll);
current_doll = doll;
draw_doll(DollCacheImg, &doll);
ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1);
}
void TileGhostInit(struct ghost_demon &ghost)
{
dolls_data doll;
int x, y;
unsigned int pseudo_rand = ghost.values[GVAL_MAX_HP]*54321*54321;
char mask[TILE_X*TILE_Y];
int g_gender = (pseudo_rand >>8)&1;
for (x=0; x<TILE_X; x++)
for (y=0; y<TILE_X; y++)
mask[x+y*TILE_X] = (x+y)&1;
for(x = 0; x < TILEP_PARTS_TOTAL; x++)
{
doll.parts[x] = 0;
current_parts[x] = 0;
}
tilep_race_default(ghost.values[GVAL_SPECIES], g_gender,
ghost.values[GVAL_EXP_LEVEL], doll.parts);
tilep_job_default (ghost.values[GVAL_CLASS], g_gender, doll.parts);
for(x = TILEP_PART_CLOAK; x < TILEP_PARTS_TOTAL; x++)
{
if (doll.parts[x] == TILEP_SHOW_EQUIP)
{
doll.parts[x] = 1 + (pseudo_rand % tilep_parts_total[x]);
if (x == TILEP_PART_BODY)
{
int p = 0;
int ac = ghost.values[GVAL_AC];
ac *= (5 + (pseudo_rand/11) % 11);
ac /= 10;
if (ac > 25) p= TILEP_BODY_PLATE_BLACK;
else
if (ac > 20) p= TILEP_BODY_BANDED;
else
if (ac > 15) p= TILEP_BODY_SCALEMAIL;
else
if (ac > 10) p= TILEP_BODY_CHAINMAIL;
else
if (ac > 5 ) p= TILEP_BODY_LEATHER_HEAVY;
else
p= TILEP_BODY_ROBE_BLUE;
doll.parts[x] = p;
}
}
}
int sk = ghost.values[GVAL_BEST_SKILL];
int dam = ghost.values[GVAL_DAMAGE];
int p = 0;
dam *= (5 + pseudo_rand % 11);
dam /= 10;
if (sk == SK_MACES_FLAILS)
{
if (dam>30) p = TILEP_HAND1_GREAT_FRAIL;
else
if (dam>25) p = TILEP_HAND1_GREAT_MACE;
else
if (dam>20) p = TILEP_HAND1_SPIKED_FRAIL;
else
if (dam>15) p = TILEP_HAND1_MORNINGSTAR;
else
if (dam>10) p = TILEP_HAND1_FRAIL;
else
if (dam>5) p = TILEP_HAND1_MACE;
else
p = TILEP_HAND1_CLUB_SLANT;
doll.parts[TILEP_PART_HAND1] = p;
}
else
if (sk == SK_SHORT_BLADES)
{
if (dam>20) p = TILEP_HAND1_SABRE;
else
if (dam>10) p = TILEP_HAND1_SHORT_SWORD_SLANT;
else
p = TILEP_HAND1_DAGGER_SLANT;
doll.parts[TILEP_PART_HAND1] = p;
}
else
if (sk == SK_LONG_SWORDS)
{
if (dam>25) p = TILEP_HAND1_GREAT_SWORD_SLANT;
else
if (dam>20) p = TILEP_HAND1_KATANA_SLANT;
else
if (dam>15) p = TILEP_HAND1_SCIMITAR;
else
if (dam>10) p = TILEP_HAND1_LONG_SWORD_SLANT;
else
p = TILEP_HAND1_FALCHION;
doll.parts[TILEP_PART_HAND1] = p;
}
else
if (sk == SK_AXES)
{
if (dam>30) p = TILEP_HAND1_EXECUTIONERS_AXE;
else
if (dam>20) p = TILEP_HAND1_BATTLEAXE;
else
if (dam>15) p = TILEP_HAND1_BROAD_AXE;
else
if (dam>10) p = TILEP_HAND1_WAR_AXE;
else
p = TILEP_HAND1_HAND_AXE;
doll.parts[TILEP_PART_HAND1] = p;
}
else
if (sk == SK_POLEARMS)
{
if (dam>30) p = TILEP_HAND1_GLAIVE;
else
if (dam>20) p = TILEP_HAND1_SCYTHE;
else
if (dam>15) p = TILEP_HAND1_HALBERD;
else
if (dam>10) p = TILEP_HAND1_TRIDENT2;
else
if (dam>10) p = TILEP_HAND1_HAMMER;
else
p = TILEP_HAND1_SPEAR;
doll.parts[TILEP_PART_HAND1] = p;
}
else
if (sk == SK_BOWS)
doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BOW2;
else
if (sk == SK_CROSSBOWS)
doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_CROSSBOW;
else
if (sk == SK_SLINGS)
doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SLING;
else
if (sk == SK_UNARMED_COMBAT)
doll.parts[TILEP_PART_HAND1] = doll.parts[TILEP_PART_HAND2] = 0;
ImgClear(DollCacheImg);
// Clear
ImgCopyToTileImg(TILE_MONS_PLAYER_GHOST, DollCacheImg, 0, 0, 1);
draw_doll(DollCacheImg, &doll);
ImgCopyToTileImg(TILE_MONS_PLAYER_GHOST, DollCacheImg, 0, 0, 1, mask, false);
redraw_spx_tcache(TILE_MONS_PLAYER_GHOST);
}
void TileInitItems()
{
for(int i=0; i<NUM_POTIONS; i++)
{
int special = you.item_description[IDESC_POTIONS][i];
int tile0 = TILE_POTION_OFFSET + special % 14;
int tile1 = TILE_POT_HEALING + i;
ImgCopyFromTileImg(tile0, DollCacheImg, 0, 0, 1);
ImgCopyFromTileImg(tile1, DollCacheImg, 0, 0, 0);
ImgCopyToTileImg (tile1, DollCacheImg, 0, 0, 1);
}
for(int i=0; i<NUM_WANDS; i++)
{
int special = you.item_description[IDESC_WANDS][i];
int tile0 = TILE_WAND_OFFSET + special % 12;
int tile1 = TILE_WAND_FLAME + i;
ImgCopyFromTileImg(tile0, DollCacheImg, 0, 0, 1);
ImgCopyFromTileImg(tile1, DollCacheImg, 0, 0, 0);
ImgCopyToTileImg (tile1, DollCacheImg, 0, 0, 1);
}
//Hack: call it again
init_tileflag();
}
// Monster weapon tile
#define N_MCACHE (TILE_MCACHE_END - TILE_MCACHE_START +1)
typedef struct mcache mcache;
struct mcache
{
bool lock_flag;
mcache *next;
int mon_tile;
int equ_tile;
int draco;
int idx;
};
mcache mc_data[N_MCACHE];
mcache *mc_head = NULL;
static void ImgCopyDoll(int equ_tile, int hand, int ofs_x, int ofs_y)
{
int handidx = hand == 1 ? TILEP_PART_HAND1 : TILEP_PART_HAND2;
int nx = tilep_parts_nx[handidx];
int ny = tilep_parts_ny[handidx];
int ox = tilep_parts_ox[handidx];
int oy = tilep_parts_oy[handidx];
int wx = std::min(TILE_X/nx + ofs_x, TILE_X/nx);
int wy = std::min(TILE_Y/ny + ofs_y, TILE_Y/ny);
int idx = equ_tile -1;
int tidx = tilep_parts_start[handidx] +
idx/(nx*ny);
//Source pos
int xs = (tidx % TILEP_PER_ROW)*TILE_X +
(idx % nx)*(TILE_X/nx) - ofs_x;
int ys = (tidx / TILEP_PER_ROW)*TILE_Y +
((idx/nx) % ny)*(TILE_Y/ny) - ofs_y;
ImgCopy(PlayerImg, xs, ys, wx, wy,
DollCacheImg, ox, oy, 0);
}
static void mcache_compose(int tile_idx, int mon_tile, int equ_tile)
{
int ofs_x=0;
int ofs_y=0;
switch(mon_tile)
{
case TILE_MONS_ORC:
case TILE_MONS_URUG:
case TILE_MONS_BLORK_THE_ORC:
case TILE_MONS_ORC_WARRIOR:
case TILE_MONS_ORC_KNIGHT:
case TILE_MONS_ORC_WARLORD:
ofs_y = 2;
break;
case TILE_MONS_GOBLIN:
case TILE_MONS_IJYB:
ofs_y = 4;
break;
case TILE_MONS_GNOLL:
ofs_x = -1;
break;
case TILE_MONS_BOGGART:
ofs_y = 2;
break;
case TILE_MONS_DEEP_ELF_FIGHTER:
case TILE_MONS_DEEP_ELF_SOLDIER:
ofs_y = 2;
break;
case TILE_MONS_DEEP_ELF_KNIGHT:
ofs_y = 1;
break;
case TILE_MONS_KOBOLD:
ofs_x = 3;
ofs_y = 4;
break;
case TILE_MONS_KOBOLD_DEMONOLOGIST:
ofs_y = -10;
break;
case TILE_MONS_BIG_KOBOLD:
ofs_x = 2;
ofs_y = 3;
break;
case TILE_MONS_MIDGE:
ofs_y = -2;
break;
case TILE_MONS_NAGA:
case TILE_MONS_GREATER_NAGA:
case TILE_MONS_NAGA_WARRIOR:
case TILE_MONS_GUARDIAN_NAGA:
case TILE_MONS_NAGA_MAGE:
ofs_y = 1;
break;
case TILE_MONS_HELL_KNIGHT:
ofs_x = -1;
ofs_y = 3;
break;
case TILE_MONS_RED_DEVIL:
ofs_x = 2;
ofs_y = -3;
break;
case TILE_MONS_WIZARD:
ofs_x = 2;
ofs_y = -2;
break;
case TILE_MONS_HUMAN:
ofs_x = 5;
ofs_y = 2;
break;
case TILE_MONS_ELF:
ofs_y = 1;
ofs_x = 4;
break;
case TILE_MONS_OGRE_MAGE:
ofs_y = -2;
ofs_x = -4;
break;
case TILE_MONS_DEEP_ELF_MAGE:
case TILE_MONS_DEEP_ELF_SUMMONER:
case TILE_MONS_DEEP_ELF_CONJURER:
case TILE_MONS_DEEP_ELF_PRIEST:
case TILE_MONS_DEEP_ELF_HIGH_PRIEST:
case TILE_MONS_DEEP_ELF_DEMONOLOGIST:
case TILE_MONS_DEEP_ELF_ANNIHILATOR:
case TILE_MONS_DEEP_ELF_SORCERER:
ofs_x = -1;
ofs_y = -2;
break;
case TILE_MONS_DEEP_ELF_DEATH_MAGE:
ofs_x = -1;
break;
}
// Copy monster tile
ImgCopyFromTileImg(mon_tile, DollCacheImg, 0, 0, 1);
// Overlay weapon tile
ImgCopyDoll(equ_tile, 1, ofs_x, ofs_y);
// In some cases, overlay a second weapon tile...
if (mon_tile == TILE_MONS_DEEP_ELF_BLADEMASTER)
{
int eq2;
switch (equ_tile)
{
case TILEP_HAND1_DAGGER:
eq2 = TILEP_HAND2_DAGGER;
break;
case TILEP_HAND1_SABRE:
eq2 = TILEP_HAND2_SABRE;
break;
default:
case TILEP_HAND1_SHORT_SWORD_SLANT:
eq2 = TILEP_HAND2_SHORT_SWORD_SLANT;
break;
};
ImgCopyDoll(eq2, 2, -ofs_x, ofs_y);
}
// Copy to the buffer
ImgCopyToTileImg(tile_idx, DollCacheImg, 0, 0, 1);
redraw_spx_tcache(tile_idx);
}
static void mcache_compose_draco(int tile_idx, int race, int cls, int w)
{
extern int draconian_color(int race, int level);
dolls_data doll;
int x;
int color = draconian_color(race, -1);
int armour = 0;
int armour2 = 0;
int weapon = 0;
int weapon2 = 0;
int arm = 0;
for(x = 0; x < TILEP_PARTS_TOTAL; x++)
{
doll.parts[x] = 0;
current_parts[x] = 0;
}
doll.parts[TILEP_PART_SHADOW] = 1;
doll.parts[TILEP_PART_BASE] = TILEP_BASE_DRACONIAN + color *2;
doll.parts[TILEP_PART_DRCWING] = 1 + color;
doll.parts[TILEP_PART_DRCHEAD] = 1 + color;
switch(cls)
{
case MONS_DRACONIAN_CALLER:
weapon = TILEP_HAND1_STAFF_EVIL;
weapon2 = TILEP_HAND2_BOOK_YELLOW;
armour = TILEP_BODY_ROBE_BROWN;
break;
case MONS_DRACONIAN_MONK:
arm = TILEP_ARM_GLOVE_SHORT_BLUE;
armour = TILEP_BODY_KARATE2;
break;
case MONS_DRACONIAN_ZEALOT:
weapon = TILEP_HAND1_MACE;
weapon2 = TILEP_HAND2_BOOK_CYAN;
armour = TILEP_BODY_MONK_BLUE;
break;
case MONS_DRACONIAN_SHIFTER:
weapon = TILEP_HAND1_STAFF_LARGE;
armour = TILEP_BODY_ROBE_CYAN;
weapon2 = TILEP_HAND2_BOOK_GREEN;
break;
case MONS_DRACONIAN_ANNIHILATOR:
weapon = TILEP_HAND1_STAFF_RUBY;
weapon2 = TILEP_HAND2_FIRE_CYAN;
armour = TILEP_BODY_ROBE_GREEN_GOLD;
break;
case MONS_DRACONIAN_KNIGHT:
weapon = w;
weapon2 = TILEP_HAND2_SHIELD_KNIGHT_GRAY;
armour = TILEP_BODY_BPLATE_METAL1;
armour2 = TILEP_LEG_BELT_GRAY;
break;
case MONS_DRACONIAN_SCORCHER:
weapon = TILEP_HAND1_FIRE_RED;
weapon2 = TILEP_HAND2_BOOK_RED;
armour = TILEP_BODY_ROBE_RED;
break;
default:
weapon = w;
armour = TILEP_BODY_BELT2;
armour2 = TILEP_LEG_LOINCLOTH_RED;
break;
}
doll.parts[TILEP_PART_HAND1] = weapon;
doll.parts[TILEP_PART_HAND2] = weapon2;
doll.parts[TILEP_PART_BODY] = armour;
doll.parts[TILEP_PART_LEG] = armour2;
doll.parts[TILEP_PART_ARM] = arm;
ImgClear(DollCacheImg);
draw_doll(DollCacheImg, &doll, true, false);
// Copy to the buffer
ImgCopyToTileImg(tile_idx, DollCacheImg, 0, 0, 1);
redraw_spx_tcache(tile_idx);
}
static void mcache_init()
{
int i;
for(i=0;i<N_MCACHE;i++)
{
mc_data[i].lock_flag = false;
mc_data[i].next = NULL;
if (i!=N_MCACHE-1)
mc_data[i].next = &mc_data[i+1];
mc_data[i].idx = TILE_MCACHE_START + i;
mc_data[i].mon_tile = 0;
mc_data[i].equ_tile = 0;
mc_data[i].draco = 0;
}
mc_head = &mc_data[0];
}
int get_base_idx_from_mcache(int tile_idx)
{
for (mcache *mc = mc_head; mc != NULL; mc = mc->next)
{
if (mc->idx == tile_idx)
return mc->mon_tile;
}
return tile_idx;
}
int get_clean_map_idx(int tile_idx)
{
int idx = tile_idx & TILE_FLAG_MASK;
if (idx >= TILE_CLOUD_FIRE_0 && idx <= TILE_CLOUD_PURP_SMOKE ||
idx >= TILE_MONS_SHADOW && idx <= TILE_MONS_WATER_ELEMENTAL ||
idx >= TILE_MCACHE_START && idx <= TILE_MCACHE_END)
{
return 0;
}
else
{
return tile_idx;
}
}
void TileMcacheUnlock()
{
int i;
for(i=0;i<N_MCACHE;i++)
{
mc_data[i].lock_flag = false;
}
}
int TileMcacheFind(int mon_tile, int equ_tile, int draco)
{
mcache *mc = mc_head;
mcache *prev = NULL;
mcache *empty = NULL;
#ifdef DEBUG_DIAGNOSTICS
int count = 0;
char cache_info[40];
#endif
int best2 = -1;
int best3 = -1;
while(1){
if(mon_tile == mc->mon_tile && equ_tile == mc->equ_tile
&& draco == mc->draco)
{
// match found
// move cache to the head to reduce future search time
if (prev != NULL) prev->next = mc->next;
if (mc != mc_head) mc->next = mc_head;
mc_head = mc;
// lock it
mc->lock_flag=true;
// return cache index
return mc->idx;
}
else if(draco != 0 && mon_tile == mc->mon_tile && draco == mc->draco)
// second best for draconian: only weapon differ
best2 = mc->idx;
else if(draco != 0 && mon_tile == mc->mon_tile)
// third best for draconian: only class matches
best3 = mc->idx;
if (!mc->lock_flag)
empty = mc;
if (mc->next == NULL)
break;
prev = mc;
mc = mc->next;
#ifdef DEBUG_DIAGNOSTICS
count++;
#endif
}//while
// cache image not found and no room do draw it
if(empty == NULL)
{
#ifdef DEBUG_DIAGNOSTICS
snprintf( cache_info, 39, "mcache (M %d, E %d) cache full",
mon_tile, equ_tile);
mpr(cache_info, MSGCH_DIAGNOSTICS );
#endif
if (best2 != -1)
return best2;
if (best3 != -1)
return best3;
if (draco != 0)
return TILE_ERROR;
else
return mon_tile;
}
mc = empty;
#ifdef DEBUG_DIAGNOSTICS
snprintf( cache_info, 39, "mcache (M %d, E %d) newly composed",
mon_tile, equ_tile);
mpr(cache_info, MSGCH_DIAGNOSTICS );
#endif
// compose new image
if (draco != 0)
// race, class, weapon
mcache_compose_draco(mc->idx, draco, mon_tile, equ_tile);
else
mcache_compose(mc->idx, mon_tile, equ_tile);
mc->mon_tile = mon_tile;
mc->equ_tile = equ_tile;
mc->draco = draco;
// move cache to the head to reduce future search time
if (prev)
prev->next = mc->next;
if(mc != mc_head)
mc->next = mc_head;
mc_head = mc;
mc->lock_flag=true;
return mc->idx;
}
void TileDrawTitle()
{
int winx, winy, tx, ty, x, y;
img_type TitleImg = ImgLoadFileSimple("title");
img_type pBuf = region_tile->backbuf;
if (!TitleImg || !pBuf) return;
tx = ImgWidth(TitleImg);
ty = ImgHeight(TitleImg);
winx = ImgWidth(pBuf);
winy = ImgHeight(pBuf);
if (tx > winx)
{
x = 0;
tx = winx;
}
else
{
x = (winx - tx)/2;
}
if (ty > winy)
{
y = 0;
ty = winy;
}
else
{
y = (winy - ty)/2;
}
ImgCopy(TitleImg, 0, 0, tx, ty, pBuf, x, y, 1);
region_tile->make_active();
region_tile->redraw();
ImgDestroy(TitleImg);
}
static void TilePutch(int c, img_type Dest, int dx, int dy)
{
int tidx = TILE_CHAR00 + (c-32)/8;
int tidx2 = c & 7;
int sx = (tidx % TILE_PER_ROW)*TILE_X + (tidx2 % 4)*(TILE_X/4);
int sy = (tidx / TILE_PER_ROW)*TILE_Y + (tidx2 / 4)*(TILE_Y/2);;
ImgCopy(TileImg, sx, sy, TILE_X/4, TILE_Y/2,
Dest, dx, dy, 0);
}
void TileRedrawInv(int region)
{
TileRegionClass *r = (region == REGION_INV1) ? region_item:region_item2;
r->flag = true;
r->make_active();
r->redraw();
}
void TileClearInv(int region)
{
TileRegionClass *r = (region == REGION_INV1) ? region_item:region_item2;
for (int i = 0; i < r->mx * r->my; i++)
{
TileDrawOneItem(region, i, 0, -1, -1, -1, false, false, false, false, false);
}
last_cursor = -1;
itemlist_n = 0;
}
void TileDrawOneItem(int region, int i, char key, int idx,
int tile, int num, bool floor,
bool select, bool equip, bool tried, bool cursed)
{
ASSERT(idx >= -1 && idx < MAX_ITEMS);
TileRegionClass *r = (region == REGION_INV1) ? region_item:region_item2;
int item_x = r->mx;
int dx = (i % item_x)*TILE_X;
int dy = (i / item_x)*TILE_Y;
if (tile == -1)
{
ImgCopyFromTileImg(TILE_DNGN_UNSEEN, r->backbuf, dx, dy, 1);
return;
}
if (floor)
ImgCopyFromTileImg(TILE_DNGN_FLOOR, r->backbuf, dx, dy, 1);
else
ImgCopyFromTileImg(TILE_ITEM_SLOT, r->backbuf, dx, dy, 1);
if (equip)
{
if (cursed)
ImgCopyFromTileImg(TILE_ITEM_SLOT_EQUIP_CURSED, r->backbuf,
dx, dy, 0);
else
ImgCopyFromTileImg(TILE_ITEM_SLOT_EQUIP, r->backbuf, dx, dy, 0);
}
else if (cursed)
{
ImgCopyFromTileImg(TILE_ITEM_SLOT_CURSED, r->backbuf, dx, dy, 0);
}
if (select)
ImgCopyFromTileImg(TILE_RAY_MESH, r->backbuf, dx, dy, 0);
if (itemlist_iflag[i] & TILEI_FLAG_CURSOR)
ImgCopyFromTileImg(TILE_CURSOR, r->backbuf, dx, dy, 0);
// Item tile
ImgCopyFromTileImg(tile, r->backbuf, dx, dy, 0);
// quantity/charge
if (num != -1)
{
// If you have that many, who cares.
if (num > 999)
num = 999;
const int offset_amount = TILE_X/4;
int offset = 0;
int c100 = num/100;
num -= c100*100;
if (c100)
{
TilePutch('0'+ c100, r->backbuf, dx+offset, dy);
offset += offset_amount;
}
int c10 = num/10;
if (c10 || c100)
{
TilePutch('0'+ c10, r->backbuf, dx+offset, dy);
offset += offset_amount;
}
int c1 = num % 10;
TilePutch('0'+ c1, r->backbuf, dx+offset, dy);
}
// '?' mark
if (tried)
{
TilePutch('?', r->backbuf, dx, dy + TILE_Y/2);
}
// record tile information as we draw it so that we can re-draw it at will
itemlist[i] = tile;
itemlist_num[i] = num;
itemlist_key[i] = key;
itemlist_idx[i] = idx;
itemlist_iflag[i] = 0;
if (floor)
itemlist_iflag[i] |= TILEI_FLAG_FLOOR;
if (tried)
itemlist_iflag[i] |= TILEI_FLAG_TRIED;
if (equip)
itemlist_iflag[i] |= TILEI_FLAG_EQUIP;
if (cursed)
itemlist_iflag[i] |= TILEI_FLAG_CURSE;
if (select)
itemlist_iflag[i] |= TILEI_FLAG_SELECT;
if (i >= itemlist_n)
itemlist_n = i+1;
}
void TileDrawInvData(int n, int flag, int *tiles, int *num, int *idx,
int *iflags)
{
int i;
TileRegionClass *r = (flag == REGION_INV1) ? region_item:region_item2;
r->flag = true;
last_cursor = -1;
int old_itemlist_n = itemlist_n;
itemlist_n = n;
int item_x = r->mx;
int item_y = r->my;
for (i=0;i<item_x*item_y;i++)
{
if (i==MAX_ITEMLIST) break;
int tile0 = (i>=n) ? -1 : tiles[i];
int idx0 = (i>=n) ? -1 : idx[i];
char key = (iflags[i]&TILEI_FLAG_FLOOR) ? 0 : index_to_letter(idx[i]);
if ( flag == itemlist_flag
&& tile0 == itemlist[i]
&& num[i] == itemlist_num[i]
&& key == itemlist_key[i]
&& idx0 == itemlist_idx[i]
&& iflags[i] == itemlist_iflag[i]
&& !force_redraw_inv
&& i < old_itemlist_n)
{
continue;
}
TileDrawOneItem(flag, i, key, idx0, tile0, num[i],
((iflags[i]&TILEI_FLAG_FLOOR) != 0),
((iflags[i]&TILEI_FLAG_SELECT) != 0),
((iflags[i]&TILEI_FLAG_EQUIP) != 0),
((iflags[i]&TILEI_FLAG_TRIED) != 0),
((iflags[i]&TILEI_FLAG_CURSE) != 0));
}
r->make_active();
r->redraw();
itemlist_flag = flag;
force_redraw_inv = false;
}
void TileDrawInvCursor(int ix, bool flag)
{
TileRegionClass *r =
(itemlist_flag == REGION_INV1) ? region_item:region_item2;
int tile0 = itemlist[ix];
int num0 = itemlist_num[ix];
if (flag)
itemlist_iflag[ix] |= TILEI_FLAG_CURSOR;
else
itemlist_iflag[ix] &= ~TILEI_FLAG_CURSOR;
TileDrawOneItem(itemlist_flag, ix, itemlist_key[ix], itemlist_idx[ix], tile0, num0,
((itemlist_iflag[ix]&TILEI_FLAG_FLOOR) != 0),
((itemlist_iflag[ix]&TILEI_FLAG_SELECT) != 0),
((itemlist_iflag[ix]&TILEI_FLAG_EQUIP) != 0),
((itemlist_iflag[ix]&TILEI_FLAG_TRIED) != 0),
((itemlist_iflag[ix]&TILEI_FLAG_CURSE) != 0)
);
r->redraw();
}
void TileMoveInvCursor(int ix)
{
if (last_cursor != -1)
TileDrawInvCursor(last_cursor, false);
if (ix != -1) TileDrawInvCursor(ix, true);
last_cursor = ix;
}
int TileInvIdx(int i)
{
if (i >= itemlist_n)
return -1;
else
return itemlist_idx[i];
}
#endif
#ifdef USE_TILE
#include <stdio.h>
#include "AppHdr.h"
#include "direct.h"
#include "externs.h"
#include "food.h"
#include "itemname.h"
#include "items.h"
#include "itemprop.h"
#include "macro.h"
#include "monstuff.h"
#include "mon-util.h"
#include "player.h"
#include "randart.h"
#include "stuff.h"
#include "terrain.h"
#include "tiles.h"
#include "tiledef-p.h"
#include "view.h"
#ifdef TILEP_DEBUG
#include "tilep-cmt.h"
#endif
/* external */
extern short get_helmet_type( const item_def &item );
extern bool player_is_airborne(void);
extern bool item_cursed( const item_def &item );
extern bool item_ident( const item_def &item, unsigned long flags );
// tile index cache to reduce tileidx() calls
static FixedArray < unsigned short, GXM, GYM > tile_dngn;
// // gv backup
static FixedArray < unsigned char, GXM, GYM > gv_now;
static FixedArray < unsigned char, GXM, GYM > wall_flag;
#define WFLAG_L 1
#define WFLAG_U 2
#define WFLAG_D 4
#define WFLAG_R 8
void TileNewLevel(bool first_time)
{
GmapInit(false);
TileLoadWall(false);
tile_clear_buf();
if (first_time)
tile_init_flavor();
}
const int TILE_TODO = TILE_ERROR;
/**** tile index routines ****/
int tile_unseen_flag(const coord_def& gc)
{
if (!map_bounds(gc))
return TILE_FLAG_UNSEEN;
else if (is_terrain_known(gc.x,gc.y)
&& !is_terrain_seen(gc.x,gc.y)
|| is_envmap_detected_item(gc.x,gc.y)
|| is_envmap_detected_mons(gc.x,gc.y))
{
return TILE_FLAG_MM_UNSEEN;
}
else
{
return TILE_FLAG_UNSEEN;
}
}
int tileidx_monster(int mon_idx)
{
int ch = TILE_ERROR;
int mons = menv[mon_idx].type;
switch(mons)
{
case MONS_GIANT_ANT: ch=TILE_MONS_GIANT_ANT; break;
case MONS_GIANT_BAT: ch=TILE_MONS_GIANT_BAT; break;
case MONS_CENTAUR: ch=TILE_MONS_CENTAUR; break;
case MONS_RED_DEVIL: ch=TILE_MONS_RED_DEVIL; break;
case MONS_ETTIN: ch=TILE_MONS_ETTIN; break;
case MONS_FUNGUS: ch=TILE_MONS_FUNGUS; break;
case MONS_GOBLIN: ch=TILE_MONS_GOBLIN; break;
case MONS_HOUND: ch=TILE_MONS_HOUND; break;
case MONS_IMP: ch=TILE_MONS_IMP; break;
case MONS_JACKAL: ch=TILE_MONS_JACKAL; break;
case MONS_KILLER_BEE: ch=TILE_MONS_KILLER_BEE; break;
case MONS_KILLER_BEE_LARVA: ch=TILE_MONS_KILLER_BEE_LARVA; break;
case MONS_MANTICORE: ch=TILE_MONS_MANTICORE; break;
case MONS_NECROPHAGE: ch=TILE_MONS_NECROPHAGE; break;
case MONS_ORC: ch=TILE_MONS_ORC; break;
case MONS_PHANTOM: ch=TILE_MONS_PHANTOM; break;
case MONS_QUASIT: ch=TILE_MONS_QUASIT; break;
case MONS_RAT: ch=TILE_MONS_RAT; break;
case MONS_SCORPION: ch=TILE_MONS_SCORPION; break;
case MONS_UGLY_THING : ch=TILE_MONS_UGLY_THING ; break;
case MONS_FIRE_VORTEX: ch=TILE_MONS_FIRE_VORTEX; break;
case MONS_WORM: ch=TILE_MONS_WORM; break;
case MONS_ABOMINATION_SMALL: ch=TILE_MONS_ABOMINATION_SMALL; break;
case MONS_YELLOW_WASP: ch=TILE_MONS_YELLOW_WASP; break;
case MONS_ZOMBIE_SMALL: ch=TILE_MONS_ZOMBIE_SMALL; break;
case MONS_ANGEL: ch=TILE_MONS_ANGEL; break;
case MONS_GIANT_BEETLE: ch=TILE_MONS_GIANT_BEETLE; break;
case MONS_CYCLOPS: ch=TILE_MONS_CYCLOPS; break;
case MONS_DRAGON: ch=TILE_MONS_DRAGON; break;
case MONS_TWO_HEADED_OGRE: ch=TILE_MONS_TWO_HEADED_OGRE; break;
case MONS_FIEND: ch=TILE_MONS_FIEND; break;
case MONS_GIANT_SPORE: ch=TILE_MONS_GIANT_SPORE; break;
case MONS_HOBGOBLIN: ch=TILE_MONS_HOBGOBLIN; break;
case MONS_ICE_BEAST: ch=TILE_MONS_ICE_BEAST; break;
case MONS_JELLY: ch=TILE_MONS_JELLY; break;
case MONS_KOBOLD: ch=TILE_MONS_KOBOLD; break;
case MONS_LICH: ch=TILE_MONS_LICH; break;
case MONS_MUMMY: ch=TILE_MONS_MUMMY; break;
case MONS_GUARDIAN_NAGA: ch=TILE_MONS_GUARDIAN_NAGA; break;
case MONS_OGRE: ch=TILE_MONS_OGRE; break;
case MONS_PLANT: ch=TILE_MONS_PLANT; break;
case MONS_QUEEN_BEE: ch=TILE_MONS_QUEEN_BEE; break;
case MONS_RAKSHASA: ch=TILE_MONS_RAKSHASA; break;
case MONS_SNAKE: ch=TILE_MONS_SNAKE; break;
case MONS_TROLL: ch=TILE_MONS_TROLL; break;
case MONS_UNSEEN_HORROR: ch=TILE_MONS_UNSEEN_HORROR; break;
case MONS_VAMPIRE: ch=TILE_MONS_VAMPIRE; break;
case MONS_WRAITH: ch=TILE_MONS_WRAITH; break;
case MONS_ABOMINATION_LARGE:
{
// 7 different colours
struct monsters *mon = &menv[mon_idx];
ch = TILE_MONS_ABOMINATION_LARGE + ((mon->colour)%7);
break;
}
case MONS_YAK: ch=TILE_MONS_YAK; break;
case MONS_ZOMBIE_LARGE: ch=TILE_MONS_ZOMBIE_LARGE; break;
case MONS_ORC_WARRIOR: ch=TILE_MONS_ORC_WARRIOR; break;
case MONS_KOBOLD_DEMONOLOGIST: ch=TILE_MONS_KOBOLD_DEMONOLOGIST; break;
case MONS_ORC_WIZARD: ch=TILE_MONS_ORC_WIZARD; break;
case MONS_ORC_KNIGHT: ch=TILE_MONS_ORC_KNIGHT; break;
case MONS_WYVERN: ch=TILE_MONS_WYVERN; break;
case MONS_BIG_KOBOLD: ch=TILE_MONS_BIG_KOBOLD; break;
case MONS_GIANT_EYEBALL: ch=TILE_MONS_GIANT_EYEBALL; break;
case MONS_WIGHT: ch=TILE_MONS_WIGHT; break;
case MONS_OKLOB_PLANT: ch=TILE_MONS_OKLOB_PLANT; break;
case MONS_WOLF_SPIDER: ch=TILE_MONS_WOLF_SPIDER; break;
case MONS_SHADOW: ch=TILE_MONS_SHADOW; break;
case MONS_HUNGRY_GHOST: ch=TILE_MONS_HUNGRY_GHOST; break;
case MONS_EYE_OF_DRAINING: ch=TILE_MONS_EYE_OF_DRAINING; break;
case MONS_BUTTERFLY:
{
// 7 different colours
struct monsters *mon = &menv[mon_idx];
ch = TILE_MONS_BUTTERFLY + ((mon->colour)%7);
break;
}
case MONS_WANDERING_MUSHROOM: ch=TILE_MONS_WANDERING_MUSHROOM; break;
case MONS_EFREET: ch=TILE_MONS_EFREET; break;
case MONS_BRAIN_WORM: ch=TILE_MONS_BRAIN_WORM; break;
case MONS_GIANT_ORANGE_BRAIN: ch=TILE_MONS_GIANT_ORANGE_BRAIN; break;
case MONS_BOULDER_BEETLE: ch=TILE_MONS_BOULDER_BEETLE; break;
case MONS_FLYING_SKULL: ch=TILE_MONS_FLYING_SKULL; break;
case MONS_HELL_HOUND: ch=TILE_MONS_HELL_HOUND; break;
case MONS_MINOTAUR: ch=TILE_MONS_MINOTAUR; break;
case MONS_ICE_DRAGON: ch=TILE_MONS_ICE_DRAGON; break;
case MONS_SLIME_CREATURE: ch=TILE_MONS_SLIME_CREATURE; break;
case MONS_FREEZING_WRAITH: ch=TILE_MONS_FREEZING_WRAITH; break;
case MONS_RAKSHASA_FAKE: ch=TILE_MONS_RAKSHASA_FAKE; break;
case MONS_GREAT_ORB_OF_EYES: ch=TILE_MONS_GREAT_ORB_OF_EYES; break;
case MONS_HELLION: ch=TILE_MONS_HELLION; break;
case MONS_ROTTING_DEVIL: ch=TILE_MONS_ROTTING_DEVIL; break;
case MONS_TORMENTOR: ch=TILE_MONS_TORMENTOR; break;
case MONS_REAPER: ch=TILE_MONS_REAPER; break;
case MONS_SOUL_EATER: ch=TILE_MONS_SOUL_EATER; break;
case MONS_HAIRY_DEVIL: ch=TILE_MONS_HAIRY_DEVIL; break;
case MONS_ICE_DEVIL: ch=TILE_MONS_ICE_DEVIL; break;
case MONS_BLUE_DEVIL: ch=TILE_MONS_BLUE_DEVIL; break;
case MONS_BEAST: ch=TILE_MONS_BEAST; break;
case MONS_IRON_DEVIL: ch=TILE_MONS_IRON_DEVIL; break;
case MONS_GLOWING_SHAPESHIFTER: ch=TILE_MONS_GLOWING_SHAPESHIFTER; break;
case MONS_SHAPESHIFTER: ch=TILE_MONS_SHAPESHIFTER; break;
case MONS_GIANT_MITE: ch=TILE_MONS_GIANT_MITE; break;
case MONS_STEAM_DRAGON: ch=TILE_MONS_STEAM_DRAGON; break;
case MONS_VERY_UGLY_THING: ch=TILE_MONS_VERY_UGLY_THING; break;
case MONS_ORC_SORCERER: ch=TILE_MONS_ORC_SORCERER; break;
case MONS_HIPPOGRIFF: ch=TILE_MONS_HIPPOGRIFF; break;
case MONS_GRIFFON: ch=TILE_MONS_GRIFFON; break;
case MONS_HYDRA:
{
// Number of heads
struct monsters *mon = &menv[mon_idx];
int heads = mon->number;
if (heads > 7) heads = 7;
ch = TILE_MONS_HYDRA + heads - 1;
break;
}
case MONS_SKELETON_SMALL: ch=TILE_MONS_SKELETON_SMALL; break;
case MONS_SKELETON_LARGE: ch=TILE_MONS_SKELETON_LARGE; break;
case MONS_HELL_KNIGHT: ch=TILE_MONS_HELL_KNIGHT; break;
case MONS_NECROMANCER: ch=TILE_MONS_NECROMANCER; break;
case MONS_WIZARD: ch=TILE_MONS_WIZARD; break;
case MONS_ORC_PRIEST: ch=TILE_MONS_ORC_PRIEST; break;
case MONS_ORC_HIGH_PRIEST: ch=TILE_MONS_ORC_HIGH_PRIEST; break;
case MONS_HUMAN: ch=TILE_MONS_HUMAN; break;
case MONS_GNOLL: ch=TILE_MONS_GNOLL; break;
case MONS_CLAY_GOLEM: ch=TILE_MONS_CLAY_GOLEM; break;
case MONS_WOOD_GOLEM: ch=TILE_MONS_WOOD_GOLEM; break;
case MONS_STONE_GOLEM: ch=TILE_MONS_STONE_GOLEM; break;
case MONS_IRON_GOLEM: ch=TILE_MONS_IRON_GOLEM; break;
case MONS_CRYSTAL_GOLEM: ch=TILE_MONS_CRYSTAL_GOLEM; break;
case MONS_TOENAIL_GOLEM: ch=TILE_MONS_TOENAIL_GOLEM; break;
case MONS_MOTTLED_DRAGON: ch=TILE_MONS_MOTTLED_DRAGON; break;
case MONS_EARTH_ELEMENTAL: ch=TILE_MONS_EARTH_ELEMENTAL; break;
case MONS_FIRE_ELEMENTAL: ch=TILE_MONS_FIRE_ELEMENTAL; break;
case MONS_AIR_ELEMENTAL: ch=TILE_MONS_AIR_ELEMENTAL; break;
case MONS_ICE_FIEND: ch=TILE_MONS_ICE_FIEND; break;
case MONS_SHADOW_FIEND: ch=TILE_MONS_SHADOW_FIEND; break;
case MONS_BROWN_SNAKE: ch=TILE_MONS_BROWN_SNAKE; break;
case MONS_GIANT_LIZARD: ch=TILE_MONS_GIANT_LIZARD; break;
case MONS_SPECTRAL_WARRIOR: ch=TILE_MONS_SPECTRAL_WARRIOR; break;
case MONS_PULSATING_LUMP: ch=TILE_MONS_PULSATING_LUMP; break;
case MONS_STORM_DRAGON: ch=TILE_MONS_STORM_DRAGON; break;
case MONS_YAKTAUR: ch=TILE_MONS_YAKTAUR; break;
case MONS_DEATH_YAK: ch=TILE_MONS_DEATH_YAK; break;
case MONS_ROCK_TROLL: ch=TILE_MONS_ROCK_TROLL; break;
case MONS_STONE_GIANT: ch=TILE_MONS_STONE_GIANT; break;
case MONS_FLAYED_GHOST: ch=TILE_MONS_FLAYED_GHOST; break;
case MONS_BUMBLEBEE: ch=TILE_MONS_BUMBLEBEE; break;
case MONS_REDBACK: ch=TILE_MONS_REDBACK; break;
case MONS_INSUBSTANTIAL_WISP: ch=TILE_MONS_INSUBSTANTIAL_WISP; break;
case MONS_VAPOUR: ch=TILE_MONS_VAPOUR; break;
case MONS_OGRE_MAGE: ch=TILE_MONS_OGRE_MAGE; break;
case MONS_SPINY_WORM: ch=TILE_MONS_SPINY_WORM; break;
case MONS_DANCING_WEAPON:
{
// Use item tile
item_def item = mitm[menv[mon_idx].inv[MSLOT_WEAPON]];
ch = tileidx_item(item);
break;
}
case MONS_TITAN: ch=TILE_MONS_TITAN; break;
case MONS_GOLDEN_DRAGON: ch=TILE_MONS_GOLDEN_DRAGON; break;
case MONS_ELF: ch=TILE_MONS_ELF; break;
case MONS_LINDWURM: ch=TILE_MONS_LINDWURM; break;
case MONS_ELEPHANT_SLUG: ch=TILE_MONS_ELEPHANT_SLUG; break;
case MONS_WAR_DOG: ch=TILE_MONS_WAR_DOG; break;
case MONS_GREY_RAT: ch=TILE_MONS_GREY_RAT; break;
case MONS_GREEN_RAT: ch=TILE_MONS_GREEN_RAT; break;
case MONS_ORANGE_RAT: ch=TILE_MONS_ORANGE_RAT; break;
case MONS_BLACK_SNAKE: ch=TILE_MONS_BLACK_SNAKE; break;
case MONS_SHEEP: ch=TILE_MONS_SHEEP; break;
case MONS_GHOUL: ch=TILE_MONS_GHOUL; break;
case MONS_HOG: ch=TILE_MONS_HOG; break;
case MONS_GIANT_MOSQUITO: ch=TILE_MONS_GIANT_MOSQUITO; break;
case MONS_GIANT_CENTIPEDE: ch=TILE_MONS_GIANT_CENTIPEDE; break;
case MONS_IRON_TROLL: ch=TILE_MONS_IRON_TROLL; break;
case MONS_NAGA: ch=TILE_MONS_NAGA; break;
case MONS_FIRE_GIANT: ch=TILE_MONS_FIRE_GIANT; break;
case MONS_FROST_GIANT: ch=TILE_MONS_FROST_GIANT; break;
case MONS_FIREDRAKE: ch=TILE_MONS_FIREDRAKE; break;
case MONS_SHADOW_DRAGON: ch=TILE_MONS_SHADOW_DRAGON; break;
case MONS_YELLOW_SNAKE: ch=TILE_MONS_YELLOW_SNAKE; break;
case MONS_GREY_SNAKE: ch=TILE_MONS_GREY_SNAKE; break;
case MONS_DEEP_TROLL: ch=TILE_MONS_DEEP_TROLL; break;
case MONS_GIANT_BLOWFLY: ch=TILE_MONS_GIANT_BLOWFLY; break;
case MONS_RED_WASP: ch=TILE_MONS_RED_WASP; break;
case MONS_SWAMP_DRAGON: ch=TILE_MONS_SWAMP_DRAGON; break;
case MONS_SWAMP_DRAKE: ch=TILE_MONS_SWAMP_DRAKE; break;
case MONS_SOLDIER_ANT: ch=TILE_MONS_SOLDIER_ANT; break;
case MONS_HILL_GIANT: ch=TILE_MONS_HILL_GIANT; break;
case MONS_QUEEN_ANT: ch=TILE_MONS_QUEEN_ANT; break;
case MONS_ANT_LARVA: ch=TILE_MONS_ANT_LARVA; break;
case MONS_GIANT_FROG: ch=TILE_MONS_GIANT_FROG; break;
case MONS_GIANT_BROWN_FROG: ch=TILE_MONS_GIANT_BROWN_FROG; break;
case MONS_SPINY_FROG: ch=TILE_MONS_SPINY_FROG; break;
case MONS_BLINK_FROG: ch=TILE_MONS_BLINK_FROG; break;
case MONS_GIANT_COCKROACH: ch=TILE_MONS_GIANT_COCKROACH; break;
case MONS_SMALL_SNAKE: ch=TILE_MONS_SMALL_SNAKE; break;
case MONS_SHUGGOTH: ch=TILE_TODO; break;
case MONS_WOLF: ch=TILE_MONS_WOLF; break;
case MONS_WARG: ch=TILE_MONS_WARG; break;
case MONS_BEAR: ch=TILE_MONS_BEAR; break;
case MONS_GRIZZLY_BEAR: ch=TILE_MONS_GRIZZLY_BEAR; break;
case MONS_POLAR_BEAR: ch=TILE_MONS_POLAR_BEAR; break;
case MONS_BLACK_BEAR: ch=TILE_MONS_BLACK_BEAR; break;
case MONS_SIMULACRUM_SMALL: ch=TILE_MONS_SIMULACRUM_SMALL; break;
case MONS_SIMULACRUM_LARGE: ch=TILE_MONS_SIMULACRUM_LARGE; break;
case MONS_WHITE_IMP: ch=TILE_MONS_WHITE_IMP; break;
case MONS_LEMURE: ch=TILE_MONS_LEMURE; break;
case MONS_UFETUBUS: ch=TILE_MONS_UFETUBUS; break;
case MONS_MANES: ch=TILE_MONS_MANES; break;
case MONS_MIDGE: ch=TILE_MONS_MIDGE; break;
case MONS_NEQOXEC: ch=TILE_MONS_NEQOXEC; break;
case MONS_ORANGE_DEMON: ch=TILE_MONS_ORANGE_DEMON; break;
case MONS_HELLWING: ch=TILE_MONS_HELLWING; break;
case MONS_SMOKE_DEMON: ch=TILE_MONS_SMOKE_DEMON; break;
case MONS_YNOXINUL: ch=TILE_MONS_YNOXINUL; break;
case MONS_EXECUTIONER: ch=TILE_MONS_EXECUTIONER; break;
case MONS_GREEN_DEATH: ch=TILE_MONS_GREEN_DEATH; break;
case MONS_BLUE_DEATH: ch=TILE_MONS_BLUE_DEATH; break;
case MONS_BALRUG: ch=TILE_MONS_BALRUG; break;
case MONS_CACODEMON: ch=TILE_MONS_CACODEMON; break;
case MONS_DEMONIC_CRAWLER: ch=TILE_MONS_DEMONIC_CRAWLER; break;
case MONS_SUN_DEMON: ch=TILE_MONS_SUN_DEMON; break;
case MONS_SHADOW_IMP: ch=TILE_MONS_SHADOW_IMP; break;
case MONS_SHADOW_DEMON: ch=TILE_MONS_SHADOW_DEMON; break;
case MONS_LOROCYPROCA: ch=TILE_MONS_LOROCYPROCA; break;
case MONS_SHADOW_WRAITH: ch=TILE_MONS_SHADOW_WRAITH; break;
case MONS_GIANT_AMOEBA: ch=TILE_MONS_GIANT_AMOEBA; break;
case MONS_GIANT_SLUG: ch=TILE_MONS_GIANT_SLUG; break;
case MONS_GIANT_SNAIL: ch=TILE_MONS_GIANT_SNAIL; break;
case MONS_SPATIAL_VORTEX: ch=TILE_MONS_SPATIAL_VORTEX; break;
case MONS_PIT_FIEND: ch=TILE_MONS_PIT_FIEND; break;
case MONS_BORING_BEETLE: ch=TILE_MONS_BORING_BEETLE; break;
case MONS_GARGOYLE: ch=TILE_MONS_GARGOYLE; break;
case MONS_METAL_GARGOYLE: ch=TILE_MONS_METAL_GARGOYLE; break;
case MONS_MOLTEN_GARGOYLE: ch=TILE_MONS_MOLTEN_GARGOYLE; break;
case MONS_PROGRAM_BUG: ch=TILE_MONS_PROGRAM_BUG; break;
case MONS_MNOLEG: ch=TILE_MONS_MNOLEG; break;
case MONS_LOM_LOBON: ch=TILE_MONS_LOM_LOBON; break;
case MONS_CEREBOV: ch=TILE_MONS_CEREBOV; break;
case MONS_GLOORX_VLOQ: ch=TILE_MONS_GLOORX_VLOQ; break;
case MONS_MOLLUSC_LORD: ch=TILE_TODO; break;
case MONS_NAGA_MAGE: ch=TILE_MONS_NAGA_MAGE; break;
case MONS_NAGA_WARRIOR: ch=TILE_MONS_NAGA_WARRIOR; break;
case MONS_ORC_WARLORD: ch=TILE_MONS_ORC_WARLORD; break;
case MONS_DEEP_ELF_SOLDIER: ch=TILE_MONS_DEEP_ELF_SOLDIER; break;
case MONS_DEEP_ELF_FIGHTER: ch=TILE_MONS_DEEP_ELF_FIGHTER; break;
case MONS_DEEP_ELF_KNIGHT: ch=TILE_MONS_DEEP_ELF_KNIGHT; break;
case MONS_DEEP_ELF_MAGE: ch=TILE_MONS_DEEP_ELF_MAGE; break;
case MONS_DEEP_ELF_SUMMONER: ch=TILE_MONS_DEEP_ELF_SUMMONER; break;
case MONS_DEEP_ELF_CONJURER: ch=TILE_MONS_DEEP_ELF_CONJURER; break;
case MONS_DEEP_ELF_PRIEST: ch=TILE_MONS_DEEP_ELF_PRIEST; break;
case MONS_DEEP_ELF_HIGH_PRIEST: ch=TILE_MONS_DEEP_ELF_HIGH_PRIEST; break;
case MONS_DEEP_ELF_DEMONOLOGIST: ch=TILE_MONS_DEEP_ELF_DEMONOLOGIST; break;
case MONS_DEEP_ELF_ANNIHILATOR: ch=TILE_MONS_DEEP_ELF_ANNIHILATOR; break;
case MONS_DEEP_ELF_SORCERER: ch=TILE_MONS_DEEP_ELF_SORCERER; break;
case MONS_DEEP_ELF_DEATH_MAGE: ch=TILE_MONS_DEEP_ELF_DEATH_MAGE; break;
case MONS_BROWN_OOZE: ch=TILE_MONS_BROWN_OOZE; break;
case MONS_AZURE_JELLY: ch=TILE_MONS_AZURE_JELLY; break;
case MONS_DEATH_OOZE: ch=TILE_MONS_DEATH_OOZE; break;
case MONS_ACID_BLOB: ch=TILE_MONS_ACID_BLOB; break;
case MONS_ROYAL_JELLY: ch=TILE_MONS_ROYAL_JELLY; break;
case MONS_TERENCE: ch=TILE_MONS_TERENCE; break;
case MONS_JESSICA: ch=TILE_MONS_JESSICA; break;
case MONS_IJYB: ch=TILE_MONS_IJYB; break;
case MONS_SIGMUND: ch=TILE_MONS_SIGMUND; break;
case MONS_BLORK_THE_ORC: ch=TILE_MONS_BLORK_THE_ORC; break;
case MONS_EDMUND: ch=TILE_MONS_EDMUND; break;
case MONS_PSYCHE: ch=TILE_MONS_PSYCHE; break;
case MONS_EROLCHA: ch=TILE_MONS_EROLCHA; break;
case MONS_DONALD: ch=TILE_MONS_DONALD; break;
case MONS_URUG: ch=TILE_MONS_URUG; break;
case MONS_MICHAEL: ch=TILE_MONS_MICHAEL; break;
case MONS_JOSEPH: ch=TILE_MONS_JOSEPH; break;
case MONS_SNORG: ch=TILE_MONS_SNORG; break;
case MONS_ERICA: ch=TILE_MONS_ERICA; break;
case MONS_JOSEPHINE: ch=TILE_MONS_JOSEPHINE; break;
case MONS_HAROLD: ch=TILE_MONS_HAROLD; break;
case MONS_NORBERT: ch=TILE_MONS_NORBERT; break;
case MONS_JOZEF: ch=TILE_MONS_JOZEF; break;
case MONS_AGNES: ch=TILE_MONS_AGNES; break;
case MONS_MAUD: ch=TILE_MONS_MAUD; break;
case MONS_LOUISE: ch=TILE_MONS_LOUISE; break;
case MONS_FRANCIS: ch=TILE_MONS_FRANCIS; break;
case MONS_FRANCES: ch=TILE_MONS_FRANCES; break;
case MONS_RUPERT: ch=TILE_MONS_RUPERT; break;
case MONS_WAYNE: ch=TILE_MONS_WAYNE; break;
case MONS_DUANE: ch=TILE_MONS_DUANE; break;
case MONS_XTAHUA: ch=TILE_MONS_XTAHUA; break;
case MONS_NORRIS: ch=TILE_MONS_NORRIS; break;
case MONS_FREDERICK: ch=TILE_MONS_FREDERICK; break;
case MONS_MARGERY: ch=TILE_MONS_MARGERY; break;
case MONS_POLYPHEMUS: ch=TILE_MONS_POLYPHEMUS; break;
case MONS_BORIS: ch=TILE_MONS_BORIS; break;
// Draconians handled above
case MONS_MURRAY: ch=TILE_MONS_MURRAY; break;
case MONS_TIAMAT: ch=TILE_MONS_TIAMAT; break;
case MONS_DEEP_ELF_BLADEMASTER: ch=TILE_MONS_DEEP_ELF_BLADEMASTER; break;
case MONS_DEEP_ELF_MASTER_ARCHER: ch=TILE_MONS_DEEP_ELF_MASTER_ARCHER; break;
case MONS_GERYON: ch=TILE_MONS_GERYON; break;
case MONS_DISPATER: ch=TILE_MONS_DISPATER; break;
case MONS_ASMODEUS: ch=TILE_MONS_ASMODEUS; break;
case MONS_ANTAEUS: ch=TILE_MONS_ANTAEUS; break;
case MONS_ERESHKIGAL: ch=TILE_MONS_ERESHKIGAL; break;
case MONS_ANCIENT_LICH: ch=TILE_MONS_ANCIENT_LICH; break;
case MONS_OOZE: ch=TILE_MONS_OOZE; break;
case MONS_VAULT_GUARD: ch=TILE_MONS_VAULT_GUARD; break;
case MONS_CURSE_SKULL: ch=TILE_MONS_CURSE_SKULL; break;
case MONS_VAMPIRE_KNIGHT: ch=TILE_MONS_VAMPIRE_KNIGHT; break;
case MONS_VAMPIRE_MAGE: ch=TILE_MONS_VAMPIRE_MAGE; break;
case MONS_SHINING_EYE: ch=TILE_MONS_SHINING_EYE; break;
case MONS_ORB_GUARDIAN: ch=TILE_MONS_ORB_GUARDIAN; break;
case MONS_DAEVA: ch=TILE_MONS_DAEVA; break;
case MONS_SPECTRAL_THING: ch=TILE_MONS_SPECTRAL_THING; break;
case MONS_GREATER_NAGA: ch=TILE_MONS_GREATER_NAGA; break;
case MONS_SKELETAL_DRAGON: ch=TILE_MONS_SKELETAL_DRAGON; break;
case MONS_TENTACLED_MONSTROSITY: ch=TILE_MONS_TENTACLED_MONSTROSITY; break;
case MONS_SPHINX: ch=TILE_MONS_SPHINX; break;
case MONS_ROTTING_HULK: ch=TILE_MONS_ROTTING_HULK; break;
case MONS_GUARDIAN_MUMMY: ch=TILE_MONS_GUARDIAN_MUMMY; break;
case MONS_GREATER_MUMMY: ch=TILE_MONS_GREATER_MUMMY; break;
case MONS_MUMMY_PRIEST: ch=TILE_MONS_MUMMY_PRIEST; break;
case MONS_CENTAUR_WARRIOR: ch=TILE_MONS_CENTAUR_WARRIOR; break;
case MONS_YAKTAUR_CAPTAIN: ch=TILE_MONS_YAKTAUR_CAPTAIN; break;
case MONS_KILLER_KLOWN: ch=TILE_MONS_KILLER_KLOWN; break;
case MONS_ELECTRIC_GOLEM: ch=TILE_MONS_ELECTRIC_GOLEM; break;
case MONS_BALL_LIGHTNING: ch=TILE_MONS_BALL_LIGHTNING; break;
case MONS_ORB_OF_FIRE: ch=TILE_MONS_ORB_OF_FIRE; break;
case MONS_QUOKKA: ch=TILE_MONS_QUOKKA; break;
case MONS_EYE_OF_DEVASTATION: ch=TILE_MONS_EYE_OF_DEVASTATION; break;
case MONS_MOTH_OF_WRATH: ch=TILE_MONS_MOTH_OF_WRATH; break;
case MONS_DEATH_COB: ch=TILE_MONS_DEATH_COB; break;
case MONS_CURSE_TOE: ch=TILE_MONS_CURSE_TOE; break;
// case MONS_GOLD_MIMIC: ch=TILE_MONS_GOLD_MIMIC; break;
case MONS_GOLD_MIMIC:
case MONS_WEAPON_MIMIC:
case MONS_ARMOUR_MIMIC:
case MONS_SCROLL_MIMIC:
case MONS_POTION_MIMIC:
{
// Use item tile
item_def item;
struct monsters *mon = &menv[mon_idx];
get_mimic_item( mon, item );
ch = tileidx_item(item);
break;
}
case MONS_HELL_HOG: ch=TILE_MONS_HELL_HOG; break;
case MONS_SERPENT_OF_HELL: ch=TILE_MONS_SERPENT_OF_HELL; break;
case MONS_BOGGART: ch=TILE_MONS_BOGGART; break;
case MONS_QUICKSILVER_DRAGON: ch=TILE_MONS_QUICKSILVER_DRAGON; break;
case MONS_IRON_DRAGON: ch=TILE_MONS_IRON_DRAGON; break;
case MONS_SKELETAL_WARRIOR: ch=TILE_MONS_SKELETAL_WARRIOR; break;
case MONS_PLAYER_GHOST: ch=TILE_MONS_PLAYER_GHOST; break;
case MONS_PANDEMONIUM_DEMON: ch=TILE_MONS_PANDEMONIUM_DEMON; break;
case MONS_GIANT_NEWT: ch=TILE_MONS_GIANT_NEWT; break;
case MONS_GIANT_GECKO: ch=TILE_MONS_GIANT_GECKO; break;
case MONS_GIANT_IGUANA: ch=TILE_MONS_GIANT_IGUANA; break;
case MONS_GILA_MONSTER: ch=TILE_MONS_GILA_MONSTER; break;
case MONS_KOMODO_DRAGON: ch=TILE_MONS_KOMODO_DRAGON; break;
case MONS_LAVA_WORM: ch=TILE_MONS_LAVA_WORM; break;
case MONS_LAVA_FISH: ch=TILE_MONS_LAVA_FISH; break;
case MONS_LAVA_SNAKE: ch=TILE_MONS_LAVA_SNAKE; break;
case MONS_SALAMANDER: ch=TILE_MONS_SALAMANDER; break;
case MONS_BIG_FISH: ch=TILE_MONS_BIG_FISH; break;
case MONS_GIANT_GOLDFISH: ch=TILE_MONS_GIANT_GOLDFISH; break;
case MONS_ELECTRICAL_EEL: ch=TILE_MONS_ELECTRICAL_EEL; break;
case MONS_JELLYFISH: ch=TILE_MONS_JELLYFISH; break;
case MONS_WATER_ELEMENTAL: ch=TILE_MONS_WATER_ELEMENTAL; break;
case MONS_SWAMP_WORM: ch=TILE_MONS_SWAMP_WORM; break;
case MONS_ORANGE_STATUE: ch = TILE_DNGN_ORANGE_CRYSTAL_STATUE; break;
case MONS_SILVER_STATUE: ch = TILE_DNGN_SILVER_STATUE; break;
case MONS_ICE_STATUE: ch = TILE_DNGN_ICE_STATUE; break;
case MONS_DEATH_DRAKE: ch=TILE_MONS_DEATH_DRAKE; break;
}
if(mons_flies(&menv[mon_idx])) ch |= TILE_FLAG_FLYING;
if(menv[mon_idx].has_ench(ENCH_HELD)) ch |= TILE_FLAG_NET;
if(mons_friendly(&menv[mon_idx]))
{
ch |= TILE_FLAG_PET;
}
else if (Options.stab_brand != CHATTR_NORMAL &&
mons_looks_stabbable(&menv[mon_idx]))
{
ch |= TILE_FLAG_STAB;
}
else if (Options.may_stab_brand != CHATTR_NORMAL &&
mons_looks_distracted(&menv[mon_idx]))
{
ch |= TILE_FLAG_MAY_STAB;
}
return ch;
}
int tileidx_fixed_artifact(int special)
{
int ch = TILE_ERROR;
switch(special)
{
case SPWPN_SINGING_SWORD: ch=TILE_SPWPN_SINGING_SWORD; break;
case SPWPN_WRATH_OF_TROG: ch=TILE_SPWPN_WRATH_OF_TROG; break;
case SPWPN_SCYTHE_OF_CURSES: ch=TILE_SPWPN_SCYTHE_OF_CURSES; break;
case SPWPN_MACE_OF_VARIABILITY: ch=TILE_SPWPN_MACE_OF_VARIABILITY; break;
case SPWPN_GLAIVE_OF_PRUNE: ch=TILE_SPWPN_GLAIVE_OF_PRUNE; break;
case SPWPN_SCEPTRE_OF_TORMENT: ch=TILE_SPWPN_SCEPTRE_OF_TORMENT; break;
case SPWPN_SWORD_OF_ZONGULDROK: ch=TILE_SPWPN_SWORD_OF_ZONGULDROK; break;
case SPWPN_SWORD_OF_CEREBOV: ch=TILE_SPWPN_SWORD_OF_CEREBOV; break;
case SPWPN_STAFF_OF_DISPATER: ch=TILE_SPWPN_STAFF_OF_DISPATER; break;
case SPWPN_SCEPTRE_OF_ASMODEUS: ch=TILE_SPWPN_SCEPTRE_OF_ASMODEUS; break;
case SPWPN_SWORD_OF_POWER: ch=TILE_SPWPN_SWORD_OF_POWER; break;
case SPWPN_KNIFE_OF_ACCURACY: ch=TILE_SPWPN_KNIFE_OF_ACCURACY; break;
case SPWPN_STAFF_OF_OLGREB: ch=TILE_SPWPN_STAFF_OF_OLGREB; break;
case SPWPN_VAMPIRES_TOOTH: ch=TILE_SPWPN_VAMPIRES_TOOTH; break;
case SPWPN_STAFF_OF_WUCAD_MU: ch=TILE_SPWPN_STAFF_OF_WUCAD_MU; break;
}
return ch;
}
int tileidx_unrand_artifact(int idx)
{
switch (idx)
{
case 1: return TILE_URAND_BLOODBANE;
case 2: return TILE_URAND_SHADOWS;
case 3: return TILE_URAND_FLAMING_DEATH;
case 4: return TILE_URAND_IGNORANCE;
case 5: return TILE_URAND_ZIN;
case 6: return TILE_URAND_AUGMENTATION;
case 7: return TILE_URAND_BRILLIANCE;
case 8: return TILE_URAND_THIEF;
case 9: return TILE_URAND_BULLSEYE;
case 10: return TILE_URAND_DYROVEPREVA;
case 11: return TILE_URAND_LEECH;
case 12: return TILE_URAND_CEKUGOB;
case 13: return TILE_URAND_MISFORTUNE;
case 14: return TILE_URAND_CHILLY_DEATH;
case 15: return TILE_URAND_FOUR_WINDS;
case 16: return TILE_URAND_MORG;
case 17: return TILE_URAND_FINISHER;
case 18: return TILE_URAND_PUNK;
case 19: return TILE_URAND_KRISHNA;
case 20: return TILE_URAND_FLASH;
case 21: return TILE_URAND_SKULLCRUSHER;
case 22: return TILE_URAND_ASSASSIN;
case 23: return TILE_URAND_GUARD;
case 24: return TILE_URAND_JIHAD;
case 25: return TILE_URAND_LEAR;
case 26: return TILE_URAND_ZHOR;
case 27: return TILE_URAND_FIERY_DEVIL;
case 28: return TILE_URAND_SALAMANDER;
case 29: return TILE_URAND_WAR;
case 30: return TILE_URAND_DOOM_KNIGHT;
case 31: return TILE_URAND_RESISTANCE;
case 32: return TILE_URAND_FOLLY;
case 33: return TILE_URAND_BLOODLUST;
case 34: return TILE_URAND_EOS;
case 35: return TILE_URAND_SHAOLIN;
case 36: return TILE_URAND_ROBUSTNESS;
case 37: return TILE_URAND_EDISON;
case 38: return TILE_URAND_VOO_DOO;
case 39: return TILE_URAND_OCTOPUS_KING;
case 40: return TILE_URAND_DRAGONMASK;
case 41: return TILE_URAND_ARGA;
case 42: return TILE_URAND_ELEMENTAL;
case 43: return TILE_URAND_SNIPER;
case 44: return TILE_URAND_ERCHIDEL;
case 45: return TILE_URAND_NIGHT;
case 46: return TILE_URAND_PLUTONIUM;
case 47: return TILE_URAND_UNDERADHUNTER;
case 48: return TILE_URAND_DRAGON_KING;
case 49: return TILE_URAND_ALCHEMIST;
case 50: return TILE_URAND_FENCER;
case 51: return TILE_URAND_MAGE;
case 52: return TILE_URAND_BLOWGUN;
}
return 0;
}
int get_etype(const item_def &item)
{
int etype;
switch (item.flags & ISFLAG_COSMETIC_MASK)
{
case ISFLAG_EMBROIDERED_SHINY:
etype = 1;
break;
case ISFLAG_RUNED:
etype = 2;
break;
case ISFLAG_GLOWING:
etype = 3;
break;
default:
etype = is_random_artefact(item) ? 4 : 0;
break;
}
return etype;
}
int tileidx_weapon(const item_def &item)
{
int ch = TILE_ERROR;
int race = item.flags & ISFLAG_RACIAL_MASK;
int etype = get_etype(item);
static const int etable[4][4] = {
{0, 0, 0, 0}, // No ego tile
{0, 1, 1, 1}, // One ego tile
{0, 1, 1, 2}, // Two ego tile
{0, 1, 2, 3}
};
if (etype > 1)
etype--;
switch(item.sub_type)
{
case WPN_KNIFE: ch=TILE_WPN_KNIFE; break;
case WPN_DAGGER:
ch=TILE_WPN_DAGGER;
if (race == ISFLAG_ORCISH) ch = TILE_WPN_DAGGER_ORC;
if (race == ISFLAG_ELVEN ) ch = TILE_WPN_DAGGER_ELF;
break;
case WPN_SHORT_SWORD:
ch=TILE_WPN_SHORT_SWORD + etable[1][etype];
if (race == ISFLAG_ORCISH) ch = TILE_WPN_SHORT_SWORD_ORC;
if (race == ISFLAG_ELVEN ) ch = TILE_WPN_SHORT_SWORD_ELF;
break;
case WPN_QUICK_BLADE: ch=TILE_WPN_QUICK_BLADE; break;
case WPN_SABRE:
ch=TILE_WPN_SABRE + etable[1][etype];
break;
case WPN_FALCHION: ch=TILE_WPN_FALCHION; break;
case WPN_KATANA:
ch=TILE_WPN_KATANA + etable[1][etype];
break;
case WPN_LONG_SWORD:
ch=TILE_WPN_LONG_SWORD + etable[1][etype];
if (race == ISFLAG_ORCISH) ch = TILE_WPN_LONG_SWORD_ORC;
break;
case WPN_GREAT_SWORD:
ch=TILE_WPN_GREAT_SWORD + etable[1][etype];
if (race == ISFLAG_ORCISH) ch = TILE_WPN_GREAT_SWORD_ORC;
break;
case WPN_SCIMITAR:
ch=TILE_WPN_SCIMITAR + etable[1][etype];
break;
case WPN_DOUBLE_SWORD: ch=TILE_WPN_DOUBLE_SWORD; break;
case WPN_TRIPLE_SWORD: ch=TILE_WPN_TRIPLE_SWORD; break;
case WPN_HAND_AXE: ch=TILE_WPN_HAND_AXE; break;
case WPN_WAR_AXE: ch=TILE_WPN_WAR_AXE; break;
case WPN_BROAD_AXE:
ch=TILE_WPN_BROAD_AXE + etable[1][etype];
break;
case WPN_BATTLEAXE:
ch=TILE_WPN_BATTLEAXE + etable[1][etype];
break;
case WPN_EXECUTIONERS_AXE:
ch=TILE_WPN_EXECUTIONERS_AXE + etable[1][etype];
break;
case WPN_BLOWGUN:
ch=TILE_WPN_BLOWGUN + etable[1][etype];
break;
case WPN_SLING: ch=TILE_WPN_SLING; break;
case WPN_BOW:
ch=TILE_WPN_BOW + etable[1][etype];
break;
case WPN_CROSSBOW:
ch=TILE_WPN_CROSSBOW + etable[1][etype];
break;
case WPN_HAND_CROSSBOW:
ch=TILE_WPN_HAND_CROSSBOW + etable[1][etype];
break;
case WPN_SPEAR:
ch=TILE_WPN_SPEAR + etable[1][etype];
break;
case WPN_TRIDENT:
ch=TILE_WPN_TRIDENT + etable[1][etype];
break;
case WPN_HALBERD:
ch=TILE_WPN_HALBERD + etable[1][etype];
break;
case WPN_SCYTHE:
ch=TILE_WPN_SCYTHE + etable[1][etype];
break;
case WPN_GLAIVE:
ch=TILE_WPN_GLAIVE + etable[1][etype];
if (race == ISFLAG_ORCISH) ch = TILE_WPN_GLAIVE_ORC;
break;
case WPN_QUARTERSTAFF: ch=TILE_WPN_QUARTERSTAFF; break;
case WPN_CLUB: ch=TILE_WPN_CLUB; break;
case WPN_HAMMER:
ch=TILE_WPN_HAMMER + etable[1][etype];
break;
case WPN_MACE:
ch=TILE_WPN_MACE + etable[1][etype];
break;
case WPN_FLAIL:
ch=TILE_WPN_FLAIL + etable[1][etype];
break;
case WPN_SPIKED_FLAIL:
ch=TILE_WPN_SPIKED_FLAIL + etable[1][etype];
break;
case WPN_GREAT_MACE:
ch=TILE_WPN_GREAT_MACE + etable[1][etype];
break;
case WPN_DIRE_FLAIL:
ch=TILE_WPN_GREAT_FLAIL + etable[1][etype];
break;
case WPN_MORNINGSTAR:
ch=TILE_WPN_MORNINGSTAR + etable[1][etype];
break;
case WPN_EVENINGSTAR:
ch=TILE_WPN_EVENINGSTAR + etable[1][etype];
break;
case WPN_GIANT_CLUB: ch=TILE_WPN_GIANT_CLUB; break;
case WPN_GIANT_SPIKED_CLUB: ch=TILE_WPN_GIANT_SPIKED_CLUB; break;
case WPN_ANCUS: ch=TILE_WPN_ANCUS; break;
case WPN_WHIP: ch=TILE_WPN_WHIP; break;
case WPN_DEMON_BLADE: ch=TILE_WPN_DEMON_BLADE; break;
case WPN_DEMON_WHIP: ch=TILE_WPN_DEMON_WHIP; break;
case WPN_DEMON_TRIDENT: ch=TILE_WPN_DEMON_TRIDENT; break;
case WPN_BLESSED_BLADE: ch=TILE_WPN_BLESSED_BLADE; break;
case WPN_LONGBOW: ch=TILE_WPN_LONGBOW; break;
case WPN_LAJATANG: ch=TILE_WPN_LAJATANG; break;
case WPN_BARDICHE: ch=TILE_WPN_LOCHABER_AXE; break;
}
return ch;
}
int tileidx_missile(const item_def &item)
{
int ch = TILE_ERROR;
int brand = item.special;
switch(item.sub_type)
{
case MI_STONE: ch=TILE_MI_STONE; break;
case MI_ARROW: ch=TILE_MI_ARROW; break;
case MI_BOLT: ch=TILE_MI_BOLT; break;
case MI_DART:
ch=TILE_MI_DART;
if (brand == SPMSL_POISONED || brand == SPMSL_POISONED_II)
ch = TILE_MI_DART_P;
break;
case MI_NEEDLE:
ch=TILE_MI_NEEDLE;
if (brand == SPMSL_POISONED || brand == SPMSL_POISONED_II)
ch = TILE_MI_NEEDLE_P;
break;
case MI_LARGE_ROCK: ch=TILE_MI_LARGE_ROCK; break;
case MI_SLING_BULLET: ch=TILE_MI_SLING_BULLET; break;
case MI_JAVELIN: ch=TILE_MI_JAVELIN; break;
case MI_THROWING_NET: ch=TILE_MI_THROWING_NET; break;
}
return ch;
}
int tileidx_armour(const item_def &item)
{
int ch = TILE_ERROR;
int race = item.flags & ISFLAG_RACIAL_MASK;
int type=item.sub_type;
int etype = get_etype(item);
static const int etable[5][5] = {
{0, 0, 0, 0, 0}, // No ego tile
{0, 1, 1, 1, 1}, // One ego tile
{0, 1, 1, 1, 2}, // Two ego tile
{0, 1, 1, 2, 3},
{0, 1, 2, 3, 4}
};
switch(type)
{
case ARM_ROBE:
ch= TILE_ARM_ROBE + etable[2][etype];
break;
case ARM_LEATHER_ARMOUR:
ch=TILE_ARM_LEATHER_ARMOUR + etable[2][etype];
if (race == ISFLAG_ORCISH) ch = TILE_ARM_LEATHER_ARMOUR_ORC;
if (race == ISFLAG_ELVEN ) ch = TILE_ARM_LEATHER_ARMOUR_ELF;
break;
case ARM_RING_MAIL:
ch=TILE_ARM_RING_MAIL + etable[1][etype];
if (race == ISFLAG_ORCISH) ch = TILE_ARM_RING_MAIL_ORC;
if (race == ISFLAG_ELVEN ) ch = TILE_ARM_RING_MAIL_ELF;
if (race == ISFLAG_DWARVEN ) ch = TILE_ARM_RING_MAIL_DWA;
break;
case ARM_SCALE_MAIL:
ch=TILE_ARM_SCALE_MAIL + etable[1][etype];
if (race == ISFLAG_ELVEN ) ch = TILE_ARM_SCALE_MAIL_ELF;
break;
case ARM_CHAIN_MAIL:
ch=TILE_ARM_CHAIN_MAIL + etable[1][etype];
if (race == ISFLAG_ELVEN) ch = TILE_ARM_CHAIN_MAIL_ELF;
if (race == ISFLAG_ORCISH) ch = TILE_ARM_CHAIN_MAIL_ORC;
break;
case ARM_SPLINT_MAIL: ch=TILE_ARM_SPLINT_MAIL; break;
case ARM_BANDED_MAIL: ch=TILE_ARM_BANDED_MAIL; break;
case ARM_PLATE_MAIL:
ch=TILE_ARM_PLATE_MAIL;
if (race == ISFLAG_ORCISH) ch = TILE_ARM_PLATE_MAIL_ORC;
break;
case ARM_CRYSTAL_PLATE_MAIL: ch=TILE_ARM_CRYSTAL_PLATE_MAIL; break;
case ARM_SHIELD: ch=TILE_ARM_SHIELD + etable[2][etype]; break;
case ARM_CLOAK:
ch=TILE_ARM_CLOAK + etable[3][etype];
break;
case ARM_WIZARD_HAT:
ch=TILE_THELM_WIZARD_HAT + etable[1][etype]; break;
case ARM_CAP:
ch=TILE_THELM_CAP; break;
case ARM_HELMET:
ch=TILE_THELM_HELM + etable[3][etype]; break;
case ARM_GLOVES:
ch=TILE_ARM_GLOVES + etable[3][etype];
break;
case ARM_BOOTS:
ch=TILE_ARM_BOOTS + etable[3][etype];
break;
case ARM_BUCKLER:
ch=TILE_ARM_BUCKLER + etable[1][etype];
break;
case ARM_LARGE_SHIELD:
ch=TILE_ARM_LARGE_SHIELD + etable[2][etype];
break;
case ARM_CENTAUR_BARDING: ch=TILE_ARM_CENTAUR_BARDING; break;
case ARM_NAGA_BARDING: ch=TILE_ARM_NAGA_BARDING; break;
case ARM_ANIMAL_SKIN: ch=TILE_ARM_ANIMAL_SKIN + etable[1][etype]; break;
case ARM_TROLL_HIDE: ch=TILE_ARM_TROLL_HIDE; break;
case ARM_TROLL_LEATHER_ARMOUR: ch=TILE_ARM_TROLL_LEATHER_ARMOUR; break;
case ARM_DRAGON_HIDE: ch=TILE_ARM_DRAGON_HIDE; break;
case ARM_DRAGON_ARMOUR: ch=TILE_ARM_DRAGON_ARMOUR; break;
case ARM_ICE_DRAGON_HIDE: ch=TILE_ARM_ICE_DRAGON_HIDE; break;
case ARM_ICE_DRAGON_ARMOUR: ch=TILE_ARM_ICE_DRAGON_ARMOUR; break;
case ARM_STEAM_DRAGON_HIDE: ch=TILE_ARM_STEAM_DRAGON_HIDE; break;
case ARM_STEAM_DRAGON_ARMOUR: ch=TILE_ARM_STEAM_DRAGON_ARMOUR; break;
case ARM_MOTTLED_DRAGON_HIDE: ch=TILE_ARM_MOTTLED_DRAGON_HIDE; break;
case ARM_MOTTLED_DRAGON_ARMOUR: ch=TILE_ARM_MOTTLED_DRAGON_ARMOUR; break;
case ARM_STORM_DRAGON_HIDE: ch=TILE_ARM_STORM_DRAGON_HIDE; break;
case ARM_STORM_DRAGON_ARMOUR: ch=TILE_ARM_STORM_DRAGON_ARMOUR; break;
case ARM_GOLD_DRAGON_HIDE: ch=TILE_ARM_GOLD_DRAGON_HIDE; break;
case ARM_GOLD_DRAGON_ARMOUR: ch=TILE_ARM_GOLD_DRAGON_ARMOUR; break;
case ARM_SWAMP_DRAGON_HIDE: ch=TILE_ARM_SWAMP_DRAGON_HIDE; break;
case ARM_SWAMP_DRAGON_ARMOUR: ch=TILE_ARM_SWAMP_DRAGON_ARMOUR; break;
}
return ch;
}
int tileidx_food(const item_def &item)
{
int ch = TILE_ERROR;
int type=item.sub_type;
switch(type)
{
case FOOD_MEAT_RATION: ch=TILE_FOOD_MEAT_RATION; break;
case FOOD_BREAD_RATION: ch=TILE_FOOD_BREAD_RATION; break;
case FOOD_PEAR: ch=TILE_FOOD_PEAR; break;
case FOOD_APPLE: ch=TILE_FOOD_APPLE; break;
case FOOD_CHOKO: ch=TILE_FOOD_CHOKO; break;
case FOOD_HONEYCOMB: ch=TILE_FOOD_HONEYCOMB; break;
case FOOD_ROYAL_JELLY: ch=TILE_FOOD_ROYAL_JELLY; break;
case FOOD_SNOZZCUMBER: ch=TILE_FOOD_SNOZZCUMBER; break;
case FOOD_PIZZA: ch=TILE_FOOD_PIZZA; break;
case FOOD_APRICOT: ch=TILE_FOOD_APRICOT; break;
case FOOD_ORANGE: ch=TILE_FOOD_ORANGE; break;
case FOOD_BANANA: ch=TILE_FOOD_BANANA; break;
case FOOD_STRAWBERRY: ch=TILE_FOOD_STRAWBERRY; break;
case FOOD_RAMBUTAN: ch=TILE_FOOD_RAMBUTAN; break;
case FOOD_LEMON: ch=TILE_FOOD_LEMON; break;
case FOOD_GRAPE: ch=TILE_FOOD_GRAPE; break;
case FOOD_SULTANA: ch=TILE_FOOD_SULTANA; break;
case FOOD_LYCHEE: ch=TILE_FOOD_LYCHEE; break;
case FOOD_BEEF_JERKY: ch=TILE_FOOD_BEEF_JERKY; break;
case FOOD_CHEESE: ch=TILE_FOOD_CHEESE; break;
case FOOD_SAUSAGE: ch=TILE_FOOD_SAUSAGE; break;
case FOOD_CHUNK:
ch=TILE_FOOD_CHUNK;
if (item.special < 100) ch = TILE_FOOD_CHUNK_ROTTEN;
break;
}
return ch;
}
int tileidx_corpse(int mon)
{
int ch = TILE_ERROR;
switch(mon)
{
case MONS_GIANT_ANT: ch=TILE_CORPSE_GIANT_ANT; break;
case MONS_GIANT_BAT: ch=TILE_CORPSE_GIANT_BAT; break;
case MONS_CENTAUR: ch=TILE_CORPSE_CENTAUR; break;
case MONS_GOBLIN: ch=TILE_CORPSE_GOBLIN; break;
case MONS_HOUND: ch=TILE_CORPSE_HOUND; break;
case MONS_JACKAL: ch=TILE_CORPSE_JACKAL; break;
case MONS_KILLER_BEE: ch=TILE_CORPSE_KILLER_BEE; break;
case MONS_KILLER_BEE_LARVA: ch=TILE_CORPSE_KILLER_BEE_LARVA; break;
case MONS_MANTICORE: ch=TILE_CORPSE_MANTICORE; break;
case MONS_NECROPHAGE: ch=TILE_CORPSE_NECROPHAGE; break;
case MONS_ORC: ch=TILE_CORPSE_ORC; break;
case MONS_RAT: ch=TILE_CORPSE_RAT; break;
case MONS_SCORPION: ch=TILE_CORPSE_SCORPION; break;
case MONS_UGLY_THING: ch=TILE_CORPSE_UGLY_THING; break;
case MONS_WORM: ch=TILE_CORPSE_WORM; break;
case MONS_YELLOW_WASP: ch=TILE_CORPSE_YELLOW_WASP; break;
case MONS_GIANT_BEETLE: ch=TILE_CORPSE_GIANT_BEETLE; break;
case MONS_CYCLOPS: ch=TILE_CORPSE_CYCLOPS; break;
case MONS_DRAGON: ch=TILE_CORPSE_DRAGON; break;
case MONS_TWO_HEADED_OGRE: ch=TILE_CORPSE_TWO_HEADED_OGRE; break;
case MONS_HOBGOBLIN: ch=TILE_CORPSE_HOBGOBLIN; break;
case MONS_KOBOLD: ch=TILE_CORPSE_KOBOLD; break;
case MONS_GUARDIAN_NAGA: ch=TILE_CORPSE_GUARDIAN_NAGA; break;
case MONS_OGRE: ch=TILE_CORPSE_OGRE; break;
case MONS_QUEEN_BEE: ch=TILE_CORPSE_QUEEN_BEE; break;
case MONS_SNAKE: ch=TILE_CORPSE_SNAKE; break;
case MONS_TROLL: ch=TILE_CORPSE_TROLL; break;
case MONS_YAK: ch=TILE_CORPSE_YAK; break;
case MONS_WYVERN: ch=TILE_CORPSE_WYVERN; break;
case MONS_GIANT_EYEBALL: ch=TILE_CORPSE_GIANT_EYEBALL; break;
case MONS_WOLF_SPIDER: ch=TILE_CORPSE_WOLF_SPIDER; break;
case MONS_EYE_OF_DRAINING: ch=TILE_CORPSE_EYE_OF_DRAINING; break;
case MONS_BUTTERFLY: ch=TILE_CORPSE_BUTTERFLY; break;
case MONS_BRAIN_WORM: ch=TILE_CORPSE_BRAIN_WORM; break;
case MONS_GIANT_ORANGE_BRAIN: ch=TILE_CORPSE_GIANT_ORANGE_BRAIN; break;
case MONS_BOULDER_BEETLE: ch=TILE_CORPSE_BOULDER_BEETLE; break;
case MONS_MINOTAUR: ch=TILE_CORPSE_MINOTAUR; break;
case MONS_ICE_DRAGON: ch=TILE_CORPSE_ICE_DRAGON; break;
case MONS_GREAT_ORB_OF_EYES: ch=TILE_CORPSE_GREAT_ORB_OF_EYES; break;
case MONS_GLOWING_SHAPESHIFTER: ch=TILE_CORPSE_GLOWING_SHAPESHIFTER; break;
case MONS_SHAPESHIFTER: ch=TILE_CORPSE_SHAPESHIFTER; break;
case MONS_GIANT_MITE: ch=TILE_CORPSE_GIANT_MITE; break;
case MONS_STEAM_DRAGON: ch=TILE_CORPSE_STEAM_DRAGON; break;
case MONS_VERY_UGLY_THING: ch=TILE_CORPSE_VERY_UGLY_THING; break;
// case MONS_ORC_SORCERER: ch=TILE_CORPSE_ORC_SORCERER; break;
case MONS_HIPPOGRIFF: ch=TILE_CORPSE_HIPPOGRIFF; break;
case MONS_GRIFFON: ch=TILE_CORPSE_GRIFFON; break;
case MONS_HYDRA: ch=TILE_CORPSE_HYDRA; break;
case MONS_HELL_KNIGHT: ch=TILE_CORPSE_HELL_KNIGHT; break;
case MONS_NECROMANCER: ch=TILE_CORPSE_NECROMANCER; break;
case MONS_WIZARD: ch=TILE_CORPSE_WIZARD; break;
// case MONS_ORC_PRIEST: ch=TILE_CORPSE_ORC_PRIEST; break;
// case MONS_ORC_HIGH_PRIEST: ch=TILE_CORPSE_ORC_HIGH_PRIEST; break;
case MONS_HUMAN: ch=TILE_CORPSE_HUMAN; break;
case MONS_GNOLL: ch=TILE_CORPSE_GNOLL; break;
case MONS_MOTTLED_DRAGON: ch=TILE_CORPSE_MOTTLED_DRAGON; break;
case MONS_BROWN_SNAKE: ch=TILE_CORPSE_BROWN_SNAKE; break;
case MONS_GIANT_LIZARD: ch=TILE_CORPSE_GIANT_LIZARD; break;
case MONS_STORM_DRAGON: ch=TILE_CORPSE_STORM_DRAGON; break;
case MONS_YAKTAUR: ch=TILE_CORPSE_YAKTAUR; break;
case MONS_DEATH_YAK: ch=TILE_CORPSE_DEATH_YAK; break;
case MONS_ROCK_TROLL: ch=TILE_CORPSE_ROCK_TROLL; break;
case MONS_STONE_GIANT: ch=TILE_CORPSE_STONE_GIANT; break;
case MONS_BUMBLEBEE: ch=TILE_CORPSE_BUMBLEBEE; break;
case MONS_REDBACK: ch=TILE_CORPSE_REDBACK; break;
case MONS_SPINY_WORM: ch=TILE_CORPSE_SPINY_WORM; break;
case MONS_TITAN: ch=TILE_CORPSE_TITAN; break;
case MONS_GOLDEN_DRAGON: ch=TILE_CORPSE_GOLDEN_DRAGON; break;
case MONS_ELF: ch=TILE_CORPSE_ELF; break;
case MONS_LINDWURM: ch=TILE_CORPSE_LINDWURM; break;
case MONS_ELEPHANT_SLUG: ch=TILE_CORPSE_ELEPHANT_SLUG; break;
case MONS_WAR_DOG: ch=TILE_CORPSE_WAR_DOG; break;
case MONS_GREY_RAT: ch=TILE_CORPSE_GREY_RAT; break;
case MONS_GREEN_RAT: ch=TILE_CORPSE_GREEN_RAT; break;
case MONS_ORANGE_RAT: ch=TILE_CORPSE_ORANGE_RAT; break;
case MONS_BLACK_SNAKE: ch=TILE_CORPSE_BLACK_SNAKE; break;
case MONS_SHEEP: ch=TILE_CORPSE_SHEEP; break;
case MONS_GHOUL: ch=TILE_CORPSE_GHOUL; break;
case MONS_HOG: ch=TILE_CORPSE_HOG; break;
case MONS_GIANT_MOSQUITO: ch=TILE_CORPSE_GIANT_MOSQUITO; break;
case MONS_GIANT_CENTIPEDE: ch=TILE_CORPSE_GIANT_CENTIPEDE; break;
case MONS_IRON_TROLL: ch=TILE_CORPSE_IRON_TROLL; break;
case MONS_NAGA: ch=TILE_CORPSE_NAGA; break;
case MONS_FIRE_GIANT: ch=TILE_CORPSE_FIRE_GIANT; break;
case MONS_FROST_GIANT: ch=TILE_CORPSE_FROST_GIANT; break;
case MONS_FIREDRAKE: ch=TILE_CORPSE_FIREDRAKE; break;
case MONS_SHADOW_DRAGON: ch=TILE_CORPSE_SHADOW_DRAGON; break;
case MONS_YELLOW_SNAKE: ch=TILE_CORPSE_YELLOW_SNAKE; break;
case MONS_GREY_SNAKE: ch=TILE_CORPSE_GREY_SNAKE; break;
case MONS_DEEP_TROLL: ch=TILE_CORPSE_DEEP_TROLL; break;
case MONS_GIANT_BLOWFLY: ch=TILE_CORPSE_GIANT_BLOWFLY; break;
case MONS_RED_WASP: ch=TILE_CORPSE_RED_WASP; break;
case MONS_SWAMP_DRAGON: ch=TILE_CORPSE_SWAMP_DRAGON; break;
case MONS_SWAMP_DRAKE: ch=TILE_CORPSE_SWAMP_DRAKE; break;
case MONS_SOLDIER_ANT: ch=TILE_CORPSE_SOLDIER_ANT; break;
case MONS_HILL_GIANT: ch=TILE_CORPSE_HILL_GIANT; break;
case MONS_QUEEN_ANT: ch=TILE_CORPSE_QUEEN_ANT; break;
case MONS_ANT_LARVA: ch=TILE_CORPSE_ANT_LARVA; break;
case MONS_GIANT_FROG: ch=TILE_CORPSE_GIANT_FROG; break;
case MONS_GIANT_BROWN_FROG: ch=TILE_CORPSE_GIANT_BROWN_FROG; break;
case MONS_SPINY_FROG: ch=TILE_CORPSE_SPINY_FROG; break;
case MONS_BLINK_FROG: ch=TILE_CORPSE_BLINK_FROG; break;
case MONS_GIANT_COCKROACH: ch=TILE_CORPSE_GIANT_COCKROACH; break;
case MONS_SMALL_SNAKE: ch=TILE_CORPSE_SMALL_SNAKE; break;
case MONS_GIANT_AMOEBA: ch=TILE_CORPSE_GIANT_AMOEBA; break;
case MONS_GIANT_SLUG: ch=TILE_CORPSE_GIANT_SLUG; break;
case MONS_GIANT_SNAIL: ch=TILE_CORPSE_GIANT_SNAIL; break;
case MONS_BORING_BEETLE: ch=TILE_CORPSE_BORING_BEETLE; break;
// case MONS_NAGA_MAGE: ch=TILE_CORPSE_NAGA_MAGE; break;
// case MONS_NAGA_WARRIOR: ch=TILE_CORPSE_NAGA_WARRIOR; break;
// case MONS_ORC_WARLORD: ch=TILE_CORPSE_ORC_WARLORD; break;
// case MONS_DEEP_ELF_SOLDIER: ch=TILE_CORPSE_DEEP_ELF_SOLDIER; break;
// case MONS_DEEP_ELF_FIGHTER: ch=TILE_CORPSE_DEEP_ELF_FIGHTER; break;
// case MONS_DEEP_ELF_KNIGHT: ch=TILE_CORPSE_DEEP_ELF_KNIGHT; break;
// case MONS_DEEP_ELF_MAGE: ch=TILE_CORPSE_DEEP_ELF_MAGE; break;
// case MONS_DEEP_ELF_SUMMONER: ch=TILE_CORPSE_DEEP_ELF_SUMMONER; break;
// case MONS_DEEP_ELF_CONJURER: ch=TILE_CORPSE_DEEP_ELF_CONJURER; break;
// case MONS_DEEP_ELF_PRIEST: ch=TILE_CORPSE_DEEP_ELF_PRIEST; break;
// case MONS_DEEP_ELF_HIGH_PRIEST: ch=TILE_CORPSE_DEEP_ELF_HIGH_PRIEST; break;
// case MONS_DEEP_ELF_DEMONOLOGIST: ch=TILE_CORPSE_DEEP_ELF_DEMONOLOGIST; break;
// case MONS_DEEP_ELF_ANNIHILATOR: ch=TILE_CORPSE_DEEP_ELF_ANNIHILATOR; break;
// case MONS_DEEP_ELF_SORCERER: ch=TILE_CORPSE_DEEP_ELF_SORCERER; break;
// case MONS_DEEP_ELF_DEATH_MAGE: ch=TILE_CORPSE_DEEP_ELF_DEATH_MAGE; break;
case MONS_GREATER_NAGA: ch=TILE_CORPSE_GREATER_NAGA; break;
// case MONS_CENTAUR_WARRIOR: ch=TILE_CORPSE_CENTAUR_WARRIOR; break;
// case MONS_YAKTAUR_CAPTAIN: ch=TILE_CORPSE_YAKTAUR_CAPTAIN; break;
case MONS_QUOKKA: ch=TILE_CORPSE_QUOKKA; break;
// case MONS_SHUGGOTH: ch=TILE_CORPSE_SHUGGOTH; break;
case MONS_WOLF: ch=TILE_CORPSE_WOLF; break;
case MONS_WARG: ch=TILE_CORPSE_WARG; break;
case MONS_BEAR: ch=TILE_CORPSE_BEAR; break;
case MONS_GRIZZLY_BEAR: ch=TILE_CORPSE_GRIZZLY_BEAR; break;
case MONS_POLAR_BEAR: ch=TILE_CORPSE_POLAR_BEAR; break;
case MONS_BLACK_BEAR: ch=TILE_CORPSE_BLACK_BEAR; break;
case MONS_GIANT_NEWT: ch=TILE_CORPSE_GIANT_NEWT; break;
case MONS_GIANT_GECKO: ch=TILE_CORPSE_GIANT_GECKO; break;
case MONS_GIANT_IGUANA: ch=TILE_CORPSE_GIANT_IGUANA; break;
case MONS_GILA_MONSTER: ch=TILE_CORPSE_GILA_MONSTER; break;
case MONS_KOMODO_DRAGON: ch=TILE_CORPSE_KOMODO_DRAGON; break;
case MONS_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_BROWN; break;
case MONS_BLACK_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_BLACK; break;
case MONS_YELLOW_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_YELLOW; break;
case MONS_GREEN_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_GREEN; break;
case MONS_MOTTLED_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_MOTTLED; break;
case MONS_PALE_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_PALE; break;
case MONS_PURPLE_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_PURPLE; break;
case MONS_RED_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_RED; break;
case MONS_WHITE_DRACONIAN: ch=TILE_CORPSE_DRACONIAN_WHITE; break;
case MONS_DEATH_DRAKE: ch=TILE_CORPSE_DEATH_DRAKE; break;
}
return ch;
}
int tileidx_misc(int type)
{
int ch = TILE_ERROR;
switch(type)
{
case MISC_BOTTLED_EFREET: ch = TILE_MISC_BOTTLED_EFREET; break;
case MISC_CRYSTAL_BALL_OF_SEEING: ch = TILE_MISC_CRYSTAL_BALL_OF_SEEING; break;
case MISC_AIR_ELEMENTAL_FAN: ch = TILE_MISC_AIR_ELEMENTAL_FAN; break;
case MISC_LAMP_OF_FIRE: ch = TILE_MISC_LAMP_OF_FIRE; break;
case MISC_STONE_OF_EARTH_ELEMENTALS: ch = TILE_MISC_STONE_OF_EARTH_ELEMENTALS; break;
case MISC_LANTERN_OF_SHADOWS: ch = TILE_MISC_LANTERN_OF_SHADOWS; break;
case MISC_HORN_OF_GERYON: ch = TILE_MISC_HORN_OF_GERYON; break;
case MISC_BOX_OF_BEASTS: ch = TILE_MISC_BOX_OF_BEASTS; break;
case MISC_CRYSTAL_BALL_OF_ENERGY: ch = TILE_MISC_CRYSTAL_BALL_OF_ENERGY; break;
case MISC_EMPTY_EBONY_CASKET: ch = TILE_MISC_EMPTY_EBONY_CASKET; break;
case MISC_CRYSTAL_BALL_OF_FIXATION: ch = TILE_MISC_CRYSTAL_BALL_OF_FIXATION; break;
case MISC_DISC_OF_STORMS: ch = TILE_MISC_DISC_OF_STORMS; break;
case MISC_DECK_OF_ESCAPE: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_DECK_OF_DESTRUCTION: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_DECK_OF_DUNGEONS: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_DECK_OF_SUMMONING: ch = TILE_MISC_DECK_OF_SUMMONINGS; break;
case MISC_DECK_OF_WONDERS: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_DECK_OF_PUNISHMENT: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_DECK_OF_WAR: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_DECK_OF_CHANGES: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_DECK_OF_DEFENSE: ch = TILE_MISC_DECK_OF_WONDERS; break;
case MISC_RUNE_OF_ZOT: ch = TILE_MISC_RUNE_OF_ZOT; break;
}
return ch;
}
/*****************************************************/
int tileidx_item(const item_def &item)
{
int clas=item.base_type;
int type=item.sub_type;
int special=item.special;
int color=item.colour;
id_arr& id = get_typeid_array();
switch (clas)
{
case OBJ_WEAPONS:
if(is_fixed_artefact(item))
return tileidx_fixed_artifact(special);
else
if (is_unrandom_artefact( item ))
return tileidx_unrand_artifact(find_unrandart_index(item));
else
return tileidx_weapon(item);
break;
case OBJ_MISSILES:
return tileidx_missile(item);
break;
case OBJ_ARMOUR:
if (is_unrandom_artefact( item ))
return tileidx_unrand_artifact(find_unrandart_index(item));
else
return tileidx_armour(item);
break;
case OBJ_WANDS:
#if 1 //ID Item
if (id[ IDTYPE_WANDS ][type] == ID_KNOWN_TYPE
|| (item.flags &ISFLAG_KNOW_TYPE ))
return TILE_WAND_FLAME + type;
else
#endif
return TILE_WAND_OFFSET + special % 12;
break;
case OBJ_FOOD:
return tileidx_food(item);
break;
case OBJ_SCROLLS:
#if 1 //ID Item
if (id[ IDTYPE_SCROLLS ][type] == ID_KNOWN_TYPE
|| (item.flags &ISFLAG_KNOW_TYPE ))
return TILE_SCR_IDENTIFY + type;
#endif
return TILE_SCROLL;
break;
case OBJ_GOLD:
return TILE_GOLD;
break;
case OBJ_JEWELLERY:
if (type < AMU_RAGE)
{ // rings
if(is_random_artefact( item ))
return TILE_RING_RANDOM_OFFSET + color - 1;
else
return TILE_RING_NORMAL_OFFSET + special % 13;
} else { // amu
if (is_unrandom_artefact( item ))
return tileidx_unrand_artifact(find_unrandart_index(item));
else
if(is_random_artefact( item ))
return TILE_AMU_RANDOM_OFFSET + color - 1;
else
return TILE_AMU_NORMAL_OFFSET + special % 13;
}
break;
case OBJ_POTIONS:
if (id[ IDTYPE_POTIONS ][type] == ID_KNOWN_TYPE
|| (item.flags &ISFLAG_KNOW_TYPE ))
return TILE_POT_HEALING + type;
else
return TILE_POTION_OFFSET + special % 14;
break;
case OBJ_BOOKS:
type= special % 10;
if(type<2) return TILE_BOOK_PAPER_OFFSET + color;
if(type==2) return TILE_BOOK_LEATHER_OFFSET + special/10;
if(type==3) return TILE_BOOK_METAL_OFFSET + special/10;
if(type==4) return TILE_BOOK_PAPYRUS;
break;
case OBJ_STAVES:
return TILE_STAFF_OFFSET + special % 10;
break;
case OBJ_CORPSES:
if (item.sub_type == CORPSE_SKELETON)
return TILE_FOOD_BONE;
else
return tileidx_corpse(item.plus);
break;
case OBJ_ORBS:
return TILE_ORB;
break;
case OBJ_MISCELLANY:
return tileidx_misc(type);
break;
default:
break;
}
return TILE_ERROR;
}
/*
Determine Octant of missile direction
---> X+
|
| 701
Y 6O2
+ 543
the octant boundary slope tan(pi/8)=sqrt(2)-1 = 0.414 is approximated by 2/5
*/
static int tile_bolt_dir(int dx, int dy)
{
int ax = abs(dx);
int ay = abs(dy);
if ( 5*ay < 2*ax )
{
return (dx > 0)? 2:6;
}
else if ( 5*ax < 2*ay)
{
return ( dy > 0 )? 4:0;
}
else
{
if (dx>0)
return (dy>0)? 3:1;
else
return (dy>0)? 5:7;
}
}
int tileidx_item_throw(const item_def &item, int dx, int dy)
{
if (item.base_type == OBJ_MISSILES)
{
int ch = -1;
int dir = tile_bolt_dir(dx, dy);
// Thrown items with multiple directions
switch(item.sub_type)
{
case MI_ARROW:
ch = TILE_MI_ARROW0;
break;
case MI_BOLT:
ch = TILE_MI_BOLT0;
break;
case MI_DART:
ch = TILE_MI_DART0;
break;
case MI_NEEDLE:
ch = TILE_MI_NEEDLE0;
break;
case MI_JAVELIN:
ch = TILE_MI_JAVELIN0;
break;
case MI_THROWING_NET:
ch = TILE_MI_THROWING_NET0;
default:
break;
}
if (ch != -1)
return ch + dir;
// Thrown items with a single direction
switch(item.sub_type)
{
case MI_STONE:
ch = TILE_MI_STONE0;
break;
case MI_SLING_BULLET:
ch = TILE_MI_SLING_BULLET0;
break;
case MI_LARGE_ROCK:
ch = TILE_MI_LARGE_ROCK0;
break;
case MI_THROWING_NET:
ch = TILE_MI_THROWING_NET0;
break;
default:
break;
}
if (ch != -1)
return ch;
}
// If not a special case, just return the default tile.
return tileidx_item(item);
}
int tileidx_feature(int object){
int ch = TILE_ERROR;
switch (object)
{
case DNGN_UNSEEN: ch=TILE_DNGN_UNSEEN; break;
case DNGN_ROCK_WALL:
case DNGN_PERMAROCK_WALL:
case DNGN_SECRET_DOOR:
ch=TILE_DNGN_ROCK_WALL_OFS; break;
case DNGN_STONE_WALL: ch=TILE_DNGN_STONE_WALL; break;
case DNGN_CLOSED_DOOR: ch=TILE_DNGN_CLOSED_DOOR; break;
case DNGN_METAL_WALL: ch=TILE_DNGN_METAL_WALL; break;
case DNGN_GREEN_CRYSTAL_WALL: ch=TILE_DNGN_GREEN_CRYSTAL_WALL; break;
case DNGN_ORCISH_IDOL: ch=TILE_DNGN_ORCISH_IDOL; break;
case DNGN_WAX_WALL: ch=TILE_DNGN_WAX_WALL; break;
//case DNGN_LAST_SOLID_CH: ch=TILE_DNGN_LAST_SOLID_CH; break;
case DNGN_GRANITE_STATUE: ch=TILE_DNGN_GRANITE_STATUE; break;
// case DNGN_STATUE_39: ch=TILE_DNGN_STATUE_39; break;
case DNGN_LAVA: ch=TILE_DNGN_LAVA; break;
case DNGN_DEEP_WATER: ch=TILE_DNGN_DEEP_WATER; break;
case DNGN_SHALLOW_WATER: ch=TILE_DNGN_SHALLOW_WATER; break;
// case DNGN_WATER_STUCK: ch=TILE_DNGN_WATER_STUCK; break;
case DNGN_FLOOR:
case DNGN_UNDISCOVERED_TRAP:
ch=TILE_DNGN_FLOOR; break;
case DNGN_FLOOR_SPECIAL:
ch=TILE_DNGN_FLOOR_SPECIAL; break;
case DNGN_ENTER_HELL: ch=TILE_DNGN_ENTER_HELL; break;
case DNGN_OPEN_DOOR: ch=TILE_DNGN_OPEN_DOOR; break;
// case DNGN_BRANCH_STAIRS: ch=TILE_DNGN_BRANCH_STAIRS; break;
case DNGN_TRAP_MECHANICAL: ch=TILE_DNGN_TRAP_MECHANICAL; break;
case DNGN_TRAP_MAGICAL: ch=TILE_DNGN_TRAP_MAGICAL; break;
// case DNGN_TRAP_III: ch=TILE_DNGN_TRAP_III; break;
case DNGN_ENTER_SHOP: ch=TILE_DNGN_ENTER_SHOP; break;
case DNGN_ENTER_LABYRINTH: ch=TILE_DNGN_ENTER_LABYRINTH; break;
case DNGN_STONE_STAIRS_DOWN_I:
case DNGN_STONE_STAIRS_DOWN_II:
case DNGN_STONE_STAIRS_DOWN_III: ch=TILE_DNGN_STONE_STAIRS_DOWN; break;
case DNGN_ROCK_STAIRS_DOWN: ch=TILE_DNGN_ROCK_STAIRS_DOWN; break;
case DNGN_STONE_STAIRS_UP_I:
case DNGN_STONE_STAIRS_UP_II:
case DNGN_STONE_STAIRS_UP_III: ch=TILE_DNGN_STONE_STAIRS_UP; break;
case DNGN_ROCK_STAIRS_UP: ch=TILE_DNGN_ROCK_STAIRS_UP; break;
case DNGN_ENTER_DIS: ch=TILE_DNGN_ENTER_DIS; break;
case DNGN_ENTER_GEHENNA: ch=TILE_DNGN_ENTER_GEHENNA; break;
case DNGN_ENTER_COCYTUS: ch=TILE_DNGN_ENTER_COCYTUS; break;
case DNGN_ENTER_TARTARUS: ch=TILE_DNGN_ENTER_TARTARUS; break;
case DNGN_ENTER_ABYSS: ch=TILE_DNGN_ENTER_ABYSS; break;
case DNGN_EXIT_ABYSS:
case DNGN_EXIT_HELL:
ch=TILE_DNGN_EXIT_ABYSS; break;
case DNGN_STONE_ARCH: ch=TILE_DNGN_STONE_ARCH; break;
case DNGN_ENTER_PANDEMONIUM: ch=TILE_DNGN_ENTER_PANDEMONIUM; break;
case DNGN_EXIT_PANDEMONIUM: ch=TILE_DNGN_EXIT_PANDEMONIUM; break;
case DNGN_TRANSIT_PANDEMONIUM: ch=TILE_DNGN_TRANSIT_PANDEMONIUM; break;
// case DNGN_BUILDER_SPECIAL_WALL: ch=TILE_DNGN_BUILDER_SPECIAL_WALL; break;
// case DNGN_BUILDER_SPECIAL_FLOOR: ch=TILE_DNGN_BUILDER_SPECIAL_FLOOR; 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_ZOT:
case DNGN_ENTER_TEMPLE:
case DNGN_ENTER_SNAKE_PIT:
case DNGN_ENTER_ELVEN_HALLS:
case DNGN_ENTER_TOMB:
case DNGN_ENTER_SWAMP:
case DNGN_ENTER_SHOALS:
case DNGN_ENTER_RESERVED_2:
case DNGN_ENTER_RESERVED_3:
case DNGN_ENTER_RESERVED_4:
ch=TILE_DNGN_ENTER; 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_ZOT:
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 DNGN_RETURN_FROM_SHOALS:
case DNGN_RETURN_RESERVED_2:
case DNGN_RETURN_RESERVED_3:
case DNGN_RETURN_RESERVED_4:
ch=TILE_DNGN_RETURN; break;
case DNGN_ENTER_PORTAL_VAULT:
case DNGN_EXIT_PORTAL_VAULT:
ch=TILE_DNGN_TRANSIT_PANDEMONIUM; break;
case DNGN_ALTAR_ZIN: ch=TILE_DNGN_ALTAR_ZIN; break;
case DNGN_ALTAR_SHINING_ONE: ch=TILE_DNGN_ALTAR_SHINING_ONE; break;
case DNGN_ALTAR_KIKUBAAQUDGHA: ch=TILE_DNGN_ALTAR_KIKUBAAQUDGHA; break;
case DNGN_ALTAR_YREDELEMNUL: ch=TILE_DNGN_ALTAR_YREDELEMNUL; break;
case DNGN_ALTAR_XOM: ch=TILE_DNGN_ALTAR_XOM; break;
case DNGN_ALTAR_VEHUMET: ch=TILE_DNGN_ALTAR_VEHUMET; break;
case DNGN_ALTAR_OKAWARU: ch=TILE_DNGN_ALTAR_OKAWARU; break;
case DNGN_ALTAR_MAKHLEB: ch=TILE_DNGN_ALTAR_MAKHLEB; break;
case DNGN_ALTAR_SIF_MUNA: ch=TILE_DNGN_ALTAR_SIF_MUNA; break;
case DNGN_ALTAR_TROG: ch=TILE_DNGN_ALTAR_TROG; break;
case DNGN_ALTAR_NEMELEX_XOBEH: ch=TILE_DNGN_ALTAR_NEMELEX_XOBEH; break;
case DNGN_ALTAR_ELYVILON: ch=TILE_DNGN_ALTAR_ELYVILON; break;
case DNGN_ALTAR_LUGONU: ch=TILE_DNGN_ALTAR_LUGONU; break;
case DNGN_ALTAR_BEOGH: ch=TILE_DNGN_ALTAR_BEOGH; break;
case DNGN_BLUE_FOUNTAIN: ch=TILE_DNGN_BLUE_FOUNTAIN; break;
case DNGN_DRY_FOUNTAIN_I:
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 :
ch=TILE_DNGN_DRY_FOUNTAIN; break;
case DNGN_SPARKLING_FOUNTAIN: ch=TILE_DNGN_SPARKLING_FOUNTAIN; break;
}
return ch;
}
int tileidx_cloud(int type, int decay){
int ch = TILE_ERROR;
int dur = decay/20;
if (dur>2) dur = 2;
switch (type)
{
case CLOUD_FIRE:
ch = TILE_CLOUD_FIRE_0 + dur;
break;
case CLOUD_COLD:
ch = TILE_CLOUD_COLD_0 + dur;
break;
case CLOUD_STINK:
case CLOUD_POISON:
ch = TILE_CLOUD_POISON_0 + dur;
break;
case CLOUD_BLUE_SMOKE:
ch = TILE_CLOUD_BLUE_SMOKE;
break;
case CLOUD_PURP_SMOKE:
ch = TILE_CLOUD_PURP_SMOKE;
break;
case CLOUD_MIASMA:
ch = TILE_CLOUD_MIASMA;
break;
case CLOUD_BLACK_SMOKE:
ch = TILE_CLOUD_BLACK_SMOKE;
break;
default:
ch = TILE_CLOUD_GREY_SMOKE;
break;
}
return (ch | TILE_FLAG_FLYING);
}
/**********************************************************/
int tileidx_player(int job){
int ch = TILE_PLAYER;
// Handle shapechange first
switch (you.symbol)
{
case 's': ch = TILE_MONS_WOLF_SPIDER;break;
case 'I': ch = TILE_MONS_ICE_BEAST;break;
case '8': ch = TILE_MONS_STONE_GOLEM;break;
case 'D': ch = TILE_MONS_DRAGON;break;
case 'L': ch = TILE_MONS_LICH;break;
case '#': ch = TILE_MONS_VAPOUR;break;
case 'S': ch = TILE_MONS_LAVA_SNAKE;break;
case 'b': ch = TILE_MONS_GIANT_BAT;break;
}
if (player_is_airborne())
ch |= TILE_FLAG_FLYING;
if (you.attribute[ATTR_HELD])
ch |= TILE_FLAG_NET;
return ch;
}
int tileidx_unseen(int ch, const coord_def& gc)
{
int res = TILE_ERROR;
ch &= 0xff;
if (ch<32) ch=32;
if ( (ch>='@' && ch<='Z') || (ch>='a' && ch<='z') || ch=='&'
|| (ch>='1' && ch<='5') || ch == ';')
return TILE_UNSEEN_MONSTER | tile_unseen_flag(gc);
switch (ch)
{
//blank, walls, and floors first, since they are frequent
case ' ': res = TILE_DNGN_UNSEEN; break;
case 127: //old
case 176:
case 177: res = TILE_DNGN_ROCK_WALL_OFS; break;
case 130:
case ',':
case '.':
case 249:
case 250: res = TILE_DNGN_FLOOR; break;
// old;
case 137: res = TILE_DNGN_WAX_WALL; break;
case 138: res = TILE_DNGN_STONE_WALL; break;
case 139: res = TILE_DNGN_METAL_WALL; break;
case 140: res = TILE_DNGN_GREEN_CRYSTAL_WALL; break;
// others
case '!': res = TILE_POTION_OFFSET + 13; break;
case '"': res = TILE_AMU_NORMAL_OFFSET + 2; break;
case '#': res = TILE_CLOUD_GREY_SMOKE; break;
case '$': res = TILE_GOLD; break;
case '%': res = TILE_FOOD_MEAT_RATION; break;
case 142: res = TILE_UNSEEN_CORPSE; break;
case '\'':
case 134: res = TILE_DNGN_OPEN_DOOR; break;
case '(':
case ')': res = TILE_UNSEEN_WEAPON; break;
case '*': res = TILE_DNGN_ROCK_WALL_OFS ; break;
case '+': res = TILE_BOOK_PAPER_OFFSET + 15; break;
case '/': res = TILE_WAND_OFFSET; break;
case '8': res = TILE_DNGN_SILVER_STATUE; break;
case '<': res = TILE_DNGN_STONE_STAIRS_UP; break;
case '=': res = TILE_RING_NORMAL_OFFSET + 1; break;
case '>': res = TILE_DNGN_STONE_STAIRS_DOWN; break;
case '?': res = TILE_SCROLL; break;
case '[':
case ']': res = TILE_UNSEEN_ARMOUR; break;
case '\\': res = TILE_STAFF_OFFSET; break;
case '^': res = TILE_DNGN_TRAP_MAGICAL; break;
case '_':
case 131: res = TILE_UNSEEN_ALTAR; break;
case '~': res = TILE_UNSEEN_ITEM; break;
case '{':
case 135: res = TILE_DNGN_DEEP_WATER; break;
case 133: res = TILE_DNGN_BLUE_FOUNTAIN; break;
case '}': res = TILE_MISC_CRYSTAL_BALL_OF_SEEING; break;
case 128: //old
case 254: res = TILE_DNGN_CLOSED_DOOR; break;
case 129: res = TILE_DNGN_RETURN; break;
case 132: res = TILE_UNSEEN_ENTRANCE; break;
case 136: res = TILE_DNGN_ENTER; break;
case 141: res = TILE_DNGN_LAVA; break;
}
//if(res == TILE_ERROR)printf("undefined mapchar %d [%c]\n",ch,ch);
return res | tile_unseen_flag(gc);
}
int tileidx_bolt(const bolt &bolt)
{
int col = bolt.colour;
return tileidx_zap(col);
}
int tileidx_zap(int color)
{
int col = color;
if (col > 8) col -= 8;
if (col < 1) col = 7;
return TILE_SYM_BOLT_OFS -1 + col;
}
// Convert normal tile to 3D tile if it exists
// Plus modify wall tile index depending on
// 1: floor/wall flavor in 2D mode
// 2: connectivity in 3D mode
void finalize_tile(short unsigned int *tile, unsigned char wflag,
char wall_flv, char floor_flv, char special_flv)
{
int orig = (*tile) & TILE_FLAG_MASK;
int flag = (*tile) & (~TILE_FLAG_MASK);
// Hack: Swap rock/stone in crypt and tomb, because there are
// only stone walls.
if ((you.where_are_you == BRANCH_CRYPT || you.where_are_you == BRANCH_TOMB)
&& orig == TILE_DNGN_STONE_WALL)
orig = TILE_DNGN_ROCK_WALL_OFS;
// If there are special tiles for this level, then use them.
// Otherwise, we'll fall through to the next case and replace
// special tiles with normal floor.
if (orig == TILE_DNGN_FLOOR_SPECIAL &&
get_num_floor_special_flavors() > 0)
{
(*tile) = get_floor_special_tile_idx() + special_flv;
ASSERT(special_flv >= 0 &&
special_flv < get_num_floor_special_flavors());
}
else if (orig == TILE_DNGN_FLOOR || orig == TILE_DNGN_FLOOR_SPECIAL)
{
(*tile) = get_floor_tile_idx() + floor_flv;
}
else if (orig == TILE_DNGN_ROCK_WALL_OFS)
{
(*tile) = get_wall_tile_idx() + wall_flv;
}
(*tile) |= flag;
}
void tilep_calc_flags(int parts[], int flag[])
{
int i;
for(i=0;i<TILEP_PARTS_TOTAL;i++) flag[i]=TILEP_FLAG_NORMAL;
if (parts[TILEP_PART_HELM]-1 >= TILEP_HELM_HELM_OFS)
flag[TILEP_PART_HAIR]=TILEP_FLAG_HIDE;
if (parts[TILEP_PART_HELM]-1 >= TILEP_HELM_FHELM_OFS)
flag[TILEP_PART_BEARD]=TILEP_FLAG_HIDE;
if(parts[TILEP_PART_BASE]== TILEP_BASE_NAGA ||
parts[TILEP_PART_BASE]== TILEP_BASE_NAGA+1)
{
flag[TILEP_PART_BOOTS]=flag[TILEP_PART_LEG]=TILEP_FLAG_HIDE;
flag[TILEP_PART_BODY] = TILEP_FLAG_CUT_NAGA;
}
if(parts[TILEP_PART_BASE]== TILEP_BASE_CENTAUR ||
parts[TILEP_PART_BASE]== TILEP_BASE_CENTAUR+1)
{
flag[TILEP_PART_BOOTS]=flag[TILEP_PART_LEG]=TILEP_FLAG_HIDE;
flag[TILEP_PART_BODY] = TILEP_FLAG_CUT_CENTAUR;
}
if (parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER ||
parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER +1)
{
flag[TILEP_PART_BOOTS] = TILEP_FLAG_HIDE;
flag[TILEP_PART_LEG] = TILEP_FLAG_HIDE;
flag[TILEP_PART_SHADOW] = TILEP_FLAG_HIDE;
}
}
/*
* Set default parts of each race
* body + optional beard, hair, etc
*/
int draconian_color(int race, int level)
{
if (level < 0) // hack:monster
{
switch(race)
{
case MONS_DRACONIAN: return 0;
case MONS_BLACK_DRACONIAN: return 1;
case MONS_YELLOW_DRACONIAN: return 2;
case MONS_GREEN_DRACONIAN: return 4;
case MONS_MOTTLED_DRACONIAN:return 5;
case MONS_PALE_DRACONIAN: return 6;
case MONS_PURPLE_DRACONIAN: return 7;
case MONS_RED_DRACONIAN: return 8;
case MONS_WHITE_DRACONIAN: return 9;
}
}
if (level < 7)
return 0;
switch(race)
{
case SP_BLACK_DRACONIAN: return 1;
case SP_GOLDEN_DRACONIAN: return 2;
case SP_GREY_DRACONIAN: return 3;
case SP_GREEN_DRACONIAN: return 4;
case SP_MOTTLED_DRACONIAN: return 5;
case SP_PALE_DRACONIAN: return 6;
case SP_PURPLE_DRACONIAN: return 7;
case SP_RED_DRACONIAN: return 8;
case SP_WHITE_DRACONIAN: return 9;
}
return 0;
}
void tilep_race_default(int race, int gender, int level, int *parts)
{
int result;
int hair;
int beard=0;
if(gender==TILEP_GENDER_MALE)
hair = TILEP_HAIR_SHORT_BLACK;
else
hair = TILEP_HAIR_LONG_BLACK;
switch(race)
{
case SP_HUMAN:
result = TILEP_BASE_HUMAN;
break;
case SP_ELF:
case SP_HIGH_ELF:
case SP_GREY_ELF:
case SP_SLUDGE_ELF:
result = TILEP_BASE_ELF;
hair = TILEP_HAIR_ELF_YELLOW;
break;
case SP_DEEP_ELF:
result = TILEP_BASE_DEEP_ELF;
hair = TILEP_HAIR_ELF_WHITE;
break;
case SP_HILL_DWARF:
case SP_MOUNTAIN_DWARF:
result = TILEP_BASE_DWARF;
if(gender==TILEP_GENDER_MALE)
{
hair = TILEP_HAIR_SHORT_RED;
beard = TILEP_BEARD_LONG_RED;
}
else
{
hair = TILEP_HAIR_LONG_RED;
beard = TILEP_BEARD_SHORT_RED;
}
break;
case SP_HALFLING:
result = TILEP_BASE_HALFLING;
break;
case SP_HILL_ORC:
result = TILEP_BASE_ORC;
hair = 0;
break;
case SP_KOBOLD:
result = TILEP_BASE_KOBOLD;
hair = 0;
break;
case SP_MUMMY:
result = TILEP_BASE_MUMMY;
hair = 0;
break;
case SP_NAGA:
result = TILEP_BASE_NAGA;
break;
case SP_GNOME:
result = TILEP_BASE_GNOME;
break;
case SP_OGRE:
result = TILEP_BASE_OGRE;
break;
case SP_TROLL:
result = TILEP_BASE_TROLL;
hair = 0;
break;
case SP_OGRE_MAGE:
result = TILEP_BASE_OGRE_MAGE;
break;
case SP_BASE_DRACONIAN:
case SP_RED_DRACONIAN:
case SP_WHITE_DRACONIAN:
case SP_GREEN_DRACONIAN:
case SP_GOLDEN_DRACONIAN:
case SP_GREY_DRACONIAN:
case SP_BLACK_DRACONIAN:
case SP_PURPLE_DRACONIAN:
case SP_MOTTLED_DRACONIAN:
case SP_PALE_DRACONIAN:
hair = 0;
if (you.mutation[MUT_BIG_WINGS])
{
parts[TILEP_PART_DRCWING] = 1 + draconian_color(race, level);
}
result = TILEP_BASE_DRACONIAN + draconian_color(race, level)*2;
break;
case SP_CENTAUR:
result = TILEP_BASE_CENTAUR;
break;
case SP_DEMIGOD:
result = TILEP_BASE_DEMIGOD;
break;
case SP_SPRIGGAN:
result = TILEP_BASE_SPRIGGAN;
break;
case SP_MINOTAUR:
result = TILEP_BASE_MINOTAUR;
hair = 0;
break;
case SP_DEMONSPAWN:
result = TILEP_BASE_DEMONSPAWN;
hair = 0;
break;
case SP_GHOUL:
result = TILEP_BASE_GHOUL;
hair = 0;
break;
case SP_KENKU:
result = TILEP_BASE_KENKU;
break;
case SP_MERFOLK:
result = player_in_water() ?
TILEP_BASE_MERFOLK_WATER :
TILEP_BASE_MERFOLK;
break;
case SP_VAMPIRE:
result = TILEP_BASE_VAMPIRE;
break;
default:
result = TILEP_BASE_HUMAN;
break;
}
if(gender==TILEP_GENDER_MALE) result++;
parts[TILEP_PART_BASE]=result;
parts[TILEP_PART_HAIR]=hair;
parts[TILEP_PART_BEARD]=beard;
parts[TILEP_PART_SHADOW]= 1;
}
void tilep_job_default(int job, int gender, int *parts)
{
parts[TILEP_PART_CLOAK]= 0;
parts[TILEP_PART_BOOTS]= 0;
parts[TILEP_PART_LEG]= 0;
parts[TILEP_PART_BODY]= 0;
parts[TILEP_PART_ARM]= 0;
parts[TILEP_PART_HAND1]=0;
parts[TILEP_PART_HAND2]= 0;
parts[TILEP_PART_HELM]= 0;
switch(job)
{
case JOB_FIGHTER:
parts[TILEP_PART_BODY]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_LEG]=TILEP_LEG_METAL_SILVER;
parts[TILEP_PART_HAND2]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
break;
case JOB_CRUSADER:
parts[TILEP_PART_BODY]=TILEP_BODY_SHIRT_WHITE3;
parts[TILEP_PART_LEG]=TILEP_LEG_SKIRT_OFS;
parts[TILEP_PART_HELM]=TILEP_HELM_HELM_OFS;
parts[TILEP_PART_ARM]=TILEP_ARM_GLOVE_GRAY;
parts[TILEP_PART_BOOTS]=TILEP_BOOTS_MIDDLE_GRAY;
parts[TILEP_PART_CLOAK]=TILEP_CLOAK_BLUE;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND2]=TILEP_SHOW_EQUIP;
break;
case JOB_PALADIN:
parts[TILEP_PART_BODY]=TILEP_BODY_ROBE_WHITE;
parts[TILEP_PART_LEG]=TILEP_LEG_PANTS_BROWN;
parts[TILEP_PART_HELM]=TILEP_HELM_HELM_OFS;
parts[TILEP_PART_ARM]=TILEP_ARM_GLOVE_GRAY;
parts[TILEP_PART_BOOTS]=TILEP_BOOTS_MIDDLE_GRAY;
parts[TILEP_PART_CLOAK]=TILEP_CLOAK_BLUE;
parts[TILEP_PART_HAND2]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
break;
case JOB_DEATH_KNIGHT:
parts[TILEP_PART_BODY]=TILEP_BODY_SHIRT_BLACK3;
parts[TILEP_PART_LEG]=TILEP_LEG_METAL_GRAY;
parts[TILEP_PART_HELM]=TILEP_HELM_FHELM_OFS;
parts[TILEP_PART_ARM]=TILEP_ARM_GLOVE_BLACK;
parts[TILEP_PART_CLOAK]=TILEP_CLOAK_YELLOW;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND2]=TILEP_HAND2_BOOK_BLACK;
break;
case JOB_CHAOS_KNIGHT:
parts[TILEP_PART_BODY]=TILEP_BODY_BELT1;
parts[TILEP_PART_LEG]=TILEP_LEG_METAL_GRAY;
parts[TILEP_PART_HELM]=TILEP_HELM_FHELM_PLUME;
parts[TILEP_PART_BOOTS]=TILEP_BOOTS_SHORT_BROWN;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND2]=TILEP_SHOW_EQUIP;
break;
case JOB_BERSERKER:
parts[TILEP_PART_BODY]=TILEP_BODY_ANIMAL_SKIN;
parts[TILEP_PART_LEG]=TILEP_LEG_BELT_REDBROWN;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND2]=TILEP_SHOW_EQUIP;
break;
case JOB_REAVER:
parts[TILEP_PART_BODY]=TILEP_BODY_ROBE_BLACK_GOLD;
parts[TILEP_PART_LEG]=TILEP_LEG_PANTS_BROWN;
parts[TILEP_PART_HAND2]=TILEP_HAND2_BOOK_RED_DIM;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_THIEF:
parts[TILEP_PART_HELM] = TILEP_HELM_HOOD_YBROWN;
parts[TILEP_PART_BODY]=TILEP_BODY_LEATHER_JACKET;
parts[TILEP_PART_LEG]=TILEP_LEG_PANTS_SHORT_GRAY;
parts[TILEP_PART_HAND1]= TILEP_HAND1_SWORD_THIEF;
parts[TILEP_PART_ARM]=TILEP_ARM_GLOVE_WRIST_PURPLE;
parts[TILEP_PART_CLOAK]=TILEP_CLOAK_LBROWN;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_BROWN2;
break;
case JOB_STALKER:
parts[TILEP_PART_HELM] = TILEP_HELM_HOOD_GREEN;
parts[TILEP_PART_BODY]=TILEP_BODY_LEATHER_JACKET;
parts[TILEP_PART_LEG]=TILEP_LEG_PANTS_SHORT_GRAY;
parts[TILEP_PART_HAND1]= TILEP_HAND1_SWORD_THIEF;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_GREEN_DIM;
parts[TILEP_PART_ARM]=TILEP_ARM_GLOVE_WRIST_PURPLE;
parts[TILEP_PART_CLOAK]=TILEP_CLOAK_GREEN;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_BROWN2;
break;
case JOB_ASSASSIN:
parts[TILEP_PART_HELM] = TILEP_HELM_MASK_NINJA_BLACK;
parts[TILEP_PART_BODY]=TILEP_BODY_SHIRT_BLACK3;
parts[TILEP_PART_LEG]=TILEP_LEG_PANTS_BLACK;
parts[TILEP_PART_HAND1]= TILEP_HAND1_SWORD_THIEF;
parts[TILEP_PART_ARM]=TILEP_ARM_GLOVE_BLACK;
parts[TILEP_PART_CLOAK]=TILEP_CLOAK_BLACK;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN2;
break;
case JOB_WIZARD:
parts[TILEP_PART_BODY]= TILEP_BODY_GANDALF_G;
parts[TILEP_PART_HAND1]= TILEP_HAND1_GANDALF;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_CYAN_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF;
break;
case JOB_PRIEST:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_WHITE;
parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_WHITE;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_HEALER:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_WHITE;
parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_WHITE;
parts[TILEP_PART_HAND1]= 38;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
parts[TILEP_PART_HELM] = TILEP_HELM_FHELM_HEALER;
break;
case JOB_NECROMANCER:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_BLACK;
parts[TILEP_PART_HAND1]= TILEP_HAND1_STAFF_SKULL;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_BLACK;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_FIRE_ELEMENTALIST:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_RED;
parts[TILEP_PART_HAND1]= TILEP_HAND1_GANDALF;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_RED_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_ICE_ELEMENTALIST:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_BLUE;
parts[TILEP_PART_HAND1]= TILEP_HAND1_GANDALF;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_BLUE_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_AIR_ELEMENTALIST:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_CYAN;
parts[TILEP_PART_HAND1]= TILEP_HAND1_GANDALF;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_CYAN_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_EARTH_ELEMENTALIST:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_YELLOW;
parts[TILEP_PART_HAND1]= TILEP_HAND1_GANDALF;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_YELLOW_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_VENOM_MAGE:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_GREEN;
parts[TILEP_PART_HAND1]= TILEP_HAND1_GANDALF;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_GREEN_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_TRANSMUTER:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_RAINBOW;
parts[TILEP_PART_HAND1]= TILEP_HAND1_STAFF_MAGE;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_MAGENTA_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_CONJURER:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_MAGENTA;
parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF;
parts[TILEP_PART_HAND1]= TILEP_HAND1_STAFF_MAGE;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_RED_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_ENCHANTER:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_YELLOW;
parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF;
parts[TILEP_PART_HAND1]= TILEP_HAND1_STAFF_MAGE;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_BLUE_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_SUMMONER:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_BROWN;
parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF;
parts[TILEP_PART_HAND1]= TILEP_HAND1_STAFF_MAGE;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_YELLOW_DIM;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
break;
case JOB_WARPER:
parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_BROWN;
parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF;
parts[TILEP_PART_HAND1]= 42;
parts[TILEP_PART_HAND2]= TILEP_HAND2_BOOK_WHITE;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN;
parts[TILEP_PART_CLOAK]=TILEP_CLOAK_RED;
break;
case JOB_HUNTER:
parts[TILEP_PART_BODY]=TILEP_BODY_LEATHER_ARMOUR2;
parts[TILEP_PART_LEG]=TILEP_LEG_PANTS_BROWN;
parts[TILEP_PART_HAND1]=TILEP_HAND1_BOW;
parts[TILEP_PART_ARM] = 7;
parts[TILEP_PART_BOOTS]= TILEP_BOOTS_MIDDLE_BROWN;
break;
case JOB_GLADIATOR:
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND2]= 10;
if(gender==TILEP_GENDER_MALE)
{
parts[TILEP_PART_BODY]= TILEP_BODY_BELT1;
parts[TILEP_PART_LEG]= TILEP_LEG_BELT_GRAY;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_GRAY;
}
else
{
parts[TILEP_PART_BODY]= TILEP_BODY_BIKINI_RED;
parts[TILEP_PART_LEG]= TILEP_LEG_BIKINI_RED;
parts[TILEP_PART_BOOTS] = TILEP_BOOTS_LONG_RED;
}
break;
case JOB_MONK:
parts[TILEP_PART_BODY]= TILEP_BODY_MONK_BLACK;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND2]=TILEP_SHOW_EQUIP;
break;
case JOB_WANDERER:
parts[TILEP_PART_BODY]= TILEP_BODY_SHIRT_HAWAII;
parts[TILEP_PART_LEG]= TILEP_LEG_PANTS_SHORT_BROWN;
parts[TILEP_PART_HAND1]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_HAND2]=TILEP_SHOW_EQUIP;
parts[TILEP_PART_BOOTS] = 11;
break;
}
}
/*
* Patrs index to string
*/
void tilep_part_to_str(int number, char *buf)
{
//special
if (number == TILEP_SHOW_EQUIP)
{
buf[0] = buf[1] = buf[2] ='*';
}
else
{
//normal 2 digits
buf[0] = '0' + (number/100) % 10;
buf[1] = '0' + (number/ 10) % 10;
buf[2] = '0' + number % 10;
}
buf[3] ='\0';
}
/*
* Parts string to index
*/
int tilep_str_to_part(char *str)
{
//special
if (str[0]=='*') return TILEP_SHOW_EQUIP;
//normal 2 digits
return atoi(str);
}
const int parts_saved[] ={
TILEP_PART_SHADOW,
TILEP_PART_BASE,
TILEP_PART_CLOAK,
TILEP_PART_BOOTS,
TILEP_PART_LEG,
TILEP_PART_BODY,
TILEP_PART_ARM,
TILEP_PART_HAND1,
TILEP_PART_HAND2,
TILEP_PART_HAIR,
TILEP_PART_BEARD,
TILEP_PART_HELM,
-1
};
/*
* scan input line from dolls.txt
*/
void tilep_scan_parts(char *fbuf, int *parts)
{
char ibuf[8];
int gcount = 0;
int ccount = 0;
for(int i = 0; parts_saved[i] != -1; i++)
{
int idx;
ccount = 0;
int p = parts_saved[i];
while ( (fbuf[gcount] != ':') && (fbuf[gcount] != '\n')
&& (ccount<4) && (gcount<48) )
{
ibuf[ccount] = fbuf[gcount];
ccount ++;
gcount ++;
}
ibuf[ccount] = '\0';
gcount ++;
idx = tilep_str_to_part(ibuf);
if (p == TILEP_PART_BASE)
{
int p0 = (parts[p]-1) & (0xfe);
if (((1-idx) & 1) == 1) p0++;
parts[p] = p0 + 1;
}
else if (idx == TILEP_SHOW_EQUIP)
parts[p] = TILEP_SHOW_EQUIP;
else if (idx < 0) // no negative value
parts[p] = 0;
else if (idx > tilep_parts_total[p]) // bound it
parts[p] = tilep_parts_total[p];
else
parts[p] = idx;
}
}
/*
* format-print parts
*/
void tilep_print_parts(char *fbuf, int *parts)
{
int i;
char *ptr = fbuf;
for(i = 0; parts_saved[i] != -1; i++)
{
int p = parts_saved[i];
if (p == TILEP_PART_BASE) // 0:female 1:male
{
sprintf(ptr, "%03d", parts[p]%2);
ptr += 3;
}
else
{
tilep_part_to_str(parts[p], ptr);
ptr += 3;
}
*ptr = ':';
ptr++;
}
ptr--; // erase the last ':'
*ptr = 0;
}
/*
* return equip-dependent parts index
*/
int tilep_equ_weapon(const item_def &item)
{
if (item.base_type == OBJ_STAVES) return TILEP_HAND1_STAFF_MAGE;
if (item.base_type ==OBJ_MISCELLANY)
{
switch(item.sub_type)
{
case MISC_BOTTLED_EFREET: return TILEP_HAND1_BOTTLE;
case MISC_AIR_ELEMENTAL_FAN: return TILEP_HAND1_FAN;
case MISC_STONE_OF_EARTH_ELEMENTALS: return TILEP_HAND1_STONE;
case MISC_DISC_OF_STORMS: return TILEP_HAND1_DISC;
case MISC_CRYSTAL_BALL_OF_SEEING:
case MISC_CRYSTAL_BALL_OF_ENERGY:
case MISC_CRYSTAL_BALL_OF_FIXATION: return TILEP_HAND1_CRYSTAL;
case MISC_LAMP_OF_FIRE: return TILEP_HAND1_LANTERN;
case MISC_LANTERN_OF_SHADOWS: return TILEP_HAND1_BONE_LANTERN;
case MISC_HORN_OF_GERYON: return TILEP_HAND1_HORN;
case MISC_BOX_OF_BEASTS:
case MISC_EMPTY_EBONY_CASKET: return TILEP_HAND1_BOX;
case MISC_DECK_OF_ESCAPE:
case MISC_DECK_OF_DESTRUCTION:
case MISC_DECK_OF_DUNGEONS:
case MISC_DECK_OF_SUMMONING:
case MISC_DECK_OF_WONDERS:
case MISC_DECK_OF_PUNISHMENT:
case MISC_DECK_OF_WAR:
case MISC_DECK_OF_CHANGES:
case MISC_DECK_OF_DEFENSE: return TILEP_HAND1_DECK;
}
}
if (item.base_type != OBJ_WEAPONS) return 0;
if (is_fixed_artefact( item ))
{
switch(item.special)
{
case SPWPN_SINGING_SWORD: return TILEP_HAND1_SINGING_SWORD;
case SPWPN_WRATH_OF_TROG: return TILEP_HAND1_AXE_TROG;
case SPWPN_SCYTHE_OF_CURSES: return TILEP_HAND1_FINISHER;
case SPWPN_MACE_OF_VARIABILITY: return TILEP_HAND1_MACE_OF_VARIABILITY;
case SPWPN_GLAIVE_OF_PRUNE: return TILEP_HAND1_GLAIVE_OF_PRUNE;
case SPWPN_SCEPTRE_OF_TORMENT: return TILEP_HAND1_MACE_RUBY;
case SPWPN_SWORD_OF_ZONGULDROK: return TILEP_HAND1_ZONGULDROK;
case SPWPN_SWORD_OF_CEREBOV: return TILEP_HAND1_SWORD_TWIST;
case SPWPN_STAFF_OF_DISPATER: return TILEP_HAND1_DISPATER;
case SPWPN_SCEPTRE_OF_ASMODEUS: return TILEP_HAND1_ASMODEUS;
case SPWPN_SWORD_OF_POWER: break;
case SPWPN_KNIFE_OF_ACCURACY: break;
case SPWPN_STAFF_OF_OLGREB: return TILEP_HAND1_OLGREB;
case SPWPN_VAMPIRES_TOOTH: break;
case SPWPN_STAFF_OF_WUCAD_MU: break;
}
}
if (is_unrandom_artefact( item ))
{
int x = find_unrandart_index(item);
switch(x+1)
{
// Bloodbane
case 2: return TILEP_HAND1_BLOODBANE;
// Flaming Death
case 4: return TILEP_HAND1_FLAMING_DEATH;
//mace of Brilliance
case 8: return TILEP_HAND1_MACE_OF_VARIABILITY;
//demon blade Leech
case 12: return TILEP_HAND1_LEECH;
//dagger of Chilly Death
case 15: return TILEP_HAND1_CHILLY_DEATH;
//dagger \"Morg\"
case 17: return TILEP_HAND1_MORG;
//scythe \"Finisher
case 18: return TILEP_HAND1_FINISHER;
//sling \"Punk
case 19: return TILEP_HAND1_PUNK;
//bow of Krishna
case 20: return TILEP_HAND1_KRISHNA;
//giant club \"Skullcrusher
case 22: break;
//glaive of the Guard
case 24: break;
//sword of Jihad
case 25: return TILEP_HAND1_JIHAD;
//crossbow \"Fiery Devil
case 28: return TILEP_HAND1_FIERY_DEVIL;
//sword of Doom Knight
case 31: return TILEP_HAND1_DOOM_KNIGHT;
//Eos
case 35: break;
//spear of Voo-Doo
case 39: return TILEP_HAND1_VOODOO;
//trident of the Octopus king
case 40: break;
//mithril axe \"Arga
case 42: return TILEP_HAND1_ARGA;
//Elemental Staff
case 43: return TILEP_HAND1_ELEMENTAL_STAFF;
//hand crossbow \"Sniper
case 44: return TILEP_HAND1_SNIPER;
//bow \"Erchidel
case 45: return TILEP_HAND1_GREAT_BOW;
//plutonium sword
case 47: return TILEP_HAND1_PLUTONIUM_SWORD;
//mace \"Undeadhunter
case 48: return TILEP_HAND1_LARGE_MACE;
}
}
switch (item.sub_type)
{
// Blunt
case WPN_CLUB: return TILEP_HAND1_CLUB_SLANT;
case WPN_MACE: return TILEP_HAND1_MACE;
case WPN_GREAT_MACE: return TILEP_HAND1_GREAT_MACE;
case WPN_FLAIL: return TILEP_HAND1_FRAIL;
case WPN_SPIKED_FLAIL: return TILEP_HAND1_SPIKED_FRAIL;
case WPN_DIRE_FLAIL: return TILEP_HAND1_GREAT_FRAIL;
case WPN_MORNINGSTAR: return TILEP_HAND1_MORNINGSTAR;
case WPN_EVENINGSTAR: return TILEP_HAND1_EVENINGSTAR;
case WPN_GIANT_CLUB: return TILEP_HAND1_GIANT_CLUB_SLANT;
case WPN_GIANT_SPIKED_CLUB: return TILEP_HAND1_GIANT_CLUB_SPIKE_SLANT;
case WPN_ANCUS: return TILEP_HAND1_MACE;
case WPN_WHIP: return TILEP_HAND1_WHIP;
case WPN_DEMON_WHIP: return TILEP_HAND1_BLACK_WHIP;
// Edge
case WPN_KNIFE: return TILEP_HAND1_DAGGER_SLANT;
case WPN_DAGGER: return TILEP_HAND1_DAGGER_SLANT;
case WPN_SHORT_SWORD: return TILEP_HAND1_SHORT_SWORD_SLANT;
case WPN_LONG_SWORD: return TILEP_HAND1_LONG_SWORD_SLANT;
case WPN_GREAT_SWORD: return TILEP_HAND1_GREAT_SWORD_SLANT;
case WPN_SCIMITAR: return TILEP_HAND1_SCIMITAR;
case WPN_FALCHION: return TILEP_HAND1_FALCHION;
case WPN_SABRE: return TILEP_HAND1_SABRE;
case WPN_DEMON_BLADE: return TILEP_HAND1_SWORD_BLACK;
case WPN_QUICK_BLADE: return TILEP_HAND1_DAGGER;
case WPN_KATANA: return TILEP_HAND1_KATANA_SLANT;
case WPN_DOUBLE_SWORD: return TILEP_HAND1_DOUBLE_SWORD;
case WPN_TRIPLE_SWORD: return TILEP_HAND1_TRIPLE_SWORD;
case WPN_BLESSED_BLADE: return TILEP_HAND1_BLESSED_BLADE;
// Axe
case WPN_HAND_AXE: return TILEP_HAND1_HAND_AXE;
case WPN_BATTLEAXE: return TILEP_HAND1_BATTLEAXE;
case WPN_BROAD_AXE: return TILEP_HAND1_BROAD_AXE;
case WPN_WAR_AXE: return TILEP_HAND1_WAR_AXE;
case WPN_EXECUTIONERS_AXE: return TILEP_HAND1_EXECUTIONERS_AXE;
case WPN_BARDICHE: return TILEP_HAND1_GLAIVE3;
//Pole
case WPN_SPEAR: return TILEP_HAND1_SPEAR;
case WPN_HALBERD: return TILEP_HAND1_HALBERD;
case WPN_GLAIVE: return TILEP_HAND1_GLAIVE;
case WPN_QUARTERSTAFF: return TILEP_HAND1_QUARTERSTAFF1;
case WPN_SCYTHE: return TILEP_HAND1_SCYTHE;
case WPN_HAMMER: return TILEP_HAND1_HAMMER;
case WPN_DEMON_TRIDENT: return TILEP_HAND1_DEMON_TRIDENT;
case WPN_TRIDENT: return TILEP_HAND1_TRIDENT2;
case WPN_LAJATANG: return TILEP_HAND1_D_GLAIVE;
//Ranged
case WPN_SLING: return TILEP_HAND1_SLING;
case WPN_BOW: return TILEP_HAND1_BOW2;
case WPN_CROSSBOW: return TILEP_HAND1_CROSSBOW;
case WPN_HAND_CROSSBOW: return TILEP_HAND1_CROSSBOW;
case WPN_BLOWGUN: return TILEP_HAND1_BLOWGUN;
case WPN_LONGBOW: return TILEP_HAND1_BOW3;
default: return 0;
}
}
int tilep_equ_armour(const item_def &item)
{
if (item.base_type !=OBJ_ARMOUR) return 0;
if (is_unrandom_artefact( item ))
{
int x = find_unrandart_index(item);
switch(x+1)
{
// Holy Armour of Zin
case 6: return TILEP_BODY_ARMOR_MUMMY;
// robe of Augmentation
case 7: return TILEP_BODY_ROBE_RED2;
// robe of Misfortune
case 14: return TILEP_BODY_ARWEN;
// Lear's chain mail
case 26: return TILEP_BODY_LEARS_CHAIN_MAIL;
// skin of Zhor
case 27: return TILEP_BODY_ZHOR; break;
// salamander hide armour
case 29: return TILEP_BODY_LEATHER_RED;
// robe of Folly
case 33: return TILEP_BODY_ROBE_BLACK;
// Edison's patent armour
case 38: return TILEP_BODY_EDISON;
// robe of Night
case 46: return TILEP_BODY_ROBE_OF_NIGHT;
// armour of the Dragon King
case 49: break;
}
}
switch (item.sub_type)
{
case ARM_ROBE:
switch(item.colour)
{
// We've got a zillion robes; let's use 'em!
case BLACK: return TILEP_BODY_ROBE_BLACK_RED;
case BLUE: return TILEP_BODY_ROBE_BLUE;
case LIGHTBLUE: return TILEP_BODY_ROBE_BLUE_WHITE;
case GREEN: return TILEP_BODY_ROBE_GREEN;
case LIGHTGREEN: return TILEP_BODY_ROBE_BLUE_GREEN;
case CYAN: return TILEP_BODY_ROBE_WHITE_GREEN;
case LIGHTCYAN: return TILEP_BODY_ROBE_CYAN;
case RED: return TILEP_BODY_ROBE_RED;
case LIGHTRED: return TILEP_BODY_ROBE_RED_GOLD;
case MAGENTA: return TILEP_BODY_ROBE_MAGENTA;
case LIGHTMAGENTA:return TILEP_BODY_ROBE_RED3;
case BROWN: return TILEP_BODY_ROBE_BROWN;
case YELLOW: return TILEP_BODY_ROBE_YELLOW;
case LIGHTGREY: return TILEP_BODY_ROBE_GRAY2;
case DARKGREY: return TILEP_BODY_GANDALF_G;
case WHITE: return TILEP_BODY_ROBE_WHITE;
default: return 0;
}
case ARM_LEATHER_ARMOUR: return TILEP_BODY_LEATHER_ARMOUR3;
case ARM_RING_MAIL: return TILEP_BODY_RINGMAIL;
case ARM_CHAIN_MAIL: return TILEP_BODY_CHAINMAIL;
case ARM_SCALE_MAIL: return TILEP_BODY_SCALEMAIL;
case ARM_SPLINT_MAIL: return TILEP_BODY_BANDED;
case ARM_BANDED_MAIL: return TILEP_BODY_BANDED;
case ARM_PLATE_MAIL: return TILEP_BODY_PLATE_BLACK;
case ARM_CRYSTAL_PLATE_MAIL: return TILEP_BODY_CRYSTAL_PLATE;
case ARM_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_GREEN;
case ARM_ICE_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_CYAN;
case ARM_STEAM_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_WHITE;
case ARM_MOTTLED_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_MAGENTA;
case ARM_STORM_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_BLUE;
case ARM_GOLD_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_GOLD;
case ARM_SWAMP_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_BROWN;
case ARM_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_GREEN;
case ARM_ICE_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_CYAN;
case ARM_STEAM_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_WHITE;
case ARM_MOTTLED_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_MAGENTA;
case ARM_STORM_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_BLUE;
case ARM_GOLD_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_GOLD;
case ARM_SWAMP_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_BROWN;
case ARM_ANIMAL_SKIN: return TILEP_BODY_ANIMAL_SKIN;
case ARM_TROLL_HIDE:
case ARM_TROLL_LEATHER_ARMOUR: return TILEP_BODY_TROLL_HIDE;
default: return 0;
}
}
int tilep_equ_shield(const item_def &item)
{
if (you.equip[EQ_SHIELD] == -1) return 0;
if (item.base_type !=OBJ_ARMOUR) return 0;
if (is_unrandom_artefact( item ))
{
int x = find_unrandart_index(item);
switch(x+1)
{
// shield of Ignorance
case 5: return TILEP_HAND2_SHIELD_SHAMAN;
// Bullseye
case 10: return TILEP_HAND2_BULLSEYE;
// shield of Resistance
case 32: return TILEP_HAND2_SHIELD_OF_RESISTANCE;
}
}
switch (item.sub_type)
{
case ARM_SHIELD: return TILEP_HAND2_SHIELD_KNIGHT_BLUE;
case ARM_BUCKLER: return TILEP_HAND2_SHIELD_ROUND_SMALL;
case ARM_LARGE_SHIELD: return TILEP_HAND2_SHIELD_LONG_RED;
default: return 0;
}
}
int tilep_equ_cloak(const item_def &item)
{
if (you.equip[EQ_CLOAK] == -1) return 0;
if (item.base_type !=OBJ_ARMOUR) return 0;
if (item.sub_type != ARM_CLOAK) return 0;
switch (item.colour)
{
case BLACK:
case BLUE:
case LIGHTBLUE: return TILEP_CLOAK_BLUE;
case GREEN:
case LIGHTGREEN: return TILEP_CLOAK_GREEN;
case CYAN:
case LIGHTCYAN: return TILEP_CLOAK_CYAN;
case RED:
case LIGHTRED: return TILEP_CLOAK_RED;
case MAGENTA:
case LIGHTMAGENTA:return TILEP_CLOAK_MAGENTA;
case BROWN: return TILEP_CLOAK_LBROWN;
case YELLOW: return TILEP_CLOAK_YELLOW;
case LIGHTGREY: return TILEP_CLOAK_GRAY;
case DARKGREY: return TILEP_CLOAK_BLACK;
case WHITE: return TILEP_CLOAK_WHITE;
default: return 0;
}
}
int tilep_equ_helm(const item_def &item)
{
if (you.equip[EQ_HELMET] == -1)
return 0;
if (item.base_type != OBJ_ARMOUR)
return 0;
if (is_unrandom_artefact(item))
{
int idx = find_unrandart_index(item);
switch (idx + 1)
{
case 11:
// crown of Dyrovepreva
return TILEP_HELM_DYROVEPREVA;
case 41:
// mask of the Dragon
return TILEP_HELM_ART_DRAGONHELM;
case 50:
// hat of the Alchemist
return TILEP_HELM_TURBAN_PURPLE;
}
// Although there shouldn't be any, just in case
// unhandled artefacts fall through to defaults...
}
int etype = get_etype(item);
int helmet_desc = get_helmet_desc(item);
switch (item.sub_type)
{
case ARM_CAP:
switch (item.colour)
{
case BLACK:
case BLUE:
case LIGHTBLUE:
return TILEP_HELM_FEATHER_BLUE;
case GREEN:
case LIGHTGREEN:
case CYAN:
case LIGHTCYAN:
return TILEP_HELM_FEATHER_GREEN;
case RED:
case LIGHTRED:
case MAGENTA:
case LIGHTMAGENTA:
return TILEP_HELM_FEATHER_RED;
case BROWN:
case YELLOW:
return TILEP_HELM_FEATHER_YELLOW;
case LIGHTGREY:
case DARKGREY:
case WHITE:
return TILEP_HELM_FEATHER_WHITE;
}
return 0;
case ARM_WIZARD_HAT:
switch (item.colour)
{
case MAGENTA:
case LIGHTMAGENTA:
case BLACK:
return TILEP_HELM_WIZARD_BLACKRED;
case BLUE:
case LIGHTBLUE:
return TILEP_HELM_WIZARD_BLUE;
case GREEN:
case LIGHTGREEN:
return TILEP_HELM_WIZARD_DARKGREEN;
case CYAN:
return TILEP_HELM_WIZARD_PURPLE;
case LIGHTCYAN:
return TILEP_HELM_WIZARD_BLUEGREEN;
case RED:
case LIGHTRED:
return TILEP_HELM_WIZARD_RED;
case BROWN:
return TILEP_HELM_WIZARD_BROWN;
case YELLOW:
return TILEP_HELM_WIZARD_BLACKGOLD;
case LIGHTGREY:
case DARKGREY:
case WHITE:
return TILEP_HELM_WIZARD_WHITE;
}
return 0;
// Why are there both helms and helmets? -Enne
// It'd be like having catsup and ketchup in the same game.
case ARM_HELM:
case ARM_HELMET:
switch (helmet_desc)
{
case THELM_DESC_PLAIN:
switch (etype)
{
default:
return TILEP_HELM_CHAIN;
case 1:
return TILEP_HELM_HELM_GIMLI;
case 2:
return TILEP_HELM_HELM_OFS; // urgh
case 3:
return TILEP_HELM_FHELM_GRAY2;
case 4:
return TILEP_HELM_FHELM_BLACK;
}
case THELM_DESC_WINGED:
return TILEP_HELM_YELLOW_WING;
case THELM_DESC_HORNED:
switch (etype)
{
default:
return TILEP_HELM_FHELM_HORN2;
case 1:
return TILEP_HELM_BLUE_HORN_GOLD;
case 2:
return TILEP_HELM_FHELM_HORN_GRAY;
case 3:
return TILEP_HELM_FHELM_HORN_YELLOW;
case 4:
return TILEP_HELM_FHELM_OFS; // urgh
}
case THELM_DESC_CRESTED:
return TILEP_HELM_FHELM_ISILDUR;
case THELM_DESC_PLUMED:
return TILEP_HELM_FHELM_PLUME;
case THELM_DESC_SPIKED:
return TILEP_HELM_FHELM_EVIL;
case THELM_DESC_VISORED:
return TILEP_HELM_FHELM_GRAY3;
case THELM_DESC_JEWELLED:
return TILEP_HELM_FULL_GOLD;
}
}
return 0;
}
int tilep_equ_gloves(const item_def &item)
{
if (you.equip[EQ_GLOVES] == -1)
return 0;
if (item.base_type != OBJ_ARMOUR)
return 0;
if (item.sub_type != ARM_GLOVES)
return 0;
if (is_unrandom_artefact(item))
{
int idx = find_unrandart_index(item);
switch (idx + 1)
{
case 30: // gauntlets of War (thick brown)
return TILEP_ARM_GLOVE_BLACK;
case 51: // fencer's gloves (white)
return TILEP_ARM_GLOVE_WHITE;
}
}
int etype = get_etype(item);
switch (etype)
{
default:
case 0:
switch (item.colour)
{
case LIGHTBLUE:
return TILEP_ARM_GLOVE_BLUE;
default:
case BROWN:
return TILEP_ARM_GLOVE_BROWN;
}
case 1:
case 2:
case 3:
case 4:
switch (item.colour)
{
case LIGHTBLUE:
default:
return TILEP_ARM_GLOVE_CHUNLI;
case BROWN:
return TILEP_ARM_GLOVE_GRAYFIST;
}
}
return 0;
}
int tilep_equ_boots(const item_def &item)
{
if (you.equip[EQ_BOOTS] == -1)
return 0;
if (item.base_type != OBJ_ARMOUR)
return 0;
if (item.sub_type == ARM_NAGA_BARDING)
return TILEP_BOOTS_NAGA_BARDING;
if (item.sub_type == ARM_CENTAUR_BARDING)
return TILEP_BOOTS_CENTAUR_BARDING;
if (item.sub_type != ARM_BOOTS)
return 0;
if (is_unrandom_artefact(item))
{
int idx = find_unrandart_index(item);
switch (idx + 1)
{
case 23: // boots of the assassin
return TILEP_BOOTS_MIDDLE_GRAY;
}
}
int etype = get_etype(item);
switch (etype)
{
default:
case 0:
return TILEP_BOOTS_MIDDLE_BROWN3;
case 1:
case 2:
switch (item.colour)
{
case BROWN:
default:
return TILEP_BOOTS_MESH_RED;
case BLUE:
return TILEP_BOOTS_MESH_BLUE;
}
case 3:
case 4:
switch (item.colour)
{
case BROWN:
return TILEP_BOOTS_LONG_RED;
default:
case BLUE:
return TILEP_BOOTS_BLUE_GOLD;
}
}
return 0;
}
#ifdef TILEP_DEBUG
/*
* Debugging routines
*/
const char *get_ctg_name(int part)
{
return tilep_parts_name[part];
}
int get_ctg_idx(char *name)
{
int i;
for(i=0;i<TILEP_PARTS_TOTAL;i++)
if(strcmp(name, tilep_parts_name[i])==0) return i;
return 0;
}
const char *get_parts_name(int part, int idx)
{
static char tmp[10];
const char *ptr = tilep_comment[ tilep_comment_ofs[part] -1 + idx ];
if(idx==0) return "";
if(ptr[0]==0)
{
sprintf(tmp,"%02d",idx);
return tmp;
}
return ptr;
}
// �p�[�c�̖��O�𐔎��ɕϊ�
int get_parts_idx(int part, char *name)
{
int res = atoi(name);
int i;
for(i=0;i<tilep_parts_total[part];i++)
if(strcmp(name, tilep_comment[ tilep_comment_ofs[part]+i])==0)
return i+1;
return res;
}
#endif /* TILEP_DEBUG */
/*
* Tile data preparation
*/
// for clarity
enum SpecialIdx
{
SPECIAL_N = 0,
SPECIAL_NE = 1,
SPECIAL_E = 2,
SPECIAL_SE = 3,
SPECIAL_S = 4,
SPECIAL_SW = 5,
SPECIAL_W = 6,
SPECIAL_NW = 7,
SPECIAL_FULL = 8
};
int jitter(SpecialIdx i)
{
return (i + random_range(-1, 1) + 8) % 8;
}
void tile_init_flavor()
{
for (int x = 0; x < GXM; x++)
{
for (int y = 0; y < GYM; y++)
{
int max_wall_flavor = get_num_wall_flavors() - 1;
int max_floor_flavor = get_num_floor_flavors() - 1;
int wall_flavor = random_range(0, max_wall_flavor);
int floor_flavor = random_range(0, max_floor_flavor);
env.tile_flavor[x][y].floor = floor_flavor;
env.tile_flavor[x][y].wall = wall_flavor;
if (grd[x][y] == DNGN_FLOOR_SPECIAL)
{
int left_grd = (x > 0) ? grd[x-1][y] : DNGN_ROCK_WALL;
int right_grd = (x < GXM - 1) ? grd[x+1][y] : DNGN_ROCK_WALL;
int up_grd = (y > 0) ? grd[x][y-1] : DNGN_ROCK_WALL;
int down_grd = (y < GYM - 1) ? grd[x][y+1] : DNGN_ROCK_WALL;
// The special tiles contains part floor and part special, so
// if there are adjacent floor or special tiles, we should
// do our best to "connect" them appropriately. If there are
// are other tiles there (walls, doors, whatever...) then it
// doesn't matter.
bool l_nrm = left_grd == DNGN_FLOOR;
bool r_nrm = right_grd == DNGN_FLOOR;
bool u_nrm = up_grd == DNGN_FLOOR;
bool d_nrm = down_grd == DNGN_FLOOR;
bool l_spc = left_grd == DNGN_FLOOR_SPECIAL;
bool r_spc = right_grd == DNGN_FLOOR_SPECIAL;
bool u_spc = up_grd == DNGN_FLOOR_SPECIAL;
bool d_spc = down_grd == DNGN_FLOOR_SPECIAL;
if (l_nrm && r_nrm || u_nrm && d_nrm)
{
// Not much to do here...
env.tile_flavor[x][y].special = SPECIAL_FULL;
}
else if (l_nrm)
{
if (u_nrm)
env.tile_flavor[x][y].special = SPECIAL_NW;
else if (d_nrm)
env.tile_flavor[x][y].special = SPECIAL_SW;
else if (u_spc && d_spc)
env.tile_flavor[x][y].special = SPECIAL_W;
else if (u_spc && r_spc)
env.tile_flavor[x][y].special = SPECIAL_SW;
else if (d_spc && r_spc)
env.tile_flavor[x][y].special = SPECIAL_NW;
else if (u_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_W : SPECIAL_SW;
else if (d_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_W : SPECIAL_NW;
else
env.tile_flavor[x][y].special = jitter(SPECIAL_W);
}
else if (r_nrm)
{
if (u_nrm)
env.tile_flavor[x][y].special = SPECIAL_NE;
else if (d_nrm)
env.tile_flavor[x][y].special = SPECIAL_SE;
else if (u_spc && d_spc)
env.tile_flavor[x][y].special = SPECIAL_E;
else if (u_spc && l_spc)
env.tile_flavor[x][y].special = SPECIAL_SE;
else if (d_spc && l_spc)
env.tile_flavor[x][y].special = SPECIAL_NE;
else if (u_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_E : SPECIAL_SE;
else if (d_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_E : SPECIAL_NE;
else
env.tile_flavor[x][y].special = jitter(SPECIAL_E);
}
else if (u_nrm)
{
if (r_spc && l_spc)
env.tile_flavor[x][y].special = SPECIAL_N;
else if (r_spc && d_spc)
env.tile_flavor[x][y].special = SPECIAL_NW;
else if (l_spc && d_spc)
env.tile_flavor[x][y].special = SPECIAL_NE;
else if (r_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_N : SPECIAL_NW;
else if (l_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_N : SPECIAL_NE;
else
env.tile_flavor[x][y].special = jitter(SPECIAL_N);
}
else if (d_nrm)
{
if (r_spc && l_spc)
env.tile_flavor[x][y].special = SPECIAL_S;
else if (r_spc && u_spc)
env.tile_flavor[x][y].special = SPECIAL_SW;
else if (l_spc && u_spc)
env.tile_flavor[x][y].special = SPECIAL_SE;
else if (r_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_S : SPECIAL_SW;
else if (l_spc)
env.tile_flavor[x][y].special = coinflip() ?
SPECIAL_S : SPECIAL_SE;
else
env.tile_flavor[x][y].special = jitter(SPECIAL_S);
}
else if (u_spc && d_spc)
{
// We know this value is already initialized and
// is necessarily in bounds.
char t = env.tile_flavor[x][y-1].special;
if (t == SPECIAL_NE || t == SPECIAL_E)
env.tile_flavor[x][y].special = SPECIAL_E;
else if (t == SPECIAL_NW || t == SPECIAL_W)
env.tile_flavor[x][y].special = SPECIAL_W;
else
env.tile_flavor[x][y].special = SPECIAL_FULL;
}
else if (r_spc && l_spc)
{
// We know this value is already initialized and
// is necessarily in bounds.
char t = env.tile_flavor[x-1][y].special;
if (t == SPECIAL_NW || t == SPECIAL_N)
env.tile_flavor[x][y].special = SPECIAL_N;
else if (t == SPECIAL_SW || t == SPECIAL_S)
env.tile_flavor[x][y].special = SPECIAL_S;
else
env.tile_flavor[x][y].special = SPECIAL_FULL;
}
else if (u_spc && l_spc)
{
env.tile_flavor[x][y].special = SPECIAL_SE;
}
else if (u_spc && r_spc)
{
env.tile_flavor[x][y].special = SPECIAL_SW;
}
else if (d_spc && l_spc)
{
env.tile_flavor[x][y].special = SPECIAL_NE;
}
else if (d_spc && r_spc)
{
env.tile_flavor[x][y].special = SPECIAL_NW;
}
else
{
env.tile_flavor[x][y].special = SPECIAL_FULL;
}
}
else
{
env.tile_flavor[x][y].special = 0;
}
}
}
// Second pass for clean up. The only bad part about the above
// algorithm is that it could turn a block of floor like this:
//
// N4NN
// 3125
// NN6N
//
// (KEY: N = normal floor, # = special floor)
//
// Into these flavors:
// 1 - SPECIAL_S
// 2 - SPECIAL_N
// 3-6, not important
//
// Generally the tiles don't fit with a north to the right or left
// of a south tile. What we really want to do is to separate the
// two regions, by making 1 a SPECIAL_SE and 2 a SPECIAL_NW tile.
for (int x = 0; x < GXM - 1; x++)
{
for (int y = 0; y < GYM - 1; y++)
{
if (grd[x][y] != DNGN_FLOOR_SPECIAL)
continue;
if (env.tile_flavor[x][y].special != SPECIAL_N &&
env.tile_flavor[x][y].special != SPECIAL_S &&
env.tile_flavor[x][y].special != SPECIAL_E &&
env.tile_flavor[x][y].special != SPECIAL_W)
{
continue;
}
int right_flavor = x < GXM - 1 ? env.tile_flavor[x+1][y].special :
SPECIAL_FULL;
int down_flavor = y < GYM - 1 ? env.tile_flavor[x][y+1].special :
SPECIAL_FULL;
int this_flavor = env.tile_flavor[x][y].special;
if (this_flavor == SPECIAL_N && right_flavor == SPECIAL_S)
{
env.tile_flavor[x][y].special = SPECIAL_NE;
env.tile_flavor[x+1][y].special = SPECIAL_SW;
}
else if (this_flavor == SPECIAL_S && right_flavor == SPECIAL_N)
{
env.tile_flavor[x][y].special = SPECIAL_SE;
env.tile_flavor[x+1][y].special = SPECIAL_NW;
}
else if (this_flavor == SPECIAL_E && down_flavor == SPECIAL_W)
{
env.tile_flavor[x][y].special = SPECIAL_SE;
env.tile_flavor[x][y+1].special = SPECIAL_NW;
}
else if (this_flavor == SPECIAL_W && down_flavor == SPECIAL_E)
{
env.tile_flavor[x][y].special = SPECIAL_NE;
env.tile_flavor[x][y+1].special = SPECIAL_SW;
}
}
}
}
void tile_clear_buf()
{
for (int y = 0; y < GYM; y++)
{
for (int x = 0; x < GXM; x++)
{
unsigned char this_is_wall = 128;
gv_now[x][y]=0;
tile_dngn[x][y]=TILE_DNGN_UNSEEN;
if (env.map[x][y].glyph() != 0)
{
int g = grd[x][y];
if (g >= DNGN_ORCISH_IDOL && g != DNGN_OPEN_DOOR)
this_is_wall = 0;
}
wall_flag[x][y] = this_is_wall;
}
}
for (int y = 0; y < GYM; y++)
{
for (int x = 0; x < GXM; x++)
{
unsigned char w = wall_flag[x][y]&0x80;
if (w)
{
if (x != 0) wall_flag[x-1][y] |= WFLAG_R;
if (x != GXM-1) wall_flag[x+1][y] |= WFLAG_L;
if (y != 0) wall_flag[x][y-1] |= WFLAG_D;
if (y != GYM-1) wall_flag[x][y+1] |= WFLAG_U;
}
wall_flag[x][y] &= 0xf;
}
}
}
/* called from view.cc */
void tile_draw_floor()
{
int cx, cy;
for (cy = 0; cy < env.tile_fg.height(); cy++)
{
for (cx = 0; cx < env.tile_fg.width(); cx++)
{
const coord_def ep(cx+1, cy+1);
const coord_def gc = view2grid(show2view(ep));
int bg = TILE_DNGN_UNSEEN | tile_unseen_flag(gc);
int object = env.show(ep);
if (in_bounds(gc) && object != 0)
{
if (object != gv_now[gc.x][gc.y])
{
if (object == DNGN_SECRET_DOOR)
object = (int)grid_secret_door_appearance(gc.x, gc.y);
tile_dngn[gc.x][gc.y] = tileidx_feature(object);
gv_now[gc.x][gc.y] = object;
unsigned char wall = 0xff;
if (object >= DNGN_ORCISH_IDOL && object != DNGN_OPEN_DOOR)
wall = 0;
if (gc.x != 0)
{
wall_flag[gc.x-1][gc.y] = (wall_flag[gc.x-1][gc.y] &
(~WFLAG_R)) | (wall & WFLAG_R);
}
if (gc.x != GXM-1)
{
wall_flag[gc.x+1][gc.y] = (wall_flag[gc.x+1][gc.y] &
(~WFLAG_L)) | (wall & WFLAG_L);
}
if (gc.y != 0)
{
wall_flag[gc.x][gc.y-1] = (wall_flag[gc.x][gc.y-1] &
(~WFLAG_D)) | (wall & WFLAG_D);
}
if (gc.y != GYM-1)
{
wall_flag[gc.x][gc.y+1] = (wall_flag[gc.x][gc.y+1] &
(~WFLAG_U)) | (wall & WFLAG_U);
}
}
bg = tile_dngn[gc.x][gc.y];
}
// init tiles
env.tile_bg[ep.x-1][ep.y-1] = bg;
env.tile_fg[ep.x-1][ep.y-1] = 0;
}
}
}
// Called from item() in view.cc
void tile_place_item(int x, int y, int idx)
{
int t = tileidx_item(mitm[idx]);
if (mitm[idx].link != NON_ITEM)
t |= TILE_FLAG_S_UNDER;
env.tile_fg[x-1][y-1]=t;
if (item_needs_autopickup(mitm[idx]))
env.tile_bg[x-1][y-1] |= TILE_FLAG_CURSOR3;
}
void tile_place_item_bk(int gx, int gy, int idx)
{
int t = tileidx_item(mitm[idx]);
env.tile_bk_fg[gx][gy] = t;
if (item_needs_autopickup(mitm[idx]))
env.tile_bk_bg[gx][gy] |= TILE_FLAG_CURSOR3;
}
void tile_place_tile_bk(int gx, int gy, int tileidx)
{
env.tile_bk_fg[gx][gy] = tileidx;
}
// Called from item() in view.cc
void tile_place_item_marker(int x, int y, int idx)
{
env.tile_fg[x-1][y-1] |= TILE_FLAG_S_UNDER;
if (item_needs_autopickup(mitm[idx]))
env.tile_bg[x-1][y-1] |= TILE_FLAG_CURSOR3;
}
// Called from monster_grid() in view.cc
void tile_place_monster(int gx, int gy, int idx, bool foreground)
{
if (idx == NON_MONSTER)
{
return;
}
const coord_def gc(gx, gy);
const coord_def ep = view2show(grid2view(gc));
int t = tileidx_monster(idx);
int t0 = t & TILE_FLAG_MASK;
int flag = t & (~TILE_FLAG_MASK);
int mon_wep = menv[idx].inv[MSLOT_WEAPON];
if (menv[idx].type >= MONS_DRACONIAN &&
menv[idx].type <= MONS_DRACONIAN_SCORCHER)
{
int race = draco_subspecies(&menv[idx]);
int cls = menv[idx].type;
int eq = 0;
if (mon_wep != NON_ITEM &&
(cls == race || cls == MONS_DRACONIAN_KNIGHT))
eq = tilep_equ_weapon(mitm[mon_wep]);
t = flag | TileMcacheFind(cls, eq, race);
}
else if (mon_wep != NON_ITEM)
{
int eq = tilep_equ_weapon(mitm[mon_wep]);
switch(t0)
{
// 3D chars
case TILE_MONS_VAULT_GUARD:
case TILE_MONS_BLORK_THE_ORC:
case TILE_MONS_ORC:
case TILE_MONS_ORC_KNIGHT:
case TILE_MONS_ORC_WARLORD:
case TILE_MONS_ORC_WARRIOR:
case TILE_MONS_URUG:
case TILE_MONS_GOBLIN:
case TILE_MONS_IJYB:
case TILE_MONS_HOBGOBLIN:
case TILE_MONS_GNOLL:
case TILE_MONS_BOGGART:
case TILE_MONS_KOBOLD:
case TILE_MONS_KOBOLD_DEMONOLOGIST:
case TILE_MONS_BIG_KOBOLD:
case TILE_MONS_DEEP_ELF_FIGHTER:
case TILE_MONS_DEEP_ELF_SOLDIER:
case TILE_MONS_DEEP_ELF_KNIGHT:
case TILE_MONS_DEEP_ELF_BLADEMASTER:
case TILE_MONS_DEEP_ELF_MASTER_ARCHER:
case TILE_MONS_DEEP_ELF_MAGE:
case TILE_MONS_DEEP_ELF_SUMMONER:
case TILE_MONS_DEEP_ELF_CONJURER:
case TILE_MONS_DEEP_ELF_PRIEST:
case TILE_MONS_DEEP_ELF_HIGH_PRIEST:
case TILE_MONS_DEEP_ELF_DEMONOLOGIST:
case TILE_MONS_DEEP_ELF_ANNIHILATOR:
case TILE_MONS_DEEP_ELF_SORCERER:
case TILE_MONS_DEEP_ELF_DEATH_MAGE:
case TILE_MONS_MIDGE:
case TILE_MONS_IMP:
case TILE_MONS_NAGA:
case TILE_MONS_GREATER_NAGA:
case TILE_MONS_NAGA_WARRIOR:
case TILE_MONS_NAGA_MAGE:
case TILE_MONS_OGRE_MAGE:
case TILE_MONS_RED_DEVIL:
case TILE_MONS_WIZARD:
case TILE_MONS_HUMAN:
case TILE_MONS_ELF:
case TILE_MONS_ANGEL:
case TILE_MONS_HELL_KNIGHT:
case TILE_MONS_NORRIS:
case TILE_MONS_MAUD:
case TILE_MONS_DUANE:
case TILE_MONS_EDMUND:
case TILE_MONS_FRANCES:
case TILE_MONS_HAROLD:
case TILE_MONS_JOSEPH:
case TILE_MONS_JOZEF:
case TILE_MONS_RUPERT:
case TILE_MONS_TERENCE:
case TILE_MONS_WAYNE:
case TILE_MONS_FREDERICK:
case TILE_MONS_RAKSHASA:
case TILE_MONS_RAKSHASA_FAKE:
case TILE_MONS_VAMPIRE_KNIGHT:
case TILE_MONS_SKELETAL_WARRIOR:
if (eq != 0 )
t = flag | TileMcacheFind(t0, eq);
break;
}
}
if (foreground)
{
env.tile_fg[ep.x-1][ep.y-1] = t;
}
else
{
env.tile_bk_fg[gc.x][gc.y] = t0;
}
}
void tile_place_cloud(int x, int y, int type, int decay)
{
env.tile_fg[x-1][y-1]= tileidx_cloud(type, decay);
}
unsigned int tileRayCount = 0;
FixedVector<coord_def, 30> tileRays;
void tile_place_ray(const coord_def& gc)
{
// Record rays for later. The curses version just applies
// rays directly to the screen. The tiles version doesn't have
// (nor want) such direct access. So, it batches up all of the
// rays and applies them in viewwindow(...).
if (tileRayCount < tileRays.size() - 1)
{
tileRays[tileRayCount++] = view2show(grid2view(gc));
}
}
void tile_draw_rays(bool resetCount)
{
for (unsigned int i = 0; i < tileRayCount; i++)
{
env.tile_bg[tileRays[i].x-1][tileRays[i].y-1] |= TILE_FLAG_RAY;
}
if (resetCount)
tileRayCount = 0;
}
void tile_finish_dngn(short unsigned int *tileb, int cx, int cy)
{
int x, y;
int count = 0;
for (y=0; y < crawl_view.viewsz.y; y++)
{
for (x=0; x < crawl_view.viewsz.x; x++)
{
const int gx = view2gridX(x);
const int gy = view2gridY(y);
int wall = 0;
char wall_flv = 0;
char floor_flv = 0;
char special_flv = 0;
if (map_bounds( gx, gy ))
{
wall = wall_flag[gx][gy];
wall_flv = env.tile_flavor[gx][gy].wall;
floor_flv = env.tile_flavor[gx][gy].floor;
special_flv = env.tile_flavor[gx][gy].special;
}
finalize_tile(&tileb[count], wall,
wall_flv, floor_flv, special_flv);
finalize_tile(&tileb[count+1], wall,
wall_flv, floor_flv, special_flv);
count += 2;
}
}
}
void tile_draw_dungeon(short unsigned int *tileb)
{
tile_finish_dngn(tileb, you.x_pos, you.y_pos);
TileDrawDungeon(tileb);
}
#define swapint(a, b) {int tmp = a; a = b; b = tmp;}
// Item is unided(1) or tried(2) or id'ed (0)
// Note that Jewellries are never "tried"
static int item_unid_type(const item_def &item)
{
int t = item.base_type;
int s = item.sub_type;
int id0 = 0;
id_arr& id = get_typeid_array();
if ((item.flags &ISFLAG_KNOW_TYPE) != 0)
return 0;
switch (t)
{
case OBJ_SCROLLS:
id0 = id[ IDTYPE_SCROLLS ][s];
if (id0 == ID_TRIED_TYPE)
return 2;
else
if (id0 != ID_KNOWN_TYPE)
return 1;
else
return 0;
case OBJ_WANDS:
id0 = id[ IDTYPE_WANDS ][s];
if (id0 == ID_TRIED_TYPE)
return 2;
else
if (id0 != ID_KNOWN_TYPE)
return 1;
else
return 0;
case OBJ_POTIONS:
id0 = id[ IDTYPE_POTIONS ][s];
if (id0 == ID_TRIED_TYPE)
return 2;
else
if (id0 != ID_KNOWN_TYPE)
return 1;
else
return 0;
case OBJ_JEWELLERY:
id0 = id[ IDTYPE_JEWELLERY ][s];
if (id0 != ID_KNOWN_TYPE)
return 1;
else
return 0;
}
return 0;
}
// Helper routine: sort floor item index and pack into idx
int pack_floor_item(int *idx, int *flag, int *isort, int max)
{
int n = 0;
static int isort_weapon2[NUM_WEAPONS];
static int isort_armour2[NUM_ARMOURS];
static const int isort_weapon[NUM_WEAPONS] =
{
WPN_WHIP, WPN_CLUB, WPN_HAMMER, WPN_MACE,
WPN_FLAIL, WPN_DEMON_WHIP,
WPN_ANCUS, WPN_MORNINGSTAR, WPN_EVENINGSTAR,
WPN_SPIKED_FLAIL, WPN_GREAT_MACE, WPN_DIRE_FLAIL,
WPN_GIANT_CLUB, WPN_GIANT_SPIKED_CLUB,
WPN_KNIFE, WPN_DAGGER, WPN_SHORT_SWORD, WPN_SABRE, WPN_QUICK_BLADE,
WPN_FALCHION, WPN_LONG_SWORD, WPN_SCIMITAR, WPN_KATANA,
WPN_DEMON_BLADE, WPN_DOUBLE_SWORD, WPN_GREAT_SWORD, WPN_TRIPLE_SWORD,
WPN_HAND_AXE, WPN_WAR_AXE, WPN_BROAD_AXE,
WPN_BATTLEAXE, WPN_EXECUTIONERS_AXE,
WPN_SPEAR, WPN_TRIDENT, WPN_HALBERD, WPN_SCYTHE,
WPN_GLAIVE, WPN_DEMON_TRIDENT,
WPN_QUARTERSTAFF,
WPN_SLING, WPN_BOW, WPN_CROSSBOW, WPN_HAND_CROSSBOW
};
static const int isort_armour[NUM_ARMOURS] =
{
ARM_ROBE,
ARM_ANIMAL_SKIN,
ARM_LEATHER_ARMOUR,
ARM_TROLL_LEATHER_ARMOUR,
ARM_RING_MAIL, ARM_SCALE_MAIL, ARM_CHAIN_MAIL,
ARM_SPLINT_MAIL, ARM_BANDED_MAIL, ARM_PLATE_MAIL,
ARM_CRYSTAL_PLATE_MAIL,
ARM_SWAMP_DRAGON_ARMOUR,
ARM_MOTTLED_DRAGON_ARMOUR,
ARM_STEAM_DRAGON_ARMOUR,
ARM_DRAGON_ARMOUR,
ARM_ICE_DRAGON_ARMOUR,
ARM_STORM_DRAGON_ARMOUR,
ARM_GOLD_DRAGON_ARMOUR,
ARM_TROLL_HIDE,
ARM_SWAMP_DRAGON_HIDE,
ARM_MOTTLED_DRAGON_HIDE,
ARM_STEAM_DRAGON_HIDE,
ARM_DRAGON_HIDE,
ARM_ICE_DRAGON_HIDE,
ARM_STORM_DRAGON_HIDE,
ARM_GOLD_DRAGON_HIDE,
ARM_CLOAK,
ARM_BUCKLER, ARM_SHIELD, ARM_LARGE_SHIELD,
ARM_HELMET, ARM_GLOVES, ARM_BOOTS
};
int i;
for (i=0;i<NUM_WEAPONS;i++)
isort_weapon2[isort_weapon[i]] = i;
for (i=0;i<NUM_ARMOURS;i++)
isort_armour2[isort_armour[i]] = i;
int o = igrd[you.x_pos][you.y_pos];
if (o == NON_ITEM) return 0;
while (o != NON_ITEM)
{
int id0 = item_unid_type(mitm[o]);
int next = mitm[o].link;
int typ = mitm[o].base_type;
if (n >= max) break;
idx[n] = o;
isort[n] = typ * 256 * 3;
if (typ == OBJ_WEAPONS)
{
isort[n] += 3 * isort_weapon2[ mitm[o].sub_type];
}
if (typ == OBJ_ARMOUR)
{
isort[n] += 3 * isort_armour2[ mitm[o].sub_type ];
}
flag[n] = 0;
if (item_ident( mitm[o], ISFLAG_KNOW_CURSE ) &&
item_cursed(mitm[o]))
{
flag[n] |= TILEI_FLAG_CURSE;
}
if (id0 != 0)
{
isort[n] += id0;
if (id0 == 2)
flag[n] = TILEI_FLAG_TRIED;
}
flag[n] |= TILEI_FLAG_FLOOR;
// Simple Bubble sort
int k = n;
while( (k > 0) && (isort[k-1] > isort[k]))
{
swapint(idx[k-1], idx[k]);
swapint(isort[k-1], isort[k]);
swapint(flag[k-1], flag[k]);
k--;
}
n++;
o = next;
}
return n;
}
// Helper routine: Calculate tile index and quantity data to be displayed
void finish_inven_data(int n, int *tiles, int *num, int *idx, int *iflag)
{
int i;
for(i = 0; i < n; i++)
{
int q = -1;
int j = idx[i];
item_def *itm;
if (j==-1)
{
num[i]=-1;
tiles[i]= 0;
continue;
}
if (iflag[i] & TILEI_FLAG_FLOOR)
itm = &mitm[j];
else
itm = &you.inv[j];
int type = itm->base_type;
if (type == OBJ_FOOD || type == OBJ_SCROLLS
|| type == OBJ_POTIONS || type == OBJ_MISSILES)
q = itm->quantity;
if (q==1) q = -1;
if (type == OBJ_WANDS &&
(itm->flags & ISFLAG_KNOW_PLUSES )!= 0)
q = itm->plus;
tiles[i] = tileidx_item(*itm);
num[i] = q;
}
}
// Display Inventory/floor items
#include "guic.h"
extern TileRegionClass *region_item;
extern TileRegionClass *region_item2;
extern WinClass *win_main;
void tile_draw_inv(int item_type, int flag)
{
#define MAXINV 200
int tiles[MAXINV];
int num[MAXINV];
int idx[MAXINV];
int iflag[MAXINV];
int isort[MAXINV];
int n = 0;
int i, j;
if (flag == -1)
{
flag = (win_main->active_layer == 0) ? REGION_INV1 : REGION_INV2;
}
TileRegionClass *r = (flag == REGION_INV1) ? region_item:region_item2;
int numInvTiles = r->mx * r->my;
if (numInvTiles > MAXINV)
numInvTiles = MAXINV;
// item.base_type <-> char conversion table
const static char *obj_syms = ")([/%#?=!#+\\0}x";
const static char *syms_table[] =
{
")\\", // weapons and staves
"(", // missile
"[", // armour
"/", // wands
"%", // foods
"#", // none
"?+", // scrolls and books
"=", // rings/amulets
"!", // potions
"#", // none
"?+", // books/scrolls
")\\", // weapons and staves
"0",
"}",
"x"
};
const char *item_chars = Options.show_items;
int eq_flag[ENDOFPACK];
int empty = 0;
for (j = 0; j < ENDOFPACK; j++)
{
eq_flag[j] =
(you.inv[j].quantity != 0 && is_valid_item( you.inv[j])) ? 1:0;
empty += 1-eq_flag[j];
}
for (j=0; j<NUM_EQUIP; j++)
{
int eq = you.equip[j];
if (eq >= 0 && eq < ENDOFPACK)
eq_flag[eq] = 2;
}
if (item_type >= 0)
item_chars = syms_table[item_type];
else
if (item_type == -2)
item_chars = obj_syms;
else
if (item_type == -3)
item_chars = ".";
if (item_chars[0] == 0) return;
for (i=0; i < (int)strlen(item_chars); i++)
{
int top = n;
char ic = item_chars[i];
if (n >= numInvTiles) break;
// Items on the floor
if (ic == '.')
{
n += pack_floor_item(&idx[n], &iflag[n], &isort[n], numInvTiles - n);
continue;
}
// empty slots
if (ic == '_')
{
for (j = 0; j < empty && n < numInvTiles; j++)
{
idx[n] = -1;
iflag[n] = 0;
n++;
}
continue;
}
// convert item char to item type
int type = -1;
for (j=0; j < (int)strlen(obj_syms); j++)
{
if (obj_syms[j] == ic)
{
type = j;
break;
}
}
if (type == -1) continue;
for (j = 0; j < ENDOFPACK && n < numInvTiles; j++)
{
if (you.inv[j].base_type==type && eq_flag[j] != 0)
{
int sval = NUM_EQUIP + you.inv[j].sub_type;
int base = 0;
int id0 = item_unid_type(you.inv[j]);
idx[n] = j;
iflag[n] = 0;
if (type == OBJ_JEWELLERY && sval >= AMU_RAGE)
{
base = 1000;
sval = base + sval;
}
if (id0 == 2)
{
iflag[n] |= TILEI_FLAG_TRIED;
// To the tail
sval = base + 980;
}
else if (id0 == 1)
{
// To the tail
sval = base + 990;
}
// Equipment first
if (eq_flag[j]==2)
{
//sval = base;
iflag[n] |= TILEI_FLAG_EQUIP;
}
if (item_cursed(you.inv[j]) &&
item_ident( you.inv[j], ISFLAG_KNOW_CURSE ))
{
iflag[n] |= TILEI_FLAG_CURSE;
}
if (flag == REGION_INV2)
sval = j;
isort[n] = sval;
int k = n;
while( (k > top) && (isort[k-1] > isort[k]))
{
swapint(idx[k-1], idx[k]);
swapint(isort[k-1], isort[k]);
swapint(iflag[k-1], iflag[k]);
k--;
}
n++;
} // type == base
} // j
} // i
finish_inven_data(n, tiles, num, idx, iflag);
for(i = n; i < numInvTiles; i++)
{
tiles[i] = 0;
num[i] = 0;
idx[i] = -1;
iflag[i] = 0;
}
TileDrawInvData(n, flag, tiles, num, idx, iflag);
}
#endif
tile = env.tile_bk_bg[0][0];
// bg first
for (int count_x = 0; count_x < GXM; count_x++)
{
for (int count_y = 0; count_y < GYM; count_y++)
{
last_tile = tile;
tile = env.tile_bk_bg[count_x][count_y];
if (tile == last_tile)
{
rle_count++;
if (rle_count == 0x100)
{
marshallShort(th, last_tile);
marshallByte(th, (char)0xFF);
rle_count = 1;
}
}
else
{
marshallShort(th, last_tile);
// Note: the unsigned char tile count gets streamed
// as a signed char here. It gets read back into
// an unsigned char in the read function.
marshallByte(th, rle_count);
rle_count = 1;
}
}
}
marshallShort(th, tile);
marshallByte(th, rle_count);
// fg
tile = env.tile_bk_fg[0][0];
rle_count = 0;
for (int count_x = 0; count_x < GXM; count_x++)
{
for (int count_y = 0; count_y < GYM; count_y++)
{
last_tile = tile;
tile = env.tile_bk_fg[count_x][count_y];
if (tile == last_tile)
{
rle_count++;
if (rle_count == 0x100)
{
marshallShort(th, last_tile);
marshallByte(th, (char)0xFF);
rle_count = 1;
}
}
else
{
marshallShort(th, last_tile);
marshallByte(th, rle_count);
rle_count = 1;
}
}
}
marshallShort(th, tile);
marshallByte(th, rle_count);
// flavor
for (int count_x = 0; count_x < GXM; count_x++)
{
for (int count_y = 0; count_y < GYM; count_y++)
{
marshallByte(th, env.tile_flavor[count_x][count_y].wall);
marshallByte(th, env.tile_flavor[count_x][count_y].floor);
marshallByte(th, env.tile_flavor[count_x][count_y].special);
}
}
GmapInit(false);
TileLoadWall(false);
tile_clear_buf();
#endif
}
}
}
void tag_read_level_tiles(struct tagHeader &th)
{
#ifdef USE_TILE
for (int i = 0; i < GXM; i++)
{
for (int j = 0; j < GYM; j++)
{
env.tile_bk_bg[i][j] = 0;
env.tile_bk_fg[i][j] = 0;
}
}
unsigned char rle_count = 0;
unsigned short tile = 0;
int ver = unmarshallShort(th);
if (ver == 0) return;
// map grids
// how many X?
const int gx = unmarshallShort(th);
// how many Y?
const int gy = unmarshallShort(th);
// BG first
for (int i = 0; i < gx; i++)
{
for (int j = 0; j < gy; j++)
{
if (rle_count == 0)
{
tile = unmarshallShort(th);
rle_count = unmarshallByte(th);
}
env.tile_bk_bg[i][j] = tile;
rle_count--;
}
// FG
rle_count = 0;
for (int i = 0; i < gx; i++)
{
for (int j = 0; j < gy; j++)
{
if (rle_count == 0)
{
tile = unmarshallShort(th);
rle_count = unmarshallByte(th);
}
env.tile_bk_fg[i][j] = tile;
rle_count--;
}
}
// flavor
for (int x = 0; x < gx; x++)
{
for (int y = 0; y < gy; y++)
{
env.tile_flavor[x][y].wall = unmarshallByte(th);
env.tile_flavor[x][y].floor = unmarshallByte(th);
env.tile_flavor[x][y].special = unmarshallByte(th);
}
}
#endif
#include "bm.h"
int myrand()
{
static int seed=12345;
seed *= 65539;
return(seed&0x7fffffff);
}
int same_hue(int r, int g, int b, int r0, int g0, int b0)
{
if (r==255)r=256;
if (g==255)g=256;
if (b==255)b=256;
if(r0*g == g0*r && g0*b == b0*g && b0*r == r0*b) return 1;
return 0;
}
void convert_hue(unsigned char *r, unsigned char *g, unsigned char *b,
int r0, int g0, int b0, int modif)
{
int rr,gg,bb;
int max0 = r0;
int max = *r;
if(max<*g) max=*g;
if(max<*b) max=*b;
if(max==255) max=256;
if(max0<g0) max0=g0;
if(max0<b0) max0=b0;
if (max <=32) modif /= 4;
else
if (max <=64) modif /= 2;
rr = ( (max+modif) * r0 )/ max0;
gg = ( (max+modif) * g0 )/ max0;
bb = ( (max+modif) * b0 )/ max0;
if(rr>255) rr=255;
else if(rr<0) rr=0;
if(gg>255) gg=255;
else if(gg<0) gg=0;
if(bb>255) bb=255;
else if(bb<0) bb=0;
*r=rr; *g=gg; *b=bb;
}
int main(int argc, char **argv){
unsigned char *ibuf[3];
int x,y;
int i;
char fn[100],st[1024];
char *flag;
unsigned char *nbuf[3];
int ncol[3],ccol[10][3],nccol,ccol2[10][3], modif[10];
FILE *ifp;
int level,l;
int xx,yy,c,f;
float prob,amp;
int thresh;
stdpal();
process_cpath(argv[0]);
if(argc!=1)
strcpy(fn, argv[1]);
else
sprintf(fn,"%sshade.txt",cpath);
fprintf(stderr,"FILE=[%s]\n",fn);
ifp=fopen(fn,"r");
myfget(st,ifp);
sprintf(fn,"%s%s.bmp",cpath,st);
fprintf(stderr,"Orig file=[%s]\n",fn);
ibuf[0]=ibuf[1]=ibuf[2]=NULL;
bmread(fn,&x,&y,ibuf );
fprintf(stderr,"loaded x=%d y=%d\n",x,y);
flag=malloc(x*y);
for(i=0;i<3;i++)nbuf[i]=malloc(x*y);
while(1){
myfget(st,ifp);
if(feof(ifp))break;
level=atoi(st);
//random perturbation amplitude/prob
myfget(st,ifp);
prob=atof(st);
thresh=(int)(0x7fffffff*prob);
if(prob==-1.0)thresh=-1;//ringmail
if(prob==-2.0)thresh=-2;//chainmail
myfget(st,ifp);
amp=atof(st);
printf("P=%f Amp=%f\n",prob,amp);
// Normal col
myfget(st,ifp);
fprintf(stderr,"Normal [%s]\n",st);
sscanf(st,"%d %d %d",&ncol[0],&ncol[1],&ncol[2]);
//Control col
myfget(st,ifp);
if(feof(ifp))break;
nccol=atoi(st);
for(i=0;i<nccol;i++){
myfget(st,ifp);
if(feof(ifp))exit(1);
modif[i]=0;
l=sscanf(st,"%d %d %d %d %d %d %d",&ccol[i][0],&ccol[i][1],&ccol[i][2]
,&ccol2[i][0],&ccol2[i][1],&ccol2[i][2], &modif[i]);
if(l==3){
ccol2[i][0]=ccol[i][0];
ccol2[i][1]=ccol[i][1];
ccol2[i][2]=ccol[i][2];
}
}//ncol
fprintf(stderr,"Level=%d ccol=%d\n",level,nccol);
fprintf(stderr,"Normal=%d %d %d\n",ncol[0],ncol[1],ncol[2]);
for(xx=0;xx<x;xx++){
for(yy=0;yy<y;yy++){
int ad=xx+yy*x;
flag[ad]=0;
if( same_hue(ibuf[0][ad], ibuf[1][ad], ibuf[2][ad],
ncol[0], ncol[1], ncol[2])) flag[ad]=1;
else
{
for(i=0;i<nccol;i++)
if(same_hue(ibuf[0][ad], ibuf[1][ad], ibuf[2][ad],
ccol[i][0], ccol[i][1], ccol[i][2])) flag[ad]=2+i;
}
}}
/***** convert ******/
for(xx=0;xx<x;xx++){
for(yy=0;yy<y;yy++){
int ad=xx+yy*x;
int f=flag[ad];
if(f>1) convert_hue(&ibuf[0][ad],&ibuf[1][ad],&ibuf[2][ad],
ccol2[f-2][0],ccol2[f-2][1],ccol2[f-2][2], modif[f-2]);
}
}
/********************************/
for(l=0;l<level;l++){
for(yy=0;yy<y;yy++){
for(xx=0;xx<x;xx++){
int ad=xx+yy*x;
int sum,n;
if(flag[ad]!=1){
for(c=0;c<3;c++)nbuf[c][ad]=ibuf[c][ad];
continue;
}
for(c=0;c<3;c++){
n=0;sum=0; // (int)(ibuf[c][ad])*1;
if(xx>0 && flag[ad-1]!=0){n++;sum+=ibuf[c][ad-1];}
if(xx<x-1 && flag[ad+1]!=0){n++;sum+=ibuf[c][ad+1];}
if(yy>0 && flag[ad-x]!=0){n++;sum+=ibuf[c][ad-x];}
if(yy<y-1 && flag[ad+x]!=0){n++;sum+=ibuf[c][ad+x];}
if(n!=0){
sum +=n/2;
sum/=n;
nbuf[c][ad]=sum;
}else nbuf[c][ad]=ibuf[c][ad];
}/*c*/
ad++;
}}/*xy**/
for(xx=0;xx<x;xx++){
for(yy=0;yy<y;yy++){
int ad=xx+yy*x;
for(c=0;c<3;c++){
ibuf[c][ad]=nbuf[c][ad];}}}
}/*level*/
/**random **/
if(thresh==-1){//ringmail
for(xx=0;xx<x;xx++){
for(yy=0;yy<y;yy++){
int ad=xx+yy*x;
if(flag[ad]!=0){
int dd=0;
int flag=(xx+2000-3*yy)%5;
if(flag==0)dd=+64;
if(flag==3||flag==4)dd=-32;
for(c=0;c<3;c++){
int d=(int)ibuf[c][ad];
d=(int)(d+dd);
if(d>255)d=255;
if(d<0)d=0;
ibuf[c][ad]=(unsigned char)d;
}
}
}}//XY
}//ringmail
if(thresh==-2){//chainmail
for(xx=0;xx<x;xx++){
for(yy=0;yy<y;yy++){
int ad=xx+yy*x;
if(flag[ad]!=0){
int dd=0;
int flag=(xx+2000-2*yy)%4;
if(flag==0)dd=+64;
if(flag==1)dd=+32;
if(flag==3)dd=-32;
for(c=0;c<3;c++){
int d=(int)ibuf[c][ad];
d=(int)(d+dd);
if(d>255)d=255;
if(d<0)d=0;
ibuf[c][ad]=(unsigned char)d;
}
}
}}//XY
}//chainmail
if(thresh>0){
for(xx=0;xx<x;xx++){
for(yy=0;yy<y;yy++){
int ad=xx+yy*x;
if(myrand()<thresh && flag[ad]!=0){
double r=1.0-amp+2*amp*(myrand()*1.0/0x7fffffff);
if(r<0.0)r=0.0;
for(c=0;c<3;c++){
int d=(int)ibuf[c][ad];
d=(int)(d*r);
if(d>255)d=255;
if(d<0)d=0;
ibuf[c][ad]=(unsigned char)d;
}
}
}}//XY
}//if
}/*while*/
sprintf(fn,"%sb.bmp",cpath);
bmwrite_dither(fn,x,y,ibuf ,flag);
fclose(ifp);
}
unsigned char pbuf[1024]= {
/* index B G R unused */
// Red
/* 0x00 */ 0x00, 0x00, 0xff, 0x00,
/* 0x01 */ 0x00, 0x00, 0xe0, 0x00,
/* 0x02 */ 0x00, 0x00, 0xc0, 0x00,
/* 0x03 */ 0x00, 0x00, 0xa0, 0x00,
/* 0x04 */ 0x00, 0x00, 0x80, 0x00,
/* 0x05 */ 0x00, 0x00, 0x60, 0x00,
/* 0x06 */ 0x00, 0x00, 0x40, 0x00,
/* 0x07 */ 0x00, 0x00, 0x30, 0x00,
// Dark red
/* 0x08 */ 0x00, 0x00, 0x20, 0x00,
/* 0x09 */ 0x00, 0x00, 0x18, 0x00,
/* 0x0a */ 0x00, 0x00, 0x10, 0x00,
//Pale Red
/* 0x0b */ 0x40, 0x40, 0x80, 0x00,
/* 0x0c */ 0x50, 0x50, 0xa0, 0x00,
/* 0x0d */ 0x60, 0x60, 0xc0, 0x00,
/* 0x0e */ 0x70, 0x70, 0xe0, 0x00,
/* 0x0f */ 0x80, 0x80, 0xff, 0x00,
//Red-Orange
/* 0x10 */ 0x00, 0x40, 0xff, 0x00,
/* 0x11 */ 0x00, 0x38, 0xe0, 0x00,
/* 0x12 */ 0x00, 0x30, 0xc0, 0x00,
/* 0x13 */ 0x00, 0x28, 0xa0, 0x00,
/* 0x14 */ 0x00, 0x20, 0x80, 0x00,
/* 0x15 */ 0x00, 0x18, 0x60, 0x00,
/* 0x16 */ 0x00, 0x10, 0x40, 0x00,
/* 0x17 */ 0x00, 0x0c, 0x30, 0x00,
//Dark Yellow
/* 0x18 */ 0x00, 0x20, 0x20, 0x00,
/* 0x19 */ 0x00, 0x18, 0x18, 0x00,
/* 0x1a */ 0x00, 0x10, 0x10, 0x00,
//Pale Yellow
/* 0x1b */ 0x40, 0x80, 0x80, 0x00,
/* 0x1c */ 0x50, 0xa0, 0xa0, 0x00,
/* 0x1d */ 0x60, 0xc0, 0xc0, 0x00,
/* 0x1e */ 0x70, 0xe0, 0xe0, 0x00,
/* 0x1f */ 0x80, 0xff, 0xff, 0x00,
//Orange
/* 0x20 */ 0x00, 0x80, 0xff, 0x00,
/* 0x21 */ 0x00, 0x70, 0xe0, 0x00,
/* 0x22 */ 0x00, 0x60, 0xc0, 0x00,
/* 0x23 */ 0x00, 0x50, 0xa0, 0x00,
/* 0x24 */ 0x00, 0x40, 0x80, 0x00,
/* 0x25 */ 0x00, 0x30, 0x60, 0x00,
/* 0x26 */ 0x00, 0x20, 0x40, 0x00,
/* 0x27 */ 0x00, 0x18, 0x30, 0x00,
//Dark Green
/* 0x28 */ 0x00, 0x20, 0x00, 0x00,
/* 0x29 */ 0x00, 0x18, 0x00, 0x00,
/* 0x2a */ 0x00, 0x10, 0x00, 0x00,
//Pale Green
/* 0x2b */ 0x40, 0x80, 0x40, 0x00,
/* 0x2c */ 0x50, 0xa0, 0x50, 0x00,
/* 0x2d */ 0x60, 0xc0, 0x60, 0x00,
/* 0x2e */ 0x70, 0xe0, 0x70, 0x00,
/* 0x2f */ 0x80, 0xff, 0x80, 0x00,
//Yellow Orange
/* 0x30 */ 0x00, 0xc0, 0xff, 0x00,
/* 0x31 */ 0x00, 0xa8, 0xe0, 0x00,
/* 0x32 */ 0x00, 0x90, 0xc0, 0x00,
/* 0x33 */ 0x00, 0x78, 0xa0, 0x00,
/* 0x34 */ 0x00, 0x60, 0x80, 0x00,
/* 0x35 */ 0x00, 0x48, 0x60, 0x00,
/* 0x36 */ 0x00, 0x30, 0x40, 0x00,
/* 0x37 */ 0x00, 0x24, 0x30, 0x00,
//Dark cyan
/* 0x38 */ 0x20, 0x20, 0x00, 0x00,
/* 0x39 */ 0x18, 0x18, 0x00, 0x00,
/* 0x3a */ 0x10, 0x10, 0x00, 0x00,
//Pale cyan
/* 0x3b */ 0x80, 0x80, 0x40, 0x00,
/* 0x3c */ 0xa0, 0xa0, 0x50, 0x00,
/* 0x3d */ 0xc0, 0xc0, 0x60, 0x00,
/* 0x3e */ 0xe0, 0xe0, 0x70, 0x00,
/* 0x3f */ 0xff, 0xff, 0x80, 0x00,
//Yellow
/* 0x40 */ 0x00, 0xff, 0xff, 0x00,
/* 0x41 */ 0x00, 0xe0, 0xe0, 0x00,
/* 0x42 */ 0x00, 0xc0, 0xc0, 0x00,
/* 0x43 */ 0x00, 0xa0, 0xa0, 0x00,
/* 0x44 */ 0x00, 0x80, 0x80, 0x00,
/* 0x45 */ 0x00, 0x60, 0x60, 0x00,
/* 0x46 */ 0x00, 0x40, 0x40, 0x00,
/* 0x47 */ 0x00, 0x30, 0x30, 0x00,
//Dark Blue
/* 0x48 */ 0x20, 0x00, 0x00, 0x00,
/* 0x49 */ 0x18, 0x00, 0x00, 0x00,
/* 0x4a */ 0x10, 0x00, 0x00, 0x00,
//Pale Blue
/* 0x4b */ 0x80, 0x40, 0x40, 0x00,
/* 0x4c */ 0xa0, 0x50, 0x50, 0x00,
/* 0x4d */ 0xc0, 0x60, 0x60, 0x00,
/* 0x4e */ 0xe0, 0x70, 0x70, 0x00,
/* 0x4f */ 0xff, 0x80, 0x80, 0x00,
//Yellow Green
/* 0x50 */ 0x00, 0xff, 0x80, 0x00,
/* 0x51 */ 0x00, 0xe0, 0x70, 0x00,
/* 0x52 */ 0x00, 0xc0, 0x60, 0x00,
/* 0x53 */ 0x00, 0xa0, 0x50, 0x00,
/* 0x54 */ 0x00, 0x80, 0x40, 0x00,
/* 0x55 */ 0x00, 0x60, 0x30, 0x00,
/* 0x56 */ 0x00, 0x40, 0x20, 0x00,
/* 0x57 */ 0x00, 0x30, 0x18, 0x00,
//Dark magenta
/* 0x58 */ 0x20, 0x00, 0x20, 0x00,
/* 0x59 */ 0x18, 0x00, 0x18, 0x00,
/* 0x5a */ 0x10, 0x00, 0x10, 0x00,
//Pale Magenta
/* 0x5b */ 0x80, 0x40, 0x80, 0x00,
/* 0x5c */ 0xa0, 0x50, 0xa0, 0x00,
/* 0x5d */ 0xc0, 0x60, 0xc0, 0x00,
/* 0x5e */ 0xe0, 0x70, 0xe0, 0x00,
/* 0x5f */ 0xff, 0x80, 0xff, 0x00,
//Green
/* 0x60 */ 0x00, 0xff, 0x00, 0x00,
/* 0x61 */ 0x00, 0xe0, 0x00, 0x00,
/* 0x62 */ 0x00, 0xc0, 0x00, 0x00,
/* 0x63 */ 0x00, 0xa0, 0x00, 0x00,
/* 0x64 */ 0x00, 0x80, 0x00, 0x00,
/* 0x65 */ 0x00, 0x60, 0x00, 0x00,
/* 0x66 */ 0x00, 0x40, 0x00, 0x00,
/* 0x67 */ 0x00, 0x30, 0x00, 0x00,
// Dark Pale Red
/* 0x68 */ 0x30, 0x30, 0x60, 0x00,
/* 0x69 */ 0x20, 0x20, 0x40, 0x00,
/* 0x6a */ 0x18, 0x18, 0x30, 0x00,
//Very Pale Red
/* 0x6b */ 0x60, 0x60, 0x80, 0x00,
/* 0x6c */ 0x78, 0x78, 0xa0, 0x00,
/* 0x6d */ 0x90, 0x90, 0xc0, 0x00,
/* 0x6e */ 0xa8, 0xa8, 0xe0, 0x00,
/* 0x6f */ 0xc0, 0xc0, 0xff, 0x00,
// BlueGreen
/* 0x70 */ 0x80, 0xff, 0x00, 0x00,
/* 0x71 */ 0x70, 0xe0, 0x00, 0x00,
/* 0x72 */ 0x60, 0xc0, 0x00, 0x00,
/* 0x73 */ 0x50, 0xa0, 0x00, 0x00,
/* 0x74 */ 0x40, 0x80, 0x00, 0x00,
/* 0x75 */ 0x30, 0x60, 0x00, 0x00,
/* 0x76 */ 0x20, 0x40, 0x00, 0x00,
/* 0x77 */ 0x18, 0x30, 0x00, 0x00,
// Dark Pale Yellow
/* 0x78 */ 0x30, 0x60, 0x60, 0x00,
/* 0x79 */ 0x20, 0x40, 0x40, 0x00,
/* 0x7a */ 0x18, 0x30, 0x30, 0x00,
//Very Pale Yellow
/* 0x7b */ 0x60, 0x80, 0x80, 0x00,
/* 0x7c */ 0x78, 0xa0, 0xa0, 0x00,
/* 0x7d */ 0x90, 0xc0, 0xc0, 0x00,
/* 0x7e */ 0xa8, 0xe0, 0xe0, 0x00,
/* 0x7f */ 0xc0, 0xff, 0xff, 0x00,
// Cyan
/* 0x80 */ 0xff, 0xff, 0x00, 0x00,
/* 0x81 */ 0xe0, 0xe0, 0x00, 0x00,
/* 0x82 */ 0xc0, 0xc0, 0x00, 0x00,
/* 0x83 */ 0xa0, 0xa0, 0x00, 0x00,
/* 0x84 */ 0x80, 0x80, 0x00, 0x00,
/* 0x85 */ 0x60, 0x60, 0x00, 0x00,
/* 0x86 */ 0x40, 0x40, 0x00, 0x00,
/* 0x87 */ 0x30, 0x30, 0x00, 0x00,
//Dark Pale Green
/* 0x88 */ 0x30, 0x60, 0x30, 0x00,
/* 0x89 */ 0x20, 0x40, 0x20, 0x00,
/* 0x8a */ 0x18, 0x30, 0x18, 0x00,
//Very Plae Green
/* 0x8b */ 0x60, 0x80, 0x60, 0x00,
/* 0x8c */ 0x78, 0xa0, 0x78, 0x00,
/* 0x8d */ 0x90, 0xc0, 0x90, 0x00,
/* 0x8e */ 0xa8, 0xe0, 0xa8, 0x00,
/* 0x8f */ 0xc0, 0xff, 0xc0, 0x00,
//Sky Blue
/* 0x90 */ 0xff, 0x80, 0x00, 0x00,
/* 0x91 */ 0xe0, 0x70, 0x00, 0x00,
/* 0x92 */ 0xc0, 0x60, 0x00, 0x00,
/* 0x93 */ 0xa0, 0x50, 0x00, 0x00,
/* 0x94 */ 0x80, 0x40, 0x00, 0x00,
/* 0x95 */ 0x60, 0x30, 0x00, 0x00,
/* 0x96 */ 0x40, 0x20, 0x00, 0x00,
/* 0x97 */ 0x30, 0x18, 0x00, 0x00,
//Dark Plae Cyan
/* 0x98 */ 0x60, 0x60, 0x30, 0x00,
/* 0x99 */ 0x40, 0x40, 0x20, 0x00,
/* 0x9a */ 0x30, 0x30, 0x18, 0x00,
//Very Pale Cyan
/* 0x9b */ 0x80, 0x80, 0x60, 0x00,
/* 0x9c */ 0xa0, 0xa0, 0x78, 0x00,
/* 0x9d */ 0xc0, 0xc0, 0x90, 0x00,
/* 0x9e */ 0xe0, 0xe0, 0xa8, 0x00,
/* 0x9f */ 0xff, 0xff, 0xc0, 0x00,
// Blue
/* 0xa0 */ 0xff, 0x00, 0x00, 0x00,
/* 0xa1 */ 0xe0, 0x00, 0x00, 0x00,
/* 0xa2 */ 0xc0, 0x00, 0x00, 0x00,
/* 0xa3 */ 0xa0, 0x00, 0x00, 0x00,
/* 0xa4 */ 0x80, 0x00, 0x00, 0x00,
/* 0xa5 */ 0x60, 0x00, 0x00, 0x00,
/* 0xa6 */ 0x40, 0x00, 0x00, 0x00,
/* 0xa7 */ 0x30, 0x00, 0x00, 0x00,
//Dark Pale Blue
/* 0xa8 */ 0x60, 0x30, 0x30, 0x00,
/* 0xa9 */ 0x40, 0x20, 0x20, 0x00,
/* 0xaa */ 0x30, 0x18, 0x18, 0x00,
//Very Pale Blue
/* 0xab */ 0x80, 0x60, 0x60, 0x00,
/* 0xac */ 0xa0, 0x78, 0x78, 0x00,
/* 0xad */ 0xc0, 0x90, 0x90, 0x00,
/* 0xae */ 0xe0, 0xa8, 0xa8, 0x00,
/* 0xaf */ 0xff, 0xc0, 0xc0, 0x00,
// BlueMagenta
/* 0xb0 */ 0xff, 0x00, 0x80, 0x00,
/* 0xb1 */ 0xe0, 0x00, 0x70, 0x00,
/* 0xb2 */ 0xc0, 0x00, 0x60, 0x00,
/* 0xb3 */ 0xa0, 0x00, 0x50, 0x00,
/* 0xb4 */ 0x80, 0x00, 0x40, 0x00,
/* 0xb5 */ 0x60, 0x00, 0x30, 0x00,
/* 0xb6 */ 0x40, 0x00, 0x20, 0x00,
/* 0xb7 */ 0x30, 0x00, 0x18, 0x00,
//Dark Pale Magenta
/* 0xb8 */ 0x60, 0x30, 0x60, 0x00,
/* 0xb9 */ 0x40, 0x20, 0x40, 0x00,
/* 0xba */ 0x30, 0x18, 0x30, 0x00,
//Very Pale Magenta
/* 0xbb */ 0x80, 0x60, 0x80, 0x00,
/* 0xbc */ 0xa0, 0x78, 0xa0, 0x00,
/* 0xbd */ 0xc0, 0x90, 0xc0, 0x00,
/* 0xbe */ 0xe0, 0xa8, 0xe0, 0x00,
/* 0xbf */ 0xff, 0xc0, 0xff, 0x00,
//Magenta
/* 0xc0 */ 0xff, 0x00, 0xff, 0x00,
/* 0xc1 */ 0xe0, 0x00, 0xe0, 0x00,
/* 0xc2 */ 0xc0, 0x00, 0xc0, 0x00,
/* 0xc3 */ 0xa0, 0x00, 0xa0, 0x00,
/* 0xc4 */ 0x80, 0x00, 0x80, 0x00,
/* 0xc5 */ 0x60, 0x00, 0x60, 0x00,
/* 0xc6 */ 0x40, 0x00, 0x40, 0x00,
/* 0xc7 */ 0x30, 0x00, 0x30, 0x00,
//Grayscale
/* 0xc8 */ 0xff, 0xff, 0xff, 0x00,
/* 0xc9 */ 0xe0, 0xe0, 0xe0, 0x00,
/* 0xca */ 0xc0, 0xc0, 0xc0, 0x00,
/* 0xcb */ 0xa0, 0xa0, 0xa0, 0x00,
/* 0xcc */ 0x80, 0x80, 0x80, 0x00,
/* 0xcd */ 0x60, 0x60, 0x60, 0x00,
/* 0xce */ 0x40, 0x40, 0x40, 0x00,
/* 0xcf */ 0x20, 0x20, 0x20, 0x00,
//Red Magenta
/* 0xd0 */ 0x80, 0x00, 0xff, 0x00,
/* 0xd1 */ 0x70, 0x00, 0xe0, 0x00,
/* 0xd2 */ 0x60, 0x00, 0xc0, 0x00,
/* 0xd3 */ 0x50, 0x00, 0xa0, 0x00,
/* 0xd4 */ 0x40, 0x00, 0x80, 0x00,
/* 0xd5 */ 0x30, 0x00, 0x60, 0x00,
/* 0xd6 */ 0x20, 0x00, 0x40, 0x00,
/* 0xd7 */ 0x18, 0x00, 0x30, 0x00,
//Grayscale
/* 0xd8 */ 0xf0, 0xf0, 0xf0, 0x00,
/* 0xd9 */ 0xd0, 0xd0, 0xd0, 0x00,
/* 0xda */ 0xb0, 0xb0, 0xb0, 0x00,
/* 0xdb */ 0x90, 0x90, 0x90, 0x00,
/* 0xdc */ 0x70, 0x70, 0x70, 0x00,
/* 0xdd */ 0x50, 0x50, 0x50, 0x00,
/* 0xde */ 0x30, 0x30, 0x30, 0x00,
/* 0xdf */ 0x10, 0x10, 0x10, 0x00,
// Flesh
/* 0xe0 */ 0x48, 0x5a, 0x7f, 0x00,
/* 0xe1 */ 0x5e, 0x76, 0xa5, 0x00,
/* 0xe2 */ 0x72, 0x8f, 0xca, 0x00,
/* 0xe3 */ 0x82, 0xa2, 0xe5, 0x00,
/* 0xe4 */ 0x91, 0xb6, 0xff, 0x00,
/* 0xe5 */ 0xaf, 0xd3, 0xff, 0x00,
//Gold 12:10:4
#if 0
//Old Gold colors
/* 0xe6 */ 0x1f, 0x54, 0x68, 0x00,
/* 0xe7 */ 0x20, 0x70, 0x80, 0x00,
/* 0xe8 */ 0x34, 0x88, 0xaa, 0x00,
/* 0xe9 */ 0x40, 0xa0, 0xc0, 0x00,
/* 0xea */ 0x4d, 0xc4, 0xf2, 0x00,
/* 0xeb */ 0x60, 0xe0, 0xf8, 0x00,
/* 0xec */ 0x99, 0xfc, 0xfc, 0x00,
#endif
// New gold colors r:g:b = 6:5:2
/* 0xe6 */ 0x20, 0x50, 0x60, 0x00,
/* 0xe7 */ 0x2a, 0x6a, 0x80, 0x00,
/* 0xe8 */ 0x35, 0x85, 0xa0, 0x00,
/* 0xe9 */ 0x40, 0xa0, 0xc0, 0x00,
/* 0xea */ 0x4a, 0xba, 0xe0, 0x00,
/* 0xeb */ 0x60, 0xe0, 0xf8, 0x00,
/* 0xec */ 0xa0, 0xff, 0xff, 0x00,
// Zombie
#if 0
// Old zombie skin colors
/* 0xed */ 0x58, 0x69, 0x75, 0x00, -> 607080
/* 0xee */ 0x6e, 0x87, 0x91, 0x00, -> 788ca0
/* 0xef */ 0x81, 0x9a, 0xab, 0x00, -> 90a8c0
#endif
// New zombie skin colors r:g:b=8:7:6
/* 0xed */ 0x48, 0x54, 0x60, 0x00,
/* 0xee */ 0x60, 0x70, 0x80, 0x00,
/* 0xef */ 0x78, 0x8c, 0xa0, 0x00,
/* 0xf0 */ 0x90, 0xa8, 0xc0, 0x00,
/* 0xf1 */ 0xa8, 0xc4, 0xe0, 0x00,
#if 0
// Old Brass 14:12:10, 13:10.5:5
/* 0xf0 */ 0xa0, 0xc0, 0xe0, 0x00, -> a8c4e0
/* 0xf1 */ 0x50, 0xa8, 0xd0, 0x00, -> 40a0c0
#endif
// Unused
// (reserving 16 colors for the system seemed a reasonable idea
// when I was using 256 color X-Window display, but it seems
// an obsolete idea now. However, I should be very careful to
// introduce new colors.
/* 0xf2 */ 0x00, 0x00, 0x00, 0x00,
/* 0xf3 */ 0x00, 0x00, 0x00, 0x00,
/* 0xf4 */ 0x00, 0x00, 0x00, 0x00,
/* 0xf5 */ 0x00, 0x00, 0x00, 0x00,
/* 0xf6 */ 0x00, 0x00, 0x00, 0x00,
/* 0xf7 */ 0x00, 0x00, 0x00, 0x00,
/* 0xf8 */ 0x00, 0x00, 0x00, 0x00,
/* 0xf9 */ 0x00, 0x00, 0x00, 0x00,
/* 0xfa */ 0x00, 0x00, 0x00, 0x00,
/* 0xfb */ 0x00, 0x00, 0x00, 0x00,
/* 0xfc */ 0x00, 0x00, 0x00, 0x00,
/* 0xfd */ 0x00, 0x00, 0x00, 0x00,
/* 0xfe */ 0x00, 0x00, 0x00, 0x00,
//Transparent color
/* 0xff */ 0x6c, 0x6c, 0x47, 0x00
};
#include "bm.h"
#define WID 64
/** Some global **/
int corpse=0, mesh =0,slant=0;
int rim=0;
int exp_wall;
int dsize;
int sx32 = 16;
int sy32 = 24;
FILE *mfp,*sfp;
char outname[1024], ctgname[100], subsname[100];
char sdir[300];
char realname[1024];
/*** BUFFER MEMORY ***/
#define XX 16
int xx0;
#define YY 30
#define LX (XX)
/*** tmp buffer, floor , final output, final queue ***/
unsigned char *tbuf[3],fbuf[3][128*64],
*obuf[3],dbuf[3][128*64];
unsigned char wallbuf[4][3][32*48];
unsigned char wall2buf[3][128*64];
int f_wx;
/*** normal floor*/
#define WOADR(x,y,xx,yy) \
((x)*64+xx+ xx0*64*((y)*64+yy))
#define ADR32(x,y) ((x)+(y)*32)
#define ADR64(x,y) ((x)+(y)*64)
/*** output width/height in block ***/
int bx,by;
/**************************/
/* Wrapper routines *******/
/**************************/
int load_it(char *fnam, int *wx, int *wy)
{
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,fnam);
if(bmread(realname,wx,wy,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,fnam);
if(bmread(realname,wx,wy,tbuf)==0) return 0;
if(subsname[0]){
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,subsname);
if(bmread(realname,wx,wy,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,subsname);
if(bmread(realname,wx,wy,tbuf)==0) return 0;
}
return 1;
}
void clr_dbuf() {
int xx,yy;
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
dbuf[0][ ADR64(xx,yy) ]=0x47;
dbuf[1][ ADR64(xx,yy) ]=0x6c;
dbuf[2][ ADR64(xx,yy) ]=0x6c;
}}
}
#define TILEX 64
#define TILEY 64
void make_rim(){
static unsigned char dflag[TILEX][TILEY];
int x,y,c,dd[3],ad;
int n0,n1,n2;
for(y=0;y<TILEY;y++){
for(x=0;x<TILEX;x++){
dflag[x][y]=1;
ad=x + y *TILEX;
for(c=0;c<3;c++)dd[c]=dbuf[c][ad];
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c)) dflag[x][y]=0;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0)) dflag[x][y]=2;
}
}
for(x=0;x<TILEX;x++){
for(y=0;y<TILEY;y++){
ad=x+y*TILEX;
if(dflag[x][y]==2 || dflag[x][y]==0){
n0=n1=n2=0;
if(x>0){
if(dflag[x-1][y]==0) n0++;
if(dflag[x-1][y]==1) n1++;
if(dflag[x-1][y]==2) n2++;
}
if(y>0){
if(dflag[x][y-1]==0) n0++;
if(dflag[x][y-1]==1) n1++;
if(dflag[x][y-1]==2) n2++;
}
if(x<TILEX-1){
if(dflag[x+1][y]==0) n0++;
if(dflag[x+1][y]==1) n1++;
if(dflag[x+1][y]==2) n2++;
}
if(y<TILEY-1){
if(dflag[x][y+1]==0) n0++;
if(dflag[x][y+1]==1) n1++;
if(dflag[x][y+1]==2) n2++;
}
if(n1!=0 )
dbuf[0][x+y*TILEX]=dbuf[1][x+y*TILEX]=dbuf[2][x+y*TILEX]=0x10;
}}}
}
void cp_floor_64(){
int xx,yy,c;
for(xx=0;xx<64;xx++)
for(yy=0;yy<64;yy++)
for(c=0;c<3;c++)
dbuf[c][ ADR64(xx,yy) ]=fbuf[c][ ADR64(xx,yy)];
}
void cp_floor_32(){
int xx,yy,c;
for(xx=0;xx<32;xx++)
for(yy=0;yy<32;yy++)
for(c=0;c<3;c++)
dbuf[c][ ADR64(32+xx-yy,32+(xx+yy)/2) ]=fbuf[c][ ADR32(xx,yy)];
}
void cp_monst_32(){
int xx,yy,c,dd[3],ad;
char dflag[32][32];
int xmin,xmax,ymin,ymax;
int ox=0;
int oy=0;
if(corpse==1 ){
xmin=ymin=31;
xmax=ymax=0;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
ad=ADR32(xx,yy);
for(c=0;c<3;c++)dd[c]=tbuf[c][ad];
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
if(xx<xmin)xmin=xx;
if(xx>xmax)xmax=xx;
if(yy<ymin)ymin=yy;
if(yy>ymax)ymax=yy;
}}/*xy**/
ox=(xmax+xmin)/2-16;
oy=(ymax+ymin)/2-16;
}
if(slant==1){
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
int x1 = xx-yy+32;
int y1= 32+(xx+yy)/2;
ad = ADR32(xx,yy);
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2){
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c)){
if( ((x1+y1)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1){
if( (((x1/2)+(y1/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(x1,y1)]=dd[c];}
}}
return;
}
if(dsize==1){
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
int x1 = xx*2;
int y1= yy*2;
ad = ADR32(xx,yy);
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2){
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c)){
if( ((x1+y1)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1){
if( (((x1/2)+(y1/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++)
{
dbuf[c][ADR64(x1,y1)]=dd[c];
dbuf[c][ADR64(x1+1,y1)]=dd[c];
dbuf[c][ADR64(x1,y1+1)]=dd[c];
dbuf[c][ADR64(x1+1,y1+1)]=dd[c];
}
}}
return;
}
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
dflag[xx][yy]=0;
ad=ADR32(xx,yy);
if(corpse==1){
int x1=xx+ox;
int y1=(yy+oy)*2-16;
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(yy>=cy-1 && yy<=cy+0)continue;
x1 += (y1-16)/4;
if(y1>=cy){y1-=2;x1-=3;}else {y1 +=2;x1+=3;}
if(x1<0 || x1>=32 || y1<0 || y1>=32)continue;
ad=ADR32(x1,y1);
}
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2){
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c)){
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1){
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(sx32+xx,sy32+yy)]=dd[c];}
dflag[xx][yy]=1;
}}
#if 1
if(corpse==1){
for(xx=0;xx<32;xx++){
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(dflag[xx][cy-2]==1 && dflag[xx][cy+1]==1 ){
for(yy=cy-1;yy<=cy-0;yy++){ dbuf[0][ADR64(16+xx,32+yy)]=32;
dbuf[1][ADR64(16+xx,32+yy)]=0;dbuf[2][ADR64(16+xx,32+yy)]=0;
dflag[xx][yy]=1;
}}
}
/** shade**/
for(xx=1;xx<32;xx++){
for(yy=1;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==1){
dbuf[0][ADR64(xx,yy)]=0;
dbuf[1][ADR64(xx,yy)]=0;
dbuf[2][ADR64(xx,yy)]=0;
}
}}
for(xx=3;xx<32;xx++){
for(yy=3;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==0
&& dflag[xx-2][yy-2]==1 && dflag[xx-3][yy-3]==1){
dbuf[0][ADR64(xx,yy)]=0;
dbuf[1][ADR64(xx,yy)]=0;
dbuf[2][ADR64(xx,yy)]=0;
}
}}
}
#endif
}
void cp_monst_64(){
int xx,yy,c,dd[3],ad;
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
ad=ADR64(xx,yy);
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2)
{
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c))
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
if(mesh==1)
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void cp_monst_4864(){
int xx,yy,c,dd[3],ad;
for(xx=0;xx<48;xx++){
for(yy=0;yy<64;yy++){
ad= xx+yy*48;
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2)
{
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c))
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
if(mesh==1)
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][8+xx+yy*64]=dd[c];}
}}
}
void bflush(){
int xx,yy,c;
if(rim==1) make_rim();
fprintf(mfp,"<area shape=\"rect\" coords=\"%d,%d,%d,%d\" href=%s>\n",
bx*WID,by*WID,bx*WID+WID-1,by*WID+WID-1,
realname);
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
for(c=0;c<3;c++){
obuf[c][WOADR(bx,by,xx,yy)]= dbuf[c][ADR64(xx,yy)];
}}}
}
void copy_wall(int wall_ix, int xofs, int yofs){
int xx,yy,c;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs-16;
int y=yy-yofs-8;
int ad = x+y*32;
if(x<0 || y<0 || x>=32 || y>=48) continue;
for(c=0;c<3;c++){dd[c]=wallbuf[wall_ix][c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void copy_wall_vert(int wall_ix, int xofs, int yofs){
int xx,yy,c,ymax;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs-16;
int y=yy-yofs-8;
int ad = x+y*32;
if(x<0 || y<0 || x>=32 || y>=48) continue;
ymax= 8+x/2;
if(ymax> 8+(31-x)/2) ymax=8+(31-x)/2;
if(y<=ymax) continue;
for(c=0;c<3;c++){dd[c]=wallbuf[wall_ix][c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
//Mesh
// if( ((x/2+y/2)&1) == 0) dd[0]=dd[1]=dd[2]=0;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void expand_wall(){
//unsigned char wallbuf[4][3][32*48];
int xx,yy,c,ix;
exp_wall=1;
for(ix=0;ix<4;ix++){
for(xx=0;xx<32;xx++){
for(yy=0;yy<48;yy++){
wallbuf[ix][0][xx+yy*32]=0x47;
wallbuf[ix][1][xx+yy*32]=0x6c;
wallbuf[ix][2][xx+yy*32]=0x6c;
}}}
//decompose wall bmp
for(xx=0;xx<32;xx++){
int ymax= 8+xx/2;
if(ymax> 8+(31-xx)/2) ymax=8+(31-xx)/2;
for(yy=0;yy<ymax;yy++){
ix=0;
if(2*yy+xx >=32)ix +=1;
if(2*yy-xx >=0 )ix +=2;
for(c=0;c<3;c++)wallbuf[ix][c][xx+yy*32]=tbuf[c][xx+yy*32];
}
for(yy=ymax;yy<48;yy++){
if(xx<8) ix=2;else if(xx<24) ix=3; else ix=1;
for(c=0;c<3;c++)wallbuf[ix][c][xx+yy*32]=tbuf[c][xx+yy*32];
}
}//xx
/*
0
1 1 2 2
3 4 5
6 7 8 9
A B C
4 D E 8
F
*/
for(ix=0;ix<16;ix++){
clr_dbuf();
if(f_wx==32)cp_floor_32(); else cp_floor_64();
if((ix&3)==3) copy_wall(3,0,-16);
if(ix&1) copy_wall(1,-16,-8);
if(ix&2) copy_wall(2,16,-8);
if(ix&1) copy_wall(3,-16,-8);
copy_wall(0, 0,0);
if(ix&2) copy_wall(3,16,-8);
if((ix&5)==5) {copy_wall(1,-32,0);copy_wall_vert(2,-16,0);}
copy_wall(2,0,0);
copy_wall(1,0,0);
if((ix&10)==10) {copy_wall(2,32,0);copy_wall_vert(1,16,0);}
if(ix&4) {copy_wall(0,-16,8);copy_wall_vert(3,-16,0);}
copy_wall(3,0,0);
if(ix&8) {copy_wall(0,16,8);copy_wall_vert(3,16,0);}
if(ix&4) {copy_wall(1,-16,8);copy_wall_vert(2,0,8);}
if(ix&8) {copy_wall(2,16,8); copy_wall_vert(1,0,8);}
if((ix&12)==12) {copy_wall(0,0,16);copy_wall_vert(3,0,8);}
bflush();
bx++;if(bx==xx0){bx=0;by++;}
}/*ix*/
}
static void copy_wall2_h1(int ix, int xofs, int yofs){
int xx,yy,c,ad;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs;
int y=yy-yofs;;
ad = x+64+y*128;
if (x<0 || y<0 || x>63 || y>63)continue;
if(2*y>=x+32) continue;
if(2*y>=95-x) continue;
if((ix%3)==0) if (2*y>=47-x)continue;
if((ix%3)==1) if ((2*y<47-x) || (2*y>=79-x))continue;
if((ix%3)==2) if(2*y<79-x)continue;
if((ix/3)==0) if(2*y>=x-16)continue;
if((ix/3)==1) if((2*y<x-16) || (2*y>=x+16))continue;
if((ix/3)==2) if(2*y<x+16) continue;
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void copy_wall2_h2(int ix, int xofs, int yofs){
int xx,yy,c,ad;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs;
int y=yy-yofs;;
ad = x+y*128;
if (x<0 || y<0 || x>63 || y>63)continue;
if(2*y>=x+32) continue;
if(2*y>=95-x) continue;
if ((ix%2)==0)if (2*y>=63-x)continue;
if((ix%2)==1) if (2*y<63-x)continue;
if((ix/2)==0)if(2*y>=x)continue;
if((ix/2)==1)if(2*y<x)continue;
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void copy_wall_v2(int ix, int kind, int xofs, int yofs){
int xx,yy,c,ymax,ad;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs;
int y=yy-yofs;
ad = x+kind*64+y*128;
if(x<0 || y<0 || x>=64 || y>=64) continue;
ymax= 16+x/2;
if(x>=32) ymax=16+(63-x)/2;
if(y<ymax) continue;
if(y>ymax+32)continue;
if(ix==0) if(x>=8)continue;
if(ix==1) if(x<8 || x>=24)continue;
if(ix==2) if(x<24 || x>=40)continue;
if(ix==3) if(x<40 || x>=56)continue;
if(ix==4) if(x<56)continue;
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void expand_wall2(){
//void copy_wall2_h(int kind, int ix, int xofs, int yofs)
int ix;
exp_wall=1;
for(ix=0;ix<16;ix++){
clr_dbuf();
if(f_wx==32)cp_floor_32(); else cp_floor_64();
if((ix&3)==0) copy_wall2_h1(0, 0, 8);
if((ix&3)==1) copy_wall2_h1(1, -16, 0);
if((ix&3)==2) copy_wall2_h1(3, 16, 0);
if((ix&3)==3) copy_wall2_h2(0, 0, 0);
if((ix&5)==0) copy_wall2_h1(6, 16, 0);
if((ix&5)==1) copy_wall2_h1(7, 0, -8);
if((ix&5)==4) copy_wall2_h1(3, 0, 8);
if((ix&5)==5) copy_wall2_h2(2, 0, 0);
if((ix&10)==0) copy_wall2_h1(2, -16, 0);
if((ix&10)==2) copy_wall2_h1(5, 0, -8);
if((ix&10)==8) copy_wall2_h1(1, 0, 8);
if((ix&10)==10) copy_wall2_h2(1, 0, 0);
if((ix&12)==0) copy_wall2_h1(8, 0, -8);
if((ix&12)==4) copy_wall2_h1(5, -16, 0);
if((ix&12)==8) copy_wall2_h1(7, 16, 0);
if((ix&12)==12) copy_wall2_h2(3, 0, 0);
if((ix&5)==5) copy_wall_v2(0, 0, 0, 0);
if((ix&10)==10) copy_wall_v2(4, 0, 0, 0);
if((ix&4)!=0) copy_wall_v2(1, 0, 0, 0);
if((ix&8)!=0) copy_wall_v2(3, 0, 0, 0);
if((ix&12)==12) copy_wall_v2(2, 0, 0, 0);
if((ix&5)==1) copy_wall_v2(1, 1, 0, -8);
if((ix&12)==8) copy_wall_v2(1, 1, 16, 0);
if((ix&10)==2) copy_wall_v2(3, 1, 0, -8);
if((ix&12)==4) copy_wall_v2(3, 1, -16, 0);
if((ix&5)==0) copy_wall_v2(0, 1, 16, 0);
if((ix&10)==0) copy_wall_v2(4, 1, -16, 0);
if((ix&12)==0) copy_wall_v2(2, 1, 0, -8);
bflush();
bx++;if(bx==xx0){bx=0;by++;}
}
}
void load_monst(fnam) char *fnam;{
int wx, wy;
if( load_it(fnam, &wx, &wy))
{
printf("no file %s.bmp\n",fnam);
getchar();
exit(1);
}
exp_wall=0;
if(wx==128 && wy==64) expand_wall2();
else if(wx==48 && wy==64) cp_monst_4864();
else if(wx==32 && wy==48) expand_wall();
else if(wx==32)cp_monst_32();
else if(wx==64)cp_monst_64();
bflush();
}
void process_config(char *fname)
{
int i,j;
char tmp[100],st[1024];
char *nuke;
FILE *fp=fopen(fname,"r");
if(fp==NULL){
printf("Error no config file %s\nHit return",fname);
getchar();
exit(1);
}
while(1){
fgets(tmp,99,fp);
if(feof(fp))break;
i=0;while(i<99 && tmp[i]>=32)i++;
tmp[i]=0;
fprintf(stderr,"[%s]\n",tmp);
if(getname(tmp,"back",st))
{
/*** Set Background BMP (format "%back bmpname") ***/
if(strncmp(st,"none",4)==0)
{
/** clear **/
for(i=0;i<32*32;i++){fbuf[0][i]=0x47;fbuf[1][i]=fbuf[2][i]=0x6c;}
f_wx=64;
}
else
{
int wy;
load_it(st, &f_wx, &wy);
for(i=0;i<f_wx*wy;i++)for(j=0;j<3;j++)fbuf[j][i]=tbuf[j][i];
}
continue;
}
if (getname(tmp,"include",st)){
char fn2[200];
sprintf(fn2,"%s%s",cpath, st);
if(strcmp(fname,fn2)!=0) process_config(fn2);
continue;
}
if (getval(tmp,"slant",&slant)) continue;
if (getval(tmp,"dsize",&dsize)) continue;
if (getval(tmp,"mesh",&mesh)) continue;
if (getval(tmp,"rim",&rim)) continue;
if (getval(tmp,"corpose",&corpse)) continue;
if (getname(tmp,"ctg",ctgname)) continue;
if (getname(tmp,"subst",subsname)) continue;
if (getname(tmp,"sdir",sdir)) continue;
if (getname(tmp,"name", outname)) continue;
if (getval(tmp,"width",&xx0)) continue;
if (getval(tmp,"sx",&sx32)) continue;
if (getval(tmp,"sy",&sy32)) continue;
if (tmp[0]=='#' || tmp[0]<32){
if(tmp[0]<32) {}
else fprintf(sfp,"\n//%s\n",tmp);
continue;
}
/*** normal bitmap ***/
clr_dbuf();
if(f_wx==32)cp_floor_32(); else cp_floor_64();
i=0;while(i<99 && tmp[i]>32)i++;
tmp[i]=0; strcpy(st, &tmp[i+1]);
load_monst(tmp);
if(!strstr(st,"IGNORE_COMMENT"))
{
nuke=strstr(st,"/*");if(nuke)*nuke=0;
if(exp_wall)
fprintf(sfp,"TILE_%s, (TILE_TOTAL+%d),\n",st,bx+by*xx0-16);
else
fprintf(sfp,"TILE_%s, (TILE_TOTAL+%d),\n",st,bx+by*xx0);
}
if(!exp_wall){bx++;if(bx==xx0){bx=0;by++;}}
}/* while */
fclose(fp);
}
int main(argc,argv)
int argc;
char *argv[];
{
int i;
char fn[100];
fixalloc(tbuf,256*256);
slant=corpse=mesh=dsize=0;
bx=by=0;
process_cpath(argv[0]);
fixalloc(obuf, LX*64*(YY)*64);
xx0=XX;
ctgname[0]=0;
subsname[0]=0;
sdir[0]=0;
stdpal();
strcpy(outname,"tile");
sprintf(fn,"%stiledef-qv.h",cpath);
sfp=fopen(fn,"w");
if(sfp==NULL){
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
mfp=fopen("map.htm","w");
fprintf(mfp,"<HTML><head>\n");
fprintf(mfp,"<base href=\"http://cvs.sourceforge.net/viewcvs.py/rltiles/rltiles/
\">\n");
fprintf(mfp,"</head><body><MAP NAME=\"nhmap\">\n");
fprintf(sfp,"/* Automatically generated by tile generator. */\n");
fprintf(sfp,"const int tile_qv_pair_table[] ={\n");
printf("%s\ncpath=%s\n",argv[0],cpath);
if(argc==1)
sprintf(fn,"%sdc-qv.txt",cpath);
else strcpy(fn,argv[1]);
process_config(fn);
fprintf(sfp,"-1, -1 };\n");
fprintf(sfp,"\n#define TILE_TOTAL_EX %d\n",bx+by*xx0);
fprintf(sfp,"#define TILE_PER_ROW_EX %d\n",xx0);
fclose(sfp);
i=by*64;if(bx!=0)i+=64;
sprintf(fn,"%s%s.bmp",cpath,outname);
bmwrite(fn,xx0*64,i,obuf);
fprintf(mfp,"<IMG SRC=http://rltiles.sf.net/%s.png USEMAP=\"#nhmap\" >\n</body>\
n</html>\n", outname);
fclose(mfp);
return 0;
}
#include "bm.h"
/** Some global **/
int corpse, mesh,slant, rim;
FILE *mfp,*sfp;
char outname[1024], ctgname[100], subsname[100];
char sdir[300];
char realname[1024];
/*** BUFFER MEMORY ***/
#define XX 30
int xx0;
#define YY 90
#define LX (XX)
/*** tmp buffer, floor , final output, final queue ***/
unsigned char *tbuf[3],fbuf[3][32*32], *obuf[3],dbuf[3][32*32];
/*** normal floor*/
#define WOADR(x,y,xx,yy) \
((x)*32+xx+ xx0*32*((y)*32+yy))
#define ADR(x,y) ((x)+(y)*32)
/*** output width/height in block ***/
int bx,by;
/****************************************/
/* Wrapper routines **************/
/**************************/
int load_pxxx(fnam) char *fnam;{
int x,y;
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,fnam);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,fnam);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
if(subsname[0]){
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,subsname);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,subsname);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
}
return 1;
}
void clr_buf() {
int xx,yy;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
dbuf[0][ ADR(xx,yy) ]=0x47;
dbuf[1][ ADR(xx,yy) ]=0x6c;
dbuf[2][ ADR(xx,yy) ]=0x6c;
}}
}
void cp_floor(){
int xx,yy,c;
for(xx=0;xx<32;xx++)
for(yy=0;yy<32;yy++)
for(c=0;c<3;c++)
dbuf[c][ ADR(xx,yy) ]=fbuf[c][ ADR(xx,yy)];
}
#define TILEX 32
#define TILEY 32
void make_rim(){
static unsigned char dflag[TILEX][TILEY];
int x,y,c,dd[3],ad;
int n0,n1,n2;
for(y=0;y<TILEY;y++){
for(x=0;x<TILEX;x++){
dflag[x][y]=1;
ad=ADR(x,y);
for(c=0;c<3;c++)dd[c]=dbuf[c][ad];
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c)) dflag[x][y]=0;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0)) dflag[x][y]=2;
}
}
for(x=0;x<TILEX;x++){
for(y=0;y<TILEY;y++){
ad=x+y*TILEX;
if(dflag[x][y]==2 || dflag[x][y]==0){
n0=n1=n2=0;
if(x>0){
if(dflag[x-1][y]==0) n0++;
if(dflag[x-1][y]==1) n1++;
if(dflag[x-1][y]==2) n2++;
}
if(y>0){
if(dflag[x][y-1]==0) n0++;
if(dflag[x][y-1]==1) n1++;
if(dflag[x][y-1]==2) n2++;
}
if(x<31){
if(dflag[x+1][y]==0) n0++;
if(dflag[x+1][y]==1) n1++;
if(dflag[x+1][y]==2) n2++;
}
if(y<31){
if(dflag[x][y+1]==0) n0++;
if(dflag[x][y+1]==1) n1++;
if(dflag[x][y+1]==2) n2++;
}
if(n1!=0 )
dbuf[0][x+y*32]=dbuf[1][x+y*32]=dbuf[2][x+y*32]=0x10;
}}}
}
void cp_monst_32(){
int xx,yy,c,dd[3],ad;
char dflag[32][32];
int xmin,xmax,ymin,ymax,ox,oy;
if(corpse==1 ){
xmin=ymin=31;
xmax=ymax=0;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
ad=ADR(xx,yy);
for(c=0;c<3;c++)dd[c]=tbuf[c][ad];
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
if(xx<xmin)xmin=xx;
if(xx>xmax)xmax=xx;
if(yy<ymin)ymin=yy;
if(yy>ymax)ymax=yy;
}}/*xy**/
ox=(xmax+xmin)/2-16;
oy=(ymax+ymin)/2-16;
}
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
dflag[xx][yy]=0;
ad=ADR(xx,yy);
if(corpse==1){
int x1=xx+ox;
int y1=(yy+oy)*2-16;
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(yy>=cy-1 && yy<=cy+0)continue;
x1 += (y1-16)/4;
if(y1>=cy){y1-=2;x1-=3;}else {y1 +=2;x1+=3;}
if(x1<0 || x1>=32 || y1<0 || y1>=32)continue;
ad=ADR(x1,y1);
}
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2){
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c)){
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1){
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
for(c=0;c<3;c++) {dbuf[c][ADR(xx,yy)]=dd[c];}
dflag[xx][yy]=1;
}}
#if 1
if(corpse==1){
for(xx=0;xx<32;xx++){
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(dflag[xx][cy-2]==1 && dflag[xx][cy+1]==1 ){
for(yy=cy-1;yy<=cy-0;yy++){ dbuf[0][ADR(xx,yy)]=32;
dbuf[1][ADR(xx,yy)]=0;dbuf[2][ADR(xx,yy)]=0;
dflag[xx][yy]=1;
}}
}
/** shade**/
for(xx=1;xx<32;xx++){
for(yy=1;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==1){
dbuf[0][ADR(xx,yy)]=0;
dbuf[1][ADR(xx,yy)]=0;
dbuf[2][ADR(xx,yy)]=0;
}
}}
for(xx=3;xx<32;xx++){
for(yy=3;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==0
&& dflag[xx-2][yy-2]==1 && dflag[xx-3][yy-3]==1){
dbuf[0][ADR(xx,yy)]=0;
dbuf[1][ADR(xx,yy)]=0;
dbuf[2][ADR(xx,yy)]=0;
}
}}
}
#endif
if(rim==1)make_rim();
}
void bflush(){
int xx,yy,c;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
for(c=0;c<3;c++){
obuf[c][WOADR(bx,by,xx,yy)]= dbuf[c][ADR(xx,yy)];
}}}
}
void load_monst(fnam) char *fnam;{
if( load_pxxx(fnam)){
printf("no file pxxx/%s.bmp or %s/%s.bmp\n",fnam,sdir,fnam);
getchar();
exit(1);
}
cp_monst_32();
bflush();
}
void process_config(char *fname)
{
int i,j;
char tmp[100],st[1024];
char *nuke;
FILE *fp=fopen(fname,"r");
if(fp==NULL){
printf("Error no config file %s\nHit return",fname);
getchar();
exit(1);
}
while(1){
fgets(tmp,99,fp);
if(feof(fp))break;
i=0;while(i<99 && tmp[i]>=32)i++;
tmp[i]=0;
if(getname(tmp,"back",st))
{
/*** Set Background BMP (format "%back bmpname") ***/
if(strncmp(st,"none",4)==0)
{
/** clear **/
for(i=0;i<32*32;i++){fbuf[0][i]=0x47;fbuf[1][i]=fbuf[2][i]=0x6c;}
}
else
{
load_pxxx(st);
for(i=0;i<32*32;i++)for(j=0;j<3;j++)fbuf[j][i]=tbuf[j][i];
}
continue;
}
if (getname(tmp,"include",st)){
char fn2[200];
sprintf(fn2,"%s%s",cpath, st);
if(strcmp(fname,fn2)!=0) process_config(fn2);
continue;
}
if (getval(tmp,"slant",&slant)) continue;
if (getval(tmp,"rim",&rim)) continue;
if (getval(tmp,"mesh",&mesh)) continue;
if (getval(tmp,"corpse",&corpse)) continue;
if (getname(tmp,"ctg",ctgname)) continue;
if (getname(tmp,"subst",subsname)) continue;
if (getname(tmp,"sdir",sdir)) continue;
if (getname(tmp,"name", outname)) continue;
if (getval(tmp,"width",&xx0)) continue;
if (tmp[0]=='#' || tmp[0]<32){
if(tmp[0]=='#')fprintf(sfp,"//%s\n",tmp);
if(tmp[0]<32) fprintf(sfp,"\n");
continue;
}
/*** normal bitmap ***/
#define WID 32
clr_buf();cp_floor();
i=0;while(i<99 && tmp[i]>32)i++;
tmp[i]=0; strcpy(st, &tmp[i+1]);
load_monst(tmp);
fprintf(mfp,"<area shape=\"rect\" coords=\"%d,%d,%d,%d\" href=%s>\n",
bx*WID,by*WID,bx*WID+WID-1,by*WID+WID-1,
realname);
if(!strstr(st,"IGNORE_COMMENT")){
nuke=strstr(st,"/*");if(nuke)*nuke=0;
fprintf(sfp,"#define TILE_%s %d\n",st,bx+by*xx0);
}
bx++;if(bx==xx0){bx=0;by++;;}
}/* while */
fclose(fp);
}
int main(argc,argv)
int argc;
char *argv[];
{
int i;
char fn[100],st2[100];
slant=corpse=mesh=rim=0;
bx=by=0;
process_cpath(argv[0]);
xx0=XX;
ctgname[0]=0;
subsname[0]=0;
sdir[0]=0;
stdpal();
fixalloc(tbuf,256*256);
fixalloc(obuf, LX*64*(YY)*64);
strcpy(outname,"tile");
sprintf(fn,"%smap.htm",cpath);
mfp=fopen(fn,"w");
if(mfp==NULL){
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
sprintf(fn,"%stiledef.h",cpath);
sfp=fopen(fn,"w");
if(sfp==NULL){
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
fprintf(sfp,"/* Automatically generated by tile generator. */\n");
fprintf(mfp,"<HTML><head>\n");
fprintf(mfp,"<base href=\"http://cvs.sourceforge.net/viewcvs.py/rltiles/rltiles/\">\n");
fprintf(mfp,"</head><body><MAP NAME=\"nhmap\">\n");
printf("%s\ncpath=%s\n",argv[0],cpath);
if(argc==1)
sprintf(fn,"%sdc-all.txt",cpath);
else strcpy(fn,argv[1]);
process_config(fn);
fprintf(sfp,"#define TILE_TOTAL %d\n",bx+by*xx0);
fprintf(sfp,"#define TILE_PER_ROW %d\n",xx0);
fprintf(mfp,"<IMG SRC=http://rltiles.sf.net/%s.png USEMAP=\"#nhmap\" >\n</body>\n</html>\n", outname);
fclose(mfp);
fclose(sfp);
i=by*32;if(bx!=0)i+=32;
sprintf(fn,"%s%s.bmp",cpath,outname);
bmwrite(fn,xx0*32,i,obuf);
}
#include "bm.h"
/** Some global **/
int corpse=0;
int mesh=0;
int slant=0;
int rim=0;
FILE *mfp=NULL; // map html
FILE *sfp=NULL; // "tiledef.h"
FILE *tfp=NULL; // tiles.txt
FILE *cfp=NULL; // lengths of tile counts
int tilecount = 0;
int tilecountidx = -1;
int counts[1024];
int countnames[100][100];
char outname[1024], ctgname[100], subsname[100];
char sdir[300];
char realname[1024];
char imgname[1024];
char tiledefname[1024];
char enumprefix[100];
const int read_size = 2048;
/*** BUFFER MEMORY ***/
#define XX 30
int xx0;
#define YY 90
#define LX (XX)
/*** tmp buffer, floor , final output, final queue ***/
unsigned char *tbuf[3],fbuf[3][32*32],*obuf[3], dbuf[3][32*32];
/*** compose buffer */
unsigned char cbuf[3][32*32];
/*** normal floor*/
#define WOADR(x,y,xx,yy) ((x)*32+xx+ xx0*32*((y)*32+yy))
#define ADR(x,y) ((x)+(y)*32)
/*** output width/height in block ***/
int bx,by;
int filler = 0;
unsigned char bkg[3] = { 0x47, 0x6c, 0x6c };
#define WID 32
/****************************************/
/* Wrapper routines **************/
/**************************/
int load_pxxx(fnam) char *fnam;{
int x,y;
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,fnam);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,fnam);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
if(subsname[0]){
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,subsname);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,subsname);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
}
return 1;
}
void clr_buf() {
int xx,yy;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
dbuf[0][ ADR(xx,yy) ]=bkg[0];
dbuf[1][ ADR(xx,yy) ]=bkg[1];
dbuf[2][ ADR(xx,yy) ]=bkg[2];
}
}
}
void cp_floor(){
int xx,yy,c;
for(xx=0;xx<32;xx++)
for(yy=0;yy<32;yy++)
for(c=0;c<3;c++)
dbuf[c][ ADR(xx,yy) ]=fbuf[c][ ADR(xx,yy)];
}
#define TILEX 32
#define TILEY 32
void make_rim(){
static unsigned char dflag[TILEX][TILEY];
int x,y,c,dd[3],ad;
int n0,n1,n2;
// dflag:
// 0 = background
// 1 = tile
// 2 = black
for(y=0;y<TILEY;y++){
for(x=0;x<TILEX;x++){
dflag[x][y]=1;
ad=ADR(x,y);
for(c=0;c<3;c++)dd[c]=dbuf[c][ad];
if( (dd[0]==bkg[0])&&(dd[1]==bkg[1])&& (dd[2]==bkg[2])) dflag[x][y]=0;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0)) dflag[x][y]=2;
}
}
for(x=0;x<TILEX;x++){
for(y=0;y<TILEY;y++){
ad=x+y*TILEX;
if(dflag[x][y]==2 || dflag[x][y]==0){
n0=n1=n2=0;
if(x>0){
if(dflag[x-1][y]==0) n0++;
if(dflag[x-1][y]==1) n1++;
if(dflag[x-1][y]==2) n2++;
}
if(y>0){
if(dflag[x][y-1]==0) n0++;
if(dflag[x][y-1]==1) n1++;
if(dflag[x][y-1]==2) n2++;
}
if(x<31){
if(dflag[x+1][y]==0) n0++;
if(dflag[x+1][y]==1) n1++;
if(dflag[x+1][y]==2) n2++;
}
if(y<31){
if(dflag[x][y+1]==0) n0++;
if(dflag[x][y+1]==1) n1++;
if(dflag[x][y+1]==2) n2++;
}
// n1 = tiles adjacent but not diagonal that are tile pixels
if(n1!=0 )
dbuf[0][x+y*32]=dbuf[1][x+y*32]=dbuf[2][x+y*32]=0x10;
}
}
}
}
void cp_monst_32(){
int xx,yy,c,dd[3],ad;
char dflag[32][32];
int xmin,xmax,ymin,ymax,ox,oy;
if(corpse==1)
{
xmin=ymin=31;
xmax=ymax=0;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
ad=ADR(xx,yy);
for(c=0;c<3;c++)dd[c]=tbuf[c][ad];
if( (dd[0]==bkg[0])&&(dd[1]==bkg[1])&& (dd[2]==bkg[2]))continue;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
if(xx<xmin)xmin=xx;
if(xx>xmax)xmax=xx;
if(yy<ymin)ymin=yy;
if(yy>ymax)ymax=yy;
}
}
ox=(xmax+xmin)/2-16;
oy=(ymax+ymin)/2-16;
}
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
dflag[xx][yy]=0;
ad=ADR(xx,yy);
if(corpse==1){
int x1=xx+ox;
int y1=(yy+oy)*2-16;
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(yy>=cy-1 && yy<=cy+0)continue;
x1 += (y1-16)/4;
if(y1>=cy){y1-=2;x1-=3;}else {y1 +=2;x1+=3;}
if(x1<0 || x1>=32 || y1<0 || y1>=32)continue;
ad=ADR(x1,y1);
}
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2){
if( (dd[0]!=bkg[0])||(dd[1]!=bkg[1])|| (dd[2]!=bkg[2])){
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1){
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==bkg[0])&&(dd[1]==bkg[1])&& (dd[2]==bkg[2]))continue;
if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
for(c=0;c<3;c++) {dbuf[c][ADR(xx,yy)]=dd[c];}
dflag[xx][yy]=1;
}
}
#if 1
if(corpse==1){
for(xx=0;xx<32;xx++){
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(dflag[xx][cy-2]==1 && dflag[xx][cy+1]==1 ){
for(yy=cy-1;yy<=cy-0;yy++){ dbuf[0][ADR(xx,yy)]=32;
dbuf[1][ADR(xx,yy)]=0;dbuf[2][ADR(xx,yy)]=0;
dflag[xx][yy]=1;
}}
}
/** shade**/
for(xx=1;xx<32;xx++){
for(yy=1;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==1){
dbuf[0][ADR(xx,yy)]=0;
dbuf[1][ADR(xx,yy)]=0;
dbuf[2][ADR(xx,yy)]=0;
}
}}
for(xx=3;xx<32;xx++){
for(yy=3;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==0
&& dflag[xx-2][yy-2]==1 && dflag[xx-3][yy-3]==1){
dbuf[0][ADR(xx,yy)]=0;
dbuf[1][ADR(xx,yy)]=0;
dbuf[2][ADR(xx,yy)]=0;
}
}}
}
#endif
if(rim==1)make_rim();
}
void bflush(){
int xx,yy,c;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
for(c=0;c<3;c++){
obuf[c][WOADR(bx,by,xx,yy)]= dbuf[c][ADR(xx,yy)];
}}}
}
void load_monst(fnam) char *fnam;{
if( load_pxxx(fnam)){
printf("no file pxxx/%s.bmp or %s/%s.bmp\n",fnam,sdir,fnam);
getchar();
exit(1);
}
cp_monst_32();
bflush();
}
void process_config(char *fname)
{
int x,y;
int i,j;
char tmp[read_size],st[read_size];
char *nuke;
FILE *fp=fopen(fname,"r");
if(fp==NULL){
printf("Error no config file %s\nHit return",fname);
getchar();
exit(1);
}
while(1){
fgets(tmp,read_size,fp);
if(feof(fp))break;
i=0;while(i<read_size && tmp[i]>=32)i++;
tmp[i]=0;
if(getname(tmp,"back",st))
{
/*** Set Background BMP (format "%back bmpname") ***/
if(strncmp(st,"none",4)==0)
{
/** clear **/
for(i=0;i<32*32;i++){fbuf[0][i]=bkg[0];fbuf[1][i]=bkg[1];fbuf[2][i]=bkg[2];}
}
else
{
load_pxxx(st);
for(i=0;i<32*32;i++)for(j=0;j<3;j++)fbuf[j][i]=tbuf[j][i];
}
continue;
}
if (getname(tmp,"include",st)){
char fn2[read_size];
sprintf(fn2,"%s%s",cpath, st);
if(strcmp(fname,fn2)!=0) process_config(fn2);
continue;
}
if (getname(tmp,"htmlfile",st))
{
char fn2[read_size];
sprintf(fn2,"%s%s",cpath, st);
mfp=fopen(fn2,"w");
if(mfp==NULL)
{
printf("Error could not open %s\nHit return",fn2);
getchar();
exit(1);
}
fprintf(mfp,"<HTML><head>\n");
continue;
}
if (getname(tmp,"tilelist",st))
{
char fn2[read_size];
sprintf(fn2,"%s%s",cpath, st);
tfp=fopen(fn2,"w");
if(tfp==NULL)
{
printf("Error could not open %s\nHit return",fn2);
getchar();
exit(1);
}
fprintf(tfp,"%%tilefile %s\n", imgname);
fprintf(tfp,"%%rim %d\n", rim);
continue;
}
if (getname(tmp,"tiledef",st))
{
char fn[read_size];
sprintf(fn,"%s%s",cpath,st);
strcpy(tiledefname, st);;
sfp=fopen(fn,"w");
if(sfp==NULL)
{
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
fprintf(sfp,"/* Automatically generated by tile generator. */\n");
fprintf(sfp, "enum TILE_%sIDX {\n", enumprefix);
continue;
}
if (getname(tmp,"tilecount",st))
{
char fn[read_size];
sprintf(fn,"%s%s",cpath,st);
cfp=fopen(fn,"w");
if(cfp==NULL)
{
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
fprintf(cfp,"/* Automatically generated by tile generator. */\n");
fprintf(cfp,"#include \"%s\"\n", tiledefname);
fprintf(cfp, "enum TILE_%sCOUNT_IDX {\n", enumprefix);
continue;
}
if (getname(tmp,"enumprefix",st))
{
strcpy(enumprefix, st);
continue;
}
if (getname(tmp,"htmlhead",st))
{
if(mfp)fprintf(mfp,"%s\n",st);
continue;
}
if (getname(tmp,"htmlbody",st))
{
if(mfp)fprintf(mfp,"</head><body>\n<map name=\"nhmap\">\n");
continue;
}
if (getval(tmp,"slant",&slant)) continue;
if (getval(tmp,"rim",&rim))
{
if (tfp) fprintf(tfp, "%%rim %d\n", rim);
continue;
}
if (getval(tmp,"mesh",&mesh)) continue;
if (getval(tmp,"corpse",&corpse)) continue;
if (getname(tmp,"ctg",ctgname)) continue;
if (getname(tmp,"subst",subsname)) continue;
if (getname(tmp,"sdir",sdir)) continue;
if (getname(tmp,"name", outname))
{
sprintf(imgname, "%s.bmp", outname);
continue;
}
if (getname(tmp,"htmlimg",imgname)) continue;
if (getval(tmp,"width",&xx0)) continue;
if (tmp[0]=='#' || tmp[0]<32){
if(tmp[0]<32) fprintf(sfp,"\n");
if(tmp[0]=='#')fprintf(sfp,"//%s\n",tmp);
continue;
}
// begin a 32x32 composing sequence
if (getname(tmp,"start",st))
{
clr_buf();
for (i = 0; i < 32*32; i++)
{
cbuf[0][i] = fbuf[0][i];
cbuf[1][i] = fbuf[1][i];
cbuf[2][i] = fbuf[2][i];
}
continue;
}
// compose an image onto the current buffer
if (getname(tmp,"compose",st))
{
if(load_pxxx(st)){
printf("no file pxxx/%s.bmp or %s/%s.bmp\n",st,sdir,st);
getchar();
exit(1);
}
for(i=0;i<32*32;i++)
{
if (tbuf[0][i] != bkg[0] ||
tbuf[1][i] != bkg[1] ||
tbuf[2][i] != bkg[2])
{
cbuf[0][i] = tbuf[0][i];
cbuf[1][i] = tbuf[1][i];
cbuf[2][i] = tbuf[2][i];
}
}
continue;
}
if (getname(tmp,"nextrow",st))
{
if (bx == 0)
continue;
while (bx != xx0)
{
fprintf(sfp, " TILE_%sFILLER%d,\n", enumprefix, filler++);
bx++;
}
bx = 0;
by ++;
continue;
}
// finish composing
if (getname(tmp,"finish",st))
{
realname[0] = 0;
for (i=0;i<32*32;i++)
{
tbuf[0][i] = cbuf[0][i];
tbuf[1][i] = cbuf[1][i];
tbuf[2][i] = cbuf[2][i];
}
cp_monst_32();
bflush();
}
else
{
/*** normal bitmap ***/
clr_buf();cp_floor();
i=0;while(i<read_size && tmp[i]>32)i++;
tmp[i]=0; strcpy(st, &tmp[i+1]);
if (tfp)
{
fprintf(tfp,"%%sx %d\n%%sy %d\n%%ex %d\n%%ey %d\n",
bx*WID,by*WID,bx*WID+WID-1,by*WID+WID-1);
}
load_monst(tmp);
}
if(mfp)
{
fprintf(
mfp,"<area shape=\"rect\" coords=\"%d,%d,%d,%d\" alt=\"%s\" href=\"%s\">\n",
bx*WID,by*WID,bx*WID+WID-1,by*WID+WID-1,
st,realname);
}
if (tfp)
{
if (corpse)
fprintf(tfp,"%%skip\n");
else
fprintf(tfp,"%%file %s\n", realname);
}
if(!strstr(st,"IGNORE_COMMENT")){
nuke=strstr(st,"/*");if(nuke)*nuke=0;
if (st && strcmp(st, "") != 0 && strcmp(st, "\n") != 0)
{
fprintf(sfp," TILE_%s,\n",st);
if (cfp)
{
if (tilecountidx == -1)
tilecountidx++;
else
counts[tilecountidx++] = tilecount;
fprintf(cfp, " IDX_%s,\n",st);
sprintf(countnames[tilecountidx], "TILE_%s", st);
tilecount = 1;
}
}
else
{
fprintf(sfp, " TILE_%sFILLER%d,\n", enumprefix, filler++);
tilecount++;
}
}
bx++;if(bx==xx0){bx=0;by++;;}
}/* while */
fclose(fp);
}
int main(argc,argv)
int argc;
char *argv[];
{
int i;
char fn[100];
bx=by=0;
process_cpath(argv[0]);
xx0=XX;
ctgname[0]=0;
subsname[0]=0;
sdir[0]=0;
enumprefix[0] = 0;
stdpal();
fixalloc(tbuf,256*256);
fixalloc(obuf, LX*64*(YY)*64);
strcpy(outname,"tile");
strcpy(imgname,"tile.bmp");
printf("%s\ncpath=%s\n",argv[0],cpath);
if(argc==1)
sprintf(fn,"%sdc-2d.txt",cpath);
else
strcpy(fn,argv[1]);
process_config(fn);
if (sfp)
{
fprintf(sfp, "TILE_%sTOTAL};\n\n", enumprefix);
fprintf(sfp,"#define TILE_%sPER_ROW %d\n", enumprefix, xx0);
fclose(sfp);
}
if(mfp)
{
fprintf(mfp,"</map>\n<img src=%s usemap=\"#nhmap\" >\n", imgname);
fprintf(mfp,"</body></html>\n");
fclose(mfp);
}
if (cfp)
{
int i;
fprintf(cfp, " IDX_%sTOTAL\n};\n\n", enumprefix);
counts[tilecountidx++] = tilecount;
fprintf(cfp, "int tile_%scount[IDX_%sTOTAL] =\n{\n",
enumprefix, enumprefix);
for (i = 0; i < tilecountidx; i++)
{
fprintf(cfp, (i < tilecountidx - 1) ? " %d,\n" : " %d\n",
counts[i]);
}
fprintf(cfp, "};\n\n");
fprintf(cfp, "int tile_%sstart[IDX_%sTOTAL] = \n{\n",
enumprefix, enumprefix);
for (i = 0; i < tilecountidx; i++)
{
fprintf(cfp, (i < tilecountidx - 1) ? " %s,\n" : " %s\n",
countnames[i]);
}
fprintf(cfp, "};\n\n");
close(cfp);
}
if(tfp)
{
fclose(tfp);
}
i=by*32;
if(bx!=0)i+=32;
sprintf(fn,"%s%s.bmp",cpath,outname);
bmwrite(fn,xx0*32,i,obuf);
return 0;
}
#include "bm.h"
#define TILEX (32)
#define TILEY (32)
unsigned char *tbuf[3];
unsigned char *dbuf[3];
/*** BUFFER MEMORY ***/
#define XX 30
#define YY 90
#define LX (XX)
#define BIGADR(x,y) ((x)+(y)*LX*32)
#define ADR(x,y) ((x)+(y)*32)
const int read_size = 2048;
int rim = 0;
int tile = 0;
int sx = 0;
int sy = 0;
int ex = 0;
int ey = 0;
char tilename[2048];
char compositename[2048];
unsigned char bkg[3] =
{
0x47,
0x6c,
0x6c
};
int is_background(unsigned char d[3])
{
if (bkg[0]==d[0] && bkg[1]==d[1] && bkg[2]==d[2])
return 1;
else
return 0;
}
int is_rim(unsigned char d[3])
{
if (d[0]==1 && d[1]==1 && d[2]==1)
return 1;
else
return 0;
}
int is_black(unsigned char d[3])
{
if (d[0]==0 && d[1]==0 && d[2]==0)
return 1;
else
return 0;
}
void remove_rim()
{
int dflag[32][32];
unsigned char dd[3];
int x,y,c;
int ad;
int n0, n1, n2;
// 0 - background
// 1 - tile
// 2 - black
// 3 - rim
for (x = 0; x < 32; x++)
for (y = 0; y < 32; y++)
{
ad = ADR(x,y);
dd[0]=dbuf[0][ad];
dd[1]=dbuf[1][ad];
dd[2]=dbuf[2][ad];
if (is_background(dd))
dflag[x][y] = 0;
else if (is_black(dd))
dflag[x][y] = 2;
else if (is_rim(dd))
dflag[x][y] = 3;
else
dflag[x][y] = 1;
}
for(x=0;x<TILEX;x++){
for(y=0;y<TILEY;y++){
ad=ADR(x,y);
if(dflag[x][y]==3) {
n0=n1=n2=0;
if(x>0){
if(dflag[x-1][y]==0) n0++;
if(dflag[x-1][y]==1) n1++;
if(dflag[x-1][y]==2) n2++;
}
if(y>0){
if(dflag[x][y-1]==0) n0++;
if(dflag[x][y-1]==1) n1++;
if(dflag[x][y-1]==2) n2++;
}
if(x<31){
if(dflag[x+1][y]==0) n0++;
if(dflag[x+1][y]==1) n1++;
if(dflag[x+1][y]==2) n2++;
}
if(y<31){
if(dflag[x][y+1]==0) n0++;
if(dflag[x][y+1]==1) n1++;
if(dflag[x][y+1]==2) n2++;
}
if (n1 != 0)
{
dbuf[0][ad]=bkg[0];
dbuf[1][ad]=bkg[1];
dbuf[2][ad]=bkg[2];
}
}
}
}
}
void copy_tile()
{
// copy relevant part of tbuf into dbuf, removing the rim if necessary
int xx,yy,c;
for (xx = 0; xx < 32; xx++)
for (yy = 0; yy < 32; yy++)
for (c = 0; c < 3; c++)
dbuf[c][ADR(xx,yy)] = tbuf[c][BIGADR(sx+xx,sy+yy)];
if (rim)
remove_rim();
}
void write_file()
{
// write dbuf to tilenam
bmwrite(tilename,32,32,dbuf);
}
void process_list(char *fname)
{
int i;
int x,y;
char tmp[read_size];
FILE *fp=fopen(fname,"r");
if (fp==NULL){
printf("Error: couldn't open %s\n", fname);
getchar();
exit(1);
}
while(1){
fgets(tmp,read_size,fp);
if (feof(fp))
break;
i=0;
while (i < read_size && tmp[i] >= 32)
i++;
tmp[i] = 0;
if (getname(tmp,"tilefile",compositename))
{
if (bmread(compositename,&x,&y,tbuf) != 0)
{
break;
}
}
if (getname(tmp,"skip",tilename))
continue;
if (getval(tmp,"rim",&rim))
continue;
if (getval(tmp,"sx",&sx))
continue;
if (getval(tmp,"sy",&sy))
continue;
if (getval(tmp,"ex",&ex))
continue;
if (getval(tmp,"ey",&ey))
continue;
if (getname(tmp,"file",tilename))
{
printf("Reading tile %s (%d,%d,%d,%d) rim(%d)\n",
compositename, sx, sy, ex, ey, rim);
copy_tile();
printf("Writing tile %s.\n", tilename);
write_file();
}
}
fclose(fp);
}
int main(argc, argv)
int argc;
char *argv[];
{
if (argc <= 1) return;
process_cpath(argv[0]);
stdpal();
fixalloc(tbuf, LX*64*(YY)*64);
fixalloc(dbuf, 32*32);
printf("%s\ncpath=%s\n",argv[0],cpath);
process_list(argv[1]);
}
#include "bm.h"
/** Some global **/
int corpse=0, mesh =0,slant=0;
int rim=0;
int exp_wall;
int dsize;
int sx32 = 16;
int sy32 = 24;
int end_normal = 0;
FILE *mfp,*sfp;
char outname[1024], ctgname[100], subsname[100];
char sdir[300];
/*** BUFFER MEMORY ***/
#define XX 16
int xx0;
#define YY 30
#define LX (XX)
/*** tmp buffer, floor , final output, final queue ***/
unsigned char *tbuf[3],fbuf[3][128*64],
*obuf[3],dbuf[3][128*64];
unsigned char wallbuf[4][3][32*48];
unsigned char wall2buf[3][128*64];
int f_wx;
/*** normal floor*/
#define WOADR(x,y,xx,yy) \
((x)*64+xx+ xx0*64*((y)*64+yy))
#define ADR32(x,y) ((x)+(y)*32)
#define ADR64(x,y) ((x)+(y)*64)
/*** output width/height in block ***/
int bx,by;
/**************************/
/* Wrapper routines *******/
/**************************/
int load_it(char *fnam, int *wx, int *wy)
{
char fn[100];
sprintf(fn,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,fnam);
if(bmread(fn,wx,wy,tbuf)==0) return 0;
sprintf(fn,"%s%s.bmp",cpath,fnam);
if(bmread(fn,wx,wy,tbuf)==0) return 0;
if(subsname[0]){
sprintf(fn,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,subsname);
if(bmread(fn,wx,wy,tbuf)==0) return 0;
sprintf(fn,"%s%s.bmp",cpath,subsname);
if(bmread(fn,wx,wy,tbuf)==0) return 0;
}
return 1;
}
void clr_dbuf() {
int xx,yy;
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
dbuf[0][ ADR64(xx,yy) ]=0x47;
dbuf[1][ ADR64(xx,yy) ]=0x6c;
dbuf[2][ ADR64(xx,yy) ]=0x6c;
}}
}
#define TILEX 64
#define TILEY 64
void make_rim(){
static unsigned char dflag[TILEX][TILEY];
int x,y,c,dd[3],ad;
int n0,n1,n2;
for(y=0;y<TILEY;y++){
for(x=0;x<TILEX;x++){
dflag[x][y]=1;
ad=x + y *TILEX;
for(c=0;c<3;c++)dd[c]=dbuf[c][ad];
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c)) dflag[x][y]=0;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0)) dflag[x][y]=2;
}
}
for(x=0;x<TILEX;x++){
for(y=0;y<TILEY;y++){
ad=x+y*TILEX;
if(dflag[x][y]==2 || dflag[x][y]==0){
n0=n1=n2=0;
if(x>0){
if(dflag[x-1][y]==0) n0++;
if(dflag[x-1][y]==1) n1++;
if(dflag[x-1][y]==2) n2++;
}
if(y>0){
if(dflag[x][y-1]==0) n0++;
if(dflag[x][y-1]==1) n1++;
if(dflag[x][y-1]==2) n2++;
}
if(x<TILEX-1){
if(dflag[x+1][y]==0) n0++;
if(dflag[x+1][y]==1) n1++;
if(dflag[x+1][y]==2) n2++;
}
if(y<TILEY-1){
if(dflag[x][y+1]==0) n0++;
if(dflag[x][y+1]==1) n1++;
if(dflag[x][y+1]==2) n2++;
}
if(n1!=0 )
dbuf[0][x+y*TILEX]=dbuf[1][x+y*TILEX]=dbuf[2][x+y*TILEX]=0x10;
}}}
}
void cp_floor_64(){
int xx,yy,c;
for(xx=0;xx<64;xx++)
for(yy=0;yy<64;yy++)
for(c=0;c<3;c++)
dbuf[c][ ADR64(xx,yy) ]=fbuf[c][ ADR64(xx,yy)];
}
void cp_floor_32(){
int xx,yy,c;
for(xx=0;xx<32;xx++)
for(yy=0;yy<32;yy++)
for(c=0;c<3;c++)
dbuf[c][ ADR64(32+xx-yy,32+(xx+yy)/2) ]=fbuf[c][ ADR32(xx,yy)];
}
void cp_monst_32(){
int xx,yy,c,dd[3],ad;
char dflag[32][32];
int xmin,xmax,ymin,ymax;
int ox=0;
int oy=0;
if(corpse==1 ){
xmin=ymin=31;
xmax=ymax=0;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
ad=ADR32(xx,yy);
for(c=0;c<3;c++)dd[c]=tbuf[c][ad];
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
if(xx<xmin)xmin=xx;
if(xx>xmax)xmax=xx;
if(yy<ymin)ymin=yy;
if(yy>ymax)ymax=yy;
}}/*xy**/
ox=(xmax+xmin)/2-16;
oy=(ymax+ymin)/2-16;
}
if(slant==1){
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
int x1 = xx-yy+32;
int y1= 32+(xx+yy)/2;
ad = ADR32(xx,yy);
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2){
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c)){
if( ((x1+y1)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1){
if( (((x1/2)+(y1/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(x1,y1)]=dd[c];}
}}
return;
}
if(dsize==1){
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
int x1 = xx*2;
int y1= yy*2;
ad = ADR32(xx,yy);
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2){
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c)){
if( ((x1+y1)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1){
if( (((x1/2)+(y1/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++)
{
dbuf[c][ADR64(x1,y1)]=dd[c];
dbuf[c][ADR64(x1+1,y1)]=dd[c];
dbuf[c][ADR64(x1,y1+1)]=dd[c];
dbuf[c][ADR64(x1+1,y1+1)]=dd[c];
}
}}
return;
}
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
dflag[xx][yy]=0;
ad=ADR32(xx,yy);
if(corpse==1){
int x1=xx+ox;
int y1=(yy+oy)*2-16;
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(yy>=cy-1 && yy<=cy+0)continue;
x1 += (y1-16)/4;
if(y1>=cy){y1-=2;x1-=3;}else {y1 +=2;x1+=3;}
if(x1<0 || x1>=32 || y1<0 || y1>=32)continue;
ad=ADR32(x1,y1);
}
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2)
{
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c))
{
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
else if(mesh==1)
{
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(sx32+xx,sy32+yy)]=dd[c];}
dflag[xx][yy]=1;
}}
#if 1
if(corpse==1){
for(xx=0;xx<32;xx++){
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(dflag[xx][cy-2]==1 && dflag[xx][cy+1]==1 ){
for(yy=cy-1;yy<=cy-0;yy++){ dbuf[0][ADR64(16+xx,32+yy)]=32;
dbuf[1][ADR64(16+xx,32+yy)]=0;dbuf[2][ADR64(16+xx,32+yy)]=0;
dflag[xx][yy]=1;
}}
}
/** shade**/
for(xx=1;xx<32;xx++){
for(yy=1;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==1){
dbuf[0][ADR64(xx,yy)]=0;
dbuf[1][ADR64(xx,yy)]=0;
dbuf[2][ADR64(xx,yy)]=0;
}
}}
for(xx=3;xx<32;xx++){
for(yy=3;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==0
&& dflag[xx-2][yy-2]==1 && dflag[xx-3][yy-3]==1){
dbuf[0][ADR64(xx,yy)]=0;
dbuf[1][ADR64(xx,yy)]=0;
dbuf[2][ADR64(xx,yy)]=0;
}
}}
}
#endif
}
void cp_monst_64(){
int xx,yy,c,dd[3],ad;
int dflag[64][64];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
dflag[xx][yy]=0;
ad=ADR64(xx,yy);
if(corpse==1)
{
int y1=2*(yy-26);
int x1=32+(xx-32)*5/4+(y1-32)*3/4;
y1 -= (xx-32)/3;
if(x1<0 || x1>=64 || y1<0 || y1>=64)continue;
ad=ADR64(x1,y1);
}
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
if(mesh==2)
{
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c))
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
if(mesh==1)
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
dflag[xx][yy]=1;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
if (corpse == 1)
{
for(yy=0;yy<64;yy++)
{
int thick=0;
for(xx=0;xx<64;xx++)
{
if(dflag[xx][yy]==1)
{
thick++;
if (thick>15) thick=15;
continue;
}
if (thick>0)
{
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=0;}
thick -= 3;
if (thick<0) thick=0;
}
}
}
for(xx=0;xx<64;xx++)
{
int thick=0;
for(yy=0;yy<64;yy++)
{
if(dflag[xx][yy]==1)
{
thick++;
if (thick>15) thick=15;
continue;
}
if (thick>0)
{
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=0;}
thick -= 5;
if (thick<0) thick=0;
}
}
}
}
}
void cp_monst_4864(){
int xx,yy,c,dd[3],ad;
for(xx=0;xx<48;xx++){
for(yy=0;yy<64;yy++){
ad= xx+yy*48;
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2)
{
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c))
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
if(mesh==1)
if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][8+xx+yy*64]=dd[c];}
}}
}
void bflush(){
int xx,yy,c;
if(rim==1) make_rim();
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
for(c=0;c<3;c++){
obuf[c][WOADR(bx,by,xx,yy)]= dbuf[c][ADR64(xx,yy)];
}}}
}
void copy_wall(int wall_ix, int xofs, int yofs){
int xx,yy,c;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs-16;
int y=yy-yofs-8;
int ad = x+y*32;
if(x<0 || y<0 || x>=32 || y>=48) continue;
for(c=0;c<3;c++){dd[c]=wallbuf[wall_ix][c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void copy_wall_vert(int wall_ix, int xofs, int yofs){
int xx,yy,c,ymax;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs-16;
int y=yy-yofs-8;
int ad = x+y*32;
if(x<0 || y<0 || x>=32 || y>=48) continue;
ymax= 8+x/2;
if(ymax> 8+(31-x)/2) ymax=8+(31-x)/2;
if(y<ymax) continue;
for(c=0;c<3;c++){dd[c]=wallbuf[wall_ix][c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
//Mesh
// if( ((x/2+y/2)&1) == 0) dd[0]=dd[1]=dd[2]=0;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void expand_wall(){
//unsigned char wallbuf[4][3][32*48];
int xx,yy,c,ix;
exp_wall=1;
for(ix=0;ix<4;ix++){
for(xx=0;xx<32;xx++){
for(yy=0;yy<48;yy++){
wallbuf[ix][0][xx+yy*32]=0x47;
wallbuf[ix][1][xx+yy*32]=0x6c;
wallbuf[ix][2][xx+yy*32]=0x6c;
}}}
//decompose wall bmp
for(xx=0;xx<32;xx++){
int ymax= 8+xx/2;
if(ymax> 8+(31-xx)/2) ymax=8+(31-xx)/2;
for(yy=0;yy<ymax;yy++){
ix=0;
if(2*yy+xx >=32)ix +=1;
if(2*yy-xx >=0 )ix +=2;
for(c=0;c<3;c++)wallbuf[ix][c][xx+yy*32]=tbuf[c][xx+yy*32];
}
for(yy=ymax;yy<48;yy++){
if(xx<8) ix=2;else if(xx<24) ix=3; else ix=1;
for(c=0;c<3;c++)wallbuf[ix][c][xx+yy*32]=tbuf[c][xx+yy*32];
}
}//xx
/*
0
1 1 2 2
3 4 5
6 7 8 9
A B C
4 D E 8
F
*/
for(ix=0;ix<16;ix++){
clr_dbuf();
if(f_wx==32)cp_floor_32(); else cp_floor_64();
if((ix&3)==3) copy_wall(3,0,-16);
if(ix&1) copy_wall(1,-16,-8);
if(ix&2) copy_wall(2,16,-8);
if(ix&1) copy_wall(3,-16,-8);
copy_wall(0, 0,0);
if(ix&2) copy_wall(3,16,-8);
if((ix&5)==5) {copy_wall(1,-32,0);copy_wall_vert(2,-16,0);}
copy_wall(2,0,0);
copy_wall(1,0,0);
if((ix&10)==10) {copy_wall(2,32,0);copy_wall_vert(1,16,0);}
if(ix&4) {copy_wall(0,-16,8);copy_wall_vert(3,-16,0);}
copy_wall(3,0,0);
if(ix&8) {copy_wall(0,16,8);copy_wall_vert(3,16,0);}
if(ix&4) {copy_wall(1,-16,8);copy_wall_vert(2,0,8);}
if(ix&8) {copy_wall(2,16,8); copy_wall_vert(1,0,8);}
if((ix&12)==12) {copy_wall(0,0,16);copy_wall_vert(3,0,8);}
bflush();
bx++;if(bx==xx0){bx=0;by++;}
}/*ix*/
}
static void copy_wall2_h1(int ix, int xofs, int yofs){
int xx,yy,c,ad;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs;
int y=yy-yofs;;
ad = x+64+y*128;
if (x<0 || y<0 || x>63 || y>63)continue;
if(2*y>=x+32) continue;
if(2*y>=95-x) continue;
if((ix%3)==0) if (2*y>=47-x)continue;
if((ix%3)==1) if ((2*y<47-x) || (2*y>=79-x))continue;
if((ix%3)==2) if(2*y<79-x)continue;
if((ix/3)==0) if(2*y>=x-16)continue;
if((ix/3)==1) if((2*y<x-16) || (2*y>=x+16))continue;
if((ix/3)==2) if(2*y<x+16) continue;
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void copy_wall2_h2(int ix, int xofs, int yofs){
int xx,yy,c,ad;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs;
int y=yy-yofs;;
ad = x+y*128;
if (x<0 || y<0 || x>63 || y>63)continue;
if(2*y>=x+32) continue;
if(2*y>=95-x) continue;
if ((ix%2)==0)if (2*y>=63-x)continue;
if((ix%2)==1) if (2*y<63-x)continue;
if((ix/2)==0)if(2*y>=x)continue;
if((ix/2)==1)if(2*y<x)continue;
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void copy_wall_v2(int ix, int kind, int xofs, int yofs){
int xx,yy,c,ymax,ad;
unsigned char dd[3];
for(xx=0;xx<64;xx++){
for(yy=0;yy<64;yy++){
int x=xx-xofs;
int y=yy-yofs;
ad = x+kind*64+y*128;
if(x<0 || y<0 || x>=64 || y>=64) continue;
ymax= 16+x/2;
if(x>=32) ymax=16+(63-x)/2;
if(y<ymax) continue;
if(y>ymax+32)continue;
if(ix==0) if(x>=8)continue;
if(ix==1) if(x<8 || x>=24)continue;
if(ix==2) if(x<24 || x>=40)continue;
if(ix==3) if(x<40 || x>=56)continue;
if(ix==4) if(x<56)continue;
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
for(c=0;c<3;c++) {dbuf[c][ADR64(xx,yy)]=dd[c];}
}}
}
void expand_wall2(){
//void copy_wall2_h(int kind, int ix, int xofs, int yofs)
int ix;
exp_wall=1;
for(ix=0;ix<16;ix++){
clr_dbuf();
if(f_wx==32)cp_floor_32(); else cp_floor_64();
if((ix&3)==0) copy_wall2_h1(0, 0, 8);
if((ix&3)==1) copy_wall2_h1(1, -16, 0);
if((ix&3)==2) copy_wall2_h1(3, 16, 0);
if((ix&3)==3) copy_wall2_h2(0, 0, 0);
if((ix&5)==0) copy_wall2_h1(6, 16, 0);
if((ix&5)==1) copy_wall2_h1(7, 0, -8);
if((ix&5)==4) copy_wall2_h1(3, 0, 8);
if((ix&5)==5) copy_wall2_h2(2, 0, 0);
if((ix&10)==0) copy_wall2_h1(2, -16, 0);
if((ix&10)==2) copy_wall2_h1(5, 0, -8);
if((ix&10)==8) copy_wall2_h1(1, 0, 8);
if((ix&10)==10) copy_wall2_h2(1, 0, 0);
if((ix&12)==0) copy_wall2_h1(8, 0, -8);
if((ix&12)==4) copy_wall2_h1(5, -16, 0);
if((ix&12)==8) copy_wall2_h1(7, 16, 0);
if((ix&12)==12) copy_wall2_h2(3, 0, 0);
if((ix&5)==5) copy_wall_v2(0, 0, 0, 0);
if((ix&10)==10) copy_wall_v2(4, 0, 0, 0);
if((ix&4)!=0) copy_wall_v2(1, 0, 0, 0);
if((ix&8)!=0) copy_wall_v2(3, 0, 0, 0);
if((ix&12)==12) copy_wall_v2(2, 0, 0, 0);
if((ix&5)==1) copy_wall_v2(1, 1, 0, -8);
if((ix&12)==8) copy_wall_v2(1, 1, 16, 0);
if((ix&10)==2) copy_wall_v2(3, 1, 0, -8);
if((ix&12)==4) copy_wall_v2(3, 1, -16, 0);
if((ix&5)==0) copy_wall_v2(0, 1, 16, 0);
if((ix&10)==0) copy_wall_v2(4, 1, -16, 0);
if((ix&12)==0) copy_wall_v2(2, 1, 0, -8);
bflush();
bx++;if(bx==xx0){bx=0;by++;}
}
}
void load_monst(fnam) char *fnam;{
int wx, wy;
if( load_it(fnam, &wx, &wy))
{
printf("no file %s.bmp\n",fnam);
getchar();
exit(1);
}
exp_wall=0;
if(wx==128 && wy==64) expand_wall2();
else if(wx==48 && wy==64) cp_monst_4864();
else if(wx==32 && wy==48) expand_wall();
else if(wx==32)cp_monst_32();
else if(wx==64)cp_monst_64();
bflush();
}
void process_config(char *fname)
{
int i,j;
char tmp[100],st[1024];
char *nuke;
FILE *fp=fopen(fname,"r");
if(fp==NULL){
printf("Error no config file %s\nHit return",fname);
getchar();
exit(1);
}
while(1){
int dummy;
fgets(tmp,99,fp);
if(feof(fp))break;
i=0;while(i<99 && tmp[i]>=32)i++;
tmp[i]=0;
fprintf(stderr,"[%s]\n",tmp);
if(getname(tmp,"back",st))
{
/*** Set Background BMP (format "%back bmpname") ***/
if(strncmp(st,"none",4)==0)
{
/** clear **/
for(i=0;i<32*32;i++){fbuf[0][i]=0x47;fbuf[1][i]=fbuf[2][i]=0x6c;}
f_wx=64;
}
else
{
int wy;
load_it(st, &f_wx, &wy);
for(i=0;i<f_wx*wy;i++)for(j=0;j<3;j++)fbuf[j][i]=tbuf[j][i];
}
continue;
}
if (getname(tmp,"include",st)){
char fn2[200];
sprintf(fn2,"%s%s",cpath, st);
if(strcmp(fname,fn2)!=0) process_config(fn2);
continue;
}
if (getval(tmp,"slant",&slant)) continue;
if (getval(tmp,"corpse",&corpse)) continue;
if (getval(tmp,"dsize",&dsize)) continue;
if (getval(tmp,"mesh",&mesh)) continue;
if (getval(tmp,"rim",&rim)) continue;
if (getname(tmp,"ctg",ctgname)) continue;
if (getname(tmp,"subst",subsname)) continue;
if (getname(tmp,"sdir",sdir)) continue;
if (getname(tmp,"name", outname)) continue;
if (getval(tmp,"width",&xx0)) continue;
if (getval(tmp,"sx",&sx32)) continue;
if (getval(tmp,"sy",&sy32)) continue;
if (getval(tmp,"end_normal",&dummy))
{
fprintf(sfp,"-1, -1 };\n");
end_normal = 1;
continue;
}
if (tmp[0]=='#' || tmp[0]<32)
{
if(tmp[0]=='#')fprintf(sfp,"//%s\n",tmp);
if(tmp[0]<32) fprintf(sfp,"\n");
continue;
}
/*** normal bitmap ***/
clr_dbuf();
if(f_wx==32)cp_floor_32(); else cp_floor_64();
i=0;while(i<99 && tmp[i]>32)i++;
tmp[i]=0; strcpy(st, &tmp[i+1]);
load_monst(tmp);
if(!strstr(st,"IGNORE_COMMENT"))
{
nuke=strstr(st,"/*");if(nuke)*nuke=0;
if(exp_wall)
fprintf(sfp,"TILE_%s, (TILE_TOTAL+%d),\n",st,bx+by*xx0-16);
else
if(end_normal)
fprintf(sfp,"#define TILE_%s %d\n",st,bx+by*xx0);
else
fprintf(sfp,"TILE_%s, (TILE_TOTAL+%d),\n",st,bx+by*xx0);
}
if(!exp_wall){bx++;if(bx==xx0){bx=0;by++;}}
}/* while */
fclose(fp);
}
int main(argc,argv)
int argc;
char *argv[];
{
int i;
char fn[100];
fixalloc(tbuf,256*256);
slant=corpse=mesh=dsize=0;
bx=by=0;
process_cpath(argv[0]);
fixalloc(obuf, LX*64*(YY)*64);
xx0=XX;
ctgname[0]=0;
subsname[0]=0;
sdir[0]=0;
stdpal();
strcpy(outname,"tile");
sprintf(fn,"%stiledef-qv.h",cpath);
sfp=fopen(fn,"w");
if(sfp==NULL){
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
fprintf(sfp,"/* Automatically generated by tile generator. */\n");
fprintf(sfp,"const int tile_qv_pair_table[] ={\n");
printf("%s\ncpath=%s\n",argv[0],cpath);
if(argc==1)
sprintf(fn,"%sdc-3d.txt",cpath);
else strcpy(fn,argv[1]);
process_config(fn);
if(end_normal == 0)fprintf(sfp,"-1, -1 };\n");
fprintf(sfp,"\n#define TILE_TOTAL_EX %d\n",bx+by*xx0);
fprintf(sfp,"#define TILE_PER_ROW_EX %d\n",xx0);
fclose(sfp);
i=by*64;if(bx!=0)i+=64;
sprintf(fn,"%s%s.bmp",cpath,outname);
bmwrite(fn,xx0*64,i,obuf);
return 0;
}
#include "bm.h"
/** Some global **/
//Flags
int corpse, mesh, slant,rim;
// Files
FILE *mfp,*sfp;
//Strings
char outname[1024], subsname[200], sdir[200];
char realname[1024];
/** Parts related **/
int parts_n;
#define MAXPARTS 20
int parts_nx[MAXPARTS], parts_ny[MAXPARTS];
int parts_ox[MAXPARTS], parts_oy[MAXPARTS];
int parts_start[MAXPARTS], parts_number[MAXPARTS];
char parts_names[MAXPARTS][64];
int parts_comment_ofs[MAXPARTS];
int n_comments, pos_comment;
#define MAXTOTAL 1000
int part_comment_ofs[MAXTOTAL];
char comment[MAXTOTAL*60];
int part_x,part_y;
int part_n;
int part_nx,part_ny;
char part_name[32];
int part_wx, part_wy, part_ox, part_oy;
/*** BUFFER MEMORY ***/
#define XX 30
int xx0;
#define LX (XX)
/*** tmp buffer, floor , final output, final queue ***/
unsigned char *tbuf[3],*fbuf[3],*dbuf[3], *obuf[3];
/*** normal floor*/
#define WOADR(x,y,xx,yy) \
((x)*32+xx+ xx0*32*((y)*32+yy))
#define ADR(x,y) ((x)+(y)*32)
/*** output width/height in block ***/
int bx,by;
/****************************/
/* Wrapper routines ********/
/**************************/
int load_pxxx(fnam)
char *fnam;
{
int x,y;
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,fnam);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,fnam);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
if(subsname[0])
{
sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,subsname);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
sprintf(realname,"%s%s.bmp",cpath,subsname);
if(bmread(realname,&x,&y,tbuf)==0) return 0;
}
return 1;
}
void clr_buf()
{
int xx,yy;
for(xx=0;xx<32;xx++)
{
for(yy=0;yy<32;yy++)
{
dbuf[0][ ADR(xx,yy) ]=0x47;
dbuf[1][ ADR(xx,yy) ]=0x6c;
dbuf[2][ ADR(xx,yy) ]=0x6c;
}
}
}
void cp_floor()
{
int xx,yy,c;
for(xx=0;xx<32;xx++)
for(yy=0;yy<32;yy++)
for(c=0;c<3;c++)
dbuf[c][ ADR(xx,yy) ]=fbuf[c][ ADR(xx,yy)];
}
void cp_monst_32()
{
int xx,yy,c,dd[3],ad;
char dflag[33][32];
int xmin,xmax,ymin,ymax,ox,oy;
if(corpse==1 )
{
xmin=ymin=31;
xmax=ymax=0;
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
ad=ADR(xx,yy);
for(c=0;c<3;c++)dd[c]=tbuf[c][ad];
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
if(xx<xmin)xmin=xx;
if(xx>xmax)xmax=xx;
if(yy<ymin)ymin=yy;
if(yy>ymax)ymax=yy;
}
}
ox=(xmax+xmin)/2-16;
oy=(ymax+ymin)/2-16;
}
/** copy loop **/
for(xx=0;xx<32;xx++){
for(yy=0;yy<32;yy++){
dflag[xx][yy]=0;
ad=ADR(xx,yy);
if(corpse==1)
{
int x1=xx+ox;
int y1=(yy+oy)*2-16;
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(yy>=cy-1 && yy<=cy+0)continue;
x1 += (y1-16)/4;
if(y1>=cy){y1-=2;x1-=3;}else {y1 +=2;x1+=3;}
if(x1<0 || x1>=32 || y1<0 || y1>=32)continue;
ad=ADR(x1,y1);
}
/*** normal***/
for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
if(mesh==2)
{
if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c))
{
if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
}
}
if(mesh==1)
{
if((((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
}
if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
for(c=0;c<3;c++) {dbuf[c][ADR(xx,yy)]=dd[c];}
dflag[xx][yy]=1;
}
}/*XY*/
#if 1
if(corpse==1)
{
for(xx=0;xx<32;xx++)
{
int cy=18;
if(xx<4 || xx>=28)cy+=2;else
if(xx<12 || xx>=20) cy+=1;
if(dflag[xx][cy-2]==1 && dflag[xx][cy+1]==1 )
{
for(yy=cy-1;yy<=cy-0;yy++)
{
dbuf[0][ADR(xx,yy)]=32;
dbuf[1][ADR(xx,yy)]=0;
dbuf[2][ADR(xx,yy)]=0;
dflag[xx][yy]=1;
}
}
}
/** shade**/
for(xx=1;xx<32;xx++){
for(yy=1;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==1)
{
dbuf[0][ADR(xx,yy)]=0;
dbuf[1][ADR(xx,yy)]=0;
dbuf[2][ADR(xx,yy)]=0;
}
}
}
for(xx=3;xx<32;xx++){
for(yy=3;yy<32;yy++){
if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==0
&& dflag[xx-2][yy-2]==1 && dflag[xx-3][yy-3]==1)
{
dbuf[0][ADR(xx,yy)]=0;
dbuf[1][ADR(xx,yy)]=0;
dbuf[2][ADR(xx,yy)]=0;
}
}
}
}
#endif
}
void bflush()
{
int xx,yy,c;
for(xx=part_ox;xx<part_ox+part_wx;xx++){
for(yy=part_oy;yy<part_oy+part_wy;yy++){
for(c=0;c<3;c++){
obuf[c][WOADR(bx,by,part_x*part_wx+xx-part_ox,part_y*part_wy+yy-part_oy)]
= dbuf[c][ADR(xx,yy)];
}
}
}
}
void load_monst(fnam) char *fnam;{
if( load_pxxx(fnam)){
printf("no file %s.bmp\n",fnam);
getchar();
exit(1);
}
cp_monst_32();
bflush();
}
void flush_part()
{
if(part_x!=0 || part_y!=0)
{
part_x=part_y=0;
bx++;if(bx==xx0){bx=0;by++;;}
}
parts_number[parts_n]=part_n;
parts_n++;
}
void process_config(char *fname)
{
int i,j;
char tmp[100],st[1024];
char *nuke;
FILE *fp=fopen(fname,"r");
if(fp==NULL)
{
printf("Error no config file %s\nHit return",fname);
getchar();
exit(1);
}
while(1){
fgets(tmp,99,fp);
if(feof(fp))break;
i=0;
while(i<99 && tmp[i]>=32) i++;
tmp[i]=0;
if(getname(tmp,"back",st))
{
/*** Set Background BMP (format "%back bmpname") ***/
if(strncmp(st,"none",4)==0)
{
/** clear **/
for(i=0;i<32*32;i++){fbuf[0][i]=0x47;fbuf[1][i]=fbuf[2][i]=0x6c;}
}
else
{
load_pxxx(st);
for(i=0;i<32*32;i++)for(j=0;j<3;j++)fbuf[j][i]=tbuf[j][i];
}
continue;
}
if (getname(tmp,"include",st)){
char fn2[200];
sprintf(fn2,"%s%s",cpath, st);
if(strcmp(fname,fn2)!=0) process_config(fn2);
continue;
}
if (getval(tmp,"slant",&slant)) continue;
if (getval(tmp,"rim",&rim)) continue;
if (getval(tmp,"mesh",&mesh)) continue;
if (getval(tmp,"corpse",&corpse)) continue;
if (getname(tmp,"subst",subsname)) continue;
if (getname(tmp,"sdir",sdir)) continue;
if (getname(tmp,"name", outname)) continue;
if (getval(tmp,"width",&xx0)) continue;
/****/
if (getname(tmp,"parts_ctg",part_name))
{
if(part_n!=0)
flush_part();
part_n=0;
strcpy(parts_names[parts_n],part_name);
parts_comment_ofs[parts_n] = n_comments;
parts_start[parts_n]=bx+by*xx0;
fprintf(sfp,"#define TILEP_PART_%s %d\n",part_name, parts_n);
fprintf(sfp,"enum %s {\n",part_name);
fprintf(sfp," TILEP_%s_000,\n",part_name);
continue;
}
if (getval(tmp,"parts_wx",&part_wx))
{
parts_nx[parts_n]=part_nx=32/part_wx;
continue;
}
if (getval(tmp,"parts_wy",&part_wy))
{
parts_ny[parts_n]=part_ny=32/part_wy;
continue;
}
if (getval(tmp,"parts_ox", &part_ox))
{
parts_ox[parts_n]=part_ox;
continue;
}
if (getval(tmp,"parts_oy", &part_oy))
{
parts_oy[parts_n]=part_oy;
continue;
}
/****/
if (tmp[0]=='#' || tmp[0]<32){
if(tmp[0]=='#') fprintf(sfp,"//%s\n",tmp);
continue;
}
if (strcmp(tmp, "%end") == 0)
{
fprintf(sfp," N_PART_%s};\n\n",part_name);
continue;
}
/*** normal bitmap ***/
#define WID 32
clr_buf();
cp_floor();
i=0;
while(i<99 && tmp[i]>32)i++;
tmp[i]=0; strcpy(st, &tmp[i+1]);
load_monst(tmp);
fprintf(mfp,
"<area shape=\"rect\" coords=\"%d,%d,%d,%d\" alt=\"%s\" href=%s>\n",
bx*WID + part_x*part_wx,
by*WID + part_y*part_wy,
bx*WID + part_x*part_wx + part_wx-1,
by*WID + part_y*part_wy + part_wy-1,
st, realname);
if(!strstr(st,"IGNORE_COMMENT")){
nuke=strstr(st,"/*");if(nuke)*nuke=0;
if (st && strcmp(st,"") != 0 && strcmp(st, "\n") != 0)
{
fprintf(sfp," TILEP_%s_%s,\n", part_name, st);
}
else
{
fprintf(sfp," FILLER_%s_%d,\n", part_name, part_n);
}
i=strlen(st);
strncpy(&comment[pos_comment],st,i);
part_comment_ofs[n_comments]=pos_comment;
pos_comment += i;
n_comments++;
// n_comments = pos_comment=0;
//int parts_comment_ofs[];
//int part_comment_ofs[MAXTOTAL];
//char comment[MAXTOTAL*60];
}
else
{
i=0;
part_comment_ofs[n_comments]=pos_comment;
pos_comment += i;
n_comments++;
}
part_n++;
part_x++;
if(part_x==part_nx)
{
part_x=0;
part_y++;
if(part_y==part_ny)
{
part_y=0;
bx++;
if(bx==xx0)
{
bx=0;
by++;
}
}
}
/* normal */
}/* while */
fclose(fp);
}
/********************************************/
int main(int argc, char **argv)
{
int i,j,k,l,m,n,fl;
char fn[100],st2[100];
slant=corpse=mesh=rim=0;
bx=by=0;
/* parts related */
parts_n=0;
part_x=part_y=0;
part_n=0;
part_wx=part_wy=32;
part_ox=part_oy=0;
/* comments */
n_comments = pos_comment=0;
//int parts_comment_ofs[];
//int part_comment_ofs[MAXTOTAL];
//char comment[MAXTOTAL*60];
process_cpath(argv[0]);
xx0=XX;
subsname[0]=0;
sdir[0]=0;
realname[0]=0;
stdpal();
fixalloc(tbuf,64*64);
fixalloc(dbuf,64*64);
fixalloc(fbuf,64*64);
fixalloc(obuf, 32*64*(64)*64);
strcpy(outname,"tile");
sprintf(fn,"%smap.htm",cpath);
mfp=fopen(fn,"w");
if(mfp==NULL){
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
sprintf(fn,"%stiledef-p.h",cpath);
sfp=fopen(fn,"w");
if(sfp==NULL){
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
fprintf(sfp,"/* Automatically generated by tile generator. */\n");
fprintf(mfp,"<HTML>\n");
fprintf(mfp,"<MAP NAME=\"nhmap\">\n");
printf("%s\ncpath=%s\n",argv[0],cpath);
if(argc==1)
sprintf(fn,"%sdc-pl.txt",cpath);
else
strcpy(fn,argv[1]);
process_config(fn);
if(part_n!=0)flush_part();
fprintf(sfp,"\n#define TILEP_TOTAL %d\n",bx+by*xx0);
fprintf(sfp,"#define TILEP_PER_ROW %d\n\n",xx0);
fprintf(sfp,"#define TILEP_PARTS_TOTAL %d\n\n",parts_n);
fprintf(sfp,"const int tilep_parts_start[TILEP_PARTS_TOTAL]=\n {");
for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_start[i]);
fprintf(sfp," %d};\n",parts_start[parts_n-1]);
fprintf(sfp,"const int tilep_parts_total[TILEP_PARTS_TOTAL]=\n {");
for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_number[i]);
fprintf(sfp," %d};\n",parts_number[parts_n-1]);
fprintf(sfp,"const int tilep_parts_ox[TILEP_PARTS_TOTAL]=\n {");
for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_ox[i]);
fprintf(sfp," %d};\n",parts_ox[parts_n-1]);
fprintf(sfp,"const int tilep_parts_oy[TILEP_PARTS_TOTAL]=\n {");
for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_oy[i]);
fprintf(sfp," %d};\n",parts_oy[parts_n-1]);
fprintf(sfp,"const int tilep_parts_nx[TILEP_PARTS_TOTAL]=\n {");
for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_nx[i]);
fprintf(sfp," %d};\n",parts_nx[parts_n-1]);
fprintf(sfp,"const int tilep_parts_ny[TILEP_PARTS_TOTAL]=\n {");
for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_ny[i]);
fprintf(sfp," %d};\n",parts_ny[parts_n-1]);
fclose(sfp);
sprintf(fn,"%stilep-cmt.h",cpath);
sfp=fopen(fn,"w");
if(sfp==NULL){
printf("Error could not open %s\nHit return",fn);
getchar();
exit(1);
}
fprintf(sfp,"/* Automatically generated by tile generator. */\n");
fprintf(sfp,"static const char *tilep_parts_name[%d]={\n",parts_n);
for(i=0;i<parts_n-1;i++)
{
fprintf(sfp," \"%s\",\n",parts_names[i]);
}
i=parts_n-1;
fprintf(sfp," \"%s\"\n};\n",parts_names[i]);
fprintf(sfp,"const int tilep_comment_ofs[TILEP_PARTS_TOTAL]= {\n");
for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_comment_ofs[i]);
fprintf(sfp," %d};\n",parts_comment_ofs[parts_n-1]);
fprintf(sfp,"static const char *tilep_comment[%d]={\n",n_comments);
for(i=0;i<n_comments-1;i++)
{
int len=part_comment_ofs[i+1]-part_comment_ofs[i];
strncpy(st2, &comment[part_comment_ofs[i]],len);
st2[len]=0;
fprintf(sfp," \"%s\",\n",st2);
}
i=pos_comment-part_comment_ofs[n_comments-1];
strncpy(st2, &comment[part_comment_ofs[n_comments-1]],i);
st2[i]=0;
fprintf(sfp," \"%s\" };\n",st2);
fclose(sfp);
fprintf(mfp,"<IMG SRC=%s.bmp USEMAP=\"#nhmap\" >\n", outname);
fclose(mfp);
i=by*32;if(bx!=0)i+=32;
sprintf(fn,"%s%s.bmp",cpath,outname);
bmwrite(fn,xx0*32,i,obuf);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int bmread(char *fn, int *x, int *y, unsigned char *buf3[3]);
extern void fixalloc(char *buf[3], int size);
extern void bmwrite(char *fn, int x, int y, unsigned char *buf3[3]);
extern void bmwrite24(char *fn, int x, int y, unsigned char *buf3[3]);
extern void bmwrite_dither(char *fn, int x, int y, unsigned char *buf3[3],
unsigned char *flag);
extern void stdpal();
extern void myfget(char *ss, FILE *fp);
extern int getval(char *buf, char *tag, int *val);
extern int getname(char *buf, char *tag, char *name);
extern void process_cpath(char *path);
extern void newgold();
/*** PATH to this program ***/
extern char cpath[1024];
#if defined(_WIN32)|| defined(WINDOWS)
#define PATHSEP '\\'
#else
#define PATHSEP '/'
#endif
##########################################################################
# makefile.unix
#
# This is a makefile to build all the rltiles files needed for Dungeon
# Crawl - Stone Soup.
#
# - Enne (enne.walker@gmail.com)
#
SRC = tool/
B2PSRC = bmp2png/
B2P = bmp2png
B2PTOOL = $(B2PSRC)$(B2P)
CC = cc
DELETE = rm -f
OBJECTS = \
$(SRC)bm.o \
$(SRC)dcpl.o \
$(SRC)dctile.o
TOOLS = \
dcpl \
dctile
EXTRATOOLS = \
dcreverse
HEADERS = \
tiledef.h \
tiledef-p.h \
tilep-cmt.h \
tiledef-w2d.h \
tilecount-w2d.h \
map.htm
ALLTOOLS = $(TOOLS) $(EXTRATOOLS)
TILEBMP = \
tile.bmp \
player.bmp \
wall2d.bmp
TILEPNG = $(TILEBMP:.bmp=.png)
##########################################################################
# Top-level
#
all: tools tiles
tools: $(TOOLS)
tiles: $(TILEBMP) $(TILEPNG)
##########################################################################
# Tools
#
# Note: dcreverse is not built by default. It does the opposite
# of dctile. It takes a bitmap with lots of tiles, specifies regions,
# and cuts them out into smaller pieces. It's useful only for when somebody
# updates the tiles directly and then doesn't give you the source files.
# Not that I'm bitter.
#
depend: $(OBJECTS:.o=.c)
@for i in $^; do \
$(CC) -c $$i
dcpl: $(SRC)dcpl.o $(SRC)bm.o
$(CC) $(SRC)dcpl.o $(SRC)bm.o -o dcpl
dctile: $(SRC)dctile.o $(SRC)bm.o
$(CC) $(SRC)dctile.o $(SRC)bm.o -o dctile
dcreverse: $(SRC)dcreverse.o $(SRC)bm.o
$(CC) $(SRC)dcreverse.o $(SRC)bm.o -o dcreverse
##########################################################################
# Bitmaps
#
# NOTE: the dependencies here aren't fantastic. In an ideal world,
# there would be another tool elf that could read an input text file
# and then output the .bmp and .txt dependencies for it. It's kind
# of a low priority though, as tiles will be rebuilt infrequently.
tile.bmp: dc-2d.txt dctile
./dctile dc-2d.txt
player.bmp: dc-pl.txt dcpl
./dcpl dc-pl.txt
wall2d.bmp: dc-wall2d.txt dctile
./dctile dc-wall2d.txt
##########################################################################
# PNG Conversion
#
$(B2PTOOL):
cd $(B2PSRC) && make -f makefile.lin $(B2P) && cd ..
%.png: %.bmp $(B2PTOOL)
$(DELETE) $@
$(B2PTOOL) -Q $<
##########################################################################
# Cleaning...
#
clean:
$(DELETE) $(OBJECTS)
$(DELETE) $(ALLTOOLS)
cd $(B2PSRC) && make -f makefile.lin clean && cd ..
distclean: clean
$(DELETE) $(TILEBMP)
$(DELETE) $(TILEPNG)
$(DELETE) $(HEADERS)
##########################################################################
# makefile.mgw
#
# This is a makefile to build all the rltiles files needed for Dungeon
# Crawl - Stone Soup.
#
# - Enne (enne.walker@gmail.com)
#
SRC = tool
B2PSRC = bmp2png
B2P = bmp2png.exe
B2PTOOL = $(B2PSRC)\$(B2P)
CC = mingw32-gcc
DELETE = del
MAKE = mingw32-make.exe
OBJECTS = \
$(SRC)\bm.o \
$(SRC)\dcpl.o \
$(SRC)\dctile.o
TOOLS = \
dcpl.exe \
dctile.exe
EXTRATOOLS = \
dcreverse.exe
HEADERS = \
tiledef.h \
tiledef-p.h \
tilep-cmt.h \
tiledef-w2d.h \
tilecount-w2d.h \
map.htm
ALLTOOLS = $(TOOLS) $(EXTRATOOLS)
TILEBMP = \
tile.bmp \
player.bmp \
wall2d.bmp
TILEPNG = $(TILEBMP:.bmp=.png)
##########################################################################
# Top-level
#
all: tools tiles
tools: $(TOOLS)
tiles: $(TILEBMP)
##########################################################################
# Tools
#
# Note: dcreverse is not built by default. It does the opposite
# of dctile. It takes a bitmap with lots of tiles, specifies regions,
# and cuts them out into smaller pieces. It's useful only for when somebody
# updates the tiles directly and then doesn't give you the source files.
#
depend: $(OBJECTS:.o=.c)
@for i in $^; do \
$(CC) -c $$i
dcpl.exe: $(SRC)\dcpl.o $(SRC)\bm.o
$(CC) $(SRC)\dcpl.o $(SRC)\bm.o -o dcpl
dctile.exe: $(SRC)\dctile.o $(SRC)\bm.o
$(CC) $(SRC)\dctile.o $(SRC)\bm.o -o dctile
dcreverse.exe: $(SRC)\dcreverse.o $(SRC)\bm.o
$(CC) $(SRC)\dcreverse.o $(SRC)\bm.o -o dcreverse
##########################################################################
# Bitmaps
#
# NOTE: the dependencies here aren't fantastic. In an ideal world,
# there would be another tool elf that could read an input text file
# and then output the .bmp and .txt dependencies for it. It's kind
# of a low priority though, as tiles will be rebuilt infrequently.
tile.bmp: dc-2d.txt dctile.exe
./dctile dc-2d.txt
player.bmp: dc-pl.txt dcpl.exe
./dcpl dc-pl.txt
wall2d.bmp: dc-wall2d.txt dctile.exe
./dctile dc-wall2d.txt
##########################################################################
# PNG Conversion
#
$(B2PTOOL):
pushd $(B2PSRC) && $(MAKE) -f makefile.mgw $(B2P) && popd
%.png: %.bmp $(B2PTOOL)
$(DELETE) $@
$(B2PTOOL) -Q $<
##########################################################################
# Cleaning...
#
clean:
$(DELETE) $(OBJECTS)
$(DELETE) $(ALLTOOLS)
#pushd $(B2PSRC) && $(MAKE) -f makefile.mgw clean && popd
distclean: clean
$(DELETE) $(TILEBMP)
$(DELETE) $(TILEPNG)
$(DELETE) $(HEADERS)
Part of the graphic tiles used in this program are from the public
domain roguelike tileset "RLTiles".
Some of the tiles have been modified by Enne Walker (enne.walker@gmail.com)
You can find the original tileset at:
http://rltiles.sf.net
Part of the source code used in this program is from the public
domain program "RLTiles".
Some of the source code has been modified by Enne Walker (enne.walker@gmail.com)
You can find the original source code at:
http://sourceforge.net/projects/rltiles/
%enumprefix W2D_
%tiledef tiledef-w2d.h
%tilecount tilecount-w2d.h
%width 16
%back none
%name wall2d
%sdir dc-dngn
wall/brick_brown0 WALL_NORMAL
wall/brick_brown1
wall/brick_brown2
wall/brick_brown3
floor/pebble_gray0 FLOOR_NORMAL
floor/pebble_gray1
floor/pebble_gray2
floor/pebble_gray3
floor/pebble_gray4
wall/relief0 WALL_HALL
wall/relief1
wall/relief2
wall/relief3
floor/mesh0 FLOOR_HALL
floor/mesh1
floor/mesh2
floor/mesh3
wall/hive0 WALL_HIVE
wall/hive1
wall/hive2
wall/hive3
floor/hive0 FLOOR_HIVE
floor/hive1
floor/hive2
floor/hive3
wall/ice0 WALL_ICE
wall/ice1
wall/ice2
wall/ice3
floor/ice0 FLOOR_ICE
floor/ice1
floor/ice2
floor/ice3
wall/lair0 WALL_LAIR
wall/lair1
wall/lair2
wall/lair3
floor/lair0 FLOOR_LAIR
floor/lair1
floor/lair2
floor/lair3
## orcs don't have their own floor or walls yet...
wall/lair0 WALL_ORC
wall/lair1
wall/lair2
wall/lair3
floor/hive0 FLOOR_ORC
floor/hive1
floor/hive2
floor/hive3
wall/slime0 WALL_SLIME
wall/slime1
wall/slime2
wall/slime3
floor/bog_green0 FLOOR_SLIME
floor/bog_green1
floor/bog_green2
floor/bog_green3
wall/snake0 WALL_SNAKE
wall/snake1
wall/snake2
wall/snake3
floor/snake0 FLOOR_SNAKE
floor/snake1
floor/snake2
floor/snake3
## swamp also doesn't have any unique walls...
wall/lair0 WALL_SWAMP
wall/lair1
wall/lair2
wall/lair3
floor/swamp0 FLOOR_SWAMP
floor/swamp1
floor/swamp2
floor/swamp3
wall/tomb0 WALL_TOMB
wall/tomb1
wall/tomb2
wall/tomb3
floor/tomb0 FLOOR_TOMB
floor/tomb1
floor/tomb2
floor/tomb3
wall/undead0 WALL_UNDEAD
wall/undead1
wall/undead2
wall/undead3
floor/tomb0 FLOOR_UNDEAD
floor/tomb1
floor/tomb2
floor/tomb3
wall/vault0 WALL_VAULT
wall/vault1
wall/vault2
wall/vault3
floor/rect_gray0 FLOOR_VAULT
floor/rect_gray1
floor/rect_gray2
floor/rect_gray3
wall/zot_blue0 WALL_ZOT_BLUE
wall/zot_blue1
wall/zot_blue2
wall/zot_blue3
floor/tomb0 FLOOR_ZOT_BLUE
floor/tomb1
floor/tomb2
floor/tomb3
wall/zot_cyan0 WALL_ZOT_CYAN
wall/zot_cyan1
wall/zot_cyan2
wall/zot_cyan3
floor/tomb0 FLOOR_ZOT_CYAN
floor/tomb1
floor/tomb2
floor/tomb3
wall/zot_gray0 WALL_ZOT_GRAY
wall/zot_gray1
wall/zot_gray2
wall/zot_gray3
floor/tomb0 FLOOR_ZOT_GRAY
floor/tomb1
floor/tomb2
floor/tomb3
wall/zot_green0 WALL_ZOT_GREEN
wall/zot_green1
wall/zot_green2
wall/zot_green3
floor/tomb0 FLOOR_ZOT_GREEN
floor/tomb1
floor/tomb2
floor/tomb3
wall/zot_magenta0 WALL_ZOT_MAGENTA
wall/zot_magenta1
wall/zot_magenta2
wall/zot_magenta3
floor/tomb0 FLOOR_ZOT_MAGENTA
floor/tomb1
floor/tomb2
floor/tomb3
wall/zot_red0 WALL_ZOT_RED
wall/zot_red1
wall/zot_red2
wall/zot_red3
floor/tomb0 FLOOR_ZOT_RED
floor/tomb1
floor/tomb2
floor/tomb3
wall/zot_yellow0 WALL_ZOT_YELLOW
wall/zot_yellow1
wall/zot_yellow2
wall/zot_yellow3
floor/tomb0 FLOOR_ZOT_YELLOW
floor/tomb1
floor/tomb2
floor/tomb3
wall/brick_gray0 WALL_BAZAAR_GRAY
wall/brick_gray1
wall/brick_gray2
wall/brick_gray3
wall/stone_gray0 WALL_BAZAAR_STONE
wall/stone_gray1
wall/stone_gray2
wall/stone_gray3
floor/grass0 FLOOR_BAZAAR_GRASS
floor/grass1
floor/grass2
floor/grass_n FLOOR_BAZAAR_GRASS1_SPECIAL
floor/grass_ne
floor/grass_e
floor/grass_se
floor/grass_s
floor/grass_sw
floor/grass_w
floor/grass_nw
floor/grass_full
%start
%compose floor/grass0
%compose floor/pedestal_n
%finish FLOOR_BAZAAR_GRASS2_SPECIAL
%start
%compose floor/grass1
%compose floor/pedestal_ne
%finish
%start
%compose floor/grass2
%compose floor/pedestal_e
%finish
%start
%compose floor/grass1
%compose floor/pedestal_se
%finish
%start
%compose floor/grass0
%compose floor/pedestal_s
%finish
%start
%compose floor/grass1
%compose floor/pedestal_sw
%finish
%start
%compose floor/grass2
%compose floor/pedestal_w
%finish
%start
%compose floor/grass0
%compose floor/pedestal_nw
%finish
floor/pedestal_full
%start
%compose floor/rect_gray0
%compose floor/pedestal_n
%finish FLOOR_BAZAAR_VAULT_SPECIAL
%start
%compose floor/rect_gray1
%compose floor/pedestal_ne
%finish
%start
%compose floor/rect_gray2
%compose floor/pedestal_e
%finish
%start
%compose floor/rect_gray3
%compose floor/pedestal_se
%finish
%start
%compose floor/rect_gray2
%compose floor/pedestal_s
%finish
%start
%compose floor/rect_gray1
%compose floor/pedestal_sw
%finish
%start
%compose floor/rect_gray0
%compose floor/pedestal_w
%finish
%start
%compose floor/rect_gray3
%compose floor/pedestal_nw
%finish
floor/pedestal_full
floor/dirt0 FLOOR_BAZAAR_DIRT
floor/dirt1
floor/dirt2
floor/dirt_n FLOOR_BAZAAR_DIRT_SPECIAL
floor/dirt_ne
floor/dirt_e
floor/dirt_se
floor/dirt_s
floor/dirt_sw
floor/dirt_w
floor/dirt_nw
floor/dirt_full
%sdir item
weapon/urand_bloodbane URAND_BLOODBANE
weapon/urand_fkaming_death URAND_FLAMING_DEATH
weapon/urand_brilliance URAND_BRILLIANCE
weapon/urand_leech URAND_LEECH
weapon/urand_chilly_death URAND_CHILLY_DEATH
weapon/urand_morg URAND_MORG
weapon/urand_finisher URAND_FINISHER
weapon/urand_punk URAND_PUNK
weapon/urand_krishna URAND_KRISHNA
weapon/urand_skullcrusher URAND_SKULLCRUSHER
weapon/urand_guard URAND_GUARD
weapon/urand_jihad URAND_JIHAD
weapon/urand_fiery_devil URAND_FIERY_DEVIL
weapon/urand_doom_knight URAND_DOOM_KNIGHT
weapon/urand_eos URAND_EOS
weapon/urand_voo_doo URAND_VOO_DOO
weapon/urand_octopus_king URAND_OCTOPUS_KING
weapon/urand_arga URAND_ARGA
weapon/urand_elemental URAND_ELEMENTAL
weapon/urand_sniper URAND_SNIPER
weapon/urand_erchidel URAND_ERCHIDEL
weapon/urand_plutonium URAND_PLUTONIUM
weapon/urand_undeadhunter URAND_UNDERADHUNTER
weapon/urand_blowgun URAND_BLOWGUN
armor/urand_ignorance URAND_IGNORANCE
armor/urand_zin URAND_ZIN
armor/urand_augmentation URAND_AUGMENTATION
armor/urand_thief URAND_THIEF
armor/urand_bullseye URAND_BULLSEYE
armor/urand_dyrovepreva URAND_DYROVEPREVA
armor/urand_misfortune URAND_MISFORTUNE
armor/urand_flash URAND_FLASH
armor/urand_assassin URAND_ASSASSIN
armor/urand_lear URAND_LEAR
armor/urand_zhor URAND_ZHOR
armor/urand_salamander URAND_SALAMANDER
armor/urand_war URAND_WAR
armor/urand_resistance URAND_RESISTANCE
armor/urand_folly URAND_FOLLY
armor/urand_edison URAND_EDISON
armor/urand_dragonmask URAND_DRAGONMASK
armor/urand_night URAND_NIGHT
armor/urand_dragon_king URAND_DRAGON_KING
armor/urand_alchemist URAND_ALCHEMIST
armor/urand_fencer URAND_FENCER
ring/urand_shadows URAND_SHADOWS
ring/urand_shaolin URAND_SHAOLIN
ring/urand_robustness URAND_ROBUSTNESS
ring/urand_mage URAND_MAGE
amulet/urand_cekugob URAND_CEKUGOB
amulet/urand_four_winds URAND_FOUR_WINDS
amulet/urand_bloodlust URAND_BLOODLUST
%width 20
%back none
%name player
%rim 1
###BASE
%parts_ctg BASE
%parts_wx 32
%parts_wy 32
%parts_ox 0
%parts_oy 0
%sdir player/base
human_f HUMAN
human_m
elf_f ELF
elf_m
deep_elf_f DEEP_ELF
deep_elf_m
dwarf_f DWARF
dwarf_m
halfling_f HALFLING
halfling_m
orc_f ORC
orc_m
kobold_f KOBOLD
kobold_m
mummy_f MUMMY
mummy_m
naga_f NAGA
naga_m
gnome_f GNOME
gnome_m
ogre_f OGRE
ogre_m
troll_f TROLL
troll_m
ogre_mage_f OGRE_MAGE
ogre_mage_m
draconian_f DRACONIAN
draconian_m
draconian_black_f DRACONIAN_BLACK
draconian_black_m
draconian_gold_f DRACONIAN_GOLD
draconian_gold_m
draconian_gray_f DRACONIAN_GRAY
draconian_gray_m
draconian_green_f DRACONIAN_GREEN
draconian_green_m
draconian_mottled_f DRACONIAN_MOTTLED
draconian_mottled_m
draconian_pale_f DRACONIAN_PALE
draconian_pale_m
draconian_purple_f DRACONIAN_PURPLE
draconian_purple_m
draconian_red_f DRACONIAN_RED
draconian_red_m
draconian_white_f DRACONIAN_WHITE
draconian_white_m
centaur_f CENTAUR
centaur_m
demigod_f DEMIGOD
demigod_m
spriggan_f SPRIGGAN
spriggan_m
minotaur_f MINOTAUR
minotaur_m
demonspawn_f DEMONSPAWN
demonspawn_m
ghoul_f GHOUL
ghoul_m
kenku_f KENKU
kenku_m
merfolk_f MERFOLK
merfolk_m
merfolk_water_f MERFOLK_WATER
merfolk_water_m
vampire_f VAMPIRE
vampire_m
%end
###SHADOW
%parts_ctg SHADOW
%parts_wx 32
%parts_wy 32
%parts_ox 0
%parts_oy 0
%rim 0
shadow
%rim 1
%sdir player/barding
naga_barding NAGA_BARDING
centaur_barding CENTAUR_BARDING
%end
###Cloak
%parts_ctg CLOAK
%parts_wx 32
%parts_wy 32
%parts_ox 0
%parts_oy 0
%sdir player/cloak
red RED
blue BLUE
magenta MAGENTA
yellow YELLOW
black BLACK
gray GRAY
brown LBROWN
green GREEN
cyan CYAN
white WHITE
%end
###Boots
%parts_ctg BOOTS
%parts_wx 16
%parts_wy 16
%parts_ox 8
%parts_oy 16
%sdir player/boot
short_red SHORT_RED
short_purple SHORT_PURPLE
short_brown SHORT_BROWN
short_brown2 SHORT_BROWN2
pj PJ
middle_brown MIDDLE_BROWN
middle_gray MIDDLE_GRAY
middle_ybrown MIDDLE_YBROWN
middle_brown2 MIDDLE_BROWN2
middle_brown3 MIDDLE_BROWN3
middle_gold MIDDLE_GOLD
middle_green MIDDLE_GREEN
middle_purple MIDDLE_PURPLE
long_red LONG_RED
long_white LONG_WHITE
blue_gold BLUE_GOLD
mesh_red MESH_RED
mesh_black MESH_BLACK
mesh_white MESH_WHITE
mesh_blue MESH_BLUE
hooves HOOVES
%end
### Body armour
%parts_ctg LEG
%parts_wx 16
%parts_wy 16
%parts_ox 8
%parts_oy 16
%sdir player/leg
bikini_red BIKINI_RED
loincloth_red LOINCLOTH_RED
belt_redbrown BELT_REDBROWN
belt_gray BELT_GRAY
pants_orange PANTS_ORANGE
pants_short_gray PANTS_SHORT_GRAY
garter
pj PJ
pants_black PANTS_BLACK
pants_blue PANTS_BLUE
pants_darkgreen PANTS_DARKGREEN
pants_brown PANTS_BROWN
pants_short_darkbrown PANTS_SHORT_DARKBROWN
pants_short_brown PANTS_SHORT_BROWN
pants_short_brown3 PANTS_SHORT_BROWN3
trouser_green
pants_l_white
long_red
chunli
pants_red
leg_armor00 METAL_RED
leg_armor01 METAL_SILVER
leg_armor03 METAL_GRAY
leg_armor05 METAL_GREEN
leg_armor04 LEGCHAIN_GRAY
leg_armor02 LEGCHAIN_SILVER
skirt_blue SKIRT_OFS
skirt_green SKIRT_GREEN
skirt_white SKIRT_WHITE
skirt_red
skirt_white2
metal_gray LOWARM1
metal_green LOWARM2
pants16 LOWARM3
%end
### Leg armour
%parts_ctg BODY
%parts_wx 16
%parts_wy 32
%parts_ox 8
%parts_oy 0
%sdir player/body
robe_blue ROBE_BLUE
robe_black ROBE_BLACK
robe_white ROBE_WHITE
robe_red ROBE_RED
robe_purple ROBE_MAGENTA
robe_green ROBE_GREEN
robe_yellow ROBE_YELLOW
robe_brown ROBE_BROWN
robe_cyan ROBE_CYAN
robe_rainbow ROBE_RAINBOW
gandalf_g GANDALF_G
saruman SARUMAN
robe_black_hood ROBE_BLACK_HOOD
monk_blue MONK_BLUE
monk_black MONK_BLACK
dress_green DRESS_GREEN
robe_black_gold ROBE_BLACK_GOLD
robe_white2 ROBE_WHITE2
robe_red2 ROBE_RED2
robe_white_red ROBE_WHITE_RED
robe_white_green ROBE_WHITE_GREEN
robe_blue_white ROBE_BLUE_WHITE
robe_red_gold ROBE_RED_GOLD
robe_black_red ROBE_BLACK_RED
robe_blue_green ROBE_BLUE_GREEN
robe_red3 ROBE_RED3
robe_brown2 ROBE_BROWN2
robe_green_gold ROBE_GREEN_GOLD
robe_brown3 ROBE_BROWN3
robe_gray2 ROBE_GRAY2
dress_white DRESS_WHITE
arwen ARWEN
skirt_onep_grey SKIRT_ONEP_GREY
bloody BLOODY
leather_short LEATHER_SHORT
china_red2 CHINA_RED2
animal_skin ANIMAL_SKIN
zhor ZHOR
neck NECK
belt1 BELT1
belt2 BELT2
susp_black SUSP_BLACK
shoulder_pad SHOULDER_PAD
mesh_black MESH_BLACK
mesh_red MESH_RED
leather_jacket LEATHER_JACKET
shirt_white1 SHIRT_WHITE1
shirt_white2 SHIRT_WHITE2
shirt_white3 SHIRT_WHITE3
shirt_blue SHIRT_BLUE
bikini_red BIKINI_RED
shirt_hawaii SHIRT_HAWAII
china_red CHINA_RED
leather_red LEATHER_RED
chunli CHUNLI
shirt_white_yellow SHIRT_WHITE_YELLOW
shirt_check SHIRT_CHECK
jessica JESSICA
slit_black SLIT_BLACK
leather_armour LEATHER_ARMOUR
leather_green LEATHER_GREEN
shirt_black SHIRT_BLACK
shirt_black_and_cloth SHIRT_BLACK_AND_CLOTH
shirt_black3 SHIRT_BLACK3
leather2 LEATHER2
coat_red COAT_RED
coat_black COAT_BLACK
leather_armour2 LEATHER_ARMOUR2
leather_armour3 LEATHER_ARMOUR3
shirt_vest SHIRT_VEST
karate KARATE
karate2 KARATE2
leather_heavy LEATHER_HEAVY
troll_hide TROLL_HIDE
green_chain GREEN_CHAIN
metal_blue METAL_BLUE
green_susp GREEN_SUSP
jacket2 JACKET2
jacket3 JACKET3
leather_stud LEATHER_STUD
jacket_stud JACKET_STUD
chainmail CHAINMAIL2
half_plate HALF_PLATE
half_plate2 HALF_PLATE2
half_plate3 HALF_PLATE3
breast_black BREAST_BLACK
vest_red VEST_RED
vest_red2 VEST_RED2
bplate_green BPLATE_GREEN
bplate_metal1 BPLATE_METAL1
banded BANDED2
banded2 SPLINT
armor_blue_gold
ringmail RINGMAIL
chainmail3 CHAINMAIL
plate_and_cloth PLATE_AND_CLOTH
plate_and_cloth2 PLATE_AND_CLOTH2
scalemail SCALEMAIL2
scalemail2 SCALEMAIL
leather_metal BANDED
plate PLATE2
plate2 PLATE
plate_black PLATE_BLACK
crystal_plate CRYSTAL_PLATE
armor_mummy ARMOR_MUMMY
##cloth_u_sail SAILOR
dragonsc_green DRAGONSC_GREEN
dragonsc_white DRAGONSC_WHITE
dragonsc_magenta DRAGONSC_MAGENTA
dragonsc_cyan DRAGONSC_CYAN
dragonsc_brown DRAGONSC_BROWN
dragonsc_blue DRAGONSC_BLUE
dragonsc_gold DRAGONSC_GOLD
dragonarm_green DRAGONARM_GREEN
dragonarm_white DRAGONARM_WHITE
dragonarm_magenta DRAGONARM_MAGENTA
dragonarm_cyan DRAGONARM_CYAN
dragonarm_brown DRAGONARM_BROWN
dragonarm_blue DRAGONARM_BLUE
dragonarm_gold DRAGONARM_GOLD
aragorn ARAGORN
aragorn2 ARAGORN2
boromir BOROMIR
frodo FRODO
gimli GIMLI
legolas LEGOLAS
merry MERRY
pipin PIPIN
gil-galad
isildur
pj PJ
sam SAM
vanhel1
edison EDISON
lears_chain_mail LEARS_CHAIN_MAIL
robe_of_night ROBE_OF_NIGHT
%end
### Arms
%parts_ctg ARM
%parts_wx 32
%parts_wy 16
%parts_ox 0
%parts_oy 8
%sdir player/arm
glove_red GLOVE_RED
glove_gray GLOVE_GRAY
glove_white GLOVE_WHITE
glove_blue GLOVE_BLUE
glove_black GLOVE_BLACK
glove_orange GLOVE_ORANGE
glove_brown GLOVE_BROWN
glove_black2 GLOVE_BLACK2
glove_grayfist GLOVE_GRAYFIST
glove_purple GLOVE_PURPLE
glove_wrist_purple GLOVE_WRIST_PURPLE
glove_chunli GLOVE_CHUNLI
gauntlet_blue GAUNTLET_BLUE
glove_gold GLOVE_GOLD
glove_short_yellow GLOVE_SHORT_YELLOW
glove_short_red GLOVE_SHORT_RED
glove_short_white GLOVE_SHORT_WHITE
glove_short_green GLOVE_SHORT_GREEN
glove_short_blue GLOVE_SHORT_BLUE
glove_short_gray GLOVE_SHORT_GRAY
claws CLAWS
%end
# Hand 1
%parts_ctg HAND1
%parts_wx 16
%parts_wy 32
%parts_ox 0
%parts_oy 0
%sdir player/hand1
# blades
dagger DAGGER
dagger_slant DAGGER_SLANT
short_sword SHORT_SWORD
short_sword_slant SHORT_SWORD_SLANT
short_sword2 SHORT_SWORD2
sword_thief SWORD_THIEF
long_sword LONG_SWORD
long_sword_slant LONG_SWORD_SLANT
blessed_blade BLESSED_BLADE
great_sword GREAT_SWORD
great_sword_slant GREAT_SWORD_SLANT
katana KATANA
katana_slant KATANA_SLANT
scimitar SCIMITAR
falchion FALCHION
double_sword DOUBLE_SWORD
triple_sword TRIPLE_SWORD
sword2 SWORD2
sword_tri SWORD_TRI
broadsword BROADSWORD
black_sword BLACK_SWORD
sword_black SWORD_BLACK
sword_twist SWORD_TWIST
knife KNIFE
sword_seven SWORD_SEVEN
heavy_sword HEAVY_SWORD
sabre SABRE
sword3 SWORD3
sword_breaker SWORD_BREAKER
sword_jag SWORD_JAG
###Artifacts
bloodbane BLOODBANE
chilly_death CHILLY_DEATH
doom_knight DOOM_KNIGHT
flaming_death FLAMING_DEATH
leech LEECH
morg MORG
plutonium_sword PLUTONIUM_SWORD
jihad JIHAD
singing_sword SINGING_SWORD
zonguldrok ZONGULDROK
## blunt
club CLUB
club_slant CLUB_SLANT
club2 CLUB2
club3 CLUB3
stick STICK
giant_club GIANT_CLUB
giant_club_slant GIANT_CLUB_SLANT
giant_club_spike GIANT_CLUB_SPIKE
giant_club_spike_slant GIANT_CLUB_SPIKE_SLANT
whip WHIP
sceptre SCEPTRE
mace MACE2
mace3 MACE
mace2 GREAT_MACE
mace_ruby MACE_RUBY
morningstar MORNINGSTAR2
morningstar2 MORNINGSTAR
eveningstar EVENINGSTAR
large_mace LARGE_MACE
black_whip BLACK_WHIP
hammer3 HAMMER
hammer HAMMER1
hammer2 HAMMER2
frail_stick FRAIL_STICK
frail_ball FRAIL
frail_spike SPIKED_FRAIL
frail_stick_slant GREAT_FRAIL
frail_ball2 FRAIL_BALL2
frail_balls FRAIL_BALLS
frail_ball3 FRAIL_BALL3
frail_ball4 FRAIL_BALL4
nunchaku NUNCHAKU
mace_of_variability MACE_OF_VARIABILITY
## polearms
spear1 SPEAR
spear2 SPEAR2
spear3 SPEAR3
spear4 SPEAR4
spear5 SPEAR5
hook HOOK
halberd HALBERD
pick_axe PICK_AXE
trident TRIDENT
trident_demon DEMON_TRIDENT
trident_elec TRIDENT_ELEC
trident2 TRIDENT2
trident3 TRIDENT3
lance LANCE
lance2 LANCE2
scythe SCYTHE
scythe_slant SCYTHE_SLANT
pike PIKE
quarterstaff1 QUARTERSTAFF1
quarterstaff2 QUARTERSTAFF2
quarterstaff3 QUARTERSTAFF3
quarterstaff4 QUARTERSTAFF4
sickle SICKLE
glaive GLAIVE
glaive2 GLAIVE2
glaive3 GLAIVE3
d_glaive D_GLAIVE
pole_forked POLE_FORKED
fork2 FORK2
glaive_of_prune GLAIVE_OF_PRUNE
voodoo VOODOO
finisher FINISHER
## staves
staff_skull STAFF_SKULL
staff_mage STAFF_MAGE
staff_mage2 STAFF_MAGE2
great_staff GREAT_STAFF
staff_evil STAFF_EVIL
staff_ring_blue STAFF_RING_BLUE
staff_mummy STAFF_MUMMY
staff_fork STAFF_FORK
staff_ruby STAFF_RUBY
staff_large STAFF_LARGE
elemental_staff ELEMENTAL_STAFF
asmodeus ASMODEUS
dispater DISPATER
olgreb OLGREB
## axes
axe_small AXE_SMALL
hand_axe HAND_AXE
war_axe WAR_AXE
great_axe BROAD_AXE
axe BATTLEAXE
axe_executioner EXECUTIONERS_AXE
axe_double AXE_DOUBLE
axe_blood AXE_BLOOD
axe_short AXE_SHORT
axe_trog AXE_TROG
arga ARGA
## launchers
sling SLING
bow BOW
bow2 BOW2
bow3 BOW3
great_bow GREAT_BOW
bow_blue BOW_BLUE
crossbow CROSSBOW
crossbow2 CROSSBOW2
crossbow3 CROSSBOW3
crossbow4 CROSSBOW4
blowgun BLOWGUN
punk PUNK
sniper SNIPER
crossbow_fire FIERY_DEVIL
krishna KRISHNA
##missiles
dirt DIRT
## misc
bone_lantern BONE_LANTERN
fan FAN
bottle BOTTLE
box BOX
crystal CRYSTAL
deck DECK
disc DISC
horn HORN
lantern LANTERN
orb ORB
stone STONE
fire_red FIRE_RED
fire_blue FIRE_BLUE
skull SKULL
head HEAD
fire_green FIRE_GREEN
fire_cyan FIRE_CYAN
fire_white FIRE_WHITE
light_blue LIGHT_BLUE
light_red LIGHT_RED
light_yellow LIGHT_YELLOW
spark SPARK
fire_dark FIRE_DARK
fire_white2 FIRE_WHITE2
## lotr
aragorn ARAGORN
arwen ARWEN
boromir BOROMIR
frodo FRODO
gandalf GANDALF
gimli GIMLI
legolas LEGOLAS
saruman SARUMAN
bladehands BLADEHAND
%end
### Hand 2
%parts_ctg HAND2
%parts_wx 16
%parts_wy 32
%parts_ox 16
%parts_oy 0
%sdir player/hand2
shield_round_small SHIELD_ROUND_SMALL
shield_round_small2 SHIELD_ROUND_SMALL2
bullseye BULLSEYE
shield_middle_round SHIELD_MIDDLE_ROUND
shield_skull SHIELD_SKULL
shield_round_white SHIELD_ROUND_WHITE
boromir BOROMIR
shield_round1 SHIELD_ROUND1
shield_round2 SHIELD_ROUND2
shield_round3 SHIELD_ROUND3
shield_round4 SHIELD_ROUND4
shield_round5 SHIELD_ROUND5
shield_round6 SHIELD_ROUND6
shield_round7 SHIELD_ROUND7
shield_knight_blue SHIELD_KNIGHT_BLUE
shield_knight_gray SHIELD_KNIGHT_GRAY
shield_knight_rw SHIELD_KNIGHT_RW
shield_middle_unicorn SHIELD_MIDDLE_UNICORN
shield_kite1 SHIELD_KITE1
shield_kite2 SHIELD_KITE2
shield_kite3 SHIELD_KITE3
shield_kite4 SHIELD_KITE4
shield_long_red SHIELD_LONG_RED
shield_middle_gray SHIELD_MIDDLE_GRAY
shield_diamond_yellow SHIELD_DIAMOND_YELLOW
shield_middle_brown SHIELD_MIDDLE_BROWN
shield_middle_black SHIELD_MIDDLE_BLACK
shield_middle_cyan SHIELD_MIDDLE_CYAN
shield_middle_ethn SHIELD_MIDDLE_ETHN
shield_long_cross SHIELD_LONG_CROSS
shield_shaman SHIELD_SHAMAN
shield_of_resistance SHIELD_OF_RESISTANCE
gil-galad
book_black BOOK_BLACK
book_blue BOOK_BLUE
book_red BOOK_RED
book_magenta BOOK_MAGENTA
book_green BOOK_GREEN
book_cyan BOOK_CYAN
book_yellow BOOK_YELLOW
book_white BOOK_WHITE
book_sky BOOK_SKY
book_blue_dim BOOK_BLUE_DIM
book_cyan_dim BOOK_CYAN_DIM
book_green_dim BOOK_GREEN_DIM
book_magenta_dim BOOK_MAGENTA_DIM
book_red_dim BOOK_RED_DIM
book_yellow_dim BOOK_YELLOW_DIM
fire_green FIRE_GREEN
fire_cyan FIRE_CYAN
fire_white FIRE_WHITE
light_blue LIGHT_BLUE
light_red LIGHT_RED
light_yellow LIGHT_YELLOW
spark SPARK
fire_dark FIRE_DARK
fire_white2 FIRE_WHITE2
lantern LANTERN
torch TORCH
pj PJ
torsh2 TORCH2
bladehands BLADEHAND
dagger DAGGER
sabre SABRE
short_sword_slant SHORT_SWORD_SLANT
%end
###Hair
%parts_ctg HAIR
%parts_wx 16
%parts_wy 16
%parts_ox 8
%parts_oy 0
%sdir player/hair
short_black SHORT_BLACK
short_red SHORT_RED
short_yellow SHORT_YELLOW
short_white SHORT_WHITE
long_black LONG_BLACK
long_red LONG_RED
long_yellow LONG_YELLOW
long_white LONG_WHITE
fem_black FEM_BLACK
fem_red FEM_RED
fem_yellow FEM_YELLOW
fem_white FEM_WHITE
elf_black ELF_BLACK
elf_red ELF_RED
elf_yellow ELF_YELLOW
elf_white ELF_WHITE
aragorn ARAGORN
arwen ARWEN
boromir BOROMIR
frodo FRODO
legolas LEGOLAS
merry MERRY
pj PJ
sam SAM
pigtail_red PIGTAIL_RED
brown1 BROWN1
brown2 BROWN2
%end
###Beard
%parts_ctg BEARD
%parts_wx 16
%parts_wy 16
%parts_ox 8
%parts_oy 0
%sdir player/beard
short_black SHORT_BLACK
short_red SHORT_RED
short_yellow SHORT_YELLOW
short_white SHORT_WHITE
long_black LONG_BLACK
long_red LONG_RED
long_yellow LONG_YELLOW
long_white LONG_WHITE
pj PJ
%end
###Helms
%parts_ctg HELM
%parts_wx 16
%parts_wy 16
%parts_ox 8
%parts_oy 0
%sdir player/head
cone_blue HAT_OFS
cone_red CORN_RED
straw STRAW
wizard_blue WIZARD_BLUE
cap_blue CAP_BLUE
bandana_ybrown BANDANA_YBROWN
hat_black HAT_BLACK
gandalf GANDALF
crown_gold
cap_black1
clown1
feather_green FEATHER_GREEN
feather_red FEATHER_RED
feather_blue FEATHER_BLUE
feather_yellow FEATHER_YELLOW
feather_white FEATHER_WHITE
band_white
band_red
band_yellow
band_blue
band_magenta
taiso_blue
taiso_magenta
taiso_yellow
taiso_red
taiso_white
dyrovepreva DYROVEPREVA
wizard_purple WIZARD_PURPLE
wizard_bluegreen WIZARD_BLUEGREEN
wizard_darkgreen WIZARD_DARKGREEN
wizard_brown WIZARD_BROWN
wizard_blackgold WIZARD_BLACKGOLD
wizard_blackred WIZARD_BLACKRED
wizard_red WIZARD_RED
wizard_white WIZARD_WHITE
turban_white TURBAN_WHITE
turban_brown TURBAN_BROWN
turban_purple TURBAN_PURPLE
horns1 HORNS1
horns2 HORNS2
horns3 HORNS3
iron1 HELM_OFS
helm_red HELM_RED
horned HELM_HORNED
helm_gimli HELM_GIMLI
helm_green HELM_GREEN
cheek_red
iron_red IRON_RED
blue_horn_gold BLUE_HORN_GOLD
hood_white WHITE
yellow_wing YELLOW_WING
brown_gold BROWN_GOLD
black_horn BLACK_HORN
full_gold FULL_GOLD
chain CHAIN
black_horn2 FHELM_OFS
full_black FHELM_BLACK
horn_gray FHELM_HORN_GRAY
iron2 FHELM_GRAY
iron3 FHELM_GRAY2
fhelm_gray3 FHELM_GRAY3
fhelm_horn_yellow FHELM_HORN_YELLOW
fhelm_horn2 FHELM_HORN2
horn_evil FHELM_EVIL
helm_plume FHELM_PLUME
mummy FHELM_MUMMY
isildur FHELM_ISILDUR
art_dragonhelm ART_DRAGONHELM
healer FHELM_HEALER
hood_gray HOOD_GRAY
hood_red HOOD_RED
hood_green2 HOOD_GREEN2
hood_cyan HOOD_CYAN
hood_orange HOOD_ORANGE
hood_red2 HOOD_RED2
hood_black2 HOOD_BLACK2
hood_white2 HOOD_WHITE2
hood_ybrown HOOD_YBROWN
hood_green HOOD_GREEN
ninja_black MASK_NINJA_BLACK
%end
%parts_ctg DRCWING
%parts_wx 32
%parts_wy 16
%parts_ox 0
%parts_oy 0
%sdir player/drcwing
drcwing_brown BROWN
drcwing_black BLACK
drcwing_yellow YELLOW
drcwing_grey GREY
drcwing_green GREEN
drcwing_mottled MOTTLED
drcwing_pale PALE
drcwing_purple PURPLE
drcwing_red RED
drcwing_white WHITE
%end
%parts_ctg DRCHEAD
%parts_wx 16
%parts_wy 16
%parts_ox 8
%parts_oy 0
%sdir player/drchead
drchead_brown BROWN
drchead_black BLACK
drchead_yellow YELLOW
drchead_grey GREY
drchead_green GREEN
drchead_mottled MOTTLED
drchead_pale PALE
drchead_purple PURPLE
drchead_red RED
drchead_white WHITE
%end
%subst large_mimic
%sdir dc-mon
%rim 0
shadow MONS_SHADOW /*' '*/
%rim 1
earth_elemental MONS_EARTH_ELEMENTAL /*'#'*/
fire_elemental MONS_FIRE_ELEMENTAL /*'#'*/
%rim 0
vapour MONS_VAPOUR /*'#'*/
%rim 1
#item/gem/gold_piece MONS_GOLD_MIMIC /*(YELLOW) An apparently harmless pile of gold coins hides a nasty venomous shapechanging predator.
death_cob MONS_DEATH_COB /*'%'*/
## Arch demons
asmodeus MONS_ASMODEUS /*'&'*/
cerebov MONS_CEREBOV /*'&'*/
dispater MONS_DISPATER /*'&'*/
ereshkigal MONS_ERESHKIGAL /*'&'*/
geryon MONS_GERYON /*'&'*/
gloorx_vloq MONS_GLOORX_VLOQ /*'&'*/
lom_lobon MONS_LOM_LOBON /*'&'*/
mnoleg MONS_MNOLEG /*'&'*/
pandemonium_demon MONS_PANDEMONIUM_DEMON /*'&'*/
#item/weapon/halberd MONS_DANCING_WEAPON /*'('(BLACK) A weapon dancing in the air.
#weapon_mimic MONS_WEAPON_MIMIC /*')'(BLACK) An apparently abandoned weapon, actually a vicious little beast in disguise.
ball_lightning MONS_BALL_LIGHTNING /*'*'*/
%rim 0
orb_of_fire MONS_ORB_OF_FIRE /*'*'*/
%rim 1
## Demons 1-5
balrug MONS_BALRUG /*'1'*/
blue_death MONS_BLUE_DEATH /*'1'*/
cacodemon MONS_CACODEMON /*'1'*/
executioner MONS_EXECUTIONER /*'1'*/
fiend MONS_FIEND /*'1'*/
green_death MONS_GREEN_DEATH /*'1'*/
ice_fiend MONS_ICE_FIEND /*'1'*/
pit_fiend MONS_PIT_FIEND /*'1'*/
shadow_fiend MONS_SHADOW_FIEND /*'1'*/
ice_devil MONS_ICE_DEVIL /*'2'*/
lorocyproca MONS_LOROCYPROCA /*'2'*/
reaper MONS_REAPER /*'2'*/
soul_eater MONS_SOUL_EATER /*'2'*/
sun_demon MONS_SUN_DEMON /*'2'*/
blue_devil MONS_BLUE_DEVIL /*'3'*/
demonic_crawler MONS_DEMONIC_CRAWLER /*'3'*/
hellion MONS_HELLION /*'3'*/
hellwing MONS_HELLWING /*'3'*/
iron_devil MONS_IRON_DEVIL /*'3'*/
neqoxec MONS_NEQOXEC /*'3'*/
orange_demon MONS_ORANGE_DEMON /*'3'*/
shadow_demon MONS_SHADOW_DEMON /*'3'*/
tormentor MONS_TORMENTOR /*'3'*/
ynoxinul MONS_YNOXINUL /*'3'*/
beast MONS_BEAST /*'4'*/
hairy_devil MONS_HAIRY_DEVIL /*'4'*/
red_devil MONS_RED_DEVIL /*'4'*/
rotting_devil MONS_ROTTING_DEVIL /*'4'*/
smoke_demon MONS_SMOKE_DEMON /*'4'*/
imp MONS_IMP /*'5'*/
lemure MONS_LEMURE /*'5'*/
manes MONS_MANES /*'5'*/
midge MONS_MIDGE /*'5'*/
shadow_imp MONS_SHADOW_IMP /*'5'*/
ufetubus MONS_UFETUBUS /*'5'*/
white_imp MONS_WHITE_IMP /*'5'*/
## Golems
clay_golem MONS_CLAY_GOLEM /*'8'*/
crystal_golem MONS_CRYSTAL_GOLEM /*'8'*/
%rim 0
electric_golem MONS_ELECTRIC_GOLEM /*'8'*/
%rim 1
iron_golem MONS_IRON_GOLEM /*'8'*/
stone_golem MONS_STONE_GOLEM /*'8'*/
toenail_golem MONS_TOENAIL_GOLEM /*'8'*/
wood_golem MONS_WOOD_GOLEM /*'8'*/
## Aquatics
big_fish MONS_BIG_FISH /*';'*/
electrical_eel MONS_ELECTRICAL_EEL /*';'*/
giant_goldfish MONS_GIANT_GOLDFISH /*';'*/
lava_fish MONS_LAVA_FISH /*';'*/
#scroll_mimic MONS_SCROLL_MIMIC /*'?'(LIGHTGREY) An ancient parchment covered in arcane runes. Did it just twitch?
## Humans
%subst asc/ch40
shapeshifter MONS_SHAPESHIFTER /*'@'*/
glowing_shapeshifter MONS_GLOWING_SHAPESHIFTER /*'@'*/
killer_klown MONS_KILLER_KLOWN /*'@'*/
vault_guard0 MONS_VAULT_GUARD /*'@'*/
hell_knight MONS_HELL_KNIGHT /*'@'*/
necromancer MONS_NECROMANCER /*'@'*/
wizard MONS_WIZARD /*'@'*/
human MONS_HUMAN /*'@'*/
## Unique human NO_SPELLS first
terence0 MONS_TERENCE /*'@'*/
edmund0 MONS_EDMUND /*'@'*/
donald MONS_DONALD /*'@'*/
joseph0 MONS_JOSEPH /*'@'*/
norbert MONS_NORBERT /*'@'*/
agnes MONS_AGNES /*'@'*/
maud0 MONS_MAUD /*'@'*/
adolf MONS_ADOLF /*'@'*/
duane0 MONS_DUANE /*'@'*/
frances0 MONS_FRANCES /*'@'*/
harold0 MONS_HAROLD /*'@'*/
jozef0 MONS_JOZEF /*'@'*/
norris2 MONS_NORRIS /*'@'*/
rupert0 MONS_RUPERT /*'@'*/
sigmund MONS_SIGMUND /*'@'*/
wayne0 MONS_WAYNE /*'@'*/
josephine MONS_JOSEPHINE /*'@'*/
erica MONS_ERICA /*'@'*/
francis MONS_FRANCIS /*'@'*/
jessica MONS_JESSICA /*'@'*/
louise MONS_LOUISE /*'@'*/
margery MONS_MARGERY /*'@'*/
michael MONS_MICHAEL /*'@'*/
psyche MONS_PSYCHE /*'@'*/
frederick MONS_FREDERICK
##Angels
angel MONS_ANGEL /*'A'*/
daeva MONS_DAEVA /*'A'*/
####nh-mon0/m/large_mimic MONS_SHUGGOTH /*'A'(LIGHTGREEN) A vile creature with an elongated head, spiked tail and wicked six-fingered claws. Its awesome strength is matched by its umbrage at being transported to this backwater dimension.
## Beetles
%subst asc/ch42
boring_beetle MONS_BORING_BEETLE /*'B'*/
boulder_beetle MONS_BOULDER_BEETLE /*'B'*/
giant_beetle MONS_GIANT_BEETLE /*'B'*/
program_bug MONS_PROGRAM_BUG /*'B'*/
## Giants
antaeus MONS_ANTAEUS /*'C'*/
cyclops MONS_CYCLOPS /*'C'*/
ettin MONS_ETTIN /*'C'*/
fire_giant MONS_FIRE_GIANT /*'C'*/
frost_giant MONS_FROST_GIANT /*'C'*/
hill_giant MONS_HILL_GIANT /*'C'*/
stone_giant MONS_STONE_GIANT /*'C'*/
titan MONS_TITAN /*'C'*/
polyphemus MONS_POLYPHEMUS
## Dragons
%subst asc/ch44
dragon MONS_DRAGON /*'D'*/
golden_dragon MONS_GOLDEN_DRAGON /*'D'*/
hydra1 MONS_HYDRA /*'D'*/
hydra2 MONS_HYDRA2
hydra3 MONS_HYDRA3
hydra4 MONS_HYDRA4
hydra5 MONS_HYDRA5
hydra5 MONS_HYDRA6
hydra5 MONS_HYDRA7
ice_dragon MONS_ICE_DRAGON /*'D'*/
iron_dragon MONS_IRON_DRAGON /*'D'*/
quicksilver_dragon MONS_QUICKSILVER_DRAGON /*'D'*/
serpent_of_hell MONS_SERPENT_OF_HELL /*'D'*/
shadow_dragon MONS_SHADOW_DRAGON /*'D'*/
skeletal_dragon MONS_SKELETAL_DRAGON /*'D'*/
storm_dragon MONS_STORM_DRAGON /*'D'*/
swamp_dragon MONS_SWAMP_DRAGON /*'D'*/
tiamat MONS_TIAMAT
wyvern MONS_WYVERN /*'D'*/
xtahua MONS_XTAHUA /*'D'*/
## Efreet only
efreet MONS_EFREET /*'E'*/
## Frogs
%subst asc/ch46
%rim 0
blink_frog MONS_BLINK_FROG /*'F'*/
%rim 1
giant_brown_frog MONS_GIANT_BROWN_FROG /*'F'*/
giant_frog MONS_GIANT_FROG /*'F'*/
spiny_frog MONS_SPINY_FROG /*'F'*/
## Eyes
%subst asc/ch47
eye_of_devastation MONS_EYE_OF_DEVASTATION /*'G'*/
eye_of_draining MONS_EYE_OF_DRAINING /*'G'*/
giant_eyeball MONS_GIANT_EYEBALL /*'G'*/
giant_orange_brain MONS_GIANT_ORANGE_BRAIN /*'G'*/
giant_spore MONS_GIANT_SPORE /*'G'*/
great_orb_of_eyes MONS_GREAT_ORB_OF_EYES /*'G'*/
shining_eye MONS_SHINING_EYE /*'G'*/
## Hybrids
%subst asc/ch48
griffon MONS_GRIFFON /*'H'*/
hippogriff MONS_HIPPOGRIFF /*'H'*/
sphinx MONS_SPHINX /*'H'*/
## Ice beast only
ice_beast MONS_ICE_BEAST /*'I'*/
## Jellies
%subst asc/ch4a
acid_blob MONS_ACID_BLOB /*'J'*/
azure_jelly MONS_AZURE_JELLY /*'J'*/
brown_ooze MONS_BROWN_OOZE /*'J'*/
death_ooze MONS_DEATH_OOZE /*'J'*/
giant_amoeba MONS_GIANT_AMOEBA /*'J'*/
jelly MONS_JELLY /*'J'*/
jellyfish MONS_JELLYFISH /*'J'*/
ooze MONS_OOZE /*'J'*/
pulsating_lump MONS_PULSATING_LUMP /*'J'*/
royal_jelly MONS_ROYAL_JELLY /*'J'*/
slime_creature MONS_SLIME_CREATURE /*'J'*/
## Kobolds
%subst asc/ch4b
big_kobold MONS_BIG_KOBOLD /*'K'*/
kobold MONS_KOBOLD /*'K'*/
kobold_demonologist MONS_KOBOLD_DEMONOLOGIST /*'K'*/
## Liches
%subst asc/ch4c
ancient_lich MONS_ANCIENT_LICH /*'L'*/
boris MONS_BORIS /*'L'*/
lich MONS_LICH /*'L'*/
## Mummies
%subst asc/ch4d
greater_mummy MONS_GREATER_MUMMY /*'M'*/
guardian_mummy MONS_GUARDIAN_MUMMY /*'M'*/
mummy MONS_MUMMY /*'M'*/
mummy_priest MONS_MUMMY_PRIEST /*'M'*/
## Nagas
%subst asc/ch4e
naga0 MONS_NAGA /*'N'*/
greater_naga0 MONS_GREATER_NAGA /*'N'*/
naga_warrior0 MONS_NAGA_WARRIOR /*'N'*/
guardian_naga MONS_GUARDIAN_NAGA /*'N'*/
naga_mage MONS_NAGA_MAGE /*'N'*/
%subst asc/ch4f
erolcha MONS_EROLCHA /*'O'*/
ogre MONS_OGRE /*'O'*/
ogre_mage MONS_OGRE_MAGE /*'O'*/
two_headed_ogre MONS_TWO_HEADED_OGRE /*'O'*/
%subst asc/ch50
oklob_plant MONS_OKLOB_PLANT /*'P'*/
plant MONS_PLANT /*'P'*/
%subst asc/ch51
queen_ant MONS_QUEEN_ANT /*'Q'*/
queen_bee MONS_QUEEN_BEE /*'Q'*/
%subst asc/ch52
rakshasa MONS_RAKSHASA /*'R'*/
rakshasa_fake MONS_RAKSHASA_FAKE /*'R'*/
%subst asc/ch53
black_snake MONS_BLACK_SNAKE /*'S'*/
brown_snake MONS_BROWN_SNAKE /*'S'*/
grey_snake MONS_GREY_SNAKE /*'S'*/
lava_snake MONS_LAVA_SNAKE /*'S'*/
salamander MONS_SALAMANDER /*'S'*/
small_snake MONS_SMALL_SNAKE /*'S'*/
snake MONS_SNAKE /*'S'*/
yellow_snake MONS_YELLOW_SNAKE /*'S'*/
%subst asc/ch54
deep_troll MONS_DEEP_TROLL /*'T'*/
iron_troll MONS_IRON_TROLL /*'T'*/
rock_troll MONS_ROCK_TROLL /*'T'*/
snorg MONS_SNORG /*'T'*/
troll MONS_TROLL /*'T'*/
%subst asc/ch55
bear MONS_BEAR /*'U'*/
black_bear MONS_BLACK_BEAR /*'U'*/
grizzly_bear MONS_GRIZZLY_BEAR /*'U'*/
polar_bear MONS_POLAR_BEAR /*'U'*/
%subst asc/ch56
vampire MONS_VAMPIRE /*'V'*/
vampire_knight MONS_VAMPIRE_KNIGHT /*'V'*/
vampire_mage MONS_VAMPIRE_MAGE /*'V'*/
%subst asc/ch57
freezing_wraith MONS_FREEZING_WRAITH /*'W'*/
shadow_wraith MONS_SHADOW_WRAITH /*'W'*/
spectral_thing MONS_SPECTRAL_THING /*'W'*/
spectral_warrior MONS_SPECTRAL_WARRIOR /*'W'*/
wight MONS_WIGHT /*'W'*/
wraith MONS_WRAITH /*'W'*/
%subst asc/ch58
abomination_large MONS_ABOMINATION_LARGE /*'X'*/
abomination_large1
abomination_large2
abomination_large3
abomination_large4
abomination_large5
abomination_large6
orb_guardian MONS_ORB_GUARDIAN /*'X'*/
tentacled_monstrosity MONS_TENTACLED_MONSTROSITY /*'X'*/
%subst asc/ch59
death_yak MONS_DEATH_YAK /*'Y'*/
sheep MONS_SHEEP /*'Y'*/
yak MONS_YAK /*'Y'*/
%subst asc/ch5a
simulacrum_large MONS_SIMULACRUM_LARGE /*'Z'*/
skeleton_large MONS_SKELETON_LARGE /*'Z'*/
zombie_large MONS_ZOMBIE_LARGE /*'Z'*/
#armour_mimic MONS_ARMOUR_MIMIC /*'['(BLACK) An apparently abandoned suit of finely-made armour, actually a vicious little beast in disguise.
%subst asc/ch61
giant_ant MONS_GIANT_ANT /*'a'*/
giant_cockroach MONS_GIANT_COCKROACH /*'a'*/
soldier_ant MONS_SOLDIER_ANT /*'a'*/
%subst asc/ch62
butterfly MONS_BUTTERFLY /*'b'*/
butterfly1
butterfly2
butterfly3
butterfly4
butterfly5
butterfly6
giant_bat MONS_GIANT_BAT /*'b'*/
%subst asc/ch63
centaur MONS_CENTAUR /*'c'*/
centaur_warrior MONS_CENTAUR_WARRIOR /*'c'*/
yaktaur MONS_YAKTAUR /*'c'*/
yaktaur_captain MONS_YAKTAUR_CAPTAIN /*'c'*/
%subst asc/ch64
firedrake MONS_FIREDRAKE /*'d'*/
lindwurm MONS_LINDWURM /*'d'*/
mottled_dragon MONS_MOTTLED_DRAGON /*'d'*/
steam_dragon MONS_STEAM_DRAGON /*'d'*/
swamp_drake MONS_SWAMP_DRAKE /*'d'*/
death_drake MONS_DEATH_DRAKE /*'d'*/
%subst asc/ch65
elf MONS_ELF /*'e'*/
deep_elf_fighter0 MONS_DEEP_ELF_FIGHTER /*'e'*/
deep_elf_soldier0 MONS_DEEP_ELF_SOLDIER /*'e'*/
deep_elf_knight0 MONS_DEEP_ELF_KNIGHT /*'e'*/
deep_elf_mage MONS_DEEP_ELF_MAGE /*'e'*/
deep_elf_sorcerer MONS_DEEP_ELF_SORCERER /*'e'*/
deep_elf_conjurer MONS_DEEP_ELF_CONJURER /*'e'*/
deep_elf_death_mage MONS_DEEP_ELF_DEATH_MAGE /*'e'*/
deep_elf_demonologist MONS_DEEP_ELF_DEMONOLOGIST /*'e'*/
deep_elf_summoner MONS_DEEP_ELF_SUMMONER /*'e'*/
deep_elf_annihilator MONS_DEEP_ELF_ANNIHILATOR /*'e'*/
deep_elf_priest MONS_DEEP_ELF_PRIEST /*'e'*/
deep_elf_high_priest MONS_DEEP_ELF_HIGH_PRIEST /*'e'*/
deep_elf_blademaster MONS_DEEP_ELF_BLADEMASTER
deep_elf_master_archer MONS_DEEP_ELF_MASTER_ARCHER
%subst asc/ch66
fungus MONS_FUNGUS /*'f'*/
wandering_mushroom MONS_WANDERING_MUSHROOM /*'f'*/
%subst asc/ch67
goblin0 MONS_GOBLIN /*'g'*/
hobgoblin0 MONS_HOBGOBLIN /*'g'*/
gnoll0 MONS_GNOLL /*'g'*/
ijyb0 MONS_IJYB /*'g'*/
boggart MONS_BOGGART /*'g'*/
gargoyle MONS_GARGOYLE /*'g'*/
metal_gargoyle MONS_METAL_GARGOYLE /*'g'*/
molten_gargoyle MONS_MOLTEN_GARGOYLE /*'g'*/
%subst asc/ch68
hell_hog MONS_HELL_HOG /*'h'*/
hell_hound MONS_HELL_HOUND /*'h'*/
hog MONS_HOG /*'h'*/
hound MONS_HOUND /*'h'*/
warg MONS_WARG /*'h'*/
war_dog MONS_WAR_DOG /*'h'*/
wolf MONS_WOLF /*'h'*/
%subst asc/ch6a
jackal MONS_JACKAL /*'j'*/
%subst asc/ch6b
bumblebee MONS_BUMBLEBEE /*'k'*/
killer_bee MONS_KILLER_BEE /*'k'*/
%subst asc/ch6c
giant_gecko MONS_GIANT_GECKO /*'l'*/
giant_iguana MONS_GIANT_IGUANA /*'l'*/
giant_lizard MONS_GIANT_LIZARD /*'l'*/
giant_newt MONS_GIANT_NEWT /*'l'*/
gila_monster MONS_GILA_MONSTER /*'l'*/
komodo_dragon MONS_KOMODO_DRAGON /*'l'*/
%subst asc/ch6d
elephant_slug MONS_ELEPHANT_SLUG /*'m'*/
giant_slug MONS_GIANT_SLUG /*'m'*/
giant_snail MONS_GIANT_SNAIL /*'m'*/
manticore MONS_MANTICORE /*'m'*/
minotaur MONS_MINOTAUR /*'m'*/
%subst asc/ch6e
ghoul MONS_GHOUL /*'n'*/
necrophage MONS_NECROPHAGE /*'n'*/
rotting_hulk MONS_ROTTING_HULK /*'n'*/
%subst asc/ch6f
orc0 MONS_ORC /*'o'*/
orc_warrior0 MONS_ORC_WARRIOR /*'o'*/
orc_knight0 MONS_ORC_KNIGHT /*'o'*/
orc_warlord0 MONS_ORC_WARLORD /*'o'*/
blork_the_orc0 MONS_BLORK_THE_ORC /*'o'*/
urug0 MONS_URUG /*'o'*/
orc_priest MONS_ORC_PRIEST /*'o'*/
orc_high_priest MONS_ORC_HIGH_PRIEST /*'o'*/
orc_sorcerer MONS_ORC_SORCERER /*'o'*/
orc_wizard MONS_ORC_WIZARD /*'o'*/
%subst asc/ch70
flayed_ghost MONS_FLAYED_GHOST /*'p'*/
hungry_ghost MONS_HUNGRY_GHOST /*'p'*/
%rim 0
insubstantial_wisp MONS_INSUBSTANTIAL_WISP /*'p'*/
phantom MONS_PHANTOM /*'p'*/
ghost MONS_PLAYER_GHOST /*'p'*/
%rim 1
quasit MONS_QUASIT /*'q'*/
%subst asc/ch72
green_rat MONS_GREEN_RAT /*'r'*/
grey_rat MONS_GREY_RAT /*'r'*/
orange_rat MONS_ORANGE_RAT /*'r'*/
quokka MONS_QUOKKA /*'r'*/
rat MONS_RAT /*'r'*/
%subst asc/ch73
giant_centipede MONS_GIANT_CENTIPEDE /*'s'*/
giant_mite MONS_GIANT_MITE /*'s'*/
redback MONS_REDBACK /*'s'*/
scorpion MONS_SCORPION /*'s'*/
wolf_spider MONS_WOLF_SPIDER /*'s'*/
%subst asc/ch75
ugly_thing MONS_UGLY_THING /*'u'*/
very_ugly_thing MONS_VERY_UGLY_THING /*'u'*/
%subst asc/ch76
air_elemental MONS_AIR_ELEMENTAL /*'v'*/
fire_vortex MONS_FIRE_VORTEX /*'v'*/
spatial_vortex MONS_SPATIAL_VORTEX /*'v'*/
%subst asc/ch77
killer_bee_larva MONS_ANT_LARVA /*'w'*/
brain_worm MONS_BRAIN_WORM /*'w'*/
killer_bee_larva MONS_KILLER_BEE_LARVA /*'w'*/
lava_worm MONS_LAVA_WORM /*'w'*/
spiny_worm MONS_SPINY_WORM /*'w'*/
swamp_worm MONS_SWAMP_WORM /*'w'*/
worm MONS_WORM /*'w'*/
%subst asc/ch78
abomination_small MONS_ABOMINATION_SMALL /*'x'*/
unseen_horror MONS_UNSEEN_HORROR /*'x'*/
%subst asc/ch79
giant_blowfly MONS_GIANT_BLOWFLY /*'y'*/
giant_mosquito MONS_GIANT_MOSQUITO /*'y'*/
moth_of_wrath MONS_MOTH_OF_WRATH /*'y'*/
red_wasp MONS_RED_WASP /*'y'*/
yellow_wasp MONS_YELLOW_WASP /*'y'*/
%subst asc/ch7a
curse_skull MONS_CURSE_SKULL /*'z'*/
curse_toe MONS_CURSE_TOE /*'z'*/
flying_skull MONS_FLYING_SKULL /*'z'*/
simulacrum_small MONS_SIMULACRUM_SMALL /*'z'*/
skeletal_warrior0 MONS_SKELETAL_WARRIOR /*'z'*/
skeleton_small MONS_SKELETON_SMALL /*'z'*/
zombie_small MONS_ZOMBIE_SMALL /*'z'*/
murray MONS_MURRAY
water_elemental MONS_WATER_ELEMENTAL /*'{'*/
####nh-mon0/m/large_mimic MONS_MOLLUSC_LORD
%sdir effect
#### Magic Bolts
%back none
bolt01 SYM_BOLT_OFS
bolt02
bolt03
bolt04
bolt05
bolt06
bolt07
bolt08
#########CLOUDS
cloud_fire0 CLOUD_FIRE_0
cloud_fire1 CLOUD_FIRE_1
cloud_fire2 CLOUD_FIRE_2
cloud_cold0 CLOUD_COLD_0
cloud_cold1 CLOUD_COLD_1
cloud_cold2 CLOUD_COLD_2
cloud_poison0 CLOUD_POISON_0
cloud_poison1 CLOUD_POISON_1
cloud_poison2 CLOUD_POISON_2
cloud_black_smoke CLOUD_BLACK_SMOKE
cloud_blue_smoke CLOUD_BLUE_SMOKE
cloud_grey_smoke CLOUD_GREY_SMOKE
cloud_miasma CLOUD_MIASMA
cloud_purp_smoke CLOUD_PURP_SMOKE
#########MAP
%sdir dc-misc
%corpse 0
%back none
%mesh 0
unseen_weapon UNSEEN_WEAPON
unseen_monster UNSEEN_MONSTER
unseen_armour UNSEEN_ARMOUR
unseen_item UNSEEN_ITEM
%corpse 1
%back dc-misc/blood_red
unseen_monster UNSEEN_CORPSE
%corpse 0
%back none
dc-dngn/dngn_altar UNSEEN_ALTAR
dc-dngn/dngn_entrance UNSEEN_ENTRANCE
%back none
#mask_deep_water MASK_DEEP_WATER
#mask_shallow_water MASK_SHALLOW_WATER
#mask_lava MASK_LAVA
sink_mask SINK_MASK
cursor CURSOR
cursor_red CURSOR2
cursor_green CURSOR3
heart HEART
may_stab_brand MAY_STAB_BRAND
stab_brand STAB_BRAND
unseen PLAYER
%mesh 1
blank MESH
%mesh 0
magicmap MAGIC_MAP_MESH
ray RAY_MESH
txt1 TEXT_PARTS_J
txt2 TEXT_DOLLS_J
txt3 TEXT_PARTS_E
txt4 TEXT_DOLLS_E
something_under SOMETHING_UNDER
error ERROR
char20 CHAR00
char28
char30
char38
char40
char48
char50
char58
char60
char68
char70
char78
slot ITEM_SLOT
slot_eq ITEM_SLOT_EQUIP
slot_cursed ITEM_SLOT_CURSED
slot_eq_cursed ITEM_SLOT_EQUIP_CURSED
%back unseen
dc-misc/unseen_monster MCACHE_START
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster
dc-misc/unseen_monster MCACHE_END
#####OBJ_WEAPONS
#####ARTIFACTS
%sdir item/weapon
spwpn_singing_sword SPWPN_SINGING_SWORD /* This blessed weapon loves nothing more than to sing to its owner, whether they want it to or not.
spwpn_wrath_of_trog SPWPN_WRATH_OF_TROG /* This was the favourite weapon of the old god Trog, before he lost it one day. It induces a bloodthirsty berserker rage in anyone who uses it to strike another.
spwpn_scythe_of_curses SPWPN_SCYTHE_OF_CURSES /* This weapon carries a terrible and highly irritating curse.
spwpn_mace_of_variability SPWPN_MACE_OF_VARIABILITY /* It is rather unreliable.
spwpn_glaive_of_prune SPWPN_GLAIVE_OF_PRUNE /* It is the creation of a mad god, and carries a curse which transforms anyone possessing it into a prune. Fortunately, the curse works very slowly, and one can use it briefly with no consequences worse than slightly purple skin and a few wrinkles.
spwpn_sceptre_of_torment SPWPN_SCEPTRE_OF_TORMENT /* This truly accursed weapon is an instrument of Hell.
spwpn_sword_of_zonguldrok SPWPN_SWORD_OF_ZONGULDROK /* This dreadful weapon is used at the user's peril.
spwpn_sword_of_cerebov SPWPN_SWORD_OF_CEREBOV /* Eerie flames cover its twisted blade.
spwpn_staff_of_dispater SPWPN_STAFF_OF_DISPATER /* This legendary item can unleash the fury of Hell.
spwpn_sceptre_of_asmodeus SPWPN_SCEPTRE_OF_ASMODEUS /* It carries some of the powers of the arch-fiend Asmodeus.
spwpn_sword_of_power SPWPN_SWORD_OF_POWER /* It rewards the powerful with power and the meek with weakness.
spwpn_knife_of_accuracy SPWPN_KNIFE_OF_ACCURACY /* It is almost unerringly accurate.
spwpn_staff_of_olgreb SPWPN_STAFF_OF_OLGREB /* It was the magical weapon wielded by the mighty wizard Olgreb before he met his fate somewhere within these dungeons. It grants its wielder resistance to the effects of poison and increases their ability to use venomous magic, and carries magical powers which can be evoked.
spwpn_vampires_tooth SPWPN_VAMPIRES_TOOTH /* It is lethally vampiric.
quarterstaff SPWPN_STAFF_OF_WUCAD_MU /* Its power varies in proportion to its wielder's intelligence. Using it can be a bit risky.
##### Unrandom artifacts
%include dc-urand.txt
#####NORMAL
%sdir item/weapon
%rim 1
##Blunt
club WPN_CLUB/* D5H4S12 A heavy piece of wood.
mace WPN_MACE/* D8H3S14 A long handle with a heavy lump on one end.
mace2 WPN_MACE2
mace_large WPN_GREAT_MACE/* D16H-3S18 A large and heavy mace.
mace_large2 WPN_GREAT_MACE2
flail WPN_FLAIL
flail2 WPN_FLAIL2
spiked_flail WPN_SPIKED_FLAIL
spiked_flail2 WPN_SPIKED_FLAIL2
great_flail WPN_GREAT_FLAIL
great_flail2 WPN_GREAT_FLAIL2
morningstar WPN_MORNINGSTAR
morningstar2 WPN_MORNINGSTAR2
eveningstar WPN_EVENINGSTAR
eveningstar2 WPN_EVENINGSTAR2
hammer WPN_HAMMER
hammer2 WPN_HAMMER2
ancus WPN_ANCUS/* D9H1S14 A large and vicious toothed club.
bullwhip WPN_WHIP/* D3H1S14 A whip.
demon_whip WPN_DEMON_WHIP/* D10H1S14 A terrible weapon, woven in the depths of the inferno.
giant_club WPN_GIANT_CLUB/* D15H-5S16 A giant lump of wood, shaped for an ogre's hands.
giant_spiked_club WPN_GIANT_SPIKED_CLUB/* D18H-6S17 A giant lump of wood with sharp spikes at one end.
##Edged
knife WPN_KNIFE/* D2H0S11 A simple survival knife. Designed more for utility than combat, it looks quite capable of butchering a corpse.
dagger WPN_DAGGER/* D3H6S11 A long knife or a very short sword, which can be held or thrown.
orcish_dagger WPN_DAGGER_ORC
elven_dagger WPN_DAGGER_ELF
short_sword WPN_SHORT_SWORD/* D6H5S12 A sword with a short, slashing blade.
short_sword2 WPN_SHORT_SWORD_1
orcish_short_sword WPN_SHORT_SWORD_ORC
elven_short_sword WPN_SHORT_SWORD_ELF
long_sword2 WPN_LONG_SWORD/* D10H3S14 A sword with a long, slashing blade.
%rim 0
long_sword3 WPN_LONG_SWORD_1
%rim 1
orcish_long_sword WPN_LONG_SWORD_ORC
greatsword WPN_GREAT_SWORD/* D16H-1S17 A sword with a very long, heavy blade and a long handle.
greatsword2 WPN_GREAT_SWORD_1
orcish_great_sword WPN_GREAT_SWORD_ORC
falchion WPN_FALCHION/* D8H2S13 A sword with a broad slashing blade.
scimitar WPN_SCIMITAR/* D11H1S14 A long sword with a curved blade.
scimitar2 WPN_SCIMITAR2
silver_saber WPN_SABRE/* D7H4S12 A sword with a medium length slashing blade.
sabre2 WPN_SABRE_1
quickblade WPN_QUICK_BLADE/* D5H6S7 A small and magically quick sword.
#tsurugi WPN_KATANA
katana2 WPN_KATANA/* D13H4S13 A very rare and extremely effective imported weapon, featuring a long single-edged blade.
katana3 WPN_KATANA_1
double_sword WPN_DOUBLE_SWORD/* D15H3S16 A magical weapon with two razor-sharp blades.
triple_sword WPN_TRIPLE_SWORD/* D19H-1S19 A magical weapon with three great razor-sharp blades.
demon_blade WPN_DEMON_BLADE/* D13H2S15 A terrible weapon, forged in the fires of Hell.
##Axe
hand_axe WPN_HAND_AXE/* D7H2S13 An small axe designed for either hand combat or throwing.
war_axe WPN_WAR_AXE/* D11H0S16 An axe intended for hand to hand combat.
battle_axe2 WPN_BROAD_AXE/* D14H1S17 An axe with a large blade.
broad_axe2
battle_axe WPN_BATTLEAXE/* D17H-2S18 A large axe with a double-headed blade.
battle_axe3 WPN_BATTLEAXE_1
executioner_axe WPN_EXECUTIONERS_AXE /* D20H-4S20 A huge axe.
executioner_axe2 WPN_EXECUTIONERS_AXE_1
##Ranged
blowgun WPN_BLOWGUN /* D1H0S10 A long, light tube, open at both ends. Doing very little damage, its main use is to fire poisoned needles from afar. It makes very little noise.
blowgun2 WPN_BLOWGUN1
sling WPN_SLING /* D1H-1S11 A piece of cloth and leather for launching stones, which do a small amount of damage on impact.
bow WPN_BOW /* D2H-3S11 A curved piece of wood and string, for shooting arrows. It does good damage in combat, and a skilled user can use it to great effect.
bow2 WPN_BOW1
crossbow WPN_CROSSBOW /* D2H-1S15 A piece of machinery used for firing bolts, which takes some time to load and fire. It does very good damage in combat.
crossbow2 WPN_CROSSBOW1
hand_crossbow WPN_HAND_CROSSBOW /* D1H-1S15 A small crossbow, for firing darts.
hand_crossbow2 WPN_HAND_CROSSBOW1
##Pole
quarterstaff WPN_QUARTERSTAFF /* D7H6S12 A sturdy wooden pole.
elven_spear WPN_SPEAR /* D5H3S13 A long stick with a pointy blade on one end, to be held or thrown.
spear2 WPN_SPEAR2
trident WPN_TRIDENT /* D9H-2S17 A hafted weapon with three points at one end.
trident2 WPN_TRIDENT2
halberd WPN_HALBERD /* D13H-3S19 A long pole with a spiked axe head on one end.
halberd2 WPN_HALBERD2
scythe WPN_SCYTHE /* D14H-4S22 A farm implement, usually unsuited to combat.
scythe2 WPN_SCYTHE2
glaive WPN_GLAIVE /* D15H-3S18 A pole with a large, heavy blade on one end.
glaive2 WPN_GLAIVE2
orcish_glaive WPN_GLAIVE_ORC
demon_trident WPN_DEMON_TRIDENT /* D15H-2S17 A terrible weapon, molded by fire and brimstone.
# SS new weapons
%rim 0
blessed_blade WPN_BLESSED_BLADE
%rim 1
longbow WPN_LONGBOW
lajatang WPN_LAJATANG
lochaber_axe WPN_LOCHABER_AXE
######OBJ_MISSILES
item/gem/stone MI_STONE /* D2H4 A stone.
effect/stone0 MI_STONE0
sling_bullet MI_SLING_BULLET
effect/sling_bullet0 MI_SLING_BULLET0
ya MI_ARROW /* D2H6 An arrow.
effect/arrow0 MI_ARROW0
effect/arrow1 MI_ARROW1
effect/arrow2 MI_ARROW2
effect/arrow3 MI_ARROW3
effect/arrow4 MI_ARROW4
effect/arrow5 MI_ARROW5
effect/arrow6 MI_ARROW6
effect/arrow7 MI_ARROW7
crossbow_bolt MI_BOLT /* D2H8 A crossbow bolt.
effect/bolt0 MI_BOLT0
effect/bolt1 MI_BOLT1
effect/bolt2 MI_BOLT2
effect/bolt3 MI_BOLT3
effect/bolt4 MI_BOLT4
effect/bolt5 MI_BOLT5
effect/bolt6 MI_BOLT6
effect/bolt7 MI_BOLT7
dart MI_DART /* D2H4 A small throwing weapon.
dart-p MI_DART_P
effect/dart0 MI_DART0
effect/dart1 MI_DART1
effect/dart2 MI_DART2
effect/dart3 MI_DART3
effect/dart4 MI_DART4
effect/dart5 MI_DART5
effect/dart6 MI_DART6
effect/dart7 MI_DART7
needle MI_NEEDLE /* D0H1 A needle.
needle-p MI_NEEDLE_P
effect/needle0 MI_NEEDLE0
effect/needle1 MI_NEEDLE1
effect/needle2 MI_NEEDLE2
effect/needle3 MI_NEEDLE3
effect/needle4 MI_NEEDLE4
effect/needle5 MI_NEEDLE5
effect/needle6 MI_NEEDLE6
effect/needle7 MI_NEEDLE7
javelin MI_JAVELIN
effect/javelin0 MI_JAVELIN0
effect/javelin1 MI_JAVELIN1
effect/javelin2 MI_JAVELIN2
effect/javelin3 MI_JAVELIN3
effect/javelin4 MI_JAVELIN4
effect/javelin5 MI_JAVELIN5
effect/javelin6 MI_JAVELIN6
effect/javelin7 MI_JAVELIN7
throwing_net MI_THROWING_NET
effect/throwing_net0 MI_THROWING_NET0
effect/throwing_net1 MI_THROWING_NET1
effect/throwing_net2 MI_THROWING_NET2
effect/throwing_net3 MI_THROWING_NET3
effect/throwing_net4 MI_THROWING_NET4
effect/throwing_net5 MI_THROWING_NET5
effect/throwing_net6 MI_THROWING_NET6
effect/throwing_net7 MI_THROWING_NET7
effect/net_trap TRAP_NET
item/gem/rock MI_LARGE_ROCK /* D20H10 A rock, used by giants as a missile.
effect/rock0 MI_LARGE_ROCK0
######OBJ_ARMOUR
%sdir item/armor
robe ARM_ROBE /* A1E0 A cloth robe.
robe2 ARM_ROBE_1
robe3 ARM_ROBE_2
leather_armor2 ARM_LEATHER_ARMOUR /* A2E-1 A suit made of hardened leather.
breast_plate2 ARM_LEATHER_ARMOUR_1
leather_armor4 ARM_LEATHER_ARMOUR_2
orcish_leather_armor ARM_LEATHER_ARMOUR_ORC
elven_leather_armor ARM_LEATHER_ARMOUR_ELF
ring_mail ARM_RING_MAIL /* A4E-2 A leather suit covered in little rings.
ring_mail2 ARM_RING_MAIL_1
orcish_ringmail ARM_RING_MAIL_ORC
elven_ringmail ARM_RING_MAIL_ELF
dwarven_ringmail ARM_RING_MAIL_DWA
scale_mail ARM_SCALE_MAIL /* A5E-2 A leather suit covered in little metal plates.
scale_mail2 ARM_SCALE_MAIL_2
elven_scalemail ARM_SCALE_MAIL_ELF
chain_mail1 ARM_CHAIN_MAIL /* A6E-3 A suit made of interlocking metal rings.
chain_mail2 ARM_CHAIN_MAIL_1
chain_mail3 ARM_CHAIN_MAIL_ELF
orcish_chain_mail ARM_CHAIN_MAIL_ORC
splint_mail ARM_SPLINT_MAIL /* A8E-5 A suit made of splints of metal.
banded_mail ARM_BANDED_MAIL /* A7E-4 A suit made of bands of metal.
plate_mail2 ARM_PLATE_MAIL /* A9E-5 A suit of mail and large plates of metal.
orcish_platemail ARM_PLATE_MAIL_ORC
crystal_plate_mail ARM_CRYSTAL_PLATE_MAIL /* A16E-8
animal_skin ARM_ANIMAL_SKIN /* A1E0 The skins of several animals.
animal_skin2 ARM_ANIMAL_SKIN_1
troll_hide ARM_TROLL_HIDE /* A1E-1 The stiff and knobbly hide of a troll. I suppose you could wear it if you really wanted to.
troll_leather_armour ARM_TROLL_LEATHER_ARMOUR /* A3E-1 A magical armour, made from the stiff and knobbly skin of a common troll. It magically regenerates its wearer's flesh at a fairly slow rate (unless already a troll).
green_dragon_scales ARM_DRAGON_HIDE /* A2E-2 The scaly skin of a dragon. I suppose you could wear it if you really wanted to.
green_dragon_scale_mail ARM_DRAGON_ARMOUR /* A8E-2 A magical armour, made from the scales of a fire-breathing dragon. It provides great protection from the effects of fire, but renders its wearer more susceptible to the effects of cold.
ice_dragon_hide ARM_ICE_DRAGON_HIDE /* A2E-2 The scaly skin of a dragon. I suppose you could wear it if you really wanted to.
ice_dragon_armour ARM_ICE_DRAGON_ARMOUR /* A9E-2 A magical armour, made from the scales of a cold-breathing dragon. It provides great protection from the effects of cold, but renders its wearer more susceptible to the effects of fire and heat.
silver_dragon_scales ARM_STEAM_DRAGON_HIDE /* A0E0 The soft and supple scaley skin of a steam dragon. I suppose you could wear it if you really wanted to.
silver_dragon_scale_mail ARM_STEAM_DRAGON_ARMOUR /* A3E0 A magical armour, made from the scales of a steam-breathing dragon. Although unlike the armour made from the scales of some larger dragons it does not provide its wearer with much in the way of special magical protection, it is extremely light and as supple as cloth.
mottled_dragon_hide ARM_MOTTLED_DRAGON_HIDE /* A1E-1 The weirdly-patterned scaley skin of a mottled dragon. I suppose you could wear it if you really wanted to.
mpttled_dragon_armour ARM_MOTTLED_DRAGON_ARMOUR /* A5E-1 A magical armour made from the scales of a mottled dragon. Although unlike the armour made from the scales of some larger dragons it does not provide its wearer with much in the way of special magical protection, it is as light and relatively uncumbersome as leather armour.
blue_dragon_scales ARM_STORM_DRAGON_HIDE /* A2E-5 The hide of a storm dragon, covered in extremely hard blue scales. I suppose you could wear it if you really wanted to.
blue_dragon_scale_mail ARM_STORM_DRAGON_ARMOUR /* A10E-5 A magical armour made from the scales of a lightning-breathing dragon. It is heavier than most dragon scale armours, but gives its wearer great resistance to electrical discharges.
gold_dragon_hide ARM_GOLD_DRAGON_HIDE /* A2E-10 The extremely tough and heavy skin of a golden dragon, covered in shimmering golden scales. I suppose you could wear it if you really wanted to.
gold_dragon_armour ARM_GOLD_DRAGON_ARMOUR /* A13E-10 A magical armour made from the golden scales of a golden dragon. It is extremely heavy and cumbersome, but confers resistances to fire, cold, and poison on its wearer.
swamp_dragon_hide ARM_SWAMP_DRAGON_HIDE /* A1E-2 The slimy skin of a swamp-dwelling dragon. I suppose you could wear it if you really wanted to.
swamp_dragon_armour ARM_SWAMP_DRAGON_ARMOUR /* A7E-2 A magical armour made from the scales of a swamp dragon. It confers resistance to poison on its wearer.
naga_barding ARM_NAGA_BARDING
centaur_barding ARM_CENTAUR_BARDING
elven_shield ARM_SHIELD /* A0E0 A piece of metal, to be strapped on one's arm. It is cumbersome to wear, and slightly slows the rate at which you may attack.
shield_kite2 ARM_SHIELD_1
shield_round2 ARM_SHIELD_2
#dwarvish_roundshield ARM_BUCKLER
small_shield ARM_BUCKLER /* A small shield.
small_shield2 ARM_BUCKLER_1
large_shield ARM_LARGE_SHIELD /* Like a normal shield, only larger. It is very cumbersome to wear, and slows the rate at which you may attack.
shield_large2 ARM_LARGE_SHIELD_1
shield_kite3 ARM_LARGE_SHIELD_2
leather_cloak ARM_CLOAK /* A1E0 A cloth cloak.
cloak2 ARM_CLOAK_1
cloak3 ARM_CLOAK_2
cloak4 ARM_CLOAK_3
#####ARM_HELMET
elven_leather_helm THELM_CAP /* A cloth or leather cap.
wizard_hat THELM_WIZARD_HAT /* A conical cloth hat.
wizard_hat2 THELM_WIZARD_HAT_1
visored_helmet THELM_HELM /* A1E0 A piece of metal headgear.
etched_helmet THELM_HELM_1
helm3 THELM_HELM_2
helm_visor1 THELM_HELM_3
###### GLOVES
glove1 ARM_GLOVES /* A1E0 A pair of gloves.
glove3 ARM_GLOVES_1
glove5 ARM_GLOVES_2
gauntlet2 ARM_GLOVES_3
###### BOOTS
boots_brown1 ARM_BOOTS /* A1E0 A pair of sturdy boots.
jackboots ARM_BOOTS_1
boots_stripe1 ARM_BOOTS_2
boots_green2 ARM_BOOTS_3
###########OBJ_WANDS
%sdir item/wand
gem_iron WAND_OFFSET /*iron*/
gem_brass
gem_bone
gem_wood
gem_copper
gem_gold
gem_silver
gem_bronze
gem_ivory
gem_glass
gem_lead
gem_plastic
%sdir item/wand
%back i-label
i-flame WAND_FLAME
i-frost WAND_FROST
i-slowing WAND_SLOWING
i-hasting WAND_HASTING
i-magic_darts WAND_MAGIC_DARTS
i-healing WAND_HEALING
i-paralysis WAND_PARALYSIS
i-fire WAND_FIRE
i-cold WAND_COLD
i-confusion WAND_CONFUSION
i-invisibility WAND_INVISIBILITY
i-digging WAND_DIGGING
i-fireball WAND_FIREBALL
i-teleportation WAND_TELEPORTATION
i-lightning WAND_LIGHTNING
i-polymorph_other WAND_POLYMORPH_OTHER
i-enslavement WAND_ENSLAVEMENT
i-draining WAND_DRAINING
i-random_effects WAND_RANDOM_EFFECTS
i-disintegration WAND_DISINTEGRATION
%back none
#################OBJ_FOOD
%sdir item/food
tripe_ration FOOD_MEAT_RATION
bread_ration FOOD_BREAD_RATION
pear FOOD_PEAR
apple FOOD_APPLE
choko FOOD_CHOKO
honeycomb FOOD_HONEYCOMB
lump_of_royal_jelly FOOD_ROYAL_JELLY
snozzcumber FOOD_SNOZZCUMBER
pizza FOOD_PIZZA
apricot FOOD_APRICOT
orange FOOD_ORANGE
banana FOOD_BANANA
strawberry FOOD_STRAWBERRY
rambutan FOOD_RAMBUTAN
lemon FOOD_LEMON
grape FOOD_GRAPE
sultana FOOD_SULTANA
lychee FOOD_LYCHEE
beef_jerky FOOD_BEEF_JERKY
cheese FOOD_CHEESE
sausage FOOD_SAUSAGE
corpse FOOD_CHUNK
corpse_rotten FOOD_CHUNK_ROTTEN
bone FOOD_BONE
#################OBJ_UNKNOWN_I
##################OBJ_SCROLLS
%sdir item/scroll
kernod_wel SCROLL
%back kernod_wel
%sdir item/scroll
i-identify SCR_IDENTIFY
i-teleportation SCR_TELEPORTATION
i-fear SCR_FEAR
i-noise SCR_NOISE
i-remove_curse SCR_REMOVE_CURSE
i-detect_curse SCR_DETECT_CURSE
i-summoning SCR_SUMMONING
i-enchant-weapon1 SCR_ENCHANT_WEAPON_I
i-enchant_armour SCR_ENCHANT_ARMOUR
i-torment SCR_TORMENT
i-random_uselessness SCR_RANDOM_USELESSNESS
i-curse_weapon SCR_CURSE_WEAPON
i-curse_armour SCR_CURSE_ARMOUR
i-immolation SCR_IMMOLATION
i-blinking SCR_BLINKING
item/scroll/blank_paper SCR_PAPER
i-magic_mapping SCR_MAGIC_MAPPING
i-foregetfulness SCR_FORGETFULNESS
i-acquirement SCR_ACQUIREMENT
i-enchant-weapon2 SCR_ENCHANT_WEAPON_II
i-vorpalize-weapon SCR_VORPALISE_WEAPON
i-recharging SCR_RECHARGING
i-enchant-weapon3 SCR_ENCHANT_WEAPON_III
%back none
##################OBJ_JEWELLERY
############ring
%sdir item/ring
wooden RING_NORMAL_OFFSET /*wood*/
silver
gold
iron
steel
bronze
brass
copper
granite
ivory
clay
tiger_eye
jade
glass
###########random
agate RING_RANDOM_OFFSET
clay
diamond
emerald
gold_green
gold_red
opal
pearl
coral
gold_blue
plain_red
plain_yellow
plain_black
bronze
moonstone
###amulets
%sdir item/amulet
crystal_white AMU_NORMAL_OFFSET /*zirconium*/
stone3_blue
face1_gold
stone3_green
stone2_red
eye_magenta
face2
penta_orange
celtic_red
cameo_blue
bone_gray
cylinder_gray
ring_green
ring_cyan
###random
crystal_green AMU_RANDOM_OFFSET
cameo_orange
celtic_blue
eye_cyan
penta_green
ring_red
stone1_cyan
stone1_pink
stone2_green
stone3_magenta
celtic_yellow
stone1_green
stone2_blue
crystal_red
eye_green
####################OBJ_POTIONS
%sdir item/potion
clear POTION_OFFSET /*clear*/
brilliant_blue
black
silver
cyan
magenta
orange
dark
ruby
yellow
emerald
brown
pink
white
%sdir item/potion
%back i-label
%rim 0
i-heal POT_HEALING
i-heal-wounds POT_HEAL_WOUNDS
i-speed POT_SPEED
i-might POT_MIGHT
i-gain-strength POT_GAIN_STRENGTH
i-gain-dexterity POT_GAIN_DEXTERITY
i-gain-intelligence POT_GAIN_INTELLIGENCE
i-levitation POT_LEVITATION
i-poison POT_POISON
i-slowing POT_SLOWING
i-paralysis POT_PARALYSIS
i-confusion POT_CONFUSION
i-invisibility POT_INVISIBILITY
i-porridge POT_PORRIDGE
i-degeneration POT_DEGENERATION
i-decay POT_DECAY
i-water POT_WATER
i-experience POT_EXPERIENCE
i-magic POT_MAGIC
i-restore-abilities POT_RESTORE_ABILITIES
i-strong-poison POT_STRONG_POISON
i-berserk-rage POT_BERSERK_RAGE
i-cure-mutation POT_CURE_MUTATION
i-mutation POT_MUTATION
i-blood POT_BLOOD
i-resistance POT_RESISTANCE
%back none
%rim 1
####################OBJ_UNKNOWN_II
#####################OBJ_BOOKS
###0paperback / hardback 16
%sdir item/book
book_of_the_dead BOOK_PAPER_OFFSET
dark_blue
dark_green
cyan
red
purple
tan
light_gray
dark_gray
light_blue
light_green
turquoise
pink
magenta
yellow
white
##########leather 8
parchment BOOK_LEATHER_OFFSET
leather
tan
plaid
light_brown
light_brown
dark_brown
dark_brown
###########3metal 8
bronze BOOK_METAL_OFFSET
copper
silver
gold
glittering
metal_blue
metal_cyan
metal_green
############4papi 1
cloth BOOK_PAPYRUS
#####################OBJ_STAVES
%sdir item/wand
staff00 STAFF_OFFSET /*curved*/
staff01
staff02
staff03
staff04
staff05
staff06
staff07
staff08
staff09
#OBJ_ORBS
%sdir item/misc
misc_orb ORB
#OBJ_MISCELLANY
misc_bottle MISC_BOTTLED_EFREET
misc_crystal MISC_CRYSTAL_BALL_OF_SEEING
misc_fan MISC_AIR_ELEMENTAL_FAN
misc_lamp MISC_LAMP_OF_FIRE
misc_stone MISC_STONE_OF_EARTH_ELEMENTALS
misc_lantern MISC_LANTERN_OF_SHADOWS
misc_horn MISC_HORN_OF_GERYON
misc_box MISC_BOX_OF_BEASTS
misc_deck MISC_DECK_OF_WONDERS
misc_deck MISC_DECK_OF_SUMMONINGS
misc_crystal MISC_CRYSTAL_BALL_OF_ENERGY
misc_box MISC_EMPTY_EBONY_CASKET
misc_crystal MISC_CRYSTAL_BALL_OF_FIXATION
misc_disc MISC_DISC_OF_STORMS
misc_rune MISC_RUNE_OF_ZOT
misc_deck MISC_DECK_OF_TRICKS
misc_deck MISC_DECK_OF_POWER
misc_altar MISC_PORTABLE_ALTAR_OF_NEMELEX
#OBJ_CORPSES
#OBJ_GOLD
%sdir item/gem
gold_piece GOLD
#OBJ_GEMSTONES
%sdir dc-dngn
blank BLANK
dngn_unseen DNGN_UNSEEN
floor/pebble_gray0 DNGN_FLOOR
floor/pebble_gray1
floor/pebble_gray2
floor/pebble_gray3
floor/pebble_gray3
floor/pebble_gray3
floor/pebble_gray3
floor/pebble_gray3 DNGN_FLOOR_SPECIAL
wall/brick_brown0 DNGN_ROCK_WALL_OFS
wall/brick_brown1
wall/brick_brown2
wall/brick_brown3
wall/brick_brown3
wall/brick_brown3
wall/brick_brown3
wall/brick_brown3
wall/brick_brown3
wall/brick_brown3
wall/brick_brown3
wall/brick_brown3
floor/lava0 DNGN_LAVA
floor/lava1
floor/lava2
floor/lava3
dngn_deep_water DNGN_DEEP_WATER
dngn_deep_water
dngn_deep_water
dngn_deep_water
dngn_shallow_water DNGN_SHALLOW_WATER
dngn_shallow_water
dngn_shallow_water
dngn_shallow_water
wall/stone2_gray0 DNGN_STONE_WALL
wall/stone2_gray1
wall/stone2_gray2
wall/stone2_gray3
dngn_metal_wall DNGN_METAL_WALL
dngn_green_crystal_wall DNGN_GREEN_CRYSTAL_WALL
dngn_wax_wall DNGN_WAX_WALL
#dngn_rock_wall_00 DNGN_ROCK_WALL_OFS
#dngn_rock_wall_01 IGNORE_COMMENT
#dngn_rock_wall_02 IGNORE_COMMENT
#dngn_rock_wall_03 IGNORE_COMMENT
#dngn_rock_wall_04 IGNORE_COMMENT
#dngn_rock_wall_05 IGNORE_COMMENT
#dngn_rock_wall_06 IGNORE_COMMENT
#dngn_rock_wall_07 IGNORE_COMMENT
#dngn_rock_wall_08 IGNORE_COMMENT
#dngn_rock_wall_09 IGNORE_COMMENT
#dngn_rock_wall_10 IGNORE_COMMENT
#dngn_rock_wall_11 IGNORE_COMMENT
#dngn_rock_wall_12 IGNORE_COMMENT
#dngn_rock_wall_13 IGNORE_COMMENT
#dngn_rock_wall_14 IGNORE_COMMENT
#dngn_rock_wall_15 IGNORE_COMMENT
#dngn_stone_wall DNGN_STONE_WALL
dngn_closed_door DNGN_CLOSED_DOOR
dngn_open_door DNGN_OPEN_DOOR
###dc/wal8 DNGN_SECRET_DOOR
dngn_orcish_idol DNGN_ORCISH_IDOL
dngn_silver_statue DNGN_SILVER_STATUE
dngn_granite_statue DNGN_GRANITE_STATUE
dngn_orange_crystal_statue DNGN_ORANGE_CRYSTAL_STATUE
dngn_ice_statue DNGN_ICE_STATUE
###dc/wal1 DNGN_PERMAROCK_WALL
###dc/wal1 DNGN_LAST_SOLID_TILE
dngn_enter_hell DNGN_ENTER_HELL
dngn_branch_stairs DNGN_BRANCH_STAIRS
dngn_trap_mechanical DNGN_TRAP_MECHANICAL
dngn_trap_magical DNGN_TRAP_MAGICAL
dngn_trap_iii DNGN_TRAP_III
###847 DNGN_UNDISCOVERED_TRAP
stone_stairs_down DNGN_STONE_STAIRS_DOWN
#nh-dngn/staircase_down DNGN_STONE_STAIRS_DOWN_II
#nh-dngn/staircase_down DNGN_STONE_STAIRS_DOWN_III
rock_stairs_down DNGN_ROCK_STAIRS_DOWN
stone_stairs_up DNGN_STONE_STAIRS_UP
#nh-dngn/staircase_up DNGN_STONE_STAIRS_UP_II
#nh-dngn/staircase_up DNGN_STONE_STAIRS_UP_III
rock_stairs_up DNGN_ROCK_STAIRS_UP
dngn_enter_shop DNGN_ENTER_SHOP
dngn_enter_labyrinth DNGN_ENTER_LABYRINTH
dngn_enter_dis DNGN_ENTER_DIS
dngn_enter_gehenna DNGN_ENTER_GEHENNA
dngn_enter_cocytus DNGN_ENTER_COCYTUS
dngn_enter_tartarus DNGN_ENTER_TARTARUS
dngn_enter_abyss DNGN_ENTER_ABYSS
dngn_exit DNGN_EXIT_ABYSS
dngn_stone_arch DNGN_STONE_ARCH
dngn_enter_pandemonium DNGN_ENTER_PANDEMONIUM
dngn_exit DNGN_EXIT_PANDEMONIUM
dngn_transit_pandemonium DNGN_TRANSIT_PANDEMONIUM
####846 DNGN_BUILDER_SPECIAL_WALL
####846 DNGN_BUILDER_SPECIAL_FLOOR
dngn_enter DNGN_ENTER
#851 DNGN_ENTER_ORCISH_MINES
#851 DNGN_ENTER_HIVE
#851 DNGN_ENTER_LAIR
#851 DNGN_ENTER_SLIME_PITS
#851 DNGN_ENTER_VAULTS
#851 DNGN_ENTER_CRYPT
#851 DNGN_ENTER_HALL_OF_BLADES
#851 DNGN_ENTER_ZOT
#851 DNGN_ENTER_TEMPLE
#851 DNGN_ENTER_SNAKE_PIT
#851 DNGN_ENTER_ELVEN_HALLS
#851 DNGN_ENTER_TOMB
#851 DNGN_ENTER_SWAMP
dngn_return DNGN_RETURN
#850 DNGN_RETURN_FROM_ORCISH_MINES
#850 DNGN_RETURN_FROM_HIVE
#850 DNGN_RETURN_FROM_LAIR
#850 DNGN_RETURN_FROM_SLIME_PITS
#850 DNGN_RETURN_FROM_VAULTS
#850 DNGN_RETURN_FROM_CRYPT
#850 DNGN_RETURN_FROM_HALL_OF_BLADES
#850 DNGN_RETURN_FROM_ZOT
#850 DNGN_RETURN_FROM_TEMPLE
#850 DNGN_RETURN_FROM_SNAKE_PIT
#850 DNGN_RETURN_FROM_ELVEN_HALLS
#850 DNGN_RETURN_FROM_TOMB
#850 DNGN_RETURN_FROM_SWAMP
dngn_altar_zin DNGN_ALTAR_ZIN
dngn_altar_shining_one DNGN_ALTAR_SHINING_ONE
dngn_altar_kikubaaqudgha DNGN_ALTAR_KIKUBAAQUDGHA
dngn_altar_yredelemnul DNGN_ALTAR_YREDELEMNUL
dngn_altar_xom DNGN_ALTAR_XOM
dngn_altar_vehumet DNGN_ALTAR_VEHUMET
dngn_altar_okawaru DNGN_ALTAR_OKAWARU
dngn_altar_makhleb DNGN_ALTAR_MAKHLEB
dngn_altar_sif_muna DNGN_ALTAR_SIF_MUNA
dngn_altar_trog DNGN_ALTAR_TROG
dngn_altar_nemelex_xobeh DNGN_ALTAR_NEMELEX_XOBEH
dngn_altar_elyvilon DNGN_ALTAR_ELYVILON
dngn_altar_lugonu DNGN_ALTAR_LUGONU
dngn_altar_beogh DNGN_ALTAR_BEOGH
dngn_blue_fountain DNGN_BLUE_FOUNTAIN
dngn_dry_fountain DNGN_DRY_FOUNTAIN
dngn_sparkling_fountain DNGN_SPARKLING_FOUNTAIN
#858 DNGN_DRY_FOUNTAIN_II
#858 DNGN_DRY_FOUNTAIN_III
#858 DNGN_DRY_FOUNTAIN_IV
#858 DNGN_DRY_FOUNTAIN_V
#858 DNGN_DRY_FOUNTAIN_VI
#858 DNGN_DRY_FOUNTAIN_VII
#858 DNGN_DRY_FOUNTAIN_VIII
#858 DNGN_PERMADRY_FOUNTAIN
### dungeon crawl monster corpses
%sdir dc-mon
%corpse 1
%subst large_mimic
%back dc-misc/blood_red
glowing_shapeshifter CORPSE_GLOWING_SHAPESHIFTER /* @ */
hell_knight CORPSE_HELL_KNIGHT /* @ */
human CORPSE_HUMAN /* @ */
necromancer CORPSE_NECROMANCER /* @ */
shapeshifter CORPSE_SHAPESHIFTER /* @ */
wizard CORPSE_WIZARD /* @ */
%back dc-misc/blood_green
boring_beetle CORPSE_BORING_BEETLE /* B */
boulder_beetle CORPSE_BOULDER_BEETLE /* B */
giant_beetle CORPSE_GIANT_BEETLE /* B */
%back dc-misc/blood_red
cyclops CORPSE_CYCLOPS /* C */
fire_giant CORPSE_FIRE_GIANT /* C */
frost_giant CORPSE_FROST_GIANT /* C */
hill_giant CORPSE_HILL_GIANT /* C */
stone_giant CORPSE_STONE_GIANT /* C */
titan CORPSE_TITAN /* C */
dragon CORPSE_DRAGON /* D */
golden_dragon CORPSE_GOLDEN_DRAGON /* D */
hydra5 CORPSE_HYDRA /* D */
ice_dragon CORPSE_ICE_DRAGON /* D */
shadow_dragon CORPSE_SHADOW_DRAGON /* D */
storm_dragon CORPSE_STORM_DRAGON /* D */
swamp_dragon CORPSE_SWAMP_DRAGON /* D */
wyvern CORPSE_WYVERN /* D */
blink_frog CORPSE_BLINK_FROG /* F */
giant_brown_frog CORPSE_GIANT_BROWN_FROG /* F */
giant_frog CORPSE_GIANT_FROG /* F */
spiny_frog CORPSE_SPINY_FROG /* F */
eye_of_draining CORPSE_EYE_OF_DRAINING /* G */
giant_eyeball CORPSE_GIANT_EYEBALL /* G */
giant_orange_brain CORPSE_GIANT_ORANGE_BRAIN /* G */
great_orb_of_eyes CORPSE_GREAT_ORB_OF_EYES /* G */
griffon CORPSE_GRIFFON /* H */
hippogriff CORPSE_HIPPOGRIFF /* H */
giant_amoeba CORPSE_GIANT_AMOEBA /* J */
%back dc-misc/blood_green
kobold CORPSE_KOBOLD /* K */
%back dc-misc/blood_red
greater_naga0 CORPSE_GREATER_NAGA /* N */
guardian_naga CORPSE_GUARDIAN_NAGA /* N */
naga0 CORPSE_NAGA /* N */
###naga_mage CORPSE_NAGA_MAGE /* N */
###naga_warrior CORPSE_NAGA_WARRIOR /* N */
ogre CORPSE_OGRE /* O */
two_headed_ogre CORPSE_TWO_HEADED_OGRE /* O */
%back dc-misc/blood_green
queen_ant CORPSE_QUEEN_ANT /* Q */
queen_bee CORPSE_QUEEN_BEE /* Q */
%back dc-misc/blood_red
black_snake CORPSE_BLACK_SNAKE /* S */
brown_snake CORPSE_BROWN_SNAKE /* S */
grey_snake CORPSE_GREY_SNAKE /* S */
small_snake CORPSE_SMALL_SNAKE /* S */
snake CORPSE_SNAKE /* S */
yellow_snake CORPSE_YELLOW_SNAKE /* S */
deep_troll CORPSE_DEEP_TROLL /* T */
iron_troll CORPSE_IRON_TROLL /* T */
rock_troll CORPSE_ROCK_TROLL /* T */
troll CORPSE_TROLL /* T */
bear CORPSE_BEAR /* U */
black_bear CORPSE_BLACK_BEAR /* U */
grizzly_bear CORPSE_GRIZZLY_BEAR /* U */
polar_bear CORPSE_POLAR_BEAR /* U */
death_yak CORPSE_DEATH_YAK /* Y */
sheep CORPSE_SHEEP /* Y */
yak CORPSE_YAK /* Y */
%back dc-misc/blood_green
giant_ant CORPSE_GIANT_ANT /* a */
giant_cockroach CORPSE_GIANT_COCKROACH /* a */
soldier_ant CORPSE_SOLDIER_ANT /* a */
butterfly CORPSE_BUTTERFLY /* b */
%back dc-misc/blood_red
giant_bat CORPSE_GIANT_BAT /* b */
centaur CORPSE_CENTAUR /* c */
###centaur_warrior CORPSE_CENTAUR_WARRIOR /* c */
yaktaur CORPSE_YAKTAUR /* c */
###yaktaur_captain CORPSE_YAKTAUR_CAPTAIN /* c */
firedrake CORPSE_FIREDRAKE /* d */
lindwurm CORPSE_LINDWURM /* d */
mottled_dragon CORPSE_MOTTLED_DRAGON /* d */
steam_dragon CORPSE_STEAM_DRAGON /* d */
swamp_drake CORPSE_SWAMP_DRAKE /* d */
death_drake CORPSE_DEATH_DRAKE /* d */
##deep_elf_annihilator CORPSE_DEEP_ELF_ANNIHILATOR /* e */
##deep_elf_conjurer CORPSE_DEEP_ELF_CONJURER /* e */
##deep_elf_death_mage CORPSE_DEEP_ELF_DEATH_MAGE /* e */
##deep_elf_demonologist CORPSE_DEEP_ELF_DEMONOLOGIST /* e */
##deep_elf_fighter CORPSE_DEEP_ELF_FIGHTER /* e */
##deep_elf_high_priest CORPSE_DEEP_ELF_HIGH_PRIEST /* e */
##deep_elf_knight CORPSE_DEEP_ELF_KNIGHT /* e */
##deep_elf_mage CORPSE_DEEP_ELF_MAGE /* e */
##deep_elf_priest CORPSE_DEEP_ELF_PRIEST /* e */
##deep_elf_soldier CORPSE_DEEP_ELF_SOLDIER /* e */
##deep_elf_sorcerer CORPSE_DEEP_ELF_SORCERER /* e */
##deep_elf_summoner CORPSE_DEEP_ELF_SUMMONER /* e */
elf CORPSE_ELF /* e */
gnoll0 CORPSE_GNOLL /* g */
goblin0 CORPSE_GOBLIN /* g */
hobgoblin0 CORPSE_HOBGOBLIN /* g */
hog CORPSE_HOG /* h */
hound CORPSE_HOUND /* h */
warg CORPSE_WARG /* h */
war_dog CORPSE_WAR_DOG /* h */
wolf CORPSE_WOLF /* h */
jackal CORPSE_JACKAL /* j */
%back dc-misc/blood_green
bumblebee CORPSE_BUMBLEBEE /* k */
killer_bee CORPSE_KILLER_BEE /* k */
%back dc-misc/blood_red
giant_gecko CORPSE_GIANT_GECKO /* l */
giant_iguana CORPSE_GIANT_IGUANA /* l */
giant_lizard CORPSE_GIANT_LIZARD /* l */
giant_newt CORPSE_GIANT_NEWT /* l */
gila_monster CORPSE_GILA_MONSTER /* l */
komodo_dragon CORPSE_KOMODO_DRAGON /* l */
%back dc-misc/blood_green
elephant_slug CORPSE_ELEPHANT_SLUG /* m */
giant_slug CORPSE_GIANT_SLUG /* m */
giant_snail CORPSE_GIANT_SNAIL /* m */
manticore CORPSE_MANTICORE /* m */
%back dc-misc/blood_red
minotaur CORPSE_MINOTAUR /* m */
%back dc-misc/blood_green
ghoul CORPSE_GHOUL /* n */
necrophage CORPSE_NECROPHAGE /* n */
%back dc-misc/blood_red
orc0 CORPSE_ORC /* o */
###orc_high_priest CORPSE_ORC_HIGH_PRIEST /* o */
###orc_priest CORPSE_ORC_PRIEST /* o */
###orc_sorcerer CORPSE_ORC_SORCERER /* o */
###orc_warlord CORPSE_ORC_WARLORD /* o */
green_rat CORPSE_GREEN_RAT /* r */
grey_rat CORPSE_GREY_RAT /* r */
orange_rat CORPSE_ORANGE_RAT /* r */
quokka CORPSE_QUOKKA /* r */
rat CORPSE_RAT /* r */
%back dc-misc/blood_green
giant_centipede CORPSE_GIANT_CENTIPEDE /* s */
giant_mite CORPSE_GIANT_MITE /* s */
redback CORPSE_REDBACK /* s */
scorpion CORPSE_SCORPION /* s */
wolf_spider CORPSE_WOLF_SPIDER /* s */
ugly_thing CORPSE_UGLY_THING /* u */
very_ugly_thing CORPSE_VERY_UGLY_THING /* u */
killer_bee_larva CORPSE_ANT_LARVA /* w */
brain_worm CORPSE_BRAIN_WORM /* w */
killer_bee_larva CORPSE_KILLER_BEE_LARVA /* w */
spiny_worm CORPSE_SPINY_WORM /* w */
worm CORPSE_WORM /* w */
giant_blowfly CORPSE_GIANT_BLOWFLY /* y */
giant_mosquito CORPSE_GIANT_MOSQUITO /* y */
red_wasp CORPSE_RED_WASP /* y */
yellow_wasp CORPSE_YELLOW_WASP /* y */
%sdir player
%start
%compose drcwing/drcwing_black
%compose base/draconian_black_m
%compose drchead/drchead_black
%finish CORPSE_DRACONIAN_BLACK
%start
%compose drcwing/drcwing_brown
%compose base/draconian_f
%compose drchead/drchead_brown
%finish CORPSE_DRACONIAN_BROWN
%start
%compose drcwing/drcwing_green
%compose base/draconian_green_m
%compose drchead/drchead_green
%finish CORPSE_DRACONIAN_GREEN
%start
%compose drcwing/drcwing_grey
%compose base/draconian_gray_f
%compose drchead/drchead_grey
%finish CORPSE_DRACONIAN_GREY
%start
%compose drcwing/drcwing_mottled
%compose base/draconian_mottled_m
%compose drchead/drchead_mottled
%finish CORPSE_DRACONIAN_MOTTLED
%start
%compose drcwing/drcwing_pale
%compose base/draconian_pale_f
%compose drchead/drchead_pale
%finish CORPSE_DRACONIAN_PALE
%start
%compose drcwing/drcwing_purple
%compose base/draconian_purple_m
%compose drchead/drchead_purple
%finish CORPSE_DRACONIAN_PURPLE
%start
%compose drcwing/drcwing_red
%compose base/draconian_red_f
%compose drchead/drchead_red
%finish CORPSE_DRACONIAN_RED
%start
%compose drcwing/drcwing_white
%compose base/draconian_white_m
%compose drchead/drchead_white
%finish CORPSE_DRACONIAN_WHITE
%start
%compose drcwing/drcwing_yellow
%compose base/draconian_gold_f
%compose drchead/drchead_yellow
%finish CORPSE_DRACONIAN_YELLOW
%tiledef tiledef.h
%width 30
%back none
#%htmlfile tile.htm
#%tilelist tile.txt
#%htmlbody
%name tile
## Dungeon features
%include dc-dngn.txt
## Set black rim
## Items
%include dc-item.txt
## Monsters
%include dc-mon.txt
## Clear black rim
%rim 0
## Corpse
%back dc/blood
%corpse 1
%include dc-co.txt
%back none
%corpse 0
####PLAYER
####include dc-jobs.txt
#### Effects, etc.
%include dc-misc.txt
#-------------------------------------
# bmp2png & png2bmp
# makefile for gcc/gmake
# Thanks to Gary Aviv for this file.
#-------------------------------------
ifndef BINDIR
BINDIR = /usr/local/bin
endif
CC = gcc
LD = gcc
ifndef INSTALL
INSTALL = install -s -m 755
endif
ifndef CFLAGS
CFLAGS = -O2 -g -Wall
endif
LIBS = -lpng -lz -lm
B2POBJ = bmp2png.o common.o
P2BOBJ = png2bmp.o common.o
all : bmp2png png2bmp
bmp2png : $(B2POBJ)
$(LD) $(LDFLAGS) -o bmp2png $(B2POBJ) $(LIBS)
png2bmp : $(P2BOBJ)
$(LD) $(LDFLAGS) -o png2bmp $(P2BOBJ) $(LIBS)
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
install :
$(INSTALL) bmp2png png2bmp $(BINDIR)
uninstall :
rm -f $(BINDIR)/bmp2png $(BINDIR)/png2bmp
clean :
rm -f $(B2POBJ) $(P2BOBJ) bmp2png png2bmp
bmp2png.o : bmp2png.c common.h bmphed.h
png2bmp.o : png2bmp.c common.h bmphed.h
common.o : common.c common.h
#-----------------------------
# bmp2png.exe & png2bmp.exe
# makefile for DJGPP V.2
#-----------------------------
srcdir = .
VPATH = $(srcdir)
ZINC = $(srcdir)/../zlib
PINC = $(srcdir)/../libpng
ZLIB = $(srcdir)/../zlib
PLIB = $(srcdir)/../libpng
CC = gcc
LD = gcc
CFLAGS = -O2 -Wall -mcpu=pentium -march=i386 -DPNG_USER_CONFIG \
-I$(PINC) -I$(ZINC) $(COPT)
LDFLAGS = -s -L$(PLIB) -L$(ZLIB) $(LOPT)
LIBS = -lpng -lz -lm
B2POBJ = bmp2png.o common.o
P2BOBJ = png2bmp.o common.o
B2PMAP = -Wl,-Map,bmp2png.map
P2BMAP = -Wl,-Map,png2bmp.map
all : bmp2png.exe png2bmp.exe
bmp2png.exe : $(B2POBJ)
$(LD) $(LDFLAGS) $(B2PMAP) -o $@ $(B2POBJ) $(LIBS)
png2bmp.exe : $(P2BOBJ)
$(LD) $(LDFLAGS) $(P2BMAP) -o $@ $(P2BOBJ) $(LIBS)
%.o : %.c
$(CC) $(CFLAGS) -c $<
%.s : %.c
$(CC) $(CFLAGS) -S -fverbose-asm $<
%.lst : %.s
$(CC) -Wa,-a=$@ -c -o NUL $<
clean : mostlyclean
if exist *.exe del *.exe
if exist *.map del *.map
mostlyclean :
if exist *.o del *.o
bmp2png.o : bmp2png.c common.h bmphed.h
png2bmp.o : png2bmp.c common.h bmphed.h
common.o : common.c common.h
#--------------------------------
# bmp2png.exe & png2bmp.exe
# makefile for Borland C++ 5.5
#--------------------------------
!ifndef srcdir
srcdir = .
!endif
.path.c = $(srcdir)
.path.h = $(srcdir)
ZINC = $(srcdir)/../zlib
PINC = $(srcdir)/../libpng
ZLIB = $(srcdir)/../zlib
PLIB = $(srcdir)/../libpng
CC = bcc32
LD = bcc32
CFLAGS = $(MODEL) -q -d -O2 -OS -Oi -Oc -DPNG_USER_CONFIG -I$(PINC) \
-I$(ZINC) $(COPT)
LDFLAGS = $(MODEL) -q -WC -L$(PLIB) -L$(ZLIB) $(LOPT)
LIBS = libpng.lib zlib.lib noeh32.lib
B2POBJ = bmp2png.obj common.obj
P2BOBJ = png2bmp.obj common.obj
all : bmp2png.exe png2bmp.exe
bmp2png.exe : $(B2POBJ)
$(LD) $(LDFLAGS) -e$@ $(B2POBJ) $(LIBS)
png2bmp.exe : $(P2BOBJ)
$(LD) $(LDFLAGS) -e$@ $(P2BOBJ) $(LIBS)
.c.obj :
$(CC) $(CFLAGS) -c $*.c
.c.asm :
$(CC) $(CFLAGS) -S $*.c
clean : mostlyclean
if exist *.exe del *.exe
mostlyclean :
if exist *.obj del *.obj
if exist *.tds del *.tds
bmp2png.obj : bmp2png.c common.h bmphed.h
png2bmp.obj : png2bmp.c common.h bmphed.h
common.obj : common.c common.h
/*
** bmp2png --- conversion from (Windows or OS/2 style) BMP to PNG
** png2bmp --- conversion from PNG to (Windows style) BMP
**
** Copyright (C) 1999-2005 MIYASAKA Masaru <alkaid@coral.ocn.ne.jp>
**
** Permission to use, copy, modify, and distribute this software and
** its documentation for any purpose and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and
** that both that copyright notice and this permission notice appear
** in supporting documentation. This software is provided "as is"
** without express or implied warranty.
**
** NOTE: Comments are partly written in Japanese. Sorry.
*/
#ifndef COMMON_H
#define COMMON_H
#if defined(__RSXNT__) && defined(__CRTRSXNT__)
# include <crtrsxnt.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
/* for stat() */
#include <sys/types.h>
#include <sys/stat.h>
/* for utime() */
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__LCC__)
# include <sys/utime.h>
# if defined(__LCC__)
int utime(const char *, struct _utimbuf *);
# endif
#else
# include <utime.h>
#endif
/* for isatty() */
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) || \
defined(__LCC__)
# include <io.h>
#else
# include <unistd.h>
#endif
/* for mkdir() */
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) || \
defined(__LCC__)
# include <direct.h>
# if defined(__MINGW32__)
# define MKDIR(d,m) _mkdir(d)
# else
# define MKDIR(d,m) mkdir(d)
# endif
#else
# if defined(__GO32__) && !defined(__DJGPP__) /* DJGPP v.1 */
# include <osfcn.h>
# else
# include <sys/stat.h>
# endif
# define MKDIR(d,m) mkdir(d,m)
#endif
#if !defined(BINSTDIO_FDOPEN) && !defined(BINSTDIO_SETMODE)
# if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__EMX__) || \
defined(_MSC_VER) || defined(__BORLANDC__) || defined(__LCC__) || \
defined(__DJGPP__) || defined(__GO32__)
# define BINSTDIO_SETMODE
# endif
# if 0 /* defined(__YOUR_COMPLIER_MACRO__) */
# define BINSTDIO_FDOPEN
# endif
#endif
/* for setmode() */
#ifdef BINSTDIO_SETMODE
# include <io.h>
# include <fcntl.h>
#endif
#include "png.h"
#if (PNG_LIBPNG_VER < 10004)
# error libpng version 1.0.4 or later is required.
#endif
#if (PNG_LIBPNG_VER == 10207) || (PNG_LIBPNG_VER == 10206) || \
(PNG_LIBPNG_VER == 10017) || (PNG_LIBPNG_VER == 10016)
# error Libpng versions 1.2.7, 1.2.6, 1.0.17, and 1.0.16
# error have a bug that will cause png2bmp to crash.
# error Update your libpng to latest version.
# error "http://www.libpng.org/pub/png/libpng.html"
#endif
#if !defined(PNG_READ_tRNS_SUPPORTED) || !defined(PNG_WRITE_tRNS_SUPPORTED)
# error This software requires tRNS chunk support.
#endif
#ifndef png_jmpbuf /* pngconf.h (libpng 1.0.6 or later) */
# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
#endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if defined(__CYGWIN__)
# undef WIN32
# undef MSDOS
#endif
#if defined(WIN32) || defined(__DJGPP__)
# define WIN32_LFN /* Win32-style long filename */
#endif
#if defined(WIN32) || defined(MSDOS)
# define PATHDELIM '\\'
# define DRIVESUFFIX ':'
# define IsPathDelim(c) ((c)==PATHDELIM || (c)=='/')
# define IsOptChar(c) ((c)=='-' || (c)=='/')
# ifdef JAPANESE
# define IsDBCSLead(c) ((0x81<=(c) && (c)<=0x9F) || (0xE0<=(c) && (c)<=0xFC))
# else
# define IsDBCSLead(c) (0)
# endif
#else /* UNIX */
# define PATHDELIM '/'
# define IsPathDelim(c) ((c)==PATHDELIM)
# define IsOptChar(c) ((c)=='-')
# define IsDBCSLead(c) (0)
#endif
typedef char CHAR;
typedef unsigned char BYTE;
typedef short SHORT;
typedef unsigned short WORD;
typedef int INT;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned long DWORD;
typedef enum { FALSE = 0, TRUE = 1 } BOOL;
typedef png_color PALETTE;
typedef struct tagIMAGE {
LONG width;
LONG height;
UINT pixdepth;
UINT palnum;
BOOL topdown;
BOOL alpha;
/* ----------- */
DWORD rowbytes;
DWORD imgbytes;
PALETTE *palette;
BYTE **rowptr;
BYTE *bmpbits;
/* ----------- */
png_color_8 sigbit;
} IMAGE;
extern int quietmode;
extern int errorlog;
extern const char errlogfile[];
void xxprintf(const char *, ...);
void set_status(const char *, ...);
void feed_line(void);
void init_progress_meter(png_structp, png_uint_32, png_uint_32);
void row_callback(png_structp, png_uint_32, int);
void png_my_error(png_structp, png_const_charp);
void png_my_warning(png_structp, png_const_charp);
BOOL imgbuf_alloc(IMAGE *);
void imgbuf_free(IMAGE *);
void imgbuf_init(IMAGE *);
int parsearg(int *, char **, int, char **, char *);
char **envargv(int *, char ***, const char *);
int tokenize(char *, const char *);
int makedir(const char *);
int renbak(const char *);
int cpyftime(const char *, const char *);
FILE *binary_stdio(int);
char *suffix(const char *);
char *basname(const char *);
char *addslash(char *);
char *delslash(char *);
char *path_skiproot(const char *);
char *path_nextslash(const char *);
#ifdef WIN32_LFN
int is_dos_filename(const char *);
#endif
#endif /* COMMON_H */
/*
** bmphed.h - .bmp file header macros
**
** Public domain by MIYASAKA Masaru (July 13, 2004)
*/
#ifndef BMPHED_H
#define BMPHED_H
/* BMP file signature */
#define BMP_SIGNATURE 0x4D42
#define BMP_SIG_BYTES 2
/* BITMAPFILEHEADER */
#define BFH_WTYPE 0 /* WORD bfType; */
#define BFH_DSIZE 2 /* DWORD bfSize; */
#define BFH_WRESERVED1 6 /* WORD bfReserved1; */
#define BFH_WRESERVED2 8 /* WORD bfReserved2; */
#define BFH_DOFFBITS 10 /* DWORD bfOffBits; */
#define BFH_DBIHSIZE 14 /* DWORD biSize; */
#define FILEHED_SIZE 14 /* sizeof(BITMAPFILEHEADER) */
#define BIHSIZE_SIZE 4 /* sizeof(biSize) */
/* BITMAPINFOHEADER, BITMAPV4HEADER, BITMAPV5HEADER */
#define BIH_DSIZE 0 /* DWORD biSize; */
#define BIH_LWIDTH 4 /* LONG biWidth; */
#define BIH_LHEIGHT 8 /* LONG biHeight; */
#define BIH_WPLANES 12 /* WORD biPlanes; */
#define BIH_WBITCOUNT 14 /* WORD biBitCount; */
#define BIH_DCOMPRESSION 16 /* DWORD biCompression; */
#define BIH_DSIZEIMAGE 20 /* DWORD biSizeImage; */
#define BIH_LXPELSPERMETER 24 /* LONG biXPelsPerMeter; */
#define BIH_LYPELSPERMETER 28 /* LONG biYPelsPerMeter; */
#define BIH_DCLRUSED 32 /* DWORD biClrUsed; */
#define BIH_DCLRIMPORANT 36 /* DWORD biClrImportant; */
#define B4H_DREDMASK 40 /* DWORD bV4RedMask; */
#define B4H_DGREENMASK 44 /* DWORD bV4GreenMask; */
#define B4H_DBLUEMASK 48 /* DWORD bV4BlueMask; */
#define B4H_DALPHAMASK 52 /* DWORD bV4AlphaMask; */
#define B4H_DCSTYPE 56 /* DWORD bV4CSType; */
#define B4H_XENDPOINTS 60 /* CIEXYZTRIPLE bV4Endpoints; */
#define B4H_DGAMMARED 96 /* DWORD bV4GammaRed; */
#define B4H_DGAMMAGREEN 100 /* DWORD bV4GammaGreen; */
#define B4H_DGAMMABLUE 104 /* DWORD bV4GammaBlue; */
#define B5H_DINTENT 108 /* DWORD bV5Intent; */
#define B5H_DPROFILEDATA 112 /* DWORD bV5ProfileData; */
#define B5H_DPROFILESIZE 116 /* DWORD bV5ProfileSize; */
#define B5H_DRESERVED 120 /* DWORD bV5Reserved; */
#define INFOHED_SIZE 40 /* sizeof(BITMAPINFOHEADER) */
#define BMPV4HED_SIZE 108 /* sizeof(BITMAPV4HEADER) */
#define BMPV5HED_SIZE 124 /* sizeof(BITMAPV5HEADER) */
/* BITMAPCOREHEADER */
#define BCH_DSIZE 0 /* DWORD bcSize; */
#define BCH_WWIDTH 4 /* WORD bcWidth; */
#define BCH_WHEIGHT 6 /* WORD bcHeight; */
#define BCH_WPLANES 8 /* WORD bcPlanes; */
#define BCH_WBITCOUNT 10 /* WORD bcBitCount; */
#define COREHED_SIZE 12 /* sizeof(BITMAPCOREHEADER) */
/* RGBQUAD */
#define RGBQ_BLUE 0 /* BYTE rgbBlue; */
#define RGBQ_GREEN 1 /* BYTE rgbGreen; */
#define RGBQ_RED 2 /* BYTE rgbRed; */
#define RGBQ_RESERVED 3 /* BYTE rgbReserved; */
#define RGBQUAD_SIZE 4 /* sizeof(RGBQUAD) */
/* RGBTRIPLE */
#define RGBT_BLUE 0 /* BYTE rgbtBlue; */
#define RGBT_GREEN 1 /* BYTE rgbtGreen; */
#define RGBT_RED 2 /* BYTE rgbtRed; */
#define RGBTRIPLE_SIZE 3 /* sizeof(RGBTRIPLE) */
/* Constants for the biCompression field */
#ifndef BI_RGB
#define BI_RGB 0L /* Uncompressed */
#define BI_RLE8 1L /* RLE (8 bits/pixel) */
#define BI_RLE4 2L /* RLE (4 bits/pixel) */
#define BI_BITFIELDS 3L /* Bitfield */
#define BI_JPEG 4L /* JPEG Extension */
#define BI_PNG 5L /* PNG Extension */
#endif
#endif /* BMPHED_H */
bmp2png / png2bmp version 1.62 - Sep 04, 2005
---------------------------------------------
bmp2png/png2bmp is a pair of simple command-line utilities that convert
between Windows BMP format and PNG (Portable Network Graphics).
This software is freeware.
Using them
----------
The basic command line is:
bmp2png [-options] list of bmp files ...
png2bmp [-options] list of png files ...
The input files are not modified; the output data is written to files
which have the same names except for extension. bmp2png always uses
".png" for the output file name's extension; png2bmp uses ".bmp".
To list the options, simply type "bmp2png" or "png2bmp" with no
arguments.
Copyright notice, and license
-----------------------------
bmp2png --- conversion from (Windows or OS/2 style) BMP to PNG
png2bmp --- conversion from PNG to (Windows style) BMP
Copyright (C) 1999-2005 MIYASAKA Masaru <alkaid@coral.ocn.ne.jp>
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation. This software is provided "as is"
without express or implied warranty.
The latest version
------------------
To get the latest version of bmp2png/png2bmp, please visit the
bmp2png/png2bmp home page:
http://hp.vector.co.jp/authors/VA010446/b2p-home/
Major changes
-------------
version 1.60 [August 25, 2004]
bmp2png now can read all types of BMP file, including
16/32 bits/pixel BMP, bitfield BMP, and RLE-encoded BMP.
Added -P option to bmp2png, which allows to make one particular
color fully transparent.
version 1.61 [September 4, 2004]
(executable) Fixed a file-corruption bug which was introduced
in libpng 1.2.6.
(source code) Added support for emx complier (not tested).
version 1.62 [September 4, 2005]
Added alpha channel support. (Added -A, -B and -R options.)
[end]
#ifdef USE_TILE
// We could check for this above, but we need to do this post-move
// to force the merfolk tile to be out of water.
if ((!grid_is_water(new_grid) && grid_is_water(old_grid) ||
grid_is_water(new_grid) && !grid_is_water(old_grid))
&& you.species == SP_MERFOLK)
{
TilePlayerRefresh();
}
#endif
}
#ifdef USE_TILE
void draw_hp_bar(int hp, int maxhp)
{
#define HPBAR_OX 20
#define HPBAR_OY 3
#define HPBAR_WIDTH (40-HPBAR_OX)
static int oldhp = 0;
static int oldhx = 0;
int cx;
int hx = HPBAR_WIDTH * hp / maxhp;
gotoxy(HPBAR_OX, HPBAR_OY, GOTO_STAT);
for (cx=0;cx<HPBAR_WIDTH;cx++)
{
textcolor(BLACK + DARKGRAY*16);
if (cx<hx)
textcolor(BLACK + GREEN*16);
else if (oldhp>hp && oldhx>hx && cx<oldhx && cx>=hx)
textcolor(BLACK + RED*16);
putch(' ');
}
textcolor(LIGHTGREY);
oldhp=hp;
oldhx=hx;
# -*- Makefile -*- for Dungeon Crawl (Win32, MinGW)
# makefile.obj includes a list of object files needed to build Crawl.
include makefile.obj
ifeq ($(DEBUG_CRAWL),)
OPATH := rel
else
OPATH := dbg
endif
# need .exe so make will find the right file
APPNAME = $(OPATH)\crawl.exe
CXX = g++
DELETE = del
COPY = copy
OS_TYPE = WIN32TILES
INSTALLDIR := $(OPATH)
# If you don't have flex or bison, set DOYACC to N or empty.
DOYACC := n
LEX := flex
YACC := bison -y
ifeq ($(LUASRC),)
LUASRC := util\lua\src
endif
LUALIB = lua
LUALIBA = lib$(LUALIB).a
SQLSRC := util\sqlite
SQLLIB := sqlite3
SQLIBA := lib$(SQLLIB).a
FSQLLIBA := $(SQLLIB)\$(SQLIBA)
LIB = -static -lwinmm -mwindows -lcomctl32 -L$(LUASRC) -l$(LUALIB) -L$(SQLSRC) -l$(SQLLIB)
INCLUDES := -Iutil -I. -I$(LUASRC) -I$(SQLSRC)
CFWARN := -Wall -Wwrite-strings \
-Werror \
-pedantic
# -Wshadow
CFOTHERS := -fsigned-char \
-fstrict-aliasing \
-pedantic \
-D$(OS_TYPE) $(EXTRA_FLAGS) \
-DWINMM_PLAY_SOUNDS -DCLUA_BINDINGS \
-DUSE_TILE -DWINVER=0x0400 -D_WIN32_IE=0x0400
# -DREGEX_PCRE
CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS)
YCFLAGS := $(INCLUDES) $(CFOTHERS)
OBJECTS := $(OBJECTS) libgui.o tile1.o tile2.o libwt.o guic.o guic-win.o
LDFLAGS =
UTIL = util/
YTABC := levcomp.tab.c
YTABH := levcomp.tab.h
RLTILES = rltiles
TILEHEADERS = \
tiledef.h \
tiledef-p.h \
tiledef-w2d.h \
tilecount-w2d.h \
tilep-cmt.h
TILEFILES = \
tile.bmp \
player.bmp \
wall2d.bmp
DESTTILEFILES = $(TILEFILES:%=dat\tiles\\%)
ifeq ($(LEX),)
DOYACC :=
endif
ifeq ($(YACC),)
DOYACC :=
endif
# Do the levcomp stuff first because that's the most likely to fail.
OBJECTS := levcomp.tab.o levcomp.lex.o \
$(OBJECTS)
OBJECTS := $(foreach file,$(OBJECTS),$(OPATH)/$(file))
GAME_DEPENDS := prepare $(LUASRC)\$(LUALIBA) $(FSQLLIBA) $(TILEHEADERS) $(DESTTILEFILES) $(OBJECTS)
##########################################################################
all: $(APPNAME)
prepare:
if not exist $(OPATH) mkdir $(OPATH)
DEPENDENCY_MKF := makefile.dep
-include $(DEPENDENCY_MKF)
##########################################################################
# The level compiler
#
ifeq ($(DOYACC),y)
# [ds] A plague on the broken copy command on Windoze.
prebuildyacc: $(UTIL)levcomp.lex.cc $(UTIL)levcomp.tab.cc $(UTIL)levcomp.tab.h
$(subst /,\,for %%f in ($^) do $(COPY) %%f prebuilt)
$(UTIL)levcomp.tab.cc: $(UTIL)levcomp.ypp
$(subst /,\, cd $(UTIL)) && $(YACC) -d -b levcomp levcomp.ypp
$(subst /,\, cd $(UTIL)) && move $(YTABC) levcomp.tab.cc
$(UTIL)levcomp.lex.cc: $(UTIL)levcomp.lpp
$(subst /,\, cd $(UTIL) && $(LEX) -olevcomp.lex.cc levcomp.lpp)
else
$(UTIL)levcomp.tab.cc: prebuilt/levcomp.tab.cc
$(subst /,\,$(COPY) prebuilt/*.h $(UTIL))
$(subst /,\,$(COPY) $< $@)
$(UTIL)levcomp.lex.cc: prebuilt/levcomp.lex.cc
$(subst /,\,$(COPY) $< $@)
endif
##########################################################################
# RLTiles
#
ORIGTILEHEADERS = $(TILEHEADERS:%=$(RLTILES)\\%)
ORIGTILEFILES = $(TILEFILES:%=$(RLTILES)\\%)
$(ORIGTILEHEADERS): makerltiles
makerltiles:
pushd $(RLTILES) && $(MAKE) -f makefile.mgw all && popd
$(TILEHEADERS): $(ORIGTILEHEADERS)
copy /y $(RLTILES)\$@ .
$(ORIGTILEFILES): makerltiles
dat\tiles\\%.bmp: rltiles\\%.bmp
mkdir dat\tiles 2>nul || echo "" >nul
$(COPY) $< $@
clean-rltiles:
pushd $(RLTILES) && $(MAKE) -f makefile.mgw distclean && popd
$(DELETE) $(TILEHEADERS)
##########################################################################
##########################################################################
install: $(APPNAME)
ifneq ($(OPATH),$(INSTALLDIR))
$(COPY) $(APPNAME) ${INSTALLDIR}
endif
mkdir $(INSTALLDIR)\dat 2>nul || echo "" >nul
mkdir $(INSTALLDIR)\dat\clua 2>null || echo "">nul
copy /y dat\*.des $(INSTALLDIR)\dat
copy /y dat\*.txt $(INSTALLDIR)\dat
copy /y dat\clua\*.lua $(INSTALLDIR)\dat\clua
copy /y ..\init.txt $(INSTALLDIR)
mkdir $(INSTALLDIR)\dat\tiles 2>nul || echo "" > nul
copy /y dat\tiles\*.bmp $(INSTALLDIR)\dat\tiles
clean:
$(DELETE) $(OPATH)\*.o
$(subst /,\,$(DELETE) $(UTIL)*.o)
$(subst /,\,$(DELETE) $(UTIL)*.exe)
$(subst /,\,$(DELETE) $(UTIL)*.lex.cc)
$(subst /,\,$(DELETE) $(UTIL)*.tab.cc)
$(subst /,\,$(DELETE) $(UTIL)*.tab.h)
$(subst /,\,$(DELETE) $(UTIL)*.tab.c)
$(subst /,\,$(DELETE) *.ixx)
clean-lua:
cd $(LUASRC) && $(MAKE) clean_win
clean-sql:
cd $(SQLSRC) && $(MAKE) "RM_F=del /f" clean
distclean: clean clean-lua clean-sql clean-rltiles
$(DELETE) $(OPATH)\*.o
$(DELETE) *.o
$(DELETE) bones.*
$(DELETE) $(OPATH)\bones.*
$(DELETE) morgue.txt
$(DELETE) $(OPATH)\morgue.txt
$(DELETE) scores
$(DELETE) $(OPATH)\scores
$(DELETE) crawl.exe
$(DELETE) $(subst /,\,$(APPNAME))
$(DELETE) *.sav
$(DELETE) $(OPATH)\*.sav
$(DELETE) core
$(DELETE) $(OPATH)\core
$(DELETE) *.0*
$(DELETE) $(OPATH)\*.0*
$(DELETE) *.lab
$(DELETE) $(OPATH)\*.lab
$(APPNAME): $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
strip $(APPNAME)
debug: $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
profile: $(GAME_DEPENDS)
${CXX} -g -p ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
$(OPATH)/%.o: %.cc
${CXX} ${CFLAGS} -o $@ -c $<
$(OPATH)/%.o: $(UTIL)%.cc
$(CXX) $(YCFLAGS) -o $@ -c $<
#############################################################################
# Build Lua
$(LUASRC)\$(LUALIBA):
@echo Building Lua...
@cd $(LUASRC) && $(MAKE) crawl_mingw
#############################################################################
# Build SQLite
$(FSQLLIBA):
@echo Building SQLite
cd $(SQLSRC) && $(MAKE)
# -*- Makefile -*- for Dungeon Crawl (unix)
#
# Modified for Crawl Reference by $Author: dshaligram $ on $Date: 2007-06-24T16:27:58.475101Z $
#
GAME = crawl
# this file contains a list of the libraries.
# it will make a variable called OBJECTS that contains all the libraries
include makefile.obj
OBJECTS += libgui.o tile1.o tile2.o libx11.o guic.o guic-x11.o
CXX = g++
DELETE = rm -f
COPY = cp
OS_TYPE = UNIX
EXTRA_INCLUDES = -DUSE_X11 -DUSE_TILE
# Change this to y if you want to use Unicode glyphs in the map, and you have
# libncursesw available.
UNICODE_GLYPHS = n
# If you have lex and yacc, set DOYACC to y (lowercase y).
DOYACC := y
# Permissions to set on the game executable.
MCHMOD := 2755
# Permissions to set on the save directory.
MCHMOD_SAVEDIR := 775
# The user:group to install the game as.
INSTALL_UGRP := games:games
INSTALLDIR := /usr/games/crawl
# If you're installing Crawl for multiple users, you *must* set this to a
# valid path before building Crawl. This is not necessary if you are building
# Crawl for a single user.
# SAVEDIR := /usr/games/crawl/saves/
# DATADIR := /usr/games/crawl/data/
LEX := flex
YACC := bison -y
ifeq ($(UNICODE_GLYPHS),y)
# Include path for (n)curses with Unicode support.
INCLUDES = -I/usr/include/ncursesw
# Your ncurses library may include Unicode support, and you may not have a
# separate libncursesw; in that case, change this line accordingly.
LIBCURS = ncursesw
EXTRA_FLAGS += -DUNICODE_GLYPHS
# The standard ncurses library also supports Unicode on Mac OS/Darwin.
ifeq ($(shell uname),Darwin)
LIBCURS = ncurses
endif
else
# Include path for curses or ncurses (non-Unicode).
INCLUDES = -I/usr/include/ncurses
LIBCURS = ncurses
endif
ifeq ($(LUASRC),)
LUASRC := util/lua/src
endif
LUALIB = lua
LUALIBA = l$(LUALIB).a
EXTRA_DEPENDS += $(LUASRC)$(LUALIBA)
DBH_FILE := /usr/include/db.h
NDBM_FILE := /usr/include/ndbm.h
HAVE_DBH := $(shell [ -f $(DBH_FILE) ] && echo y)
HAVE_NDBM := $(shell [ -f $(NDBM_FILE) ] && echo y)
ifeq ($(HAVE_DBH),y)
ifneq ($(shell grep dbm_open $(DBH_FILE)),)
SELDBM := -DDB_DBH
LIBDBM := -ldb
endif
endif
ifeq ($(HAVE_NDBM),y)
SELDBM ?= -DDB_NDBM
ifeq ($(SELDBM),-DDB_NDBM)
LIBDBM := -ldbm
endif
endif
SQLSRC := util/sqlite
SQLLIB := sqlite3
SQLLIBA := lib$(SQLLIB).a
FSQLLIBA := $(SQLSRC)/$(SQLLIBA)
ifeq ($(LIBDBM),)
LIBDBM := -L$(SQLSRC) -lsqlite3
EXTRA_INCLUDES += -I$(SQLSRC)
EXTRA_DEPENDS += $(FSQLLIBA)
endif
LIB = -l$(LIBCURS) -L$(LUASRC) -l$(LUALIB) $(LIBDBM) -L/usr/X11R6/lib -lX11 -lpng
INCLUDES := $(INCLUDES) -Iutil -I. -I$(LUASRC) $(EXTRA_INCLUDES)
CFWARN := -Wall -Wwrite-strings \
-Wshadow -pedantic
CFOTHERS := -fsigned-char -D$(OS_TYPE) $(EXTRA_FLAGS)
ifneq ($(SAVEDIR),)
CFOTHERS += '-DSAVE_DIR_PATH="$(SAVEDIR)"'
endif
ifneq ($(DATADIR),)
CFOTHERS += '-DDATA_DIR_PATH="$(DATADIR)"'
endif
CFOTHERS += $(SELDBM)
CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS)
YCFLAGS := $(INCLUDES) $(CFOTHERS)
UTIL = util/
YTABC := levcomp.tab.c
YTABH := levcomp.tab.h
RLTILES = rltiles/
TILEHEADERS = \
tiledef.h \
tiledef-p.h \
tiledef-w2d.h \
tilecount-w2d.h \
tilep-cmt.h
TILEFILES = \
tile.png \
player.png \
wall2d.png
DESTTILEFILES = $(TILEFILES:%=dat/tiles/%)
EXTRA_DEPENDS += $(TILEHEADERS) $(DESTTILEFILES)
OBJECTS := $(UTIL)levcomp.tab.o $(UTIL)levcomp.lex.o $(OBJECTS)
ifeq ($(LEX),)
DOYACC :=
endif
ifeq ($(YACC),)
DOYACC :=
endif
GAME_DEPENDS := $(EXTRA_DEPENDS) $(OBJECTS)
SRC_PKG_BASE := stone_soup
SRC_VERSION := $(shell egrep 'VER_NUM *".*"' version.h | \
egrep -o '[0-9]\.[0-9](\.[0-9])?')
PKG_SRC_DIR := $(SRC_PKG_BASE)-$(SRC_VERSION)-src
SRC_PKG_TAR := $(PKG_SRC_DIR).tbz2
SRC_PKG_ZIP := $(PKG_SRC_DIR).zip
PKG_TIDY_LIST := $(UTIL)*.o $(LEVCOMP) *.o \
$(UTIL)*.tab.cc $(UTIL)*.tab.h $(UTIL)*.lex.cc *.ixx
PKG_EXCLUDES := $(PWD)/misc/src-pkg-excludes.lst
##########################################################################
all: $(GAME)
##########################################################################
# Dependencies
DEPENDENCY_MKF := makefile.dep
depend: $(OBJECTS:.o=.cc)
rm -f $(DEPENDENCY_MKF)
@for i in $^; do \
echo "Updating dependencies for $$i"; \
$(CXX) -MM $(CFLAGS) $$i >>$(DEPENDENCY_MKF) 2>/dev/null; \
done
-include $(DEPENDENCY_MKF)
##########################################################################
# The level compiler
#
ifeq ($(DOYACC),y)
prebuildyacc: $(UTIL)levcomp.tab.cc $(UTIL)levcomp.tab.h $(UTIL)levcomp.lex.cc
cp $^ prebuilt/
$(UTIL)levcomp.tab.cc: $(UTIL)levcomp.ypp
cd $(UTIL) && $(YACC) -d -b levcomp levcomp.ypp \
&& mv $(YTABC) levcomp.tab.cc || false
$(UTIL)levcomp.lex.cc: $(UTIL)levcomp.lpp
cd $(UTIL) && $(LEX) -olevcomp.lex.cc levcomp.lpp
else
# Pull the level-compiler stuff up from prebuilt/
$(UTIL)levcomp.tab.cc: prebuilt/levcomp.tab.cc
cp prebuilt/*.h $(UTIL)
cp $< $@
$(UTIL)levcomp.lex.cc: prebuilt/levcomp.lex.cc
cp $< $@
endif
##########################################################################
# RLTiles
#
ORIGTILEHEADERS = $(TILEHEADERS:%=$(RLTILES)%)
ORIGTILEFILES = $(TILEFILES:%=$(RLTILES)%)
$(ORIGTILEHEADERS): makerltiles
makerltiles:
cd $(RLTILES) && make -f makefile.unix all && cd ..
$(TILEHEADERS): $(ORIGTILEHEADERS)
cp $(RLTILES)$@ .
$(ORIGTILEFILES): makerltiles
dat/tiles/%.png: rltiles/%.png
mkdir -p dat/tiles
$(COPY) $< $@
clean-rltiles:
cd $(RLTILES) && make -f makefile.unix distclean && cd ..
$(DELETE) $(TILEHEADERS)
##########################################################################
##########################################################################
# The actual build targets
#
install: $(GAME)
[ -d $(INSTALLDIR) ] || mkdir -p $(INSTALLDIR)
$(COPY) $(GAME) $(INSTALLDIR)
chown $(INSTALL_UGRP) $(INSTALLDIR)/$(GAME)
chmod ${MCHMOD} ${INSTALLDIR}/$(GAME)
ifeq ($(DATADIR),)
$(error DATADIR not set! Set DATADIR and run make clean install again)
endif
mkdir -p $(DATADIR)/dat/clua
cp dat/*.des $(DATADIR)/dat
cp dat/*.txt $(DATADIR)/dat
cp dat/clua/*.lua $(DATADIR)/dat/clua
cp -r lua $(DATADIR)/dat
mkdir -p $(DATADIR)/docs
cp ../docs/*.txt $(DATADIR)/docs
mkdir -p $(DATADIR)/dat/tiles
cp dat/tiles/*.png $(DATADIR)/dat/tiles
chown -R $(INSTALL_UGRP) $(DATADIR)
ifneq ($(SAVEDIR),)
mkdir -p $(SAVEDIR)
chown $(INSTALL_UGRP) $(SAVEDIR)
chmod $(MCHMOD_SAVEDIR) $(SAVEDIR)
endif
ln -s $(INSTALLDIR)/$(GAME) /usr/local/bin/
clean:
$(DELETE) *.o
$(DELETE) $(UTIL)*.o
$(DELETE) $(LEVCOMP)
$(DELETE) $(UTIL)*.tab.cc $(UTIL)*.tab.c $(UTIL)*.tab.h $(UTIL)*.lex.cc
$(DELETE) *.ixx
clean-lua:
cd $(LUASRC) && $(MAKE) clean
clean-sql:
cd $(SQLSRC) && $(MAKE) clean
distclean: clean clean-lua clean-sql clean-rltiles
$(DELETE) bones.*
$(DELETE) morgue.txt
$(DELETE) scores
$(DELETE) $(GAME)
$(DELETE) *.sav
$(DELETE) core
$(DELETE) *.0*
$(DELETE) *.lab
$(DELETE) $(DEPENDENCY_MKF)
$(GAME): $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
debug: $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
profile: $(GAME_DEPENDS)
${CXX} -g -p ${LDFLAGS} $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
.cc.o:
${CXX} ${CFLAGS} -c $<
# [ds] Note we don't use the standard CFLAGS here; that's intentional, most
# flex/bison combos I've tried don't produce code that passes the warnings
# test.
$(UTIL)%.o: $(UTIL)%.cc
$(CXX) $(YCFLAGS) -o $@ -c $<
#############################################################################
# Build Lua
$(LUASRC)$(LUALIBA):
echo Building Lua...
cd $(LUASRC) && $(MAKE) crawl_unix
#############################################################################
# Build SQLite
$(FSQLLIBA):
echo Building SQLite
cd $(SQLSRC) && $(MAKE)
#############################################################################
# Packaging a source tarball for release
#
# To package, you *must* have lex and yacc to generate the intermediates.
ifeq ($(DOYACC),y)
package-source: distclean prebuildyacc pkgtidy depend removeold vlink \
pkgtarbz2 pkgzip
pkgtidy:
$(DELETE) $(PKG_TIDY_LIST)
removeold:
if [ -f ../../$(SRC_PKG_TAR) ]; then $(DELETE) ../../$(SRC_PKG_TAR); fi
if [ -f ../../$(SRC_PKG_ZIP) ]; then $(DELETE) ../../$(SRC_PKG_ZIP); fi
# [ds] Existing directory names could produce a bad package!
vlink:
cd .. && WHERE=$$PWD && cd .. && \
( [ -e $(PKG_SRC_DIR) ] || ln -sf $$WHERE $(PKG_SRC_DIR) )
pkgtarbz2:
cd ../.. && tar -ch --bzip2 -f $(SRC_PKG_TAR) \
-X $(PKG_EXCLUDES) $(PKG_SRC_DIR)
pkgzip:
cd ../.. && zip -rq $(SRC_PKG_ZIP) $(PKG_SRC_DIR) \
-x@$(PKG_EXCLUDES)
endif
#include "AppHdr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef USE_X11 //Sys dep
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xutil.h>
#include <X11/Xlocale.h>
#include <X11/keysym.h>
#include <X11/keysymdef.h>
#include <X11/Xmd.h>
#endif
#include "cio.h"
#include "enum.h"
#include "externs.h"
#include "guic.h"
#include "libutil.h"
/*
* Tile related stuff
*/
#ifdef USE_TILE
#include "tiles.h"
static Display *display=NULL;
static int screen;
static int x11_keypress(XKeyEvent *xev);
static void x11_check_exposure(XEvent *xev);
extern WinClass *win_main;
void GetNextEvent(int *etype, int *key, bool *shift, bool *ctrl,
int *x1, int *y1, int *x2, int *y2)
{
XEvent xev;
while(1)
{
XNextEvent(display, &xev);
if(xev.type==KeyPress)
{
*etype = EV_KEYIN;
*key = x11_keypress(&(xev.xkey));
break;
}
else if(xev.type==Expose)
{
x11_check_exposure(&xev);
}
else if(xev.type == ConfigureNotify)
{
win_main->ox = xev.xconfigure.x;
win_main->oy = xev.xconfigure.y;
break;
}
else if(xev.type==ButtonPress)
{
*etype = EV_BUTTON;
int button = xev.xbutton.button;
*shift = (xev.xkey.state & ShiftMask) ? true : false;
*ctrl = (xev.xkey.state & ControlMask) ? true : false;
*x1 = xev.xbutton.x;
*y1 = xev.xbutton.y;
if (button == 3) button = 2;
else if (button==2) button=3;
*key = button;
break;
}
else if(xev.type==MotionNotify || xev.type==EnterNotify)
{
*etype = EV_MOVE;
*x1 = xev.xbutton.x;
*y1 = xev.xbutton.y;
break;
}
else if (xev.type==LeaveNotify)
{
*etype = EV_MOVE;
*x1 = -100;
*y1 = -100;
break;
}
else if(xev.type==ButtonRelease)
{
*etype = EV_UNBUTTON;
int button = xev.xbutton.button;
if (button == 3) button = 2;
else if (button==2) button=3;
*x1 = xev.xbutton.x;
*y1 = xev.xbutton.y;
*key = button;
break;
}
}/*while*/
}
char *my_getenv(const char *envname, const char *def)
{
const char *result = getenv(envname);
if (!result) result = def;
return (char *)result;
}
int my_getenv_int(const char *envname, int def)
{
const char *rstr = getenv(envname);
if (!rstr) return def;
return atoi(rstr);
}
#if 0
void libgui_load_prefs(struct pref_data *pref, int nprefs)
{
int i;
strcpy(font_name, my_getenv("CRAWL_X11_FONT",
"-alias-fixed-bold-r-normal--16-*"));
strcpy(font_name, my_getenv("CRAWL_X11_FONT", "9x15"));
*crt_x = my_getenv_int("CRAWL_X11_CRTX",80);
*crt_y = my_getenv_int("CRAWL_X11_CRTY",25);
*msg_x = my_getenv_int("CRAWL_X11_MSGX",80);
*msg_y = my_getenv_int("CRAWL_X11_MSGY",8);
*map_x = my_getenv_int("CRAWL_X11_MAPX",3);
*map_y = my_getenv_int("CRAWL_X11_MAPY",3);
*dngn_x = my_getenv_int("CRAWL_X11_DNGNX",17);
*dngn_y = my_getenv_int("CRAWL_X11_DNGNY",17);
}
void libgui_save_prefs()
{
}
#endif
extern WinClass *win_main;
extern TextRegionClass *region_tip;
void update_tip_text(const char *tip)
{
static char newtip[512];
static char oldtip[512];
char tbuf[35];
strncpy(newtip, tip, 500);
char* pc = strchr(newtip, '\n');
if (pc)
*pc = 0;
if (strncmp(oldtip, newtip, 500)==0)
return;
strncpy(oldtip, newtip, 500);
strncpy(tbuf,tip,34);
tbuf[34]=0;
if (win_main->active_layer == 0)
{
// avoid overruns...
if ((int)strlen(newtip) > region_tip->mx)
{
// try to remove inscriptions
char *ins = strchr(newtip, '{');
if (ins && ins[-1] == ' ') ins--;
if (ins && (ins - newtip <= region_tip->mx))
{
*ins = 0;
}
else
{
// try to remove state, e.g. "(worn)"
char *state = strchr(newtip, '(');
if (state && state[-1] == ' ') state--;
if (state && (state - newtip <= region_tip->mx))
{
*state = 0;
}
else
{
// if nothing else...
newtip[region_tip->mx] = 0;
newtip[region_tip->mx-1] = '.';
newtip[region_tip->mx-2] = '.';
}
}
}
region_tip->clear();
region_tip->gotoxy(1,1);
region_tip->addstr(newtip);
region_tip->make_active();
}
else
{
textattr( WHITE );
gotoxy(1, get_number_of_lines() + 1);
cprintf("%s", oldtip);
clear_to_end_of_line();
}
}
void TileDrawDungeonAux()
{
}
#endif /* USE_TILE */
/* X11 */
void x11_check_exposure(XEvent *xev){
int sx, sy, ex, ey;
sx = xev->xexpose.x;
ex = xev->xexpose.x + (xev->xexpose.width)-1;
sy = xev->xexpose.y;
ey = xev->xexpose.y + (xev->xexpose.height)-1;
if (xev->xany.window != win_main->win) return;
win_main->redraw(sx,sy,ex,ey);
}
/* X11 */
// This routine is taken from Angband main-x11.c
int x11_keypress(XKeyEvent *xev)
{
#define IsSpecialKey(keysym) \
((unsigned)(keysym) >= 0xFF00)
const unsigned int ck_table[9]=
{
CK_END, CK_DOWN, CK_PGDN,
CK_LEFT, CK_INSERT, CK_RIGHT,
CK_HOME, CK_UP, CK_PGUP
};
int dir, base;
int n;
bool mc, ms, ma;
unsigned int ks1;
XKeyEvent *ev = (XKeyEvent*)(xev);
KeySym ks;
char buf[256];
n = XLookupString(ev, buf, 125, &ks, NULL);
buf[n] = '\0';
if (IsModifierKey(ks)) return 0;
/* Extract "modifier flags" */
mc = (ev->state & ControlMask) ? true : false;
ms = (ev->state & ShiftMask) ? true : false;
ma = (ev->state & Mod1Mask) ? true : false;
/* Normal keys */
if (n && !IsSpecialKey(ks))
{
buf[n] = 0;
//Hack Ctrl+[0-9] etc.
if (mc && ((ks>='0' && ks<='9') || buf[0]>=' '))
{
return 1024|ks;
}
if (!ma)
{
return buf[0];
}
/* Alt + ? */
return 2048|buf[0];
}
/* Hack -- convert into an unsigned int */
ks1 = (uint)(ks);
/* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
base = dir = 0;
switch (ks1)
{
case XK_Escape:
base = 0x1b;
break;
case XK_Return:
base = '\r';
break;
case XK_Tab:
base = '\t';
break;
case XK_Delete:
case XK_BackSpace:
base = '\010';
break;
// for menus
case XK_Down:
return CK_DOWN;
case XK_Up:
return CK_UP;
case XK_Left:
return CK_LEFT;
case XK_Right:
return CK_RIGHT;
/*
* Keypad
*/
case XK_KP_1:
case XK_KP_End:
dir = 1;
break;
case XK_KP_2:
case XK_KP_Down:
dir = 2;
break;
case XK_KP_3:
case XK_KP_Page_Down:
dir = 3;
break;
case XK_KP_6:
case XK_KP_Right:
dir = 6;
break;
case XK_KP_9:
case XK_KP_Page_Up:
dir = 9;
break;
case XK_KP_8:
case XK_KP_Up:
dir = 8;
break;
case XK_KP_7:
case XK_KP_Home:
dir = 7;
break;
case XK_KP_4:
case XK_KP_Left:
dir = 4;
break;
case XK_KP_5:
dir = 5;
break;
}/* switch */
//Handle keypad first
if (dir != 0)
{
int result = ck_table[dir-1];
if (ms) result += CK_SHIFT_UP - CK_UP;
if (mc) result += CK_CTRL_UP - CK_UP;
return result;
}
if (base != 0)
{
if (ms) base |= 1024;
if (mc) base |= 2048;
if (ma) base |= 4096;
return base;
}
//Hack Special key
if (ks1 >=0xff00)
{
base = 512 + ks1 - 0xff00;
if (ms) base |= 1024;
if (mc) base |= 2048;
if (ma) base |= 4096;
return base;
}
return 0;
}
void libgui_init_sys()
{
GuicInit(&display, &screen);
}
void libgui_shutdown_sys()
{
GuicDeinit();
}
void update_screen()
{
XFlush(display);
}
int kbhit()
{
XEvent xev;
if (XCheckMaskEvent(display,
KeyPressMask | ButtonPressMask, &xev))
{
XPutBackEvent(display, &xev);
return 1;
}
return 0;
}
void delay( unsigned long time )
{
usleep( time * 1000 );
}
/* Convert value to string */
int itoa(int value, char *strptr, int radix)
{
unsigned int bitmask = 32768;
int ctr = 0;
int startflag = 0;
if (radix == 10)
{
sprintf(strptr, "%i", value);
}
if (radix == 2) /* int to "binary string" */
{
while (bitmask)
{
if (value & bitmask)
{
startflag = 1;
sprintf(strptr + ctr, "1");
}
else
{
if (startflag)
sprintf(strptr + ctr, "0");
}
bitmask = bitmask >> 1;
if (startflag)
ctr++;
}
if (!startflag) /* Special case if value == 0 */
sprintf((strptr + ctr++), "0");
strptr[ctr] = (char) NULL;
}
return (0); /* Me? Fail? Nah. */
}
// Convert string to lowercase.
char *strlwr(char *str)
{
unsigned int i;
for (i = 0; i < strlen(str); i++)
str[i] = tolower(str[i]);
return (str);
}
int stricmp( const char *str1, const char *str2 )
{
return (strcmp(str1, str2));
}
#ifndef USE_TILE
void gotoxy(int x, int y, int region)
{
switch(region)
{
case GOTO_STAT:
gotoxy_sys(x + crawl_view.hudp.x - 1, y + crawl_view.hudp.y - 1);
break;
case GOTO_MSG:
gotoxy_sys(x + crawl_view.msgp.x - 1, y + crawl_view.msgp.y - 1);
break;
case GOTO_CRT:
default:
gotoxy_sys(x, y);
break;
}
}
#endif
#endif
#ifndef LIBGUI_H
#define LIBGUI_H
#ifdef USE_TILE
#ifdef USE_X11
#include <X11/Xlib.h>
#include <X11/X.h>
#elif defined(WINDOWS)
#include <windows.h>
// windows.h defines 'near' as an empty string for compatibility.
// This breaks the use of that as a variable name. Urgh.
#ifdef near
#undef near
#endif
#include <commdlg.h>
#endif
#include "defines.h"
typedef unsigned int screen_buffer_t;
void libgui_init();
void libgui_shutdown();
void edit_prefs();
/* ***********************************************************************
Minimap related
* called from: misc view spells2
* *********************************************************************** */
void GmapInit(bool upd_tile);
void GmapDisplay(int linex, int liney);
void GmapUpdate(int x, int y, int what, bool upd_tile = true);
//dungeon display size
extern int tile_dngn_x;
extern int tile_dngn_y;
void set_mouse_enabled(bool enabled);
// mouse ops
// set mouse op mode
void mouse_set_mode(int mode);
// get mouse mode
int mouse_get_mode();
class mouse_control
{
public:
mouse_control(int mode)
{
oldmode = mouse_get_mode();
mouse_set_mode(mode);
}
~mouse_control()
{
mouse_set_mode(oldmode);
}
private:
int oldmode;
};
class coord_def;
void gui_init_view_params(coord_def &termsz, coord_def &viewsz,
coord_def &msgp, coord_def &msgsz, coord_def &hudp, coord_def &hudsz);
// If mouse on dungeon map, returns true and sets gc.
// Otherwise, it just returns false.
bool gui_get_mouse_grid_pos(coord_def &gc);
enum InvAction
{
INV_DROP,
INV_USE,
INV_PICKUP,
INV_VIEW,
INV_SELECT,
INV_NUMACTIONS
};
void gui_set_mouse_inv(int idx, InvAction act);
void gui_get_mouse_inv(int &idx, InvAction &act);
void tile_place_cursor(int x, int y, bool display);
void lock_region(int r);
void unlock_region(int r);
enum ScreenRegion
{
REGION_NONE,
REGION_CRT,
REGION_STAT,
REGION_MSG,
REGION_MAP,
REGION_DNGN,
REGION_TDNGN,
REGION_INV1,
REGION_INV2,
REGION_XMAP,
REGION_TIP,
NUM_REGIONS
};
/* text display */
void clrscr(void);
void textcolor(int color);
void gotoxy(int x, int y, int region = GOTO_CRT);
void message_out(int mline, int colour, const char *str, int firstcol = 0,
bool newline = true);
void clear_message_window();
int wherex();
int wherey();
void cprintf(const char *format,...);
void clear_to_end_of_line(void);
void clear_to_end_of_screen(void);
int get_number_of_lines(void);
int get_number_of_cols(void);
void get_input_line_gui(char *const buff, int len);
void _setcursortype(int curstype);
void textbackground(int bg);
void textcolor(int col);
void putch(unsigned char chr);
void putwch(unsigned chr);
void put_colour_ch(int colour, unsigned ch);
void writeWChar(unsigned char *ch);
void puttext(int x, int y, int lx, int ly, unsigned char *buf,
bool mono = false, int where = 0);
void ViewTextFile(const char *name);
#define textattr(x) textcolor(x)
void set_cursor_enabled(bool enabled);
bool is_cursor_enabled();
void enable_smart_cursor(bool);
bool is_smart_cursor_enabled();
#ifdef USE_X11
char *strlwr(char *str); // non-unix
int itoa(int value, char *strptr, int radix); // non-unix
int stricmp(const char *str1, const char *str2); // non-unix
#endif
void delay(unsigned long time);
int kbhit(void);
void window(int x1, int y1, int x2, int y2);
void update_screen(void);
int getch();
int getch_ck();
// types of events
#define EV_KEYIN 1
#define EV_MOVE 2
#define EV_BUTTON 3
#define EV_UNBUTTON 4
#define _NORMALCURSOR 1
#define _NOCURSOR 0
#define textcolor_cake(col) textcolor((col)<<4 | (col))
#endif // USE_TILE
#endif // LIBGUI_H
/*
* File: libx11.cc
* Summary: Functions for x11
* Written by: M.Itakura
*
* Change History (most recent first):
*
* <1> 03/08/11 Ita copied from liblinux.cc and modified
*
*/
#define deblog(x) {FILE *ddfp=fopen("log.txt","a");fprintf(ddfp,x);fprintf(ddfp,"\n");fclose(ddfp);}
#define deblog2(x,y) {FILE *ddfp=fopen("log.txt","a");fprintf(ddfp,"%s %d\n",x,y);fclose(ddfp);}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "AppHdr.h"
#include "cio.h"
#include "defines.h"
#include "describe.h"
#include "direct.h"
#include "files.h"
#include "itemname.h"
#include "items.h"
#include "externs.h"
#include "guic.h"
#include "message.h"
#include "player.h"
#include "stash.h"
#include "state.h"
#include "stuff.h"
#include "terrain.h"
#include "tiles.h"
#include "travel.h"
#include "version.h"
#include "view.h"
int tile_dngn_x;
int tile_dngn_y;
#define DCX (tile_dngn_x/2)
#define DCY (tile_dngn_y/2)
// libx11.cc or libwt.cc
extern void update_tip_text(const char *tip);
extern void libgui_init_sys();
extern void libgui_shutdown_sys();
extern void GetNextEvent(int *etype,
int *key, bool *shift, bool *ctrl,
int *x1, int *y1, int *x2, int *y2);
#ifdef WIN32TILES
// libwt.cc
extern bool windows_change_font(char *font_name, int *font_size, bool dos);
extern void windows_get_winpos(int *x, int *y);
extern void TileInitWin();
#endif
// Main window
WinClass *win_main;
// Regions
TextRegionClass *region_crt = NULL;
MapRegionClass *region_map = NULL;
TileRegionClass *region_tile = NULL;
TextRegionClass *region_stat = NULL;
TextRegionClass *region_msg = NULL;
TextRegionClass *region_dngn = NULL;
TextRegionClass *region_xmap = NULL;
TextRegionClass *region_tip = NULL;
TileRegionClass *region_item = NULL;
TileRegionClass *region_item2 = NULL;
// Raw tile images
img_type TileImg, TileIsoImg;
img_type PlayerImg;
img_type WallImg;
extern bool force_redraw_tile;
extern bool force_redraw_inv;
// for item use gui
#define MAX_ITEMLIST 60
extern int itemlist[MAX_ITEMLIST];
extern int itemlist_num[MAX_ITEMLIST];
extern int itemlist_idx[MAX_ITEMLIST];
extern char itemlist_key[MAX_ITEMLIST];
extern int itemlist_iflag[MAX_ITEMLIST];
extern int itemlist_flag;
extern int itemlist_n;
static bool gui_smart_cursor = false;
// Window prefs
static int crt_x = 80;
static int crt_y = 30;
static int map_px = 3;
static int msg_x = 80, msg_y = 8;
static int dngn_x = 17, dngn_y = 17;
static int winox = 0, winoy = 0;
#define MAX_PREF_CHAR 256
#ifdef USE_X11
#define UseDosChar false
static char font_name[MAX_PREF_CHAR+1] = "8x16";
#endif
#ifdef WIN32TILES
static char font_name[MAX_PREF_CHAR+1] = "courier";
#define UseDosChar (Options.use_dos_char)
static char dos_font_name[MAX_PREF_CHAR+1] = "Terminal";
static int dos_font_size = 16;
#endif
static int font_size = 12;
#define PREF_MODE_TEXT 0
#define PREF_MODE_TILE 1
#define PREF_MODE_ISO 2
#define PREF_MODE_NUM 3
static const char *pref_mode_name[PREF_MODE_NUM]
={ "Text", "Tile", "Iso"};
typedef struct prefs
{
const char *name;
const char *tagname;
char type;
void *ptr;
int min, max;
int dummy_idx;
}prefs;
#ifdef WIN32TILES
#define MAX_PREFS 11
#else
#define MAX_PREFS 9
#endif
#define MAX_EDIT_PREFS 5
static int dummy_int[PREF_MODE_NUM][8];
static char dummy_str[PREF_MODE_NUM][2][MAX_PREF_CHAR+1];
struct prefs pref_data[MAX_PREFS] =
{
{"DUNGEON X", "DngnX", 'I', &dngn_x, 17, 35, 0},
{"DUNGEON Y", "DngnY", 'I', &dngn_y, 17, 35, 1},
{"MAP PX ", "MapPx", 'I', &map_px, 1, 10, 2},
{"MSG X ", "MsgX", 'I', &msg_x, 40, 80, 3},
{"MSG Y ", "MsgY", 'I', &msg_y, 8, 20, 4},
{"WIN TOP ", "WindowTop", 'I', &winox, -100, 2000, 5},
{"WIN LEFT ", "WindowLeft",'I', &winoy, -100, 2000, 6},
{"FONT ", "FontName", 'S', font_name, 0,0, 0},
{"FONT SIZE", "FontSize", 'I', &font_size, 8,24, 7}
#ifdef WIN32TILES
,{"DOS FONT", "DosFontName", 'S', dos_font_name, 0,0, 1},
{"DOS FONT SIZE", "DosFontSize", 'I', &dos_font_size, 8,24, 8}
#endif
};
static int pref_mode = 0;
static void libgui_load_prefs();
static void libgui_save_prefs();
//Internal variables
static int mouse_mode = MOUSE_MODE_NORMAL;
// hack: prevent clrscr for some region
static bool region_lock[NUM_REGIONS];
static bool toggle_telescope;
#define char_is_wall(ch) (ch == 127 || (ch >= 137 && ch <= 140) \
|| ch == 177 || ch == 176 || ch == '#')
#define char_is_item(ch) ( (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) || (ch == '~'))
#define char_is_monster(ch) ( (ch>='@' && ch<='Z') || (ch>='a' && ch<='z') \
|| ch=='&' || (ch>='1' && ch<='5') || ch == ';')
/***********************************************************/
//micromap color array
#define MAP_XMAX GXM
#define MAP_YMAX GYM
static unsigned char gmap_data[GXM][GYM];
static int gmap_min_x, gmap_max_x;
static int gmap_min_y, gmap_max_y;
static int gmap_ox, gmap_oy;
// redefine color constants with shorter name to save space
#define PX_0 MAP_BLACK //unseen
#define PX_F MAP_LTGREY //floor
#define PX_W MAP_DKGREY //walls
#define PX_D MAP_BROWN //doors
#define PX_WB MAP_LTBLUE //blue wall
#define PX_I MAP_GREEN //items
#define PX_M MAP_RED //monsters
#define PX_US MAP_BLUE //upstair
#define PX_DS MAP_MAGENTA //downstair
#define PX_SS MAP_CYAN //special stair
#define PX_WT MAP_MDGREY //water
#define PX_LV MAP_MDGREY //lava
#define PX_T MAP_YELLOW //trap
#define PX_MS MAP_CYAN //misc
static const char gmap_col[256] = {
/* 0x00 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0x08 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0x10 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0x18 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* ' ' '!' '"' '#' '$' '%' '&' ''' */
/* 0x20 */ PX_0, PX_I, PX_I, PX_F, PX_I, PX_I, PX_M, PX_D,
/* '(' ')' '*' '+' ',' '-' '.' '/' */
/* 0x28 */ PX_I, PX_I, PX_WB,PX_I, PX_F, PX_0, PX_F, PX_I,
/* 0 1 2 3 4 5 6 7 */
/* 0x30 */ PX_0, PX_M, PX_M, PX_M, PX_M, PX_M, PX_0, PX_0,
/* 8 9 : ; < = > ? */
/* 0x38 */ PX_MS,PX_0, PX_0, PX_M, PX_US,PX_I, PX_DS,PX_I,
/* @ A B C D E F G */
/* 0x40 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M,
/* H I J K L M N O */
/* 0x48 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M,
/* P Q R S T U V W */
/* 0x50 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M,
/* X Y Z [ \ ] ^ _ */
/* 0x58 */ PX_M, PX_M, PX_M, PX_I, PX_I, PX_I, PX_T, PX_MS,
/* ` a b c d e f g */
/* 0x60 */ PX_0, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M,
/* h i j k l m n o */
/* 0x68 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M,
/* p q r s t u v w */
/* 0x70 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M,
/* x y z { | } ~ WALL */
/* 0x78 */ PX_M, PX_M, PX_M, PX_WT,PX_0, PX_I, PX_I, PX_W,
/* old cralwj symbols */
/* �� �s �E �� �� �� �� �� */
/* 0x80 */ PX_D, PX_SS,PX_F, PX_MS,PX_MS,PX_MS,PX_D, PX_WT,
/* �t �� �� �� �� �� �� */
/* 0x88 */ PX_SS,PX_W, PX_W, PX_W, PX_W, PX_LV, PX_I, PX_0,
/**/
/* 0x90 144*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0x98 152*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xa0 160*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xa8 168*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xb0 176*/ PX_WB,PX_W, PX_W, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xb8 184*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xc0 192*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xc8 200*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xd0 208*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xd8 216*/ PX_0, PX_0, PX_0, PX_0, PX_MS, PX_0, PX_0, PX_0,
/* 0xe0 224*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0,
/* 0xe8 232*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_MS,
/* 0xf0 240*/ PX_0, PX_0, PX_0, PX_0, PX_MS,PX_0, PX_0, PX_WT,
/* 0xf8 248*/ PX_0, PX_F, PX_F, PX_0, PX_0, PX_0, PX_D, PX_0
};
int mouse_grid_x;
int mouse_grid_y;
bool mouse_in_dngn = false;
void gui_set_mouse_view_pos(bool in_dngn, int cx, int cy)
{
const coord_def& gc = view2grid(coord_def(cx,cy));
mouse_grid_x = gc.x;
mouse_grid_y = gc.y;
ASSERT(!in_dngn || gc.x >= 0 && gc.y >= 0 && gc.x < GXM && gc.y < GYM);
mouse_in_dngn = in_dngn;
}
bool gui_get_mouse_grid_pos(coord_def &gc)
{
if (mouse_in_dngn)
{
gc.x = mouse_grid_x;
gc.y = mouse_grid_y;
ASSERT(gc.x >= 0 && gc.y >= 0 && gc.x < GXM && gc.y < GYM);
}
return mouse_in_dngn;
}
int inv_idx = 0;
InvAction inv_action = INV_NUMACTIONS;
void gui_set_mouse_inv(int idx, InvAction act)
{
inv_idx = idx;
inv_action = act;
}
void gui_get_mouse_inv(int &idx, InvAction &act)
{
idx = inv_idx;
act = inv_action;
}
int tile_idx_unseen_terrain(int x, int y, int what)
{
const coord_def gc(x,y);
unsigned int feature = grd(gc);
unsigned int grid_symbol;
unsigned short grid_color;
get_item_symbol(feature, &grid_symbol, &grid_color);
if (feature == DNGN_SECRET_DOOR)
feature = (unsigned int)grid_secret_door_appearance(x, y);
int t = tileidx_feature(feature);
if (t == TILE_ERROR || what == ' ')
t = tileidx_unseen(what, gc);
t |= tile_unseen_flag(gc);
return t;
}
void GmapUpdate(int x, int y, int what, bool upd_tile)
{
int c;
const coord_def gc(x,y);
unsigned int feature = grd(gc);
unsigned int grid_symbol;
unsigned short grid_color;
get_item_symbol(feature, &grid_symbol, &grid_color);
switch (what)
{
// In some cases (like smoke), update the gmap with the ground color
// instead. This keeps it prettier in the case of lava + smoke.
case '#':
c = gmap_col[grid_symbol & 0xff];
break;
default:
c = gmap_col[what & 0xff];
break;
}
int oldc = gmap_data[x][y];
gmap_data[x][y] = c;
// NOTE: In the case of a magic mapping, we really want the
// map to update with the correct feature (stone instead of rock wall,
// fountains instead of TILE_ERROR). tileidx_unseen won't give that
// to us. However, we can't give the player all the information,
// since that might be cheating in some cases. This could be rewritten.
int t = tile_idx_unseen_terrain(x, y, what);
if (c!=0 && c!= oldc && upd_tile)
{
if (c == PX_I || c == PX_M)
{
env.tile_bk_fg[x][y]= t;
if (env.tile_bk_bg[x][y] == 0)
env.tile_bk_bg[x][y] = tileidx_feature(DNGN_UNSEEN);
}
else
{
env.tile_bk_bg[x][y] = t;
}
}
else if (c==0)
{
// forget map
env.tile_bk_fg[x][y]=0;
env.tile_bk_bg[x][y]=t;
return;
}
if (x < gmap_min_x) gmap_min_x = x;
else
if (x > gmap_max_x) gmap_max_x = x;
if (y < gmap_min_y) gmap_min_y = y;
else
if (y > gmap_max_y) gmap_max_y = y;
}
void GmapInit(bool upd_tile)
{
int x, y;
gmap_min_x = gmap_max_x = you.x_pos -1;
gmap_min_y = gmap_max_y = you.y_pos -1;
for (y = 0; y < GYM; y++)
{
for (x = 0; x < GXM; x++)
{
GmapUpdate(x, y, env.map[x][y].glyph(), upd_tile);
}
}
}
void GmapDisplay(int linex, int liney)
{
static unsigned char buf2[GXM*GYM];
int x,y;
int count=0;
int ox, oy;
for (x = 0; x < GXM*GYM; x++)
{
buf2[x] = 0;
}
ox = ( gmap_min_x + (GXM -1 - gmap_max_x) ) / 2;
oy = ( gmap_min_y + (GYM -1 - gmap_max_y) ) / 2;
count = ox + oy * GXM;
gmap_ox = ox - gmap_min_x;
gmap_oy = oy - gmap_min_y;
for (y = gmap_min_y; y <= gmap_max_y; y++)
{
for (x = gmap_min_x; x <= gmap_max_x; x++)
{
if ( (count>=0)&&(count<GXM*GYM) )
buf2[count] = gmap_data[x][y];
count += 1;
}
count += GXM - (gmap_max_x - gmap_min_x + 1);
}
if ( (you.level_type != LEVEL_LABYRINTH)&&(you.level_type != LEVEL_ABYSS) )
{
ox += linex - gmap_min_x;
oy += liney - gmap_min_y;
buf2[ ox + oy * GXM] = MAP_WHITE;
}
region_map->flag = true;
region_map->draw_data(buf2);
}
/* initialize routines */
static void do_layout()
{
#define LAYER_NML 0
#define LAYER_CRT 1
#define LAYER_XMAP 2
win_main->wx = win_main->wy = 10;
int tm = region_crt->dx;
if (UseDosChar)
win_main->placeRegion(region_xmap, LAYER_XMAP, 0, 0, tm, tm, tm, tm);
RegionClass *lowest;
// tile 2d mode
win_main->placeRegion(region_tile, LAYER_NML, 0, 0);
win_main->placeRegion(region_msg, LAYER_NML, region_tile, PLACE_BOTTOM,
tm, tm, tm, tm);
int sx = std::max(region_msg->ex + region_msg->dx, region_tile->ex);
int sy = 0;
win_main->placeRegion(region_stat, LAYER_NML, sx, sy);
win_main->placeRegion(region_map, LAYER_NML, region_stat, PLACE_BOTTOM);
if (region_tip)
{
win_main->placeRegion(region_tip, LAYER_NML, region_map, PLACE_BOTTOM);
lowest = region_tip;
}
else
{
lowest = region_map;
}
int item_x = (win_main->wx-2*tm) / TILE_X;
int item_y = (52 + item_x -1) / item_x;
region_item2 -> resize(item_x, item_y, TILE_X, TILE_Y);
// Update crt size appropriately, based on the window size.
int crt_pwx = win_main->wx;
int crt_wx = crt_pwx / region_crt->dx;
int crt_pwy = win_main->wy - 2*tm - item_y * region_item2->dy;
int crt_wy = crt_pwy / region_crt->dy;
region_crt->resize(crt_wx, crt_wy);
win_main->placeRegion(region_crt, LAYER_CRT, 0, 0, tm, tm, tm, tm);
win_main->placeRegion (region_item2, LAYER_CRT, region_crt, PLACE_BOTTOM,
tm, tm, tm, tm);
if (Options.show_items[0] != 0)
{
item_x = (win_main->wx - lowest->sx) / TILE_X;
item_y = (win_main->wy - lowest->ey) / TILE_Y;
RegionClass *r0 = lowest;
int place = PLACE_BOTTOM;
int item_x2 = (win_main->wx - region_msg->ex) / TILE_X;
int item_y2 = (win_main->wy - region_msg->sy) / TILE_Y;
if (item_x * item_y < item_x2 * item_y2 &&
lowest->ey < region_msg->sy)
{
item_x = item_x2;
item_y = item_y2;
r0 = region_msg;
place = PLACE_RIGHT;
}
while(item_x * item_y < 40) item_y++;
region_item -> resize(item_x, item_y, TILE_X, TILE_Y);
win_main->placeRegion (region_item, LAYER_NML, r0, place);
}
}
void libgui_init()
{
int i;
int map_margin = 2;
libgui_init_sys();
for(i=0;i<NUM_REGIONS;i++)
region_lock[i] = false;
pref_mode = PREF_MODE_TILE;
libgui_load_prefs();
// Adjust sizes
if (dngn_x & 1 ==0) dngn_x++;
if (dngn_y & 1 ==0) dngn_y++;
if (font_size &1 == 1) font_size--;
tile_dngn_x = dngn_x;
tile_dngn_y = dngn_y;
/****************************************************/
win_main = new WinClass();
win_main->ox = winox;
win_main->oy = winoy;
region_crt = new TextRegionClass(crt_x, crt_y, 0, 0);
region_crt->id = REGION_CRT;
TextRegionClass::text_mode = region_crt;
region_map =
new MapRegionClass(MAP_XMAX-map_margin*2,
MAP_YMAX-map_margin*2,
map_margin, map_margin,
false);
region_map->id = REGION_MAP;
region_map->dx = map_px;
region_map->dy = map_px;
TileInit();
#ifdef WIN32TILES
TileInitWin();
#endif
if (Options.show_items[0] != 0)
{
// temporal size
region_item = new TileRegionClass(1, 1, TILE_X, TILE_Y);
region_item->id = REGION_INV1;
}
// temporal size
region_item2 = new TileRegionClass(1, 1, TILE_X, TILE_Y);
region_item2->id = REGION_INV2;
region_tile =
new TileRegionClass(tile_dngn_x, tile_dngn_y,
TILE_UX_NORMAL, TILE_UY_NORMAL);
region_tile->id = REGION_DNGN;
#if DEBUG_DIAGNOSTICS
// one more line for debug GPS
region_stat = new TextRegionClass(40, 17, 0, 0);
#else
region_stat = new TextRegionClass(40, 16, 0, 0);
#endif
region_stat->id = REGION_STAT;
region_msg = new TextRegionClass(msg_x, msg_y, 0, 0);
region_msg->id = REGION_MSG;
if (UseDosChar)
{
region_xmap = new TextRegionClass(crt_x, crt_y, 0, 0);
region_xmap->id = REGION_XMAP;
}
#ifdef WIN32TILES
region_crt->init_font(font_name, font_size);
region_stat->copy_font(region_crt);
region_msg->copy_font(region_crt);
if (UseDosChar)
{
region_xmap->dos_char = true;
region_xmap->init_font(dos_font_name, dos_font_size);
}
#elif defined(USE_X11)
region_tip = new TextRegionClass(region_stat->mx, 1, 0, 0);
region_tip->id = REGION_TIP;
region_crt->init_font(font_name);
region_stat->init_font(font_name);
region_msg->init_font(font_name);
region_tip->init_font(font_name);
if (region_dngn) region_dngn->init_font(font_name);
#endif
do_layout();
win_main->create((char*)(CRAWL " " VERSION));
region_map->init_backbuf();
region_tile -> init_backbuf();
region_item2->init_backbuf();
if (region_item) region_item->init_backbuf();
}
void libgui_shutdown()
{
if(TileImg) ImgDestroy(TileImg);
if(PlayerImg) ImgDestroy(PlayerImg);
if(WallImg) ImgDestroy(WallImg);
if(TileIsoImg) ImgDestroy(TileIsoImg);
// do this before delete win_main
libgui_save_prefs();
std::vector<RegionClass *>::iterator r;
for (r = win_main->regions.begin();r != win_main->regions.end();r++)
{
RegionClass* pRegion = *r;
delete (pRegion);
}
delete win_main;
libgui_shutdown_sys();
}
/*** Save, Load, and Edit window prefs ***/
static void libgui_load_prefs()
{
int i, mode;
FILE *fp;
char buf[256];
char tagbuf[256];
// set default
for (mode = 0; mode < PREF_MODE_NUM; mode++)
{
for(i=0;i<MAX_PREFS;i++)
{
struct prefs *p = &pref_data[i];
int idx = p->dummy_idx;
if (p->type == 'I')
dummy_int[mode][idx] = *(int *)p->ptr;
else if (p->type == 'S')
strncpy(dummy_str[mode][idx], (char *)p->ptr, MAX_PREF_CHAR);
}
}
const char *baseTxt = "wininit.txt";
std::string winTxtString = datafile_path(baseTxt, true, true);
const char *winTxt = winTxtString.c_str()[0] == 0 ?
baseTxt : winTxtString.c_str();
if ( (fp = fopen(winTxt, "r")) != NULL )
{
while(!feof(fp))
{
fgets(buf, 250, fp);
i = 0;
while(buf[i] >= 32 && i< 120) i++;
buf[i] = 0;
for(i=0;i<MAX_PREFS;i++)
{
struct prefs *p = &pref_data[i];
for (mode = 0; mode < PREF_MODE_NUM; mode++)
{
sprintf(tagbuf, "%s:%s",
pref_mode_name[mode], p->tagname);
if(strncmp(buf, tagbuf, strlen(tagbuf)) == 0)
{
char *dat = &buf[strlen(tagbuf)+1];
if (p->type == 'I')
{
int val = atoi(dat);
if (val > p->max) val = p->max;
if (val < p->min) val = p->min;
dummy_int[mode][p->dummy_idx] = val;
if (mode == pref_mode)
*(int *)p->ptr = val;
}
if (p->type == 'S')
{
strncpy(dummy_str[mode][p->dummy_idx], dat,
MAX_PREF_CHAR);
if (mode == pref_mode)
strncpy((char *)p->ptr, dat, MAX_PREF_CHAR);
}
break;
}// tag match
} //mode
}//i
}// while
}
}
static void libgui_save_prefs()
{
int i, mode;
FILE *fp;
winox = win_main->ox;
winoy = win_main->oy;
#ifdef WIN32TILES
windows_get_winpos(&winox, &winoy);
#endif
for(i=0;i<MAX_PREFS;i++)
{
struct prefs *p = &pref_data[i];
int idx = p->dummy_idx;
if (p->type == 'I')
dummy_int[pref_mode][idx] = *(int *)p->ptr;
else if (p->type == 'S')
strncpy(dummy_str[pref_mode][idx], (char *)p->ptr, MAX_PREF_CHAR);
}
const char *baseTxt = "wininit.txt";
std::string winTxtString = datafile_path(baseTxt, false, true);
const char *winTxt = winTxtString.c_str()[0] == 0 ?
baseTxt : winTxtString.c_str();
if ( (fp = fopen(winTxt, "w")) != NULL )
{
for (mode = 0; mode < PREF_MODE_NUM; mode++)
{
for(i=0;i<MAX_PREFS;i++)
{
struct prefs *p = &pref_data[i];
int idx = p->dummy_idx;
if (p->type == 'I')
fprintf(fp, "%s:%s=%d\n", pref_mode_name[mode],
p->tagname, dummy_int[mode][idx]);
if (p->type == 'S')
fprintf(fp, "%s:%s=%s\n", pref_mode_name[mode],
p->tagname, dummy_str[mode][idx]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
}
static void draw_hgauge(int x, int y, int ofs, int region, int len, int col)
{
int i;
gotoxy(x, y, region);
textcolor(col);
for (i=0; i < len; i++)
{
switch((i+ ofs) % 10)
{
case 0: cprintf("%c",'+');break;
case 4: cprintf("%c",'0' + (1+(i+ofs)/10)%10);break;
case 5: cprintf("%c",'0');break;
default: cprintf("%c",'-');
}
}
}
static void draw_vgauge(int x, int y, int ofs, int region, int len, int col)
{
int i;
textcolor(col);
for (i=0; i < len; i++)
{
gotoxy(x, y+i, region);
cprintf("%02d", ofs+i);
}
}
void edit_prefs()
{
int i;
int cur_pos = 0;
cursor_control cs(false);
bool need_draw_stat = true;
bool need_draw_msg = true;
if (region_tip)
region_tip->clear();
region_stat->clear();
region_msg->clear();
viewwindow(true, false);
while(1)
{
bool upd_msg = false;
bool upd_dngn = false;
bool upd_crt = false;
bool upd_map = false;
bool need_resize = false;
int inc = 0;
if (need_draw_msg)
{
textcolor(LIGHTGREY);
region_msg->clear();
textcolor(WHITE);
gotoxy (4, 4, GOTO_MSG);
cprintf("j, k, up, down : Select pref");
gotoxy (4, 5, GOTO_MSG);
cprintf("h, l, left, right : Decrease/Increase");
gotoxy (4, 6, GOTO_MSG);
cprintf("H, L : Dec/Inc by 10");
need_draw_msg = false;
}
if (need_draw_stat)
{
region_stat->clear();
for(i=0; i<MAX_EDIT_PREFS;i++)
{
struct prefs *p = &pref_data[i];
gotoxy(2, i+2, GOTO_STAT);
if (i == cur_pos)
{
textcolor(0xf0);
cprintf(">");
}
else
{
textcolor(LIGHTGREY);
cprintf(" ");
}
if (pref_data[i].type == 'I')
cprintf(" %s: %3d ", p->name, *(int *)p->ptr);
else
cprintf(" %s: %s", p->name, (char *)p->ptr);
}
textcolor(LIGHTGREY);
#ifdef WIN32TILES
gotoxy(4, MAX_EDIT_PREFS+3, GOTO_STAT);
cprintf("FONT: %s %d",font_name, font_size);
if (UseDosChar)
{
gotoxy(4, MAX_EDIT_PREFS+4, GOTO_STAT);
cprintf("DOSFONT: %s %d", dos_font_name, dos_font_size);
}
#else
gotoxy(4, MAX_EDIT_PREFS+3, GOTO_STAT);
cprintf("FONT: %s",font_name);
#endif
int *dat = (int *)pref_data[cur_pos].ptr;
#define WHITEIF(x) (dat == &x)?0xf0:LIGHTGREY
draw_hgauge(3, 1, 3, GOTO_MSG, msg_x-2, WHITEIF(msg_x));
clear_to_end_of_line();
draw_vgauge(1, 1, 1, GOTO_MSG, msg_y, WHITEIF(msg_y));
need_draw_stat = false;
}
int key = getch();
struct prefs *p = &pref_data[cur_pos];
int *dat = (int *)p->ptr;
if (key == 0x1b || key == '\r') break;
if (key == 'j' || key == CK_DOWN)
{
cur_pos++;
need_draw_stat = true;
}
if (key == 'k' || key == CK_UP)
{
cur_pos--;
need_draw_stat = true;
}
if (key == CK_LEFT) key = 'h';
if (key == CK_RIGHT) key = 'l';
cur_pos = (cur_pos + MAX_EDIT_PREFS) % MAX_EDIT_PREFS;
switch(key)
{
case 'l': inc=1; break;
case 'L': inc=10; break;
case 'h': inc=-1; break;
case 'H': inc=-10; break;
}
int crt_x_old = crt_x;
int crt_y_old = crt_y;
int map_px_old = map_px;
int msg_x_old = msg_x;
int msg_y_old = msg_y;
int dngn_x_old = dngn_x;
int dngn_y_old = dngn_y;
if ( (p->type == 'I') && inc != 0)
{
if (dat == &dngn_x || dat == &dngn_y )
{
if (inc==1) inc=2;
if (inc==-1) inc=-2;
}
int olddat = *dat;
(*dat)+= inc;
if (*dat > p->max) *dat = p->max;
if (*dat < p->min) *dat = p->min;
if (olddat == *dat) continue;
need_resize = true;
}// changed
if (need_resize)
{
need_draw_stat = need_draw_msg = true;
// crt screen layouts
// resize msg?
if (msg_x != msg_x_old || msg_y != msg_y_old)
{
upd_msg = true;
region_msg->resize(msg_x, msg_y);
}
// resize crt?
if (crt_x != crt_x_old || crt_y != crt_y_old)
{
upd_crt = true;
region_crt->resize(crt_x, crt_y);
}
// resize map?
if (map_px != map_px_old)
{
upd_map = true;
region_map->resize( 0, 0, map_px, map_px);
}
// resize dngn tile screen?
if (dngn_x != dngn_x_old || dngn_y != dngn_y_old)
{
clrscr();
upd_dngn = true;
tile_dngn_x = dngn_x;
tile_dngn_y = dngn_y;
region_tile->resize(dngn_x, dngn_y, 0, 0);
}
do_layout();
win_main->resize();
win_main->clear();
// Now screens are all black
if (upd_map)
region_map->resize_backbuf();
if (upd_dngn)
{
region_tile -> resize_backbuf();
force_redraw_tile = true;
TileResizeScreen(dngn_x, dngn_y);
}
if (region_item)
region_item->resize_backbuf();
if (region_item2)
region_item2->resize_backbuf();
force_redraw_inv = true;
tile_draw_inv(-1, REGION_INV1);
region_map->force_redraw = true;
viewwindow(true, true);
region_tile->redraw();
region_item->redraw();
}// need resize
}//while
clrscr();
redraw_screen();
mpr("Done.");
}
// Tiptext help info
typedef struct tip_info
{
int sx;
int ex;
int sy;
int ey;
const char *tiptext;
const char *tipfilename;
} tip_info;
static int old_tip_idx = -1;
void tip_grid(int gx, int gy, bool do_null = true, int minimap=0)
{
mesclr();
const coord_def gc(gx,gy);
terse_describe_square(gc);
}
int tile_cursor_x = -1;
int tile_cursor_y = -1;
int tile_cursor_flag=0;
void tile_place_cursor(int x, int y, bool display)
{
if (tile_cursor_x != -1)
{
// erase old cursor
TileDrawCursor(tile_cursor_x, tile_cursor_y, tile_cursor_flag);
}
if (!display)
{
tile_cursor_x = -1;
return;
}
int new_flag = TILE_FLAG_CURSOR1;
const coord_def gc = view2grid(coord_def(x+1, y+1));
if (gc.x < 0 || gc.y < 0 || gc.x >= GXM || gc.y >= GYM)
{
// off the dungeon...
tile_cursor_x = -1;
return;
}
else if (!map_bounds(gc))
{
new_flag = TILE_FLAG_CURSOR2;
}
else
{
unsigned char ch = env.map[gc.x][gc.y].glyph() & 0xff;
if (ch==0 || ch==' ' || char_is_wall(ch))
new_flag = TILE_FLAG_CURSOR2;
}
tile_cursor_x = x;
tile_cursor_y = y;
tile_cursor_flag = TileDrawCursor(x, y, new_flag);
}
int convert_cursor_pos(int mx, int my, int *cx, int *cy)
{
std::vector <RegionClass *>::iterator r;
WinClass *w = win_main;
int id = REGION_NONE;
int x, y;
int mx0 = 0;
for (r = w->regions.begin();r != w->regions.end();r++)
{
if (! (*r)->is_active()) continue;
if( (*r)->mouse_pos(mx, my, cx, cy))
{
id = (*r)->id;
mx0 = (*r)->mx;
break;
}
}
x = *cx;
y = *cy;
/********************************************/
if(id == REGION_TDNGN)
{
x--;
if (!in_viewport_bounds(x+1,y+1)) return REGION_NONE;
}
if (id == REGION_MAP)
{
x = x - gmap_ox + region_map->x_margin + 1;
y = y - gmap_oy + region_map->y_margin + 1;
}
if (id == REGION_INV1 || id == REGION_INV2)
{
x = x + y * mx0;
y = 0;
}
if (id == REGION_DNGN)
{
// Out of LOS range
if (!in_viewport_bounds(x+1,y+1))
return REGION_NONE;
}
*cx = x;
*cy = y;
return id;
}
static int handle_mouse_motion(int mouse_x, int mouse_y, bool init)
{
int cx = -1;
int cy = -1;
int mode = 0;
static int oldcx = -1;
static int oldcy = -1;
static int oldmode = -1;
static int olditem = -1;
if (init)
{
oldcx = -1;
oldcy = -1;
oldmode = -1;
old_tip_idx = -1;
olditem = -1;
return 0;
}
switch(mouse_mode)
{
case MOUSE_MODE_NORMAL:
case MOUSE_MODE_MORE:
case MOUSE_MODE_MACRO:
return 0;
break;
}
if (mouse_x < 0)
{
mode = 0;
oldcx = oldcy = -10;
}
else
mode = convert_cursor_pos(mouse_x, mouse_y, &cx, &cy);
if (oldcx == cx && oldcy == cy && oldmode == mode) return 0;
// erase old cursor
if ( oldmode == REGION_DNGN && mode != oldmode)
{
oldcx = -10;
//_setcursortype(0);
}
if (olditem != -1)
{
oldcx = -10;
TileMoveInvCursor(-1);
olditem = -1;
}
if ( oldmode == REGION_DNGN && mode != oldmode)
{
oldcx = -10;
tile_place_cursor(0, 0, false);
}
if (toggle_telescope && mode != REGION_MAP)
{
TileDrawDungeon(NULL);
toggle_telescope = false;
}
bool valid_tip_region = (mode == REGION_MAP || mode == REGION_DNGN ||
mode == REGION_INV1 || mode == REGION_INV2 || mode == REGION_MSG);
if (valid_tip_region && mode != oldmode)
{
update_tip_text("");
}
if (toggle_telescope && mode == REGION_MAP)
{
oldmode = mode;
oldcx = cx;
oldcy = cy;
tip_grid(cx-1, cy-1, 1);
TileDrawFarDungeon(cx-1, cy-1);
return 0;
}
if (mode == REGION_INV1 || mode == REGION_INV2)
{
oldcx = cx;
oldcy = cy;
oldmode = mode;
int ix = TileInvIdx(cx);
std::string desc;
if (ix != -1)
{
bool display_actions = mode == REGION_INV1;
if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR)
{
if (itemlist_key[cx])
{
desc = itemlist_key[cx];
desc += " - ";
}
desc += mitm[ix].name(DESC_NOCAP_A);
if (display_actions)
desc += EOL "[L-Click] *Pickup(g)";
}
else
{
desc = you.inv[ix].name(DESC_INVENTORY_EQUIP);
if (display_actions)
{
desc += EOL "[L-Click] ";
int type = you.inv[ix].base_type;
if (itemlist_iflag[cx] & TILEI_FLAG_EQUIP)
type += 18;
switch (type)
{
case OBJ_JEWELLERY + 18:
desc += "*(R)emove";
break;
case OBJ_WEAPONS:
case OBJ_STAVES:
desc += "*(w)ield";
break;
case OBJ_MISSILES:
desc += "*(t)hrow";
break;
case OBJ_WANDS:
desc += "*(z)ap";
break;
case OBJ_SCROLLS:
case OBJ_BOOKS:
desc += "*(r)ead";
break;
case OBJ_JEWELLERY:
desc += "*(P)ut on";
break;
case OBJ_POTIONS:
desc += "*(q)uaff";
break;
default:
desc += "*Use it";
}
desc += EOL "[R-Click] Info";
desc += EOL "[Shift-L-Click] *(d)rop";
}
}
update_tip_text(desc.c_str());
itemlist_flag = mode;
TileMoveInvCursor(cx);
olditem = cx;
}
else
update_tip_text("");
return 0;
}
if (mouse_mode == MOUSE_MODE_TARGET ||
mouse_mode == MOUSE_MODE_TARGET_DIR)
{
if (mode == REGION_DNGN || mode == REGION_TDNGN)
{
oldcx = cx;
oldcy = cy;
oldmode = mode;
gui_set_mouse_view_pos(true, cx+1, cy+1);
return CK_MOUSE_MOVE;
}
}
gui_set_mouse_view_pos(false, -1, -1);
if (mode==REGION_TDNGN || mode==REGION_DNGN)
{
oldcx = cx;
oldcy = cy;
oldmode = mode;
if(mode==REGION_DNGN)
tile_place_cursor(cx, cy, true);
if(mode==REGION_TDNGN)
{
gotoxy(cx+2, cy+1, GOTO_DNGN);
}
int gx = view2gridX(cx) + 1;
int gy = view2gridY(cy) + 1;
tip_grid(gx, gy);
return 0;
}
if (mode == REGION_MAP && mouse_mode == MOUSE_MODE_COMMAND)
{
if (oldmode != REGION_MAP)
{
update_tip_text("[L-Click] Travel / [R-Click] View");
}
else
{
tip_grid(cx - 1, cy - 1, false, 1);
}
oldmode = mode;
oldcx = cx;
oldcy = cy;
return 0;
}
if (mode == REGION_MSG && mouse_mode == MOUSE_MODE_COMMAND)
{
if (oldmode != REGION_MSG)
update_tip_text("[L-Click] Browse message history");
oldmode = mode;
oldcx = cx;
oldcy = cy;
return 0;
}
#if 0
if (mode == REGION_STAT && mouse_mode == MOUSE_MODE_COMMAND)
{
oldcx = cx;
oldcy = cy;
oldmode = mode;
int i = 0;
while( Tips[i].tiptext != NULL)
{
if (cx >= Tips[i].sx && cx <= Tips[i].ex &&
cy >= Tips[i].sy && cy <= Tips[i].ey)
break;
i++;
}
if (Tips[i].tiptext == NULL) i = -1;
if (i == old_tip_idx) return 0;
if (old_tip_idx != -1)
hilite_tip_text(old_tip_idx, false);
old_tip_idx = i;
if (i != -1)
{
hilite_tip_text(i, true);
update_tip_text((char *)Tips[i].tiptext);
}
else
update_tip_text("");
return 0;
}
#endif
return 0;
}
static int handle_mouse_button(int mx, int my, int button,
bool shift, bool ctrl)
{
int dir;
const int dx[9]={-1,0,1, -1,0,1, -1,0,1};
const int dy[9]={1,1,1,0,0,0,-1,-1,-1};
const int cmd_n[9]={'b', 'j', 'n', 'h', '.', 'l', 'y', 'k', 'u'};
const int cmd_s[9]={'B', 'J', 'N', 'H', '5', 'L', 'Y', 'K', 'U'};
const int cmd_c[9]={
CONTROL('B'), CONTROL('J'), CONTROL('N'), CONTROL('H'),
'X', CONTROL('L'), CONTROL('Y'), CONTROL('K'), CONTROL('U'),
};
const int cmd_dir[9]={'1','2','3','4','5','6','7','8','9'};
int trig = CK_MOUSE_B1;
if (button == 2) trig = CK_MOUSE_B2;
if (button == 3) trig = CK_MOUSE_B3;
if (button == 4) trig = CK_MOUSE_B4;
if (button == 5) trig = CK_MOUSE_B5;
if (shift) trig |= 512;
if (ctrl) trig |= 1024;
switch(mouse_mode)
{
case MOUSE_MODE_NORMAL:
return trig;
break;
case MOUSE_MODE_MORE:
return '\r';
break;
}
int cx,cy;
int mode;
static int oldcx = -1;
static int oldcy = -1;
static bool enable_wheel = true;
static int old_button = 0;
static int old_hp = 0;
mode = convert_cursor_pos(mx, my, &cx, &cy);
// prevent accidental wheel slip and subsequent char death
if (mouse_mode==MOUSE_MODE_COMMAND && (button == 4 || button == 5)
&& button == old_button && oldcx == cx && oldcy == cy)
{
if(!enable_wheel) return 0;
if (you.hp < old_hp)
{
mpr("Wheel move aborted (rotate opposite to resume)");
enable_wheel = false;
return 0;
}
}
old_hp = you.hp;
enable_wheel = true;
old_button = button;
oldcx = cx;
oldcy = cy;
if (toggle_telescope)
{
// quit telescope mode
TileDrawDungeon(NULL);
toggle_telescope = false;
}
// item clicked
if (mode == REGION_INV1 || mode == REGION_INV2)
{
int ix = TileInvIdx(cx);
if (ix != -1)
{
if (button == 2)
{
// describe item
if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR)
gui_set_mouse_inv(-ix, INV_VIEW);
else
gui_set_mouse_inv(ix, INV_VIEW);
TileMoveInvCursor(-1);
return CK_MOUSE_B2ITEM;
}
else if(button == 1)
{
// Floor item
if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR)
{
// try pick up one item
if (button != 1) return 0;
gui_set_mouse_inv(ix, INV_PICKUP);
return CK_MOUSE_B1ITEM;
}
// use item
if (shift)
gui_set_mouse_inv(ix, INV_DROP);
else
gui_set_mouse_inv(ix, INV_USE);
return CK_MOUSE_B1ITEM;
}
}
return trig;
}
if (mode == REGION_MSG && mouse_mode == MOUSE_MODE_COMMAND)
{
return CONTROL('P');
}
#if 0
if (mode == REGION_STAT && mouse_mode == MOUSE_MODE_COMMAND)
{
int i = 0;
while( Tips[i].tiptext != NULL)
{
if (cx >= Tips[i].sx && cx <= Tips[i].ex &&
cy >= Tips[i].sy && cy <= Tips[i].ey)
break;
i++;
}
if (Tips[i].tipfilename)
{
char fname[256];
snprintf(fname, 250, "tips_e/%s.txt", Tips[i].tipfilename);
ViewTextFile(fname);
redraw_screen();
return CK_MOUSE_DONE;
}
return 0;
}
#endif
if((mouse_mode==MOUSE_MODE_COMMAND || mouse_mode == MOUSE_MODE_MACRO) &&
(mode == REGION_DNGN || mode == REGION_TDNGN))
{
if (button == 2)
{
// describe yourself (char info)
if (cx == DCX && cy == DCY) return '%';
// trigger
if (mouse_mode == MOUSE_MODE_MACRO)
return trig;
// Right Click: try to describe grid
// otherwise return trigger key
if (!in_los_bounds(cx+1,cy+1))
return CK_MOUSE_B2;
const coord_def ep = view2show(coord_def(cx, cy));
if (env.show(ep) == 0)
return trig;
int mid = mgrd[cx][cy];
if (mid == NON_MONSTER || !player_monster_visible( &menv[mid] ))
{
return trig;
}
describe_monsters( menv[ mid ] );
redraw_screen();
mesclr( true );
return CK_MOUSE_DONE;
}
// button = 1 or 4, 5
// first, check if 3x3 grid around @ is clicked.
// if so, return equivalent numpad key
int adir = -1;
for(dir=0;dir<9;dir++)
{
if( DCX+dx[dir] == cx && DCY+dy[dir]==cy)
{
adir = dir;
break;
}
}
if (adir != -1)
{
if (shift)
return cmd_s[adir];
else if (ctrl)
return cmd_c[adir];
else return cmd_n[dir];
}
if (button != 1) return trig;
// otherwise travel to that grid
const coord_def gc = view2grid(coord_def(cx+1, cy+1));
if (!map_bounds(gc)) return 0;
// Activate travel
start_travel(gc.x, gc.y);
return CK_MOUSE_DONE;
}
if(mouse_mode==MOUSE_MODE_COMMAND && mode == REGION_MAP)
{
// begin telescope mode
if (button == 2)
{
toggle_telescope = true;
StoreDungeonView(NULL);
TileDrawFarDungeon(cx-1,cy-1);
return 0;
}
if (button != 1) return trig;
// L-click: try to travel to the grid
const coord_def gc(cx-1, cy-1);
if (!map_bounds(gc)) return 0;
// Activate travel
start_travel(gc.x, gc.y);
return CK_MOUSE_DONE;
}
// target selection
if((mouse_mode==MOUSE_MODE_TARGET || mouse_mode==MOUSE_MODE_TARGET_DIR)
&& button == 1 && (mode == REGION_DNGN || mode == REGION_TDNGN))
{
gui_set_mouse_view_pos(true, cx+1, cy+1);
return CK_MOUSE_CLICK;
}
gui_set_mouse_view_pos(false, 0, 0);
if(mouse_mode==MOUSE_MODE_TARGET_DIR && button == 1 &&
(mode == REGION_DNGN || mode == REGION_TDNGN))
{
if (cx < DCX-1 || cy < DCY-1 || cx > DCX+1 || cy > DCY+1) return 0;
for(dir=0;dir<9;dir++)
{
if( DCX+dx[dir] == cx && DCY+dy[dir]==cy)
{
return cmd_dir[dir];
}
}
return 0;
}
return trig;
}
static int handle_mouse_unbutton(int mx, int my, int button)
{
if (toggle_telescope)
{
TileDrawDungeon(NULL);
}
toggle_telescope = false;
return 0;
}
int getch_ck()
{
int etype = 0;
int x1,y1,x2,y2;
int key;
bool sh, ct;
int k;
while(1)
{
k = 0;
GetNextEvent(&etype, &key, &sh, &ct, &x1, &y1, &x2, &y2);
switch(etype)
{
case EV_BUTTON:
k = handle_mouse_button(x1, y1, key, sh, ct);
break;
case EV_MOVE:
k = handle_mouse_motion(x1, y1, false);
break;
case EV_UNBUTTON:
k = handle_mouse_unbutton(x1, y1, key);
break;
case EV_KEYIN:
k = key;
break;
default:
break;
} // switch
if (k != 0) break;
}/*while*/
return k;
}
int getch()
{
static int ck_tr[] =
{
'k', 'j', 'h', 'l', '.', 'y', 'b', '.', 'u', 'n',
'K', 'J', 'H', 'L', '5', 'Y', 'B', '5', 'U', 'N',
11, 10, 8, 12, '0', 25, 2, 'C', 21, 14
};
int keyin = getch_ck();
if (keyin >= CK_UP && keyin <= CK_CTRL_PGDN)
return ck_tr[ keyin - CK_UP ];
if (keyin == CK_DELETE)
return '.';
return keyin;
}
int m_getch()
{
return getch();
}
void set_mouse_enabled(bool enabled)
{
crawl_state.mouse_enabled = enabled;
}
void mouse_set_mode(int mode)
{
mouse_mode = mode;
// init cursor etc
handle_mouse_motion(0, 0, true);
}
int mouse_get_mode()
{
return mouse_mode;
}
void gui_init_view_params(coord_def &termsz, coord_def &viewsz,
coord_def &msgp, coord_def &msgsz, coord_def &hudp, coord_def &hudsz)
{
// TODO enne - set these other params too?
msgsz.x = msg_x;
msgsz.y = msg_y;
}
void lock_region(int r)
{
if (r >= 0 && r < NUM_REGIONS)
region_lock[r] = true;
}
void unlock_region(int r)
{
if (r >= 0 && r < NUM_REGIONS)
region_lock[r] = false;
}
/*
* Wrapper
*/
void clrscr()
{
win_main->clear();
TextRegionClass::cursor_region = NULL;
// clear Text regions
if (!region_lock[REGION_CRT])
region_crt->clear();
if (region_msg && !region_lock[REGION_MSG])
region_msg->clear();
if (region_stat && !region_lock[REGION_STAT])
region_stat->clear();
if (region_dngn && !region_lock[REGION_TDNGN])
region_dngn->clear();
if (region_tip && !region_lock[REGION_TIP])
region_tip->clear();
// Hack: Do not erase the backbuffer. Instead just hide it.
if (region_map)
{
if(region_lock[REGION_MAP])
region_map->redraw();
else
region_map->flag = false;
}
if (region_item)
{
if (region_lock[REGION_INV1])
region_item->redraw();
else
region_item->flag = false;
}
if (region_item2)
{
if (region_lock[REGION_INV2])
region_item2->redraw();
else
{
TileClearInv(REGION_INV2);
region_item2->flag = false;
}
}
gotoxy(1, 1);
}
void putch(unsigned char chr)
{
// object's method
TextRegionClass::text_mode->putch(chr);
}
void putwch(unsigned chr)
{
// No unicode support.
putch(static_cast<unsigned char>(chr));
}
void writeWChar(unsigned char *ch)
{
// object's method
TextRegionClass::text_mode->writeWChar(ch);
}
void clear_to_end_of_line()
{
// object's method
TextRegionClass::text_mode->clear_to_end_of_line();
}
void clear_to_end_of_screen()
{
// object's method
TextRegionClass::text_mode->clear_to_end_of_screen();
}
void get_input_line_gui(char *const buff, int len)
{
int y, x;
int k = 0;
int prev = 0;
int done = 0;
int kin;
TextRegionClass *r = TextRegionClass::text_mode;
static char last[128];
static int lastk = 0;
if(!r->flag)return;
/* Locate the cursor */
x = wherex();
y = wherey();
/* Paranoia -- check len */
if (len < 1) len = 1;
/* Restrict the length */
if (x + len > r->mx) len = r->mx - x;
if (len > 40) len = 40;
/* Paranoia -- Clip the default entry */
buff[len] = '\0';
buff[0] = '\0';
r->gotoxy(x, y);
putch('_');
/* Process input */
while (!done)
{
/* Get a key */
kin = getch_ck();
/* Analyze the key */
switch (kin)
{
case 0x1B:
k = 0;
done = 1;
break;
case '\n':
case '\r':
k = strlen(buff);
done = 1;
lastk = k;
strncpy(last, buff, k);
break;
case CK_UP: // history
if (lastk != 0)
{
k = lastk;
strncpy(buff, last, k);
}
break;
case 0x7F:
case '\010':
k = prev;
break;
// Escape conversion. (for ^H, etc)
case CONTROL('V'):
kin = getch();
// fallthrough
default:
{
if (k < len &&
(
isprint(kin)
|| (kin >= CONTROL('A') && kin <= CONTROL('Z'))
|| (kin >= 0x80 && kin <=0xff)
)
)
buff[k++] = kin;
break;
}
}
/* Terminate */
buff[k] = '\0';
/* Update the entry */
r->gotoxy(x, y);
int i;
//addstr(buff);
for(i=0;i<k;i++)
{
prev = i;
int c = (unsigned char)buff[i];
if (c>=0x80)
{
if (buff[i+1]==0) break;
writeWChar((unsigned char *)&buff[i]);
i++;
}
else
if (c >= CONTROL('A') && c<= CONTROL('Z'))
{
putch('^');
putch(c + 'A' - 1);
}
else
putch(c);
}
r->addstr((char *)"_ ");
r->gotoxy(x+k, y);
}/* while */
}
void cprintf(const char *format,...)
{
char buffer[2048]; // One full screen if no control seq...
va_list argp;
va_start(argp, format);
vsprintf(buffer, format, argp);
va_end(argp);
// object's method
TextRegionClass::text_mode->addstr(buffer);
TextRegionClass::text_mode->make_active();
}
void textcolor(int color)
{
TextRegionClass::textcolor(color);
}
void textbackground(int bg)
{
TextRegionClass::textbackground(bg);
}
void gotoxy(int x, int y, int region)
{
if (region == GOTO_LAST)
{
// nothing
}
else if (region == GOTO_CRT)
TextRegionClass::text_mode = region_crt;
else if (region == GOTO_MSG)
TextRegionClass::text_mode = region_msg;
else if (region == GOTO_STAT)
TextRegionClass::text_mode = region_stat;
TextRegionClass::text_mode->flag = true;
TextRegionClass::gotoxy(x, y);
}
void _setcursortype(int curstype)
{
TextRegionClass::_setcursortype(curstype);
}
void enable_smart_cursor(bool cursor)
{
gui_smart_cursor = cursor;
}
bool is_smart_cursor_enabled()
{
return (gui_smart_cursor);
}
void set_cursor_enabled(bool enabled)
{
if (gui_smart_cursor) return;
if (enabled) TextRegionClass::_setcursortype(1);
else TextRegionClass::_setcursortype(0);
}
bool is_cursor_enabled()
{
if (TextRegionClass::cursor_flag) return true;
return false;
}
int wherex()
{
return TextRegionClass::wherex();
}
int wherey()
{
return TextRegionClass::wherey();
}
int get_number_of_lines()
{
#ifdef USE_X11
// Lie about the number of lines so that we can reserve the
// bottom one for tooltips...
return region_crt->my - 1;
#else
return region_crt->my;
#endif
}
int get_number_of_cols()
{
return std::min(region_crt->mx, region_msg->mx);
}
void message_out(int which_line, int colour, const char *s, int firstcol,
bool newline)
{
if (!firstcol)
firstcol = Options.delay_message_clear ? 2 : 1;
gotoxy(firstcol, which_line + 1, GOTO_MSG);
textcolor(colour);
cprintf("%s", s);
if (newline && which_line == crawl_view.msgsz.y - 1)
region_msg->scroll();
}
void clear_message_window()
{
region_msg->clear();
}
void put_colour_ch(int colour, unsigned ch)
{
textcolor(colour);
putwch(ch);
}
void puttext(int sx, int sy, int ex, int ey, unsigned char *buf, bool mono,
int where)
{
TextRegionClass *r = (where == 1) ?region_crt:region_dngn;
if (where==1 && UseDosChar) r=region_xmap;
int xx, yy;
unsigned char *ptr = buf;
//gotoxy(1, 1, GOTO_CRT);
for(yy= sy-1; yy<= ey-1; yy++)
{
unsigned char *c = &(r->cbuf[yy*(r->mx)+sx-1]);
unsigned char *a = &(r->abuf[yy*(r->mx)+sx-1]);
for(xx= sx-1; xx<= ex-1; xx++)
{
*c = *ptr;
if (*c==0) *c=32;
#if 0 //deb
if (*c==177) *c=2;
if (*c==176) *c=2;
if (*c==249) *c=31;
#endif
ptr++;
if (mono)
{
*a = WHITE;
}
else
{
*a = *ptr;
ptr++;
}
c++;
a++;
}
}
r->make_active();
r->redraw(sx-1, sy-1, ex-1, ey-1);
}
void ViewTextFile(const char *name)
{
FILE *fp = fopen(name, "r");
int max = get_number_of_lines();
// Hack
#define MAXTEXTLINES 100
#define DELIMITER_END "-------------------------------------------------------------------------------"
#define DELIMITER_MORE "...(more)... "
unsigned char buf[80*MAXTEXTLINES], buf2[84];
int nlines = 0;
int cline = 0;
int i;
if (!fp)
{
mpr("Couldn't open file.");
return;
}
for (i=0; i<80*MAXTEXTLINES; i++) buf[i] = ' ';
while(nlines<MAXTEXTLINES)
{
fgets((char *)buf2, 82, fp);
if (feof(fp)) break;
i = 0;
while(i<79 && buf2[i] !=13 && buf2[i] != 10) i++;
memcpy(&buf[nlines*80], buf2, i);
nlines++;
}
fclose(fp);
clrscr();
while(1)
{
gotoxy(1, 1);
if (cline == 0)
cprintf(DELIMITER_END);
else
cprintf(DELIMITER_MORE);
puttext(1, 2, 80, max, &buf[cline*80], true, 1);
gotoxy(1, max);
if (cline + max-2 >= nlines)
cprintf(DELIMITER_END);
else
cprintf(DELIMITER_MORE);
gotoxy(14, max);
cprintf("[j/k/+/-/SPACE/b: scroll q/ESC/RETURN: exit]");
mouse_set_mode(MOUSE_MODE_MORE);
int key = getch();
mouse_set_mode(MOUSE_MODE_NORMAL);
if (key == 'q' || key == ESCAPE || key =='\r') break;
if (key == '-' || key == 'b') cline -= max-2;
if (key == 'k') cline --;
if (key == '+' || key == ' ') cline += max-2;
if (key == 'j') cline ++;
if (key == CK_MOUSE_B4) cline--;
if (key == CK_MOUSE_B5) cline++;
if (cline + max-2 > nlines) cline = nlines-max + 2;
if (cline < 0) cline = 0;
}
}
void window(int x1, int y1, int x2, int y2)
{
}
#ifdef USE_TILE
// Interactive menu for item drop/use
void use_item(int idx, InvAction act)
{
if (act == INV_PICKUP)
{
pickup_single_item(idx, mitm[idx].quantity);
return;
}
else if (act == INV_DROP)
{
#ifdef USE_TILE
TileMoveInvCursor(-1);
#endif
drop_item(idx, you.inv[idx].quantity);
return;
}
else if (act != INV_USE)
{
return;
}
// Equipped?
bool equipped = false;
for (unsigned int i=0; i< NUM_EQUIP;i++)
{
if (you.equip[i] == idx)
{
equipped = true;
break;
}
}
#ifdef USE_TILE
TileMoveInvCursor(-1);
#endif
// Special case for folks who are wielding something
// that they shouldn't be wielding.
if (you.equip[EQ_WEAPON] == idx)
{
if (!check_warning_inscriptions(you.inv[idx], OPER_WIELD))
return;
wield_weapon(true, PROMPT_GOT_SPECIAL);
return;
}
// Use it
switch (you.inv[idx].base_type)
{
case OBJ_WEAPONS:
case OBJ_STAVES:
if (!check_warning_inscriptions(you.inv[idx], OPER_WIELD))
return;
if (equipped)
wield_weapon(true, PROMPT_GOT_SPECIAL);
else
wield_weapon(true, idx);
return;
case OBJ_MISCELLANY:
if (equipped)
{
if (!check_warning_inscriptions(you.inv[idx], OPER_EVOKE))
return;
evoke_wielded();
}
else
{
if (!check_warning_inscriptions(you.inv[idx], OPER_WIELD))
return;
wield_weapon(true, idx);
}
return;
case OBJ_MISSILES:
if (!check_warning_inscriptions(you.inv[idx], OPER_THROW))
return;
throw_anything(idx);
return;
case OBJ_ARMOUR:
if (equipped)
{
if (!check_warning_inscriptions(you.inv[idx], OPER_TAKEOFF))
return;
takeoff_armour(idx);
}
else
{
if (!check_warning_inscriptions(you.inv[idx], OPER_WEAR))
return;
wear_armour(idx);
}
return;
case OBJ_WANDS:
if (!check_warning_inscriptions(you.inv[idx], OPER_ZAP))
return;
zap_wand(idx);
return;
case OBJ_FOOD:
if (!check_warning_inscriptions(you.inv[idx], OPER_EAT))
return;
eat_food(false, idx);
return;
case OBJ_SCROLLS:
case OBJ_BOOKS:
if (!check_warning_inscriptions(you.inv[idx], OPER_READ))
return;
read_scroll(idx);
return;
case OBJ_JEWELLERY:
if (equipped)
{
if (!check_warning_inscriptions(you.inv[idx], OPER_REMOVE))
return;
remove_ring(idx);
}
else
{
if (!check_warning_inscriptions(you.inv[idx], OPER_PUTON))
return;
puton_ring(idx, false);
}
return;
case OBJ_POTIONS:
if (!check_warning_inscriptions(you.inv[idx], OPER_QUAFF))
return;
drink(idx);
return;
default:
return;
}
}
#endif
}
}
void InvMenu::draw_stock_item(int index, const MenuEntry *me) const
{
#ifdef USE_TILE
const InvEntry *ie = dynamic_cast<const InvEntry*>(me);
if (ie && me->quantity > 0)
{
int draw_quantity = ie->quantity > 1 ? ie->quantity : -1;
bool is_item_on_floor = true;
bool is_item_tried = false;
char c = 0;
int idx = -1;
if (ie->item)
{
is_item_on_floor = ie->item->x != -1;
is_item_tried = item_type_tried(*ie->item);
c = ie->hotkeys.size() > 0 ? ie->hotkeys[0] : 0;
idx = (is_item_on_floor ? ie->item->index() :
letter_to_index(c));
}
TileDrawOneItem(REGION_INV2, get_entry_index(ie), c,
idx, tileidx_item(*ie->item), draw_quantity,
is_item_on_floor, ie->selected(), ie->is_item_equipped(),
is_item_tried, ie->is_item_cursed());
/* 1) Image manipulation routines
* 2) WinClass and RegionClass system independent imprementaions
* see guic-*.cc for system dependent implementations
*/
// Class defines
#include "guic.h"
#ifdef WIN32TILES
#else
#define dos_char false;
#endif
int TextRegionClass::print_x;
int TextRegionClass::print_y;
TextRegionClass *TextRegionClass::text_mode = NULL;
int TextRegionClass::text_col = 0;
TextRegionClass *TextRegionClass::cursor_region= NULL;
int TextRegionClass::cursor_flag = 0;
int TextRegionClass::cursor_x;
int TextRegionClass::cursor_y;
// more logical color naming
const int map_colors[MAX_MAP_COL][3]=
{
{ 0, 0, 0}, // BLACK
{128, 128, 128}, // DKGREY
{160, 160, 160}, // MDGREY
{192, 192, 192}, // LTGREY
{255, 255, 255}, // WHITE
{ 0, 64, 255}, // BLUE (actually cyan-blue)
{128, 128, 255}, // LTBLUE
{ 0, 32, 128}, // DKBLUE (maybe too dark)
{ 0, 255, 0}, // GREEN
{128, 255, 128}, // LTGREEN
{ 0, 128, 0}, // DKGREEN
{ 0, 255, 255}, // CYAN
{ 64, 255, 255}, // LTCYAN (maybe too pale)
{ 0, 128, 128}, // DKCYAN
{255, 0, 0}, // RED
{255, 128, 128}, // LTRED (actually pink)
{128, 0, 0}, // DKRED
{192, 0, 255}, // MAGENTA (actually blue-magenta)
{255, 128, 255}, // LTMAGENTA
{ 96, 0, 128}, // DKMAGENTA
{255, 255, 0}, // YELLOW
{255, 255, 64}, // LTYELLOW (maybe too pale)
{128, 128, 0}, // DKYELLOW
{165, 91, 0}, // BROWN
};
const int term_colors[MAX_TERM_COL][3]=
{
{ 0, 0, 0}, // BLACK
{ 0, 82, 255}, // BLUE
{100, 185, 70}, // GREEN
{ 0, 180, 180}, // CYAN
{255, 48, 0}, // RED
{238, 92, 238}, // MAGENTA
{165, 91, 0}, // BROWN
{162, 162, 162}, // LIGHTGREY
{ 82, 82, 82}, // DARKGREY
{ 82, 102, 255}, // LIGHTBLUE
{ 82, 255, 82}, // LIGHTGREEN
{ 82, 255, 255}, // LIGHTCYAN
{255, 82, 82}, // LIGHTRED
{255, 82, 255}, // LIGHTMAGENTA
{255, 255, 82}, // YELLOW
{255, 255, 255} // WHITE
};
/*------------------------------------------*/
// ������
WinClass::WinClass()
{
// Minimum;
wx = 10;
wy = 10;
ox = 0;
oy = 0;
SysInit();
}
// �I��
WinClass::~WinClass()
{
SysDeinit();
regions.clear();
layers.clear();
}
void WinClass::placeRegion(RegionClass *r, int layer0,
int x, int y,
int margin_top, int margin_left,
int margin_bottom, int margin_right)
{
if (r->win == NULL)
{
regions.push_back(r);
layers.push_back(layer0);
}
r->win = this;
r->layer = layer0;
r->flag = true;
r->sx = x;
r->sy = y;
r->ox = r->sx + margin_left;
r->oy = r->sy + margin_top;
r->wx = r->dx * r->mx + margin_left + margin_right;
r->wy = r->dy * r->my + margin_top + margin_bottom;
r->ex = r->sx + r->wx;
r->ey = r->sy + r->wy;
if (r->ex > wx) wx = r->ex;
if (r->ey > wy) wy = r->ey;
}
void WinClass::placeRegion(RegionClass *r, int layer0,
RegionClass *neighbor, int pflag,
int margin_top, int margin_left,
int margin_bottom, int margin_right)
{
int sx0 =0;
int sy0 =0;
int ex0 =0;
int ey0 =0;
int x = 0;
int y = 0;
if (neighbor!=NULL)
{
sx0 = neighbor->sx;
sy0 = neighbor->sy;
ex0 = neighbor->ex;
ey0 = neighbor->ey;
}
if (pflag == PLACE_RIGHT)
{
x = ex0;
y = sy0;
}
else
{
x = sx0;
y = ey0;
}
placeRegion(r, layer0, x, y, margin_top, margin_left,
margin_bottom, margin_right);
}
void WinClass::redraw(int x1, int y1, int x2, int y2)
{
std::vector <RegionClass *>::iterator r;
int cx1, cx2, cy1, cy2;
for (r = regions.begin();r != regions.end();r++)
{
if (!(*r)->is_active()) continue;
if( (*r)->convert_redraw_rect(x1, y1, x2, y2, &cx1, &cy1, &cx2, &cy2))
{
(*r)->redraw(cx1, cy1, cx2, cy2);
}
}
}
void WinClass::redraw()
{
redraw(0, 0, wx-1, wy-1);
}
void WinClass::move(int ox0, int oy0)
{
ox = ox0;
oy = oy0;
move(); // system dependent
}
void WinClass::resize(int wx0, int wy0)
{
if (wx0>0) wx = wx0;
if (wy0>0) wy = wy0;
resize(); // system dependent
}
/*------------------------------------------*/
/* �������̏���
* 0 (�e�N���X�̏����A����)
* 1 �@�틤�ʏ���
* 2 �@���ˑ�����
*
* �I�������̏���
* 1 �@���ˑ�����
* 2 �@�틤�ʏ���
* (3) (�e�N���X�̏����A����)
*/
//������
RegionClass::RegionClass()
{
flag = false;
win = NULL;
backbuf = NULL;
SysInit();
ox = oy = 0;
dx = dy = 1;
font_copied = false;
id = 0;
}
//�I������
RegionClass::~RegionClass()
{
SysDeinit();
// �o�b�N�o�b�t�@����
if (backbuf != NULL) ImgDestroy(backbuf);
}
void TextRegionClass::resize(int x, int y)
{
int i;
free(cbuf);
free(abuf);
cbuf = (unsigned char *)malloc(x*y);
abuf = (unsigned char *)malloc(x*y);
for (i=0; i<x*y; i++)
{
cbuf[i]=' ';
abuf[i]=0;
}
mx = x;
my = y;
}
// ������
TextRegionClass::TextRegionClass(int x, int y, int cx, int cy)
{
cbuf = NULL;
abuf = NULL;
resize(x, y);
// Cursor Offset
cx_ofs = cx;
cy_ofs = cy;
//�@���ˑ�����
SysInit(x, y, cx, cy);
}
//�I������
TextRegionClass::~TextRegionClass()
{
SysDeinit();
free(cbuf);
free(abuf);
}
//������
TileRegionClass::TileRegionClass(int mx0, int my0, int dx0, int dy0)
{
// Unit size
dx = dx0;
dy = dy0;
mx = mx0;
my = my0;
force_redraw = false;
//�@���ˑ�����
SysInit(mx0, my0, dx0, dy0);
}
//�I������
TileRegionClass::~TileRegionClass()
{
SysDeinit();
}
void TileRegionClass::resize(int mx0, int my0, int dx0, int dy0)
{
if (mx0 != 0) mx = mx0;
if (my0 != 0) my = my0;
if (dx0 != 0) dx = dx0;
if (dy0 != 0) dy = dy0;
}
// ������
MapRegionClass::MapRegionClass(int x, int y, int o_x, int o_y, bool iso)
{
int i;
mx2 = x;
my2 = y;
mx = mx2;
my = my2;
mbuf = (unsigned char *)malloc(mx2*my2);
for (i=0; i<mx2*my2; i++)
{
mbuf[i]=0;
}
x_margin = o_x;
y_margin = o_y;
force_redraw = false;
//�@���ˑ�����
SysInit(x, y, o_x, o_y);
}
//�I������
MapRegionClass::~MapRegionClass()
{
SysDeinit();
free(mbuf);
}
void MapRegionClass::resize(int mx0, int my0, int dx0, int dy0)
{
if (mx0 != 0) mx2 = mx0;
if (my0 != 0) my2 = my0;
if (dx0 != 0) dx = dx0;
if (dy0 != 0) dy = dy0;
if (mx0 != 0 || my0 != 0)
{
int i;
free(mbuf);
mbuf = (unsigned char *)malloc(mx2*my2);
for (i=0; i<mx2*my2; i++) mbuf[i]=0;
}
}
/*------------------------------------------*/
bool RegionClass::is_active()
{
if (!flag) return false;
if (win->active_layer == layer)
return true;
else return false;
}
void RegionClass::make_active()
{
if (!flag) return;
win->active_layer = layer;
}
void RegionClass::redraw(int x1, int y1, int x2, int y2)
{
}
void RegionClass::redraw()
{
redraw(0, 0, mx-1, my-1);
}
void MapRegionClass::redraw()
{
redraw(0, 0, mx-1, my-1);
}
void TileRegionClass::redraw()
{
redraw(0, 0, mx*dx-1, my*dy-1);
}
void MapRegionClass::set_col(int col, int x, int y)
{
mbuf[x + y * mx2] = col;
}
int MapRegionClass::get_col(int x, int y)
{
return mbuf[x + y * mx2];
}
/*------------------------------------------*/
bool RegionClass::convert_redraw_rect(int x1, int y1, int x2, int y2,
int *rx1, int *ry1, int *rx2, int *ry2)
{
int cx1 = x1-ox;
int cy1 = y1-oy;
int cx2 = x2-ox;
int cy2 = y2-oy;
if ( (cx2 < 0) || (cy2 < 0) || (cx1 >= dx*mx) || (cy1 >=dy*my))
return false;
cx1 /= dx;
cy1 /= dy;
cx2 /= dx;
cy2 /= dy;
if(cx2>=mx-1)cx2=mx-1;
if(cy2>=my-1)cy2=my-1;
if(cx1<0) cx1=0;
if(cy1<0) cy1=0;
*rx1 = cx1;
*ry1 = cy1;
*rx2 = cx2;
*ry2 = cy2;
return true;
}
bool TileRegionClass::convert_redraw_rect(int x1, int y1, int x2, int y2,
int *rx1, int *ry1, int *rx2, int *ry2)
{
int cx1 = x1-ox;
int cy1 = y1-oy;
int cx2 = x2-ox;
int cy2 = y2-oy;
int wwx = dx*mx;
int wwy = dy*my;
if ( (cx2 < 0) || (cy2 < 0) || (cx1 >= wwx) || (cy1 >=wwy))
return false;
if(cx2>=wwx-1)cx2=wwx-1;
if(cy2>=wwy-1)cy2=wwy-1;
if(cx1<0) cx1=0;
if(cy1<0) cy1=0;
*rx1 = cx1;
*ry1 = cy1;
*rx2 = cx2;
*ry2 = cy2;
return true;
}
bool RegionClass::mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy)
{
int x = mouse_x - ox;
int y = mouse_y - oy;
if (!is_active()) return false;
if ( x < 0 || y < 0 ) return false;
x /= dx;
y /= dy;
if (x >= mx || y >= my) return false;
*cx = x;
*cy = y;
return true;
}
bool MapRegionClass::mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy)
{
int x = mouse_x - ox;
int y = mouse_y - oy;
if ( x < 0 || y < 0 ) return false;
x /= dx;
y /= dy;
if (x >= mx || y >= my) return false;
if (!is_active()) return false;
*cx = x;
*cy = y;
return true;
}
bool TileRegionClass::mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy)
{
int x = mouse_x - ox;
int y = mouse_y - oy;
if (!is_active()) return false;
if ( x < 0 || y < 0 ) return false;
if ( x >= dx*mx || y >= dy*my ) return false;
x /= dx;
y /= dy;
*cx = x;
*cy = y;
return true;
}
/*
* Text related
*/
void TextRegionClass::scroll()
{
int idx;
if(!flag)
return;
for(idx=0; idx<mx*(my-1);idx++)
{
cbuf[idx] = cbuf[idx + mx];
abuf[idx] = abuf[idx + mx];
}
for(idx=mx*(my-1);idx<mx*my;idx++)
{
cbuf[idx] = ' ';
abuf[idx] = 0;
}
redraw(0, 0, mx-1, my-1);
}
void TextRegionClass::adjust_region(int *x1, int *x2, int y)
{
#ifdef JP
if (dos_char)
{
*x2 = *x2 + 1;
return;
}
int nx1 = 0;
int nx2 = mx;
unsigned char *ptr = &cbuf[y * mx];
int x = 0;
while (x<mx)
{
if(x<=*x1) nx1=x;
if(x>*x2)
{
nx2=x;
break;
}
if (ptr[x] & 0x80) x+=2;
else x++;
}
*x1 = nx1;
*x2 = nx2;
#else
*x2 = *x2 + 1;
#endif
}
void TextRegionClass::addstr(char *buffer)
{
int i,j;
char buf2[1024];
int len = strlen(buffer);
if(!flag)return;
j=0;
for(i=0;i<len+1;i++)
{
char c = buffer[i];
bool newline=false;
if (c== '\n' || c== '\r')
{
c=0;
newline = true;
if (buffer[i+1]=='\n' || buffer[i+1]=='\r')
i++;
}
buf2[j] = c;
j++;
if(c==0)
{
if (j-1 != 0)
addstr_aux(buf2, j - 1); // draw it
if (newline)
{
print_x = cx_ofs;
print_y++;
j=0;
if(print_y - cy_ofs == my)
{
scroll();
print_y--;
}
}
}
}
if (cursor_flag) gotoxy(print_x+1, print_y+1);
}
void TextRegionClass::addstr_aux(char *buffer, int len)
{
int i;
int x = print_x - cx_ofs;
int y = print_y - cy_ofs;
int adrs = y * mx;
int head = x;
int tail = x + len - 1;
if(!flag)return;
adjust_region(&head, &tail, y);
#ifdef JP
// prevent half displayed kanji
cbuf[adrs+head] = ' ';
abuf[adrs+head] = text_col;
cbuf[adrs+tail-1] = ' ';
abuf[adrs+tail-1] = text_col;
#endif
for (i=0; i < len && x + i < mx;i++)
{
cbuf[adrs+x+i]=buffer[i];
abuf[adrs+x+i]=text_col;
}
draw_string(head, y, &cbuf[adrs+head], tail-head, text_col);
print_x += len;
}
void TextRegionClass::redraw(int x1, int y1, int x2, int y2)
{
int x, y;
if(!flag)return;
for(y=y1;y<=y2;y++)
{
unsigned char *a = &abuf[y * mx];
unsigned char *c = &cbuf[y * mx];
int head = x1;
int tail = x2;
adjust_region(&head, &tail, y);
x=head;
int col = a[x];
while (x<=tail)
{
int oldcol = col;
if (x==tail)
col = -1;
else
col = a[x];
if (oldcol != col)
{
draw_string(head, y, &c[head], x-head, oldcol);
head = x;
}
#ifdef JP
if ( ((c[x] & 0x80) == 0x80) && (dos_char == false))
x+=2;
else
x++;
#else
x++;
#endif
}
}
if(cursor_region == this && cursor_flag == 1)
draw_cursor(cursor_x, cursor_y);
sys_flush();
}
void TextRegionClass::clear_to_end_of_line()
{
int i;
int cx = print_x - cx_ofs;
int cy = print_y - cy_ofs;
int col = text_col;
int adrs = cy * mx;
if(!flag)return;
for(i=cx; i<mx; i++){
cbuf[adrs+i]=' ';
abuf[adrs+i]=col;
}
redraw(cx, cy, mx-1, cy);
}
void TextRegionClass::clear_to_end_of_screen()
{
int i;
int cy = print_y - cy_ofs;
int col = text_col;
if(!flag)return;
for(i=cy*mx; i<mx*my; i++){
cbuf[i]=' ';
abuf[i]=col;
}
redraw(0, cy, mx-1, my-1);
}
void TextRegionClass::putch(unsigned char ch)
{
if (ch==0) ch=32;
addstr_aux((char *)&ch, 1);
}
void TextRegionClass::writeWChar(unsigned char *ch)
{
addstr_aux((char *)ch, 2);
}
void TextRegionClass::textcolor(int color)
{
text_col = color;
}
void TextRegionClass::textbackground(int col)
{
textcolor(col*16 + (text_col & 0xf));
}
void TextRegionClass::gotoxy(int x, int y)
{
print_x = x-1;
print_y = y-1;
if (cursor_region != NULL && cursor_flag)
{
cursor_region ->erase_cursor();
cursor_region = NULL;
}
if (cursor_flag)
{
text_mode->draw_cursor(print_x, print_y);
cursor_x = print_x;
cursor_y = print_y;
cursor_region = text_mode;
}
}
int TextRegionClass::wherex()
{
return print_x + 1;
}
int TextRegionClass::wherey()
{
return print_y + 1;
}
void TextRegionClass::_setcursortype(int curstype)
{
cursor_flag = curstype;
if (cursor_region != NULL)
cursor_region ->erase_cursor();
if (curstype)
{
text_mode->draw_cursor(print_x, print_y);
cursor_x = print_x;
cursor_y = print_y;
cursor_region = text_mode;
}
}
#if 0
int TextRegionClass::get_number_of_lines()
{
return (text_mode->cx_ofs + text_mode->my);
}
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xutil.h>
#include <X11/Xlocale.h>
#include <X11/keysym.h>
#include <X11/keysymdef.h>
#include <X11/Xmd.h>
#if DEBUG
#define ASSERT(p) {if (!(p)) printf( __FILE__, __LINE__);}
#else
#define ASSERT(p) ((void) 0)
#endif
#include "guic.h"
static Display *display;
static int screen;
static GC term_gc[MAX_TERM_COL];
static GC map_gc[MAX_MAP_COL];
static unsigned long term_pix[MAX_TERM_COL];
static unsigned long map_pix[MAX_MAP_COL];
static unsigned long pix_transparent;
static unsigned long pix_hilite;
static unsigned long pix_black;
static unsigned long pix_rimcolor;
static int x11_byte_per_pixel_ximage();
static unsigned long create_pixel(unsigned int red, unsigned int green,
unsigned int blue);
static XImage *read_png(const char *fname);
/*******************************************************/
void WinClass::SysInit()
{
win = (Window)NULL;
}
void WinClass::SysDeinit()
{}
void RegionClass::SysInit()
{
font = NULL;
}
void RegionClass::SysDeinit()
{
if (font != NULL && !font_copied) XFreeFont(display, font);
}
void TextRegionClass::SysInit(int x, int y, int cx, int cy)
{}
void TextRegionClass::SysDeinit()
{}
void TileRegionClass::SysInit(int mx0, int my0, int dx0, int dy0)
{}
void TileRegionClass::SysDeinit()
{}
void MapRegionClass::SysInit(int x, int y, int o_x, int o_y)
{}
void MapRegionClass::SysDeinit()
{}
void RegionClass::init_font(const char *name){
/*** Large part of this routine was copied from Hengband ***/
int ascent, descent, width;
font = XLoadQueryFont(display, name);
if (!font)
{
fprintf(stderr,"Error! Can't load font %s\n",name);
exit(1);
}
width = font->max_bounds.width;
ascent = font->ascent;
descent = font->descent;
int i;
for (i=0;i<MAX_TERM_COL;i++)
XSetFont(display, term_gc[i], font->fid);
fx = dx = width;
fy = dy = ascent + descent;
asc = ascent;
font_copied = false;
}
void RegionClass::copy_font(RegionClass *r)
{
fx = r->fx;
fy = r->fy;
dx = r->dx;
dy = r->dy;
asc = r->asc;
font = r->font;
font_copied = true;
}
void RegionClass::sys_flush()
{
XFlush(display);
}
void RegionClass::init_backbuf()
{
}
void TextRegionClass::init_backbuf()
{
}
void TileRegionClass::init_backbuf()
{
int x, y;
backbuf = ImgCreateSimple(mx*dx, my*dy);
for (x = 0; x < mx*dx; x++)
for (y = 0; y < my*dy; y++)
XPutPixel(backbuf, x, y, pix_black);
}
void TileRegionClass::resize_backbuf()
{
if (backbuf != NULL) ImgDestroy(backbuf);
init_backbuf();
}
void RegionClass::resize_backbuf()
{
if (backbuf != NULL) ImgDestroy(backbuf);
init_backbuf();
}
void MapRegionClass::init_backbuf()
{
int x, y;
backbuf = ImgCreateSimple(mx*dx, my*dy);
for (x = 0; x < mx*dx; x++)
for (y = 0; y < my*dy; y++)
XPutPixel(backbuf, x, y, pix_black);
}
void MapRegionClass::resize_backbuf()
{
if (backbuf != NULL)
ImgDestroy(backbuf);
init_backbuf();
}
void TextRegionClass::draw_string(int x, int y, unsigned char *buf,
int len, int col)
{
XFillRectangle(display, win->win, term_gc[col>>4],
x*dx+ox, y*dy+oy, dx * len, dy);
XDrawString(display, win->win, term_gc[col&0x0f], x*dx+ox, y*dy+asc+oy,
(char *)&cbuf[y*mx+x], len);
}
void TextRegionClass::draw_cursor(int x, int y)
{
if(!flag)return;
XDrawString(display, win->win, term_gc[0x0f], x*dx+ox, y*dy+asc+oy,
"_", 1);
sys_flush();
}
void TextRegionClass::erase_cursor()
{
WinClass *w = win;
int x0 = cursor_x;
int y0 = cursor_y;
int width = 1;
int adrs = y0 * mx + x0;
int col = abuf[adrs];
int x1 = x0;;
if(!flag)return;
XFillRectangle(display, w->win, term_gc[col>>4],
x1*dx + ox, y0*dy +oy, dx*width, dy);
XDrawString(display, w->win,
term_gc[col&0x0f], x0*dx+ ox, y0*dy+asc+ oy,
(char *)&cbuf[adrs], width );
}
void WinClass::clear()
{
fillrect(0, 0, wx, wy, PIX_BLACK);
XFlush(display);
}
void RegionClass::clear()
{
fillrect(0, 0, wx, wy, PIX_BLACK);
XFlush(display);
}
void TileRegionClass::clear()
{
RegionClass::clear();
}
void MapRegionClass::clear()
{
int i;
for (i=0; i<mx2*my2; i++)
{
mbuf[i]=PIX_BLACK;
}
RegionClass::clear();
}
void TextRegionClass::clear()
{
int i;
for (i=0; i<mx*my; i++)
{
cbuf[i]=' ';
abuf[i]=0;
}
RegionClass::clear();
}
void WinClass::create(char *name)
{
if (!win)
{
win = XCreateSimpleWindow(display, RootWindow(display,screen),
10,10, wx, wy, 0,
BlackPixel(display,screen), BlackPixel(display,screen));
XMapWindow(display, win);
XSelectInput(display, win, ExposureMask | KeyPressMask
| ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
LeaveWindowMask | EnterWindowMask | StructureNotifyMask );
move(ox, oy);
}
else
resize(0,0);
clear();
}
void WinClass::move()
{
XMoveWindow(display, win, ox, oy);
}
void WinClass::resize()
{
XResizeWindow(display, win, wx, wy);
}
void TileRegionClass::redraw(int x1, int y1, int x2, int y2)
{
int wwx = x2-x1+1;
int wwy = y2-y1+1;
if (x1<0)
{
wwx += x1;
x1 = 0;
}
if (y1<0)
{
wwy += y1;
y1 = 0;
}
if (x2 >= mx*dx)
{
wwx -= x2-mx*dx+1;
}
if (y2 >= my*dy)
{
wwy -= y2-my*dy+1;
}
XPutImage(display, win->win, term_gc[0],
backbuf, x1, y1, x1+ox, y1+oy, wwx, wwy);
}
void MapRegionClass::redraw(int x1, int y1, int x2, int y2)
{
if (!flag)
return;
XPutImage(display, win->win, term_gc[0],
backbuf, x1*dx, y1*dy,
x1*dx+ox, y1*dy+oy,
(x2-x1+1)*dx, (y2-y1+1)*dy);
}
void MapRegionClass::draw_data(unsigned char *buf){
int x, y, xx, yy;
static int px = 0;
static int py = 0;
if (!flag)
return;
for(yy=0;yy<dy*2;yy++)
{
XPutPixel(backbuf, px*dx+dx/2, yy, map_pix[MAP_BLACK]);
}
for(xx=0;xx<dx*2;xx++)
{
XPutPixel(backbuf, xx, py*dy+dy/2, map_pix[MAP_BLACK]);
}
for (y = 0; y < my; y++)
{
unsigned char *ptr =
&buf[x_margin + (y_margin + y)*(mx2 + x_margin*2)];
for (x = 0; x < mx; x++)
{
int col = ptr[x];
// Hack :remember player position
if (col == MAP_WHITE)
{
px = x;
py = y;
}
if(col != get_col(x, y) || force_redraw)
{
for(xx=0; xx<dx; xx++)
for(yy=0; yy<dy; yy++)
XPutPixel(backbuf, x*dx+xx, y*dy+yy, map_pix[col]);
set_col(col, x, y);
}
}
}
for(yy=0;yy<dy*2;yy++)
{
XPutPixel(backbuf, px*dx+dx/2, yy, map_pix[MAP_WHITE]);
}
for(xx=0;xx<dx*2;xx++)
{
XPutPixel(backbuf, xx, py*dy+dy/2, map_pix[MAP_WHITE]);
}
redraw();
XFlush(display);
force_redraw = false;
}
/* XXXXX
* img_type related
*/
bool ImgIsTransparentAt(img_type img, int x, int y)
{
ASSERT(x>=0);
ASSERT(y>=0);
ASSERT(x<(img->width));
ASSERT(y<(img->height));
return (pix_transparent == XGetPixel(img, x, y)) ? true:false;
}
void ImgSetTransparentPix(img_type img)
{
pix_transparent = XGetPixel(img, 0, 0);
}
void ImgDestroy(img_type img)
{
XDestroyImage(img);
}
img_type ImgCreateSimple(int wx, int wy)
{
if (wx ==0 || wy == 0) return NULL;
char *buf = (char *)malloc(x11_byte_per_pixel_ximage()* wx * wy);
img_type res= XCreateImage(display, DefaultVisual(display, screen),
DefaultDepth(display, screen),
ZPixmap, 0, buf, wx, wy, 8, 0);
return(res);
}
img_type ImgLoadFile(const char *name)
{
return read_png(name);
}
void ImgClear(img_type img)
{
int x,y;
ASSERT(img != NULL);
for(y=0;y<img->height;y++)
for(x=0;x<img->width;x++)
XPutPixel(img, x, y, pix_transparent);
}
// Copy internal image to another internal image
void ImgCopy(img_type src, int sx, int sy, int wx, int wy,
img_type dest, int dx, int dy, int copy)
{
int x, y;
int bpp = src->bytes_per_line / src->width;
int bpl_s = src->bytes_per_line;
int bpl_d = dest->bytes_per_line;
ASSERT(sx>=0);
ASSERT(sy>=0);
ASSERT(sx+wx<=(src->width));
ASSERT(sy+wy<=(src->height));
ASSERT(dx>=0);
ASSERT(dy>=0);
ASSERT(dx+wx<=(dest->width));
ASSERT(dy+wy<=(dest->height));
if(copy==1)
{
char *p_src = (char *)(src->data + bpl_s * sy + sx * bpp);
char *p_dest = (char *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
memcpy(p_dest, p_src, wx * bpp);
p_src += bpl_s;
p_dest += bpl_d;
}
}
else if(bpp<=1)
{
CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp);
CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] != pix_transparent)
p_dest[x] = p_src[x];
}
p_src += bpl_s;
p_dest += bpl_d;
}
}
else if(bpp<=2)
{
CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp);
CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] != pix_transparent)
p_dest[x] = p_src[x];
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
else if(bpp<=4)
{
CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp);
CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] != pix_transparent)
p_dest[x] = p_src[x];
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
}
// Copy internal image to another internal image
void ImgCopyH(img_type src, int sx, int sy, int wx, int wy,
img_type dest, int dx, int dy, int copy)
{
int x, y;
int bpp = src->bytes_per_line / src->width;
int bpl_s = src->bytes_per_line;
int bpl_d = dest->bytes_per_line;
ASSERT(sx>=0);
ASSERT(sy>=0);
ASSERT(sx+wx<=(src->width));
ASSERT(sy+wy<=(src->height));
ASSERT(dx>=0);
ASSERT(dy>=0);
ASSERT(dx+wx<=(dest->width));
ASSERT(dy+wy<=(dest->height));
if(copy==1)
{
char *p_src = (char *)(src->data + bpl_s * sy + sx * bpp);
char *p_dest = (char *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
memcpy(p_dest, p_src, wx * bpp);
p_src += bpl_s;
p_dest += bpl_d;
}
}
else if(bpp<=1)
{
CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp);
CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] == pix_rimcolor)
p_dest[x] = pix_hilite;
else if(p_src[x] != pix_transparent)
p_dest[x] = p_src[x];
}
p_src += bpl_s;
p_dest += bpl_d;
}
}
else if(bpp<=2)
{
CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp);
CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] == pix_rimcolor)
p_dest[x] = pix_hilite;
else if(p_src[x] != pix_transparent)
p_dest[x] = p_src[x];
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
else if(bpp<=4)
{
CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp);
CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] == pix_rimcolor)
p_dest[x] = pix_hilite;
else if(p_src[x] != pix_transparent)
p_dest[x] = p_src[x];
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
}
// Copy internal image to another internal image
void ImgCopyMasked(img_type src, int sx, int sy, int wx, int wy,
img_type dest, int dx, int dy, char *mask)
{
int x, y, count;
int bpp = src->bytes_per_line / src->width;
int bpl_s = src->bytes_per_line;
int bpl_d = dest->bytes_per_line;
ASSERT(sx>=0);
ASSERT(sy>=0);
ASSERT(sx+wx<=(src->width));
ASSERT(sy+wy<=(src->height));
ASSERT(dx>=0);
ASSERT(dy>=0);
ASSERT(dx+wx<=(dest->width));
ASSERT(dy+wy<=(dest->height));
count = 0;
if(bpp<=1)
{
CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp);
CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] != pix_transparent && mask[count]==0)
p_dest[x] = p_src[x];
count++;
}
p_src += bpl_s;
p_dest += bpl_d;
}
}
else if(bpp<=2)
{
CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp);
CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] != pix_transparent && mask[count]==0)
p_dest[x] = p_src[x];
count++;
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
else if(bpp<=4)
{
CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp);
CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] != pix_transparent && mask[count]==0)
p_dest[x] = p_src[x];
count++;
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
}
// Copy internal image to another internal image
void ImgCopyMaskedH(img_type src, int sx, int sy, int wx, int wy,
img_type dest, int dx, int dy, char *mask)
{
int x, y, count;
int bpp = src->bytes_per_line / src->width;
int bpl_s = src->bytes_per_line;
int bpl_d = dest->bytes_per_line;
ASSERT(sx>=0);
ASSERT(sy>=0);
ASSERT(sx+wx<=(src->width));
ASSERT(sy+wy<=(src->height));
ASSERT(dx>=0);
ASSERT(dy>=0);
ASSERT(dx+wx<=(dest->width));
ASSERT(dy+wy<=(dest->height));
count = 0;
if(bpp<=1)
{
CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp);
CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] == pix_rimcolor)
p_dest[x] = pix_hilite;
else if(p_src[x] != pix_transparent && mask[count]==0)
p_dest[x] = p_src[x];
count++;
}
p_src += bpl_s;
p_dest += bpl_d;
}
}
else if(bpp<=2)
{
CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp);
CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] == pix_rimcolor)
p_dest[x] = pix_hilite;
else if(p_src[x] != pix_transparent && mask[count]==0)
p_dest[x] = p_src[x];
count++;
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
else if(bpp<=4)
{
CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp);
CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp);
for(y=0;y<wy;y++){
for(x=0;x<wx;x++){
//X11 specific
if(p_src[x] == pix_rimcolor)
p_dest[x] = pix_hilite;
else if(p_src[x] != pix_transparent && mask[count]==0)
p_dest[x] = p_src[x];
count++;
}
p_src += bpl_s/bpp;
p_dest += bpl_d/bpp;
}
}
}
void TileRegionClass::DrawPanel(int left, int top, int width, int height)
{
framerect(left, top , left + width, top + height, PIX_WHITE);
framerect(left + 1, top + 1, left + width, top + height, PIX_DARKGREY);
fillrect (left + 1, top + 1, left + width - 1, top + height -1, PIX_LIGHTGREY);
}
void RegionClass::framerect(int left, int top, int right, int bottom,
int color)
{
XDrawRectangle(display, win->win, term_gc[color&0xf],
ox+left, oy+top, right-left, bottom-top);
}
void TileRegionClass::framerect(int left, int top, int right, int bottom,
int color)
{
int x,y;
int pix = term_pix[color];
for (x=left; x<=right; x++){
XPutPixel(backbuf, x, top, pix);
XPutPixel(backbuf, x, bottom, pix);
}
for (y=top+1; y< bottom; y++){
XPutPixel(backbuf, left, y, pix);
XPutPixel(backbuf, right, y, pix);
}
}
void WinClass::fillrect(int left, int top, int right, int bottom,
int color)
{
XFillRectangle(display, win, term_gc[color&0xf],
top, left, right-left+1, bottom-top+1);
}
void RegionClass::fillrect(int left, int top, int right, int bottom,
int color)
{
XFillRectangle(display, win->win, term_gc[color&0xf],
ox+left, oy+top, right-left, bottom-top);
}
void TileRegionClass::fillrect(int left, int top, int right, int bottom,
int color)
{
int x,y;
int pix = term_pix[color];
ASSERT(left>=0);
ASSERT(top>=0);
ASSERT(right<mx);
ASSERT(bottom<my);
for (x=left; x<=right; x++){
for (y=top; y<= bottom; y++){
XPutPixel(backbuf, x, y, pix);
}}
}
/********************************************/
bool GuicInit(Display **d, int *s)
{
int i;
setlocale(LC_ALL, "");
display= XOpenDisplay("");
if (!display)
{
fprintf(stderr,"Cannot open display\n");
return false;
}
screen=DefaultScreen(display);
*d = display;
*s = screen;
// for text display
for(i=0;i<MAX_TERM_COL;i++)
{
const int *c = term_colors[i];
term_pix[i] = create_pixel(c[0],c[1],c[2]);
term_gc[i]= XCreateGC(display,RootWindow(display,screen),0,0);
XSetForeground(display,term_gc[i], term_pix[i]);
}
// for text display
for(i=0;i<MAX_MAP_COL;i++)
{
const int *c = map_colors[i];
map_pix[i] = create_pixel(c[0],c[1],c[2]);
map_gc[i]= XCreateGC(display,RootWindow(display,screen),0,0);
XSetForeground(display, map_gc[i], map_pix[i]);
}
// for Image manipulation
pix_black = term_pix[PIX_BLACK] ;
pix_hilite = term_pix[PIX_LIGHTMAGENTA] ;
pix_rimcolor = create_pixel(1,1,1);
return true;
}
void GuicDeinit()
{
int i;
for(i=0;i<MAX_TERM_COL;i++)
XFreeGC(display,term_gc[i]);
for(i=0;i<MAX_MAP_COL;i++)
XFreeGC(display,map_gc[i]);
XCloseDisplay(display);
}
static int x11_byte_per_pixel_ximage()
{
int i = 1;
int j = (DefaultDepth(display, screen) - 1) >> 2;
while (j >>= 1) i <<= 1;
return i;
}
unsigned long create_pixel(unsigned int red, unsigned int green,
unsigned int blue)
{
Colormap cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(display));
XColor xcolour;
xcolour.red = red * 256;
xcolour.green = green * 256;
xcolour.blue = blue * 256;
xcolour.flags = DoRed | DoGreen | DoBlue;
XAllocColor(display, cmap, &xcolour);
return (xcolour.pixel);
}
/*
Copied from pngtopnm.c and modified by M.Itakura
(mostly omitted and added a few lines)
only color paletted image is handled
*/
/*
** pngtopnm.c -
** read a Portable Network Graphics file and produce a portable anymap
**
** Copyright (C) 1995,1998 by Alexander Lehmann <alex@hal.rhein-main.de>
** and Willem van Schaik <willem@schaik.com>
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
**
** modeled after giftopnm by David Koblas and
** with lots of bits pasted from libpng.txt by Guy Eric Schalnat
*/
#define VERSION "2.37.1 (3 July 1998)"
#include "png.h"
#define pm_message printf
#define pm_error(x) {fprintf(stderr,x);return NULL;}
# define TRUE 1
# define FALSE 0
# define NONE 0
#define SIG_CHECK_SIZE 4
XImage *read_png (const char *fname)
{
char sig_buf [SIG_CHECK_SIZE];
png_struct *png_ptr;
png_info *info_ptr;
png_byte **png_image;
png_byte *png_pixel;
unsigned int x, y;
int linesize;
png_uint_16 c;
unsigned int i;
//X11
XImage *res;
unsigned long pix_table[256];
FILE *ifp = fopen(fname,"r");
if(!ifp) { fprintf(stderr, "File not found: %s", fname); return NULL; }
if (fread (sig_buf, 1, SIG_CHECK_SIZE, ifp) != SIG_CHECK_SIZE)
pm_error ("input file empty or too short");
if (png_sig_cmp ((unsigned char *)sig_buf, (png_size_t) 0, (png_size_t) SIG_CHECK_SIZE) != 0)
pm_error ("input file not a PNG file");
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
pm_error ("cannot allocate LIBPNG structure");
}
info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) {
png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
pm_error ("cannot allocate LIBPNG structures");
}
if (setjmp (png_ptr->jmpbuf)) {
png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
free (png_ptr);
free (info_ptr);
pm_error ("setjmp returns error condition");
}
png_init_io (png_ptr, ifp);
png_set_sig_bytes (png_ptr, SIG_CHECK_SIZE);
png_read_info (png_ptr, info_ptr);
png_image = (png_byte **)malloc (info_ptr->height * sizeof (png_byte*));
if (png_image == NULL) {
free (png_ptr);
free (info_ptr);
pm_error ("couldn't alloc space for image");
}
if (info_ptr->bit_depth == 16)
linesize = 2 * info_ptr->width;
else
linesize = info_ptr->width;
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
linesize *= 2;
else
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB)
linesize *= 3;
else
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
linesize *= 4;
for (y = 0 ; y < info_ptr->height ; y++) {
png_image[y] = (png_byte *)malloc (linesize);
if (png_image[y] == NULL) {
for (x = 0 ; x < y ; x++)
free (png_image[x]);
free (png_image);
free (png_ptr);
free (info_ptr);
pm_error ("couldn't alloc space for image");
}
}
if (info_ptr->bit_depth < 8)
png_set_packing (png_ptr);
/* sBIT handling is very tricky. If we are extracting only the image, we
can use the sBIT info for grayscale and color images, if the three
values agree. If we extract the transparency/alpha mask, sBIT is
irrelevant for trans and valid for alpha. If we mix both, the
multiplication may result in values that require the normal bit depth,
so we will use the sBIT info only for transparency, if we know that only
solid and fully transparent is used */
if (info_ptr->valid & PNG_INFO_sBIT) {
if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
(info_ptr->sig_bit.red != info_ptr->sig_bit.green ||
info_ptr->sig_bit.red != info_ptr->sig_bit.blue) ) {
pm_message ("different bit depths for color channels not supported");
pm_message ("writing file with %d bit resolution", info_ptr->bit_depth);
} else
if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) &&
(info_ptr->sig_bit.red < 255)) {
for (i = 0 ; i < info_ptr->num_palette ; i++) {
info_ptr->palette[i].red >>= (8 - info_ptr->sig_bit.red);
info_ptr->palette[i].green >>= (8 - info_ptr->sig_bit.green);
info_ptr->palette[i].blue >>= (8 - info_ptr->sig_bit.blue);
}
} else
if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
(info_ptr->sig_bit.gray < info_ptr->bit_depth)) {
png_set_shift (png_ptr, &(info_ptr->sig_bit));
}
}
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
//X11
for (i = 0 ; i < info_ptr->num_palette ; i++)
pix_table[i] = create_pixel(info_ptr->palette[i].red,
info_ptr->palette[i].green, info_ptr->palette[i].blue);
}
else
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
{
for (i = 0 ; i < 256 ; i++)
//X11
pix_table[i] = create_pixel(i, i, i);
}
png_read_image (png_ptr, png_image);
png_read_end (png_ptr, info_ptr);
res = ImgCreateSimple(info_ptr->width, info_ptr->height);
for (y = 0 ; y < info_ptr->height ; y++) {
png_pixel = png_image[y];
for (x = 0 ; x < info_ptr->width ; x++) {
c = *png_pixel;
png_pixel++;
XPutPixel(res, x, y, pix_table[c]);
}
}
for (y = 0 ; y < info_ptr->height ; y++)
free (png_image[y]);
free (png_image);
free (png_ptr);
free (info_ptr);
fclose(ifp);
return res;
}
#ifdef USE_TILE
// indexed by grid coords
FixedArray<unsigned short,GXM, GYM> tile_bk_fg; // tile fg
FixedArray<unsigned short,GXM, GYM> tile_bk_bg; // tile bg
FixedArray<TileFlavor, GXM, GYM> tile_flavor;
// indexed by (show-1) coords
FixedArray<unsigned short,ENV_SHOW_DIAMETER-2,ENV_SHOW_DIAMETER-2> tile_fg;
FixedArray<unsigned short,ENV_SHOW_DIAMETER-2,ENV_SHOW_DIAMETER-2> tile_bg;
#endif
#ifdef USE_TILE
// if a mouse command, update location to mouse position...
if ( key_command == CMD_TARGET_MOUSE_MOVE ||
key_command == CMD_TARGET_MOUSE_SELECT )
{
coord_def gc;
if (gui_get_mouse_grid_pos(gc))
{
moves.tx = gc.x;
moves.ty = gc.y;
if ( key_command == CMD_TARGET_MOUSE_SELECT )
{
key_command = CMD_TARGET_SELECT;
}
}
else
{
key_command = CMD_NO_CMD;
}
}
#endif
// gotoxy regions
enum GotoRegion
{
GOTO_CRT, // cprintf > crt
GOTO_MSG, // cprintf > message
GOTO_STAT, // cprintf > character status
GOTO_DNGN, // cprintf > dungeon screen
GOTO_LAST // cprintf > last active region or CRT, if none
};
// Mouse modes (for tiles)
enum MouseMode
{
MOUSE_MODE_NORMAL,
MOUSE_MODE_COMMAND,
MOUSE_MODE_TARGET,
MOUSE_MODE_TARGET_DIR,
MOUSE_MODE_MORE,
MOUSE_MODE_MACRO
};
#ifdef USE_TILE
case CMD_EDIT_PREFS:
edit_prefs();
break;
case CMD_USE_ITEM:
{
int idx;
InvAction act;
gui_get_mouse_inv(idx, act);
use_item(idx, act);
}
break;
case CMD_VIEW_ITEM:
{
int idx;
InvAction act;
gui_get_mouse_inv(idx, act);
if (idx < 0)
describe_item(mitm[-idx]);
else
describe_item(you.inv[idx]);
redraw_screen();
}
break;
case CMD_EDIT_PLAYER_TILE:
TilePlayerEdit();
break;
#endif // USE_TILE
#elif defined(WIN32CONSOLE)
#include "libw32c.h"
#elif defined(WIN32CONSOLE) || defined(WIN32TILES)
#if defined(WIN32CONSOLE)
#include "libw32c.h"
#endif
Tiles:
- Edit player doll. This makes it possible to change
the appearance of the player and to override the
defaults, which are to mimic the current player's
equipment and any species defaults. These options
are saved into the dolls.txt file.
Ctrl-Q Modify screen size preferences. These changes
are saved into the wininit.txt file.