Added PNG and non-palettized image input. Added PNG output. Added better tile packing and support for tiles of different sizes. Converted all BMPs to PNGs (for space and explicit transparency reasons.) Added the 48x32 pandemonium demon tiles, but these are not yet used in game. Added Bill B.'s portal tile (finally).
The Win32 makefiles are not updated quite yet and thus will not build. Sorry.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6850 c06c8d41-db1a-0410-9941-cceddc491573
HBXWZNXAJ7LUX7FYUIHQYBTRMWVJC6CAQQL3NNZHK5ETLIFEZJ7QC
3LR4PY7TEGKBD24D5S7VQFXFWXKK4GYE4IZILVG7LKUFBQSZUKRAC
OE3D77UGMW4OBZLB4EUYSTXJL7DZ7PSISR3WROHSJJMCNJSZKYSAC
N7DJD34ZNYSYWSDGTHALDCCOUR6F7ZKU5X5MZGUXWC2HWK6PGDXAC
IIVHXFL34I7C3ZC5NEOUGI6NVCUKJGF4QKHGGDFZSPDX6PPGBO3QC
THCKJAEU267TTUIH6YUHSO2QUZFXYASECGWWHR673WITYO3ND4HAC
MLEBOFDLBVSPP4H2YQQGFU72NQK5E2C5QHNACRNU4GDG2GLMQJMQC
LM4CZJFWDPRAY6BHB75YBZIMROYZUX6RDIYZA3VDGFOJZGXQOXFQC
NIBZLTD56AH3S4E6RNBSZFTLPPLB2CUC5CKAEUHTL3HEFODMBHYQC
NEPBSPCYPPJ3UYHPU5F6FMAOJC4DUTXSTTDB3VPCZOQ3MI6KACPAC
PEZFWKRHDHV4UJTPK5XJZ3CGTZ3LPTDYSPTYBENLQ7VRSP7YFSIQC
XKNRIFG2ULQLAAQ5GC4RBZPOERV73DLCNILEA5EP37JLIX5EP3OQC
Q3B3UVMYEVC4YJUPYVSNTR4DJH4E6J4JJDHZNT5LNOCHCPPMEMXAC
25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC
4SUUJM2DQUEWHDG3UKJUDZABLHFVF2CFUX5GVAWKT7BBBGR2ISTQC
U6ILMKBXTQZYT62IGD2CALYNU4VQGRSTHN6QBFBU7BVUBHWYOEQQC
CSRWDG2SUGS4YR4PAFI574EGEXW65P6JDT4ZHWDICS2G2GZIGEUQC
D7EPLNYHJH6C4CTMHCOUUODKGHCJRE4CGKNVSCHCSABN6ZOD2ZBAC
LP5EK64IEM7AHNYQID4GGKOQJQNZLKY4DCCZN47SIUZ6IXAXH5UAC
PDOFPXD2X6VI23AHKCGQ5RVDBG74CNP2E3YOHKXLOARHHBXEK3HQC
TFHMBVXTRA2LXBHE7L7OEWK37JQN5DWZ3HOACMN7PRWVJNCS4TYQC
MQOL2SN2EYBCAVVJ7NPCXEV6C4NPBNMC6QD2AOTZPIAZB243JQ7QC
STQDS62PD6PCLYBAB7LPYTG47WMBJP3FIJL55UHC3XFDPGERC3UQC
MZLB3Q7G4EC2BR3OFMG55WPHXPFJGQSLWAIHHFJEAEATPUTYR7EAC
F7X6HVUKHZXYURABYAZJHRYBV7UZTIPOWJMGCMDK26FQ66WGKFZAC
J3M6J3UPL4AUJDXINY7UKH2JZQVQLKGH7AMOKI6L3QI7Y2F33O5QC
OCGSM3TA4KYVM4JXHTHPA2SLY7EF6NPSIU4LJDRSQ2PJ6X7BP6CQC
QRPQJ6B37PFCUHKSO2BQ374YUVL2B7ELIL5SNENEG2WWFIYZQTHQC
TUF6IG4NNHW5YD5AVRYE7GILPSFJLUV6442F5LSP436MFEIIGVUAC
ZBHENBGH5RNIC4L2NP45RJWYB3256NAM2JU2E3CD2RF6FEV4Z4FAC
HWYCA6OHOSVFTVIEDSNB2UJG6EQ2Y7FF5DWCKWAUSDUEVKAJADPAC
YP2ADVIVFDLAU4NYFG7BTHV6BMH7VPKUYQ6WVQF3Z725L3DSX7HAC
HRAL36C7UUL7V6TFXQ76FZ3VVVFEJYF7YWOP2EXYXP6C27XME2PAC
RB4PNFZOBEPUJM6PH4J4IPKF2WYYSQ2DINHZHOGDPA4ZN6E4RJAAC
GJIMGW6UJFIEZEOOHUVR6647W2C3L6MFRKIE5AKQIPZ5LIOWZWMAC
OTVV4KBC5LVECK5B2Y7ORMRV7K4OXRZMYPCAMWJCUGZCQIBVRTXQC
M2HMYLYYXSP5XGX6MCI77IT6UW5K4YSEUJWHPQPYXVSW5L36BJ2AC
SHSIZVHSB4RPTLGMFJXUDVHF3FTEZZYCRIH4CBZP4MXOBR3HC4QAC
ZNUMGZOGREVG6RNSM4RGHG2Y6NYL7O2U642V6F3HJAXMTC5JXJHAC
3SK2OEKJBQUGGYU2PJ7BWBGMKS53K2JH6HKL65AWTFN6JVZRG2PAC
RNRDGY5JBFBHF7IDQ6LDV2GULR4ILNJ7UHYNGIWZIPLN6IJYX2PQC
CD4GR4YLJMAMP5XZ3IR7MZ6SDLQJL6YSPWMH74VV5Z56TZAZDM2QC
TZLAHS2FQGDWDAO6OQFZIZALQCCRTCRBJZBNZFNQ4G7D5UYAIFQAC
EQNA77UM24FFYQ2N44FG53KQGLS43ZGEX7XS5UWR6MM2HE3JBKAAC
5FA5IEAXTMXYS2VUBVDKBKHPKAIOY4GN5SXYJORBYWQIGHVW3FFQC
7G4KWTOOBRLHOZZGFGAXGTUCDF3FGSZOXVHUZZ3V2KVWYSFE7EKAC
SQV4OUWNCYWQTAVHXNK4AENJAEOU2YZOJNJTRWVDZZHOEG6OVAFAC
TPZWAV3USKO7RX4IGHLZKVPRN36K33PJPSZYL6FZMX4XBHTYOQYAC
BWPT5FA3JZJCSFPPRDLJF76ZKAG4WGUHNIWQFAYZ4DAZLFIIMZ7AC
I4M3O5UA4UOV35WFD435G3GP6RT3EZ5NPRZ645X22A2Z7CR2E2AAC
I2G7DP3TJL4RDMYKNXAA67P3VRSO3RF7FHZWA5CYINSEWEQE2YSQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
5XNQ3SSNBFXFNWA6DPM74W6FH65NX665P3DMH6YCWVFOPZTJSYCQC
void get_texcoord_doll(int part, int idx, int ymax, float &x, float &y, float &wx, float &wy, int &wx_pix, int &wy_pix, int &ox, int &oy);
void set_info(int max, tile_info *info);
inline const tile_info &get_info(int idx);
inline void get_coords(int idx, int ofs_x, int ofs_y,
float &pos_sx, float &pos_sy,
float &pos_ex, float &pos_ey,
float &tex_sx, float &tex_sy,
float &tex_ex, float &tex_ey,
bool centre = true, int ymax = -1);
protected:
int m_tile_max;
tile_info *m_tile_info;
inline void TilesTexture::get_coords(int idx, int ofs_x, int ofs_y,
float &pos_sx, float &pos_sy,
float &pos_ex, float &pos_ey,
float &tex_sx, float &tex_sy,
float &tex_ex, float &tex_ey,
bool centre, int ymax)
{
const tile_info &inf = get_info(idx);
float fwidth = m_width;
float fheight = m_height;
// center tiles on x, but allow taller tiles to extend upwards
int size_ox = centre ? TILE_X / 2 - inf.width / 2 : 0;
int size_oy = centre ? TILE_Y - inf.height : 0;
int ey = inf.ey;
if (ymax > 0)
ey = std::min(inf.sy + ymax - inf.offset_y, ey);
pos_sx += (ofs_x + inf.offset_x + size_ox) / (float)TILE_X;
pos_sy += (ofs_y + inf.offset_y + size_oy) / (float)TILE_Y;
pos_ex = pos_sx + (inf.ex - inf.sx) / (float)TILE_X;
pos_ey = pos_sy + (ey - inf.sy) / (float)TILE_Y;
tex_sx = inf.sx / fwidth;
tex_sy = inf.sy / fheight;
tex_ex = inf.ex / fwidth;
tex_ey = ey / fheight;
}
if (img->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
if (new_width != img->w || new_height != img->h)
{
SDL_LockSurface(img);
pixels = new unsigned char[4 * new_width * new_height];
memset(pixels, 0, 4 * new_width * new_height);
int dest = 0;
for (int y = 0; y < img->h; y++)
{
for (int x = 0; x < img->w; x++)
{
unsigned char *p = ((unsigned char*)img->pixels
+ y * img->pitch + x * bpp);
unsigned int pixel = *(unsigned int*)p;
SDL_GetRGBA(pixel, img->format, &pixels[dest],
&pixels[dest+1], &pixels[dest+2],
&pixels[dest+3]);
dest += 4;
}
dest += 4 * (new_width - img->w);
}
SDL_UnlockSurface(img);
}
texture_format = GL_RGBA;
if (img->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
if (new_width != img->w || new_height != img->h)
{
SDL_LockSurface(img);
pixels = new unsigned char[4 * new_width * new_height];
memset(pixels, 0, 4 * new_width * new_height);
int dest = 0;
for (int y = 0; y < img->h; y++)
{
for (int x = 0; x < img->w; x++)
{
unsigned char *p = ((unsigned char*)img->pixels
+ y * img->pitch + x * bpp);
unsigned int pixel;
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
pixel = p[0] << 16 | p[1] << 8 | p[2];
else
pixel = p[0] | p[1] << 8 | p[2];
SDL_GetRGBA(pixel, img->format, &pixels[dest],
&pixels[dest+1], &pixels[dest+2],
&pixels[dest+3]);
dest += 4;
}
dest += 4 * (new_width - img->w);
}
SDL_UnlockSurface(img);
}
texture_format = GL_RGBA;
// Find transparent colour
// TODO enne - this should probably be removed from rltiles
// TODO enne - is there more than one transparent color??
int trans_index = -1;
for (int p = 0; p < pal->ncolors ; p++)
{
if (pal->colors[p].r == 71 &&
pal->colors[p].g == 108 &&
pal->colors[p].b == 108)
{
trans_index = p;
break;
}
}
if (!idx)
{
wy = -1;
return;
}
idx--;
tile_idx += idx / (nx * ny);
if (oy + wy_pix > ymax)
wy_pix -= oy + wy_pix - ymax;
int xs = (tile_idx % TILEP_PER_ROW) * TILE_X;
int ys = (tile_idx / TILEP_PER_ROW) * TILE_Y;
xs += (idx % nx) * TILE_X / nx;
ys += ((idx / nx) % ny) * TILE_Y / ny;
x = xs / (float)m_width;
y = ys / (float)m_height;
wx = wx_pix / (float)m_width;
wy = wy_pix / (float)m_height;
const unsigned int tile_size = 32;
unsigned int tiles_per_row = m_width / tile_size;
wx = tile_size / (float)m_width;
wy = tile_size / (float)m_height;
unsigned int row = idx / tiles_per_row;
unsigned int col = idx % tiles_per_row;
x = tile_size * col / (float)m_width;
y = tile_size * row / (float)m_height;
ASSERT(row >= 0);
ASSERT(col >= 0);
ASSERT(x + wx <= m_width);
ASSERT(y + wy <= m_height);
m_tile_max = _max;
m_tile_info = _info;
// 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)
void add_quad(TextureID tex, unsigned int idx, unsigned int x, unsigned int y, int ofs_x = 0, int ofs_y = 0);
void add_quad(TextureID tex, unsigned int idx, unsigned int x, unsigned int y, int ofs_x = 0, int ofs_y = 0, bool centre = true, int ymax = -1);
}
void DungeonRegion::add_quad_doll(unsigned int part, unsigned int idx, int ymax, unsigned int x, unsigned int y, int ox_spec, int oy_spec)
{
float tex_sx, tex_sy, tex_wx, tex_wy;
int ox_extra, oy_extra, wx_pix, wy_pix;
m_image->m_textures[TEX_DOLL].get_texcoord_doll(part, idx, ymax, tex_sx, tex_sy, tex_wx, tex_wy, wx_pix, wy_pix, ox_extra, oy_extra);
if (wx_pix <= 0 || wy_pix <= 0)
return;
float pos_ox = (ox_spec + ox_extra) / (float)TILE_X;
float pos_oy = (oy_spec + oy_extra) / (float)TILE_Y;
float tex_ex = tex_sx + tex_wx;
float tex_ey = tex_sy + tex_wy;
float pos_sx = x + pos_ox;
float pos_sy = y + pos_oy;
float pos_ex = pos_sx + wx_pix / (float)TILE_X;
float pos_ey = pos_sy + wy_pix / (float)TILE_Y;
tile_vert v;
v.pos_x = pos_sx;
v.pos_y = pos_sy;
v.tex_x = tex_sx;
v.tex_y = tex_sy;
m_verts.push_back(v);
v.pos_y = pos_ey;
v.tex_y = tex_ey;
m_verts.push_back(v);
v.pos_x = pos_ex;
v.tex_x = tex_ex;
m_verts.push_back(v);
v.pos_y = pos_sy;
v.tex_y = tex_sy;
m_verts.push_back(v);
void TileRegion::add_quad(TextureID tex, unsigned int idx, unsigned int x, unsigned int y, int ofs_x, int ofs_y)
void TileRegion::add_quad(TextureID tex, unsigned int idx, unsigned int x, unsigned int y, int ofs_x, int ofs_y, bool centre, int ymax)
float tex_sx, tex_sy, tex_wx, tex_wy;
m_image->m_textures[tex].get_texcoord(idx, tex_sx, tex_sy, tex_wx, tex_wy);
float tex_ex = tex_sx + tex_wx;
float tex_ey = tex_sy + tex_wy;
float pos_sx = x + ofs_x / (float)TILE_X;
float pos_sy = y + ofs_y / (float)TILE_Y;
float pos_ex = pos_sx + 1;
float pos_ey = pos_sy + 1;
float pos_sx = x;
float pos_sy = y;
float pos_ex, pos_ey, tex_sx, tex_sy, tex_ex, tex_ey;
m_image->m_textures[tex].get_coords(idx, ofs_x, ofs_y,
pos_sx, pos_sy, pos_ex, pos_ey,
tex_sx, tex_sy, tex_ex, tex_ey,
centre, ymax);
if (result.parts[TILEP_PART_LEG] == TILEP_SHOW_EQUIP)
result.parts[TILEP_PART_LEG] = 0;
if (result.parts[TILEP_PART_DRCWING] == TILEP_SHOW_EQUIP)
result.parts[TILEP_PART_DRCWING] = 0;
if (result.parts[TILEP_PART_DRCHEAD] == TILEP_SHOW_EQUIP)
result.parts[TILEP_PART_DRCHEAD] = 0;
if (doll.parts[p] && p == TILEP_PART_BOOTS
&& (doll.parts[p] == TILEP_BOOTS_NAGA_BARDING
|| doll.parts[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 = (doll.parts[p] == TILEP_BOOTS_NAGA_BARDING) ?
TILEP_SHADOW_NAGA_BARDING :
TILEP_SHADOW_CENTAUR_BARDING;
add_quad_doll(TILEP_PART_SHADOW, tile, TILE_Y, x, y, 0, 0);
}
else
{
add_quad_doll(p, doll.parts[p], ymax, x, y, 0, 0);
}
add_quad(TEX_DOLL, doll.parts[p], x, y, 0, 0, true, ymax);
int idx = TILE_CHAR00 + (c - 32) / 8;
int subidx = c & 7;
float tex_sx, tex_sy, tex_wx, tex_wy;
m_image->m_textures[TEX_DEFAULT].get_texcoord(idx, tex_sx, tex_sy, tex_wx, tex_wy);
tex_wx /= 4.0f;
tex_wy /= 2.0f;
tex_sx += (subidx % 4) * tex_wx;
tex_sy += (subidx / 4) * tex_wy;
float tex_ex = tex_sx + tex_wx;
float tex_ey = tex_sy + tex_wy;
float pos_sx = x + ofs_x / (float)TILE_X;
float pos_sy = y + ofs_y / (float)TILE_Y;
float pos_ex = pos_sx + 0.25f;
float pos_ey = pos_sy + 0.5f;
tile_vert v;
v.pos_x = pos_sx;
v.pos_y = pos_sy;
v.tex_x = tex_sx;
v.tex_y = tex_sy;
m_verts.push_back(v);
v.pos_y = pos_ey;
v.tex_y = tex_ey;
m_verts.push_back(v);
int num = c - '0';
assert(num >=0 && num <= 9);
int idx = TILE_NUM0 + num;
const unsigned int tile_size = 32;
const unsigned int tiles_per_row = width / tile_size;
unsigned int row = idx / tiles_per_row;
unsigned int col = idx % tiles_per_row;
unsigned char *dest = &pixels[4 * 32 * (row * width + col)];
unsigned char *dest = &pixels[4 * (inf.sy * width + inf.sx)];
size_t image_size = 32 * 32 * 4;
const tile_info &under = tile_main_info[idx_under];
const tile_info &over = tile_main_info[idx_over];
if (over.width != under.width || over.height != under.height)
return false;
if (over.ex - over.sx != over.width || over.ey - over.sy != over.height)
return false;
if (over.offset_x != 0 || over.offset_y != 0)
return false;
size_t image_size = under.width * under.height * 4;
unsigned char *under = new unsigned char[image_size];
_copy_into(under, pixels, width, height, idx_under);
unsigned char *over = new unsigned char[image_size];
_copy_into(over, pixels, width, height, idx_over);
unsigned char *under_pixels = new unsigned char[image_size];
_copy_into(under_pixels, pixels, width, height, under);
unsigned char *over_pixels = new unsigned char[image_size];
_copy_into(over_pixels, pixels, width, height, over);
_copy_under(pixels, width, height, tile0, tile1);
}
// TODO enne - fix rtiles so that it can accept PNGs.
{
size_t image_size = 32 * 32 * 4;
unsigned char *mesh = new unsigned char[image_size];
for (unsigned int i = 0; i < image_size; i += 4)
{
mesh[i] = mesh[i+1] = mesh[i+2] = 0;
mesh[i+3] = 110;
}
_copy_onto(pixels, width, height, mesh, TILE_MESH, false);
for (unsigned int i = 0; i < image_size; i += 4)
{
mesh[i] = 70;
mesh[i+1] = 70;
mesh[i+2] = 180;
mesh[i+3] = 120;
}
_copy_onto(pixels, width, height, mesh, TILE_MAGIC_MAP_MESH, false);
delete[] mesh;
success &= _copy_under(pixels, width, height, tile0, tile1);
return m_textures[TEX_DEFAULT].load_texture("tile.png", mip,
&_process_item_image);
bool success = m_textures[TEX_DEFAULT].load_texture("main.png", mip,
&_process_item_image);
m_textures[TEX_DEFAULT].set_info(TILE_MAIN_MAX, &tile_main_info[0]);
return success;
static void _finalize_tile(unsigned int *tile, bool is_special,
unsigned char wall_flv,
unsigned char floor_flv,
unsigned char special_flv)
static inline void _finalize_tile(unsigned int *tile, bool is_special,
unsigned char wall_flv,
unsigned char floor_flv,
unsigned char special_flv)
wall = IDX_WALL_BAZAAR_GRAY;
floor = IDX_FLOOR_BAZAAR_GRASS;
special = IDX_FLOOR_BAZAAR_GRASS1_SPECIAL;
wall = TILE_WALL_BAZAAR_GRAY;
floor = TILE_FLOOR_BAZAAR_GRASS;
special = TILE_FLOOR_BAZAAR_GRASS1_SPECIAL;
wall = IDX_WALL_PEBBLE_RED;
floor = IDX_FLOOR_VAULT;
special = IDX_FLOOR_BAZAAR_VAULT_SPECIAL;
wall = TILE_WALL_PEBBLE_RED;
floor = TILE_FLOOR_VAULT;
special = TILE_FLOOR_BAZAAR_VAULT_SPECIAL;
wall = IDX_WALL_HIVE;
floor = IDX_FLOOR_BAZAAR_GRASS;
special = IDX_FLOOR_BAZAAR_GRASS2_SPECIAL;
wall = TILE_WALL_HIVE;
floor = TILE_FLOOR_BAZAAR_GRASS;
special = TILE_FLOOR_BAZAAR_GRASS2_SPECIAL;
wall = IDX_WALL_BAZAAR_STONE;
floor = IDX_FLOOR_BAZAAR_GRASS;
special = IDX_FLOOR_BAZAAR_GRASS1_SPECIAL;
wall = TILE_WALL_BAZAAR_STONE;
floor = TILE_FLOOR_BAZAAR_GRASS;
special = TILE_FLOOR_BAZAAR_GRASS1_SPECIAL;
wall = IDX_WALL_BAZAAR_STONE;
floor = IDX_FLOOR_BAZAAR_DIRT;
special = IDX_FLOOR_BAZAAR_DIRT_SPECIAL;
wall = TILE_WALL_BAZAAR_STONE;
floor = TILE_FLOOR_BAZAAR_DIRT;
special = TILE_FLOOR_BAZAAR_DIRT_SPECIAL;
// TODO enne - link floor tile index to the right location rather than
// starting at floor normal
floor_tile_idx = tile_DNGN_start[floor_idx];
floor_flavors = tile_DNGN_count[floor_idx];
wall_tile_idx = tile_DNGN_start[wall_idx];
wall_flavors = tile_DNGN_count[wall_idx];
floor_flavors = tile_dngn_count[floor_tile_idx];
wall_flavors = tile_dngn_count[wall_tile_idx];
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]
/*
** 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 --- 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 */
#--------------------------------
# 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.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 & 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
#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];
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
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);
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 )
}
}
}
}
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
}
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);
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++)
{
{
}
}
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;
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(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, "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++)
{
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;
}
if (sfp)
{
fclose(sfp);
}
fprintf(cfp, (i < tilecountidx - 1) ? " TILE_%s,\n" : " TILE_%s\n",
fprintf(sfp, "\n\n");
fprintf(sfp, "enum TILE_%sCOUNT_IDX {\n", enumprefix);
for (i = 0; i < tilecountidx; i++)
{
fprintf(sfp, " IDX_%s,\n", countnames[i]);
}
fprintf(sfp, " IDX_%sTOTAL\n};\n\n", enumprefix);
fprintf(sfp, "extern int tile_%scount[IDX_%sTOTAL];\n", enumprefix, enumprefix);
fprintf(sfp, "extern int tile_%sstart[IDX_%sTOTAL];\n\n", enumprefix, enumprefix);
counts[tilecountidx++] = tilecount;
}
if (sfp)
{
fprintf(sfp, "TILE_%sTOTAL};\n\n", enumprefix);
fprintf(sfp,"#define TILE_%sPER_ROW %d\n", enumprefix, xx0);
sprintf(countnames[tilecountidx], "%s", st);
rim = storerim;
// Rim has already been applied during composing, so turn it off
// temporarily.
int storerim = rim;
rim = 0;
cbuf[0][i] = tempbuf[0][i];
cbuf[1][i] = tempbuf[1][i];
cbuf[2][i] = tempbuf[2][i];
if (tempbuf[0][i] != bkg[0] ||
tempbuf[1][i] != bkg[1] ||
tempbuf[2][i] != bkg[2])
if (rim == 1)
make_rim(tempbuf);
}
// Copy into a temporary buffer so that we can use the rim func.
for(i=0;i<TILEX*TILEY;i++)
{
tempbuf[0][i] = tbuf[0][i];
tempbuf[1][i] = tbuf[1][i];
tempbuf[2][i] = tbuf[2][i];
unsigned char tempbuf[3][TILEX * TILEY];
if(rim==1)make_rim(dbuf);
buf[0][x+y*32]=buf[1][x+y*32]=buf[2][x+y*32]=0x10;
for(c=0;c<3;c++)dd[c]=buf[c][ad];
void make_rim(unsigned char buf[3][TILEX*TILEY]){
int countnames[512][100];
#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);
}
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);
}
fprintf(sfp,"#include \"tiledef-p.h\"\n");
parts_names[i][0] = 0;
i = 1;
strncpy(&comment[pos_comment],"\0",i);
i=strlen(st);
strncpy(&comment[pos_comment],st,i);
#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
#ifndef TILE_PAGE_H
#define TILE_PAGE_H
#include <vector>
class tile;
class tile_page
{
public:
tile_page();
virtual ~tile_page();
bool place_images();
bool write_image(const char *filename);
std::vector<tile*> m_tiles;
std::vector<unsigned int> m_counts;
std::vector<int> m_texcoords;
std::vector<int> m_offsets;
protected:
int m_width;
int m_height;
};
#endif
#include "tile_page.h"
#include "tile_colour.h"
#include "tile.h"
#include <png.h>
static bool write_png(const char *filename, tile_colour *pixels,
int width, int height)
{
FILE *fp = fopen(filename, "wb");
if (!fp)
{
fprintf(stderr, "Error: Can't open file '%s' for write.\n", filename);
return false;
}
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
if (!png_ptr)
return false;
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
return false;
}
png_init_io(png_ptr, fp);
int bit_depth = 8;
int colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
int interlace_type = PNG_INTERLACE_NONE;
int compression_type = PNG_COMPRESSION_TYPE_DEFAULT;
int filter_method = PNG_FILTER_TYPE_DEFAULT;
png_set_IHDR(png_ptr, info_ptr, width, height,
bit_depth, colour_type, interlace_type,
compression_type, filter_method);
png_bytep* row_pointers = (png_bytep*)alloca(sizeof(png_bytep) * height);
for (unsigned int y = 0; y < height; y++)
row_pointers[y] = (png_byte*)&pixels[y * width];
png_set_rows(png_ptr, info_ptr, row_pointers);
int png_transforms = PNG_TRANSFORM_IDENTITY;
png_write_png(png_ptr, info_ptr, png_transforms, NULL);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return true;
}
tile_page::tile_page() : m_width(1024), m_height(0)
{
}
tile_page::~tile_page()
{
for (unsigned int i = 0; i < m_tiles.size(); i++)
{
delete m_tiles[i];
}
m_tiles.clear();
m_counts.clear();
}
bool tile_page::place_images()
{
// locate all the tiles on the page, so we can determine its size
// and the tex coords.
m_offsets.clear();
m_texcoords.clear();
int ymin, ycur, ymax;
int xmin, xcur, xmax;
ymin = ycur = ymax = xmin = xcur = xmax = 0;
for (unsigned int i = 0; i < m_tiles.size(); i++)
{
int ofs_x, ofs_y, tilew, tileh;
if (m_tiles[i]->shrink())
{
m_tiles[i]->get_bounding_box(ofs_x, ofs_y, tilew, tileh);
}
else
{
ofs_x = 0;
ofs_y = 0;
tilew = m_tiles[i]->width();
tileh = m_tiles[i]->height();
}
m_offsets.push_back(ofs_x);
m_offsets.push_back(ofs_y);
m_offsets.push_back(m_tiles[i]->width());
m_offsets.push_back(m_tiles[i]->height());
if (xcur + tilew > m_width)
{
ycur = ymin = ymax;
xcur = xmin = xmax = 0;
}
if (tileh + ycur >= ymax)
{
if (ycur != ymin)
{
ycur = ymin;
xcur = xmax;
xmin = xmax = xcur;
}
if (xcur + tilew > m_width)
{
ycur = ymin = ymax;
xcur = xmin = xmax = 0;
}
if (ycur == ymin)
{
ymax = std::max(ymin + (int)tileh, ymax);
}
}
m_height = ymax;
m_texcoords.push_back(xcur);
m_texcoords.push_back(ycur);
m_texcoords.push_back(xcur + tilew);
m_texcoords.push_back(ycur + tileh);
// Only add downwards, stretching out xmax as we go.
xmax = std::max(xmax, xcur + (int)tilew);
xcur = xmin;
ycur += tileh;
}
return true;
}
bool tile_page::write_image(const char *filename)
{
if (m_width * m_height <= 0)
{
fprintf(stderr, "Error: failed to write image. No images placed?\n");
return false;
}
tile_colour *pixels = new tile_colour[m_width * m_height];
memset(pixels, 0, m_width * m_height * sizeof(tile_colour));
for (unsigned int i = 0; i < m_tiles.size(); i++)
{
int sx = m_texcoords[i*4];
int sy = m_texcoords[i*4+1];
int ex = m_texcoords[i*4+2];
int ey = m_texcoords[i*4+3];
int wx = ex - sx;
int wy = ey - sy;
int ofs_x = m_offsets[i*4];
int ofs_y = m_offsets[i*4+1];
for (int y = 0; y < wy; y++)
{
for (int x = 0; x < wx; x++)
{
tile_colour &dest = pixels[(sx+x) + (sy+y)*m_width];
tile_colour &src = m_tiles[i]->get_pixel(ofs_x+x, ofs_y+y);
dest = src;
}
}
}
bool success = write_png(filename, pixels, m_width, m_height);
delete[] pixels;
return success;
}
#ifndef TILE_LIST_PROCESSOR_H
#define TILE_LIST_PROCESSOR_H
#include "tile.h"
#include "tile_page.h"
#include <string>
#include <vector>
class tile_list_processor
{
public:
tile_list_processor();
bool process_list(const char *list_file);
bool write_data();
protected:
bool load_image(tile &img, const char *filename);
bool process_line(char *read_line, const char *list_file, int line);
void add_image(tile &img, const char *enumname);
std::string m_name;
tile_page m_page;
unsigned int m_last_enum;
// image options
bool m_rim;
bool m_corpsify;
bool m_composing;
bool m_shrink;
tile m_back;
std::string m_parts_ctg;
std::string m_sdir;
std::string m_prefix;
std::vector<std::string> m_categories;
std::vector<int> m_ctg_counts;
tile m_compose;
};
#endif
#include "tile_list_processor.h"
#include <assert.h>
#include <iostream>
#include <fstream>
tile_list_processor::tile_list_processor() :
m_last_enum(~0),
m_rim(false),
m_corpsify(false),
m_composing(false),
m_shrink(true),
m_prefix("TILE")
{
}
bool tile_list_processor::load_image(tile &img, const char *filename)
{
assert(filename);
char temp[1024];
const int num_ext = 3;
const char *ext[3] =
{
".png",
".bmp",
""
};
if (m_sdir != "")
{
for (unsigned int e = 0; e < num_ext; e++)
{
sprintf(temp, "%s/%s%s", m_sdir.c_str(), filename, ext[e]);
if (img.load(temp))
return true;
}
}
for (unsigned int e = 0; e < num_ext; e++)
{
sprintf(temp, "%s%s", filename, ext[e]);
if (img.load(temp))
return true;
}
return false;
}
bool tile_list_processor::process_list(const char *list_file)
{
int line = 1;
std::ifstream input(list_file);
if (!input.is_open())
{
fprintf(stderr, "Error: couldn't open '%s' for read.\n", list_file);
return false;
}
const size_t bufsize = 1024;
char read_line[bufsize];
bool success = true;
while (!input.getline(read_line, bufsize).eof())
{
success &= process_line(read_line, list_file, line++);
}
return success;
}
static void eat_whitespace(char *&text)
{
if (!text)
return;
while (*text)
{
if (*text != ' ' && *text != '\n' && *text != '\r')
break;
text++;
}
if (!*text)
return;
char *idx = &text[strlen(text) - 1];
while (*idx)
{
if (*idx != ' ' && *idx != '\n' && *idx != '\r')
break;
*idx = 0;
idx--;
}
}
static void eat_comments(char *&text)
{
if (!text)
return;
char *idx = text;
while (*idx)
{
if (idx[0] == '/' && idx[1] == '*')
{
char *end = idx + 2;
bool found = false;
while (*end)
{
if (end[0] == '*' && end[1] == '/')
{
found = true;
end += 2;
char *begin = idx;
while (*end)
{
*begin = *end;
begin++;
end++;
}
*begin = 0;
}
end++;
}
if (!found)
{
*idx = 0;
break;
}
}
idx++;
}
}
bool tile_list_processor::process_line(char *read_line, const char *list_file,
int line)
{
eat_comments(read_line);
const char *delim = " ";
char *arg1 = strtok(read_line, delim);
if (!arg1)
return true;
eat_whitespace(arg1);
if (!*arg1)
return true;
if (arg1[0] == '#')
return true;
char *arg2 = strtok(NULL, delim);
eat_whitespace(arg2);
while (char *extra = strtok(NULL, delim))
{
eat_whitespace(extra);
if (!*extra)
continue;
fprintf(stderr, "Error (%s:%d): too many args.\n", list_file, line);
return false;
}
if (arg1[0] == '%')
{
arg1++;
#define CHECK_NO_ARG2 \
if (arg2) \
{ \
fprintf(stderr, "Error (%s:%d): " \
"invalid arg following '%s'.\n", \
list_file, line, arg1); \
return false; \
}
#define CHECK_ARG2 \
if (!arg2) \
{ \
fprintf(stderr, "Error (%s:%d): " \
"missing arg following '%s'.\n", \
list_file, line, arg1); \
return false; \
}
if (strcmp(arg1, "back") == 0)
{
CHECK_ARG2;
if (strcmp(arg2, "none") == 0)
{
m_back.unload();
}
else
{
if (!load_image(m_back, arg2))
{
fprintf(stderr, "Error(%s:%d): couldn't load image "
"'%s'.\n", list_file, line, arg2);
return false;
}
}
}
else if (strcmp(arg1, "compose") == 0)
{
CHECK_ARG2;
if (!m_composing)
{
fprintf(stderr, "Error (%s:%d): not composing yet.\n",
list_file, line);
return false;
}
if (m_compose.valid())
{
tile img;
if (!load_image(img, arg2))
{
fprintf(stderr, "Error(%s:%d): couldn't load image "
"'%s'.\n", list_file, line, arg2);
return false;
}
if (m_rim)
img.add_rim(tile_colour::black);
if (!m_compose.compose(img))
{
fprintf(stderr, "Error (%s:%d): failed composing '%s'"
" onto compose image.\n", list_file, line, arg2);
return false;
}
}
else
{
if (!load_image(m_compose, arg2))
{
fprintf(stderr, "Error(%s:%d): couldn't load image "
"'%s'.\n", list_file, line, arg2);
return false;
}
}
}
else if (strcmp(arg1, "corpse") == 0)
{
CHECK_ARG2;
m_corpsify = (bool)atoi(arg2);
}
else if (strcmp(arg1, "end") == 0)
{
CHECK_NO_ARG2;
if (m_parts_ctg.empty())
{
fprintf(stderr, "Error (%s:%d): no category to end.\n",
list_file, line);
return false;
}
m_parts_ctg.clear();
}
else if (strcmp(arg1, "finish") == 0)
{
if (!m_composing)
{
fprintf(stderr, "Error (%s:%d): not composing yet.\n",
list_file, line);
return false;
}
if (m_corpsify)
m_compose.corpsify();
else if (m_rim)
m_compose.add_rim(tile_colour::black);
if (m_back.valid())
{
tile img(m_back);
if (!img.compose(m_compose))
{
fprintf(stderr, "Error (%s:%d): failed composing '%s'"
" onto back image '%s'.\n", list_file, line,
arg1, m_back.filename().c_str());
return false;
}
add_image(img, arg2);
}
else
{
add_image(m_compose, arg2);
}
m_compose.unload();
m_composing = false;
}
else if (strcmp(arg1, "include") == 0)
{
CHECK_ARG2;
if (!process_list(arg2))
{
fprintf(stderr, "Error (%s:%d): include failed.\n",
list_file, line);
return false;
}
}
else if (strcmp(arg1, "name") == 0)
{
CHECK_ARG2;
if (m_name != "")
{
fprintf(stderr,
"Error (%s:%d): name already specified as '%s'\n",
list_file, line, m_name.c_str());
return false;
}
m_name = arg2;
}
else if (strcmp(arg1, "parts_ctg") == 0)
{
CHECK_ARG2;
for (unsigned int i = 0; i < m_categories.size(); i++)
{
if (arg2 == m_categories[i])
{
fprintf(stderr,
"Error (%s:%d): category '%s' already used.\n",
list_file, line, arg2);
return false;
}
}
m_parts_ctg = arg2;
m_categories.push_back(m_parts_ctg);
m_ctg_counts.push_back(0);
}
else if (strcmp(arg1, "prefix") == 0)
{
CHECK_ARG2;
m_prefix = arg2;
}
else if (strcmp(arg1, "rim") == 0)
{
CHECK_ARG2;
m_rim = (bool)atoi(arg2);
}
else if (strcmp(arg1, "sdir") == 0)
{
CHECK_ARG2;
m_sdir = arg2;
}
else if (strcmp(arg1, "shrink") == 0)
{
CHECK_ARG2;
m_shrink = (bool)atoi(arg2);
}
else if (strcmp(arg1, "start") == 0)
{
CHECK_NO_ARG2;
if (m_composing)
{
fprintf(stderr, "Error (%s:%d): already composing.\n",
list_file, line);
return false;
}
m_composing = true;
m_compose.unload();
}
else
{
fprintf(stderr, "Error (%s:%d): unknown command '%%%s'\n",
list_file, line, arg1);
return false;
}
}
else
{
if (m_composing)
{
fprintf(stderr, "Error (%s:%d): can't load while composing.\n",
list_file, line);
return false;
}
tile img;
if (m_back.valid())
{
// compose
if (!load_image(m_compose, arg1))
{
fprintf(stderr, "Error (%s:%d): couldn't load image "
"'%s'.\n", list_file, line, arg1);
return false;
}
if (m_corpsify)
m_compose.corpsify();
img.copy(m_back);
if (!img.compose(m_compose))
{
fprintf(stderr, "Error (%s:%d): failed composing '%s'"
" onto back image '%s'.\n", list_file, line,
arg1, m_back.filename().c_str());
return false;
}
}
else
{
if (!load_image(img, arg1))
{
fprintf(stderr, "Error (%s:%d): couldn't load image "
"'%s'.\n", list_file, line, arg1);
return false;
}
if (m_corpsify)
img.corpsify();
}
if (m_rim && !m_corpsify)
img.add_rim(tile_colour::black);
// push tile onto tile page
add_image(img, arg2);
}
return true;
}
void tile_list_processor::add_image(tile &img, const char *enumname)
{
tile *new_img = new tile(img, enumname, m_parts_ctg.c_str());
new_img->set_shrink(m_shrink);
m_page.m_tiles.push_back(new_img);
m_page.m_counts.push_back(1);
if (enumname)
m_last_enum = m_page.m_counts.size() - 1;
else if (m_last_enum < m_page.m_counts.size())
m_page.m_counts[m_last_enum]++;
if (m_categories.size() > 0)
{
m_ctg_counts[m_categories.size()-1]++;
}
}
bool tile_list_processor::write_data()
{
if (m_name == "")
{
fprintf(stderr, "Error: can't write data with no %name specified.\n");
return false;
}
std::string lcname = m_name;
std::string ucname = m_name;
for (unsigned int i = 0; i < m_name.size(); i++)
{
lcname[i] = std::tolower(m_name[i]);
ucname[i] = std::toupper(m_name[i]);
}
std::string max = m_prefix;
max += "_";
max += ucname;
max += "_MAX";
std::string ctg_max = m_prefix;
ctg_max += "_PART_MAX";
// write image page
{
if (!m_page.place_images())
return false;
char filename[1024];
sprintf(filename, "%s.png", lcname.c_str());
if (!m_page.write_image(filename))
return false;
}
int *part_min = NULL;
// write "tiledef-%name.h"
{
char filename[1024];
sprintf(filename, "tiledef-%s.h", lcname.c_str());
FILE *fp = fopen(filename, "w");
if (!fp)
{
fprintf(stderr, "Error: couldn't open '%s' for write.\n", filename);
return false;
}
if (m_categories.size() > 0)
{
part_min = new int[m_categories.size()];
memset(part_min, 0, sizeof(int) * m_categories.size());
}
fprintf(fp, "// This file has been automatically generated.\n\n");
fprintf(fp, "#ifndef TILEDEF_%s_H\n#define TILEDEF_%s_H\n\n",
ucname.c_str(), ucname.c_str());
fprintf(fp, "#include \"tiledef_defines.h\"\n\n");
fprintf(fp, "enum tile_%s_type\n{\n", lcname.c_str());
for (unsigned int i = 0; i < m_page.m_tiles.size(); i++)
{
const std::string &enumname = m_page.m_tiles[i]->enumname();
const std::string &parts_ctg = m_page.m_tiles[i]->parts_ctg();
if (enumname.empty())
{
fprintf(fp, " %s_%s_FILLER_%d,\n", m_prefix.c_str(),
ucname.c_str(), i);
}
else if (parts_ctg.empty())
{
fprintf(fp, " %s_%s,\n", m_prefix.c_str(),
enumname.c_str());
}
else
{
fprintf(fp, " %s_%s_%s,\n", m_prefix.c_str(),
parts_ctg.c_str(), enumname.c_str());
}
if (!parts_ctg.empty())
{
int idx;
for (idx = 0; idx < m_categories.size(); idx++)
{
if (parts_ctg == m_categories[idx])
break;
}
assert(idx < m_categories.size());
if (part_min[idx] == 0)
part_min[idx] = i;
}
}
fprintf(fp, " %s_%s_MAX\n};\n\n", m_prefix.c_str(), ucname.c_str());
fprintf(fp, "extern int tile_%s_count[%s];\n",
lcname.c_str(), max.c_str());
fprintf(fp, "extern const char *tile_%s_name[%s];\n",
lcname.c_str(), max.c_str());
fprintf(fp, "extern tile_info tile_%s_info[%s];\n",
lcname.c_str(), max.c_str());
if (m_categories.size() > 0)
{
fprintf(fp, "\nenum tile_%s_parts\n{\n", lcname.c_str());
for (unsigned int i = 0; i < m_categories.size(); i++)
{
fprintf(fp, " %s_PART_%s,\n", m_prefix.c_str(),
m_categories[i].c_str());
}
fprintf(fp, " %s\n};\n\n", ctg_max.c_str());
fprintf(fp, "extern int tile_%s_part_count[%s];\n",
lcname.c_str(), ctg_max.c_str());
fprintf(fp, "extern int tile_%s_part_start[%s];\n",
lcname.c_str(), ctg_max.c_str());
}
fprintf(fp, "\n#endif\n\n");
fclose(fp);
}
// write "tiledef-%name.cc"
{
char filename[1024];
sprintf(filename, "tiledef-%s.cc", lcname.c_str());
FILE *fp = fopen(filename, "w");
if (!fp)
{
fprintf(stderr, "Error: couldn't open '%s' for write.\n", filename);
return false;
}
fprintf(fp, "// This file has been automatically generated.\n\n");
fprintf(fp, "#include \"tiledef-%s.h\"\n\n", lcname.c_str());
fprintf(fp, "int tile_%s_count[%s] =\n{\n",
lcname.c_str(), max.c_str());
for (unsigned int i = 0; i < m_page.m_counts.size(); i++)
fprintf(fp, " %d,\n", m_page.m_counts[i]);
fprintf(fp, "};\n\n");
fprintf(fp, "const char *tile_%s_name[%s] =\n{\n",
lcname.c_str(), max.c_str());
for (unsigned int i = 0; i < m_page.m_tiles.size(); i++)
{
const std::string &enumname = m_page.m_tiles[i]->enumname();
if (enumname.empty())
fprintf(fp, " \"%s_FILLER_%d\",\n", ucname.c_str(), i);
else
fprintf(fp, " \"%s\",\n", enumname.c_str());
}
fprintf(fp, "};\n\n");
fprintf(fp, "tile_info tile_%s_info[%s] =\n{\n",
lcname.c_str(), max.c_str());
for (unsigned int i = 0; i < m_page.m_offsets.size(); i+=4)
{
fprintf(fp, " tile_info(%d, %d, %d, %d, %d, %d, %d, %d),\n",
m_page.m_offsets[i+2], m_page.m_offsets[i+3],
m_page.m_offsets[i], m_page.m_offsets[i+1],
m_page.m_texcoords[i], m_page.m_texcoords[i+1],
m_page.m_texcoords[i+2], m_page.m_texcoords[i+3]);
}
fprintf(fp, "};\n\n");
if (m_categories.size() > 0)
{
fprintf(fp, "int tile_%s_part_count[%s] =\n{\n",
lcname.c_str(), ctg_max.c_str());
for (int i = 0; i < m_ctg_counts.size(); i++)
{
fprintf(fp, " %d,\n", m_ctg_counts[i]);
}
fprintf(fp, "};\n\n");
fprintf(fp, "int tile_%s_part_start[%s] =\n{\n",
lcname.c_str(), ctg_max.c_str());
for (int i = 0; i < m_categories.size(); i++)
{
fprintf(fp, " %d,\n", part_min[i]);
}
fprintf(fp, "};\n\n");
}
}
delete[] part_min;
return true;
}
#ifndef TILE_COLOUR_H
#define TILE_COLOUR_H
class tile_colour
{
public:
tile_colour() {};
tile_colour(unsigned char _r, unsigned char _g, unsigned char _b,
unsigned char _a) : r(_r), g(_g), b(_b), a(_a) {}
bool operator==(const tile_colour &rhs) const;
bool operator!=(const tile_colour &rhs) const;
const tile_colour &operator=(const tile_colour &rhs);
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
static tile_colour background;
static tile_colour transparent;
static tile_colour black;
};
#endif
#include "tile_colour.h"
tile_colour tile_colour::background(71, 108, 108, 255);
tile_colour tile_colour::transparent(0, 0, 0, 0);
tile_colour tile_colour::black(0, 0, 0, 255);
bool tile_colour::operator==(const tile_colour &rhs) const
{
return (r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a);
}
bool tile_colour::operator!=(const tile_colour &rhs) const
{
return (r != rhs.r || g != rhs.g || b != rhs.b || a != rhs.a);
}
const tile_colour &tile_colour::operator=(const tile_colour &rhs)
{
r = rhs.r;
g = rhs.g;
b = rhs.b;
a = rhs.a;
return *this;
}
#ifndef TILE_H
#define TILE_H
#include "tile_colour.h"
#include <string>
class tile
{
public:
tile();
tile(const tile &img, const char *enumname = NULL,
const char *parts_ctg = NULL);
virtual ~tile();
bool load(const std::string &filename);
bool load(const std::string &filename, const std::string &enumname);
void unload();
bool valid() const;
void resize(int new_width, int new_height);
void add_rim(const tile_colour &rim);
void corpsify();
void corpsify(int corpse_width, int corpse_height,
int cut_separate, int cut_height, const tile_colour &wound);
void copy(const tile &img);
bool compose(const tile &img);
void replace_colour(tile_colour &find, tile_colour &replace);
void fill(const tile_colour &fill);
const std::string &filename();
const std::string &enumname();
const std::string &parts_ctg();
int width();
int height();
bool shrink();
void set_shrink(bool shrink);
void get_bounding_box(int &x0, int &y0, int &width, int &height);
tile_colour &get_pixel(unsigned int x, unsigned int y);
protected:
int m_width;
int m_height;
std::string m_filename;
std::string m_enumname;
std::string m_parts_ctg;
tile_colour *m_pixels;
bool m_shrink;
};
#endif
#include "tile.h"
#include <assert.h>
#include <SDL.h>
#include <SDL_image.h>
tile::tile() : m_width(0), m_height(0), m_pixels(NULL), m_shrink(true)
{
}
tile::tile(const tile &img, const char *enumname, const char *parts_ctg) :
m_width(0), m_height(0), m_pixels(NULL)
{
copy(img);
if (enumname)
m_enumname = enumname;
if (parts_ctg)
m_parts_ctg = parts_ctg;
}
tile::~tile()
{
unload();
}
void tile::unload()
{
delete[] m_pixels;
m_pixels = NULL;
m_width = m_height = 0;
}
bool tile::valid() const
{
return m_pixels && m_width && m_height;
}
const std::string &tile::filename()
{
return m_filename;
}
const std::string &tile::enumname()
{
return m_enumname;
}
const std::string &tile::parts_ctg()
{
return m_parts_ctg;
}
int tile::width()
{
return m_width;
}
int tile::height()
{
return m_height;
}
bool tile::shrink()
{
return m_shrink;
}
void tile::set_shrink(bool shrink)
{
m_shrink = shrink;
}
void tile::resize(int new_width, int new_height)
{
delete[] m_pixels;
m_width = new_width;
m_height = new_height;
m_pixels = NULL;
if (!m_width || !m_height)
return;
m_pixels = new tile_colour[m_width * m_height];
}
void tile::add_rim(const tile_colour &rim)
{
bool *flags = new bool[m_width * m_height];
for (unsigned int y = 0; y < m_height; y++)
{
for (unsigned int x = 0; x < m_width; x++)
{
flags[x + y * m_width] = ((get_pixel(x, y).a > 0) &&
(get_pixel(x,y) != rim));
}
}
for (unsigned int y = 0; y < m_height; y++)
{
for (unsigned int x = 0; x < m_width; x++)
{
if (flags[x + y * m_width])
continue;
if (x > 0 && flags[(x-1) + y * m_width] ||
y > 0 && flags[x + (y-1) * m_width] ||
x < m_width - 1 && flags[(x+1) + y * m_width] ||
y < m_height - 1 && flags[x + (y+1) * m_width])
{
get_pixel(x,y) = rim;
}
}
}
delete[] flags;
}
void tile::corpsify()
{
// TODO enne - different wound colours for different bloods
// TODO enne - use blood variations
tile_colour red_blood(0, 0, 32, 255);
int separate_x = 3;
int separate_y = 4;
// force all corpses into 32x32, even if bigger.
corpsify(32, 32, separate_x, separate_y, red_blood);
}
static int corpse_cut_height(int x, int width, int height)
{
unsigned int cy = height / 2 + 2;
// Make the cut bend upwards in the middle
int limit1 = width / 8;
int limit2 = width / 3;
if (x < limit1 || x >= width - limit1)
cy += 2;
else if (x < limit2 || x >= width - limit2)
cy += 1;
return cy;
}
// Adapted from rltiles' cp_monst_32 and then ruthlessly rewritten for clarity.
// rltiles can be found at http://rltiles.sourceforge.net
void tile::corpsify(int corpse_width, int corpse_height,
int cut_separate, int cut_height, const tile_colour &wound)
{
int wound_height = std::min(2, cut_height);
// Make a temporary backup
tile orig(*this);
resize(corpse_width, corpse_height);
fill(tile_colour::transparent);
// Track which pixels have been written to with valid image data
bool *flags = new bool[corpse_width * corpse_height];
memset(flags, 0, corpse_width * corpse_height * sizeof(bool));
#define flags(x,y) (flags[((x) + (y) * corpse_width)])
// Find extents
int xmin, ymin, bbwidth, bbheight;
orig.get_bounding_box(xmin, ymin, bbwidth, bbheight);
int xmax = xmin + bbwidth - 1;
int ymax = ymin + bbheight - 1;
int centerx = (xmax + xmin) / 2;
int centery = (ymax + ymin) / 2;
// Use maximum scale in case aspect ratios differ.
float width_scale = (float)m_width / (float)corpse_width;
float height_scale = (float)m_height / (float)corpse_height;
float image_scale = std::max(width_scale, height_scale);
// Amount to scale height by to fake a projection.
float height_proj = 2.0f;
for (int y = 0; y < corpse_height; y++)
{
for (int x = 0; x < corpse_width; x++)
{
int cy = corpse_cut_height(x, corpse_width, corpse_height);
if (y > cy - cut_height && y <= cy)
continue;
// map new center to old center, including image scale
int x1 = ((x - m_width/2) * image_scale) + centerx;
int y1 = ((y - m_height/2) * height_proj * image_scale) + centery;
if (y >= cy)
{
x1 -= cut_separate;
y1 -= cut_height / 2;
}
else
{
x1 += cut_separate;
y1 += cut_height / 2 + cut_height % 2;
}
if (x1 < 0 || x1 >= m_width || y1 < 0 || y1 >= m_height)
continue;
tile_colour &mapped = orig.get_pixel(x1, y1);
// ignore rims, shadows, and transparent pixels.
if (mapped == tile_colour::black ||
mapped == tile_colour::transparent)
{
continue;
}
get_pixel(x,y) = mapped;
flags(x, y) = true;
}
}
// Add some colour to the cut wound
for (int x = 0; x < corpse_width; x++)
{
unsigned int cy = corpse_cut_height(x, corpse_width, corpse_height);
if (flags(x, cy-cut_height))
{
unsigned int start = cy - cut_height + 1;
for (int y = start; y < start + wound_height; y++)
{
get_pixel(x, y) = wound;
}
}
}
// Add diagonal shadowing...
for (int y = 1; y < corpse_height; y++)
{
for (int x = 1; x < corpse_width; x++)
{
if (!flags(x, y) && flags(x-1, y-1) &&
get_pixel(x,y) == tile_colour::transparent)
{
get_pixel(x, y) = tile_colour::black;
}
}
}
// Extend shadow...
for (int y = 3; y < corpse_height; y++)
{
for (int x = 3; x < corpse_width; x++)
{
// Extend shadow if there are two real pixels along
// the diagonal. Also, don't extend if the top or
// left pixel is not filled in. This prevents lone
// shadow pixels only connected via diagonals.
if (get_pixel(x-1,y-1) == tile_colour::black &&
flags(x-2, y-2) && flags(x-3, y-3) &&
get_pixel(x-1, y) == tile_colour::black &&
get_pixel(x, y-1) == tile_colour::black)
{
get_pixel(x, y) = tile_colour::black;
}
}
}
delete[] flags;
}
void tile::copy(const tile &img)
{
unload();
m_width = img.m_width;
m_height = img.m_height;
m_filename = img.m_filename;
m_pixels = new tile_colour[m_width * m_height];
m_shrink = img.m_shrink;
memcpy(m_pixels, img.m_pixels, m_width * m_height * sizeof(tile_colour));
// enum explicitly not copied
m_enumname.clear();
}
bool tile::compose(const tile &img)
{
if (!valid())
{
fprintf(stderr, "Error: can't compose onto an unloaded image.\n");
return false;
}
if (!img.valid())
{
fprintf(stderr, "Error: can't compose from an unloaded image.\n");
return false;
}
if (m_width != img.m_width || m_height != img.m_height)
{
fprintf(stderr, "Error: can't compose with mismatched dimensions. "
"(%d, %d) onto (%d, %d)\n", img.m_width, img.m_height, m_width,
m_height);
return false;
}
for (unsigned int i = 0; i < m_width * m_height; i += 1)
{
const tile_colour *src = &img.m_pixels[i];
tile_colour *dest = &m_pixels[i];
dest->r = (src->r * src->a + dest->r * (255 - src->a)) / 255;
dest->g = (src->g * src->a + dest->g * (255 - src->a)) / 255;
dest->b = (src->b * src->a + dest->b * (255 - src->a)) / 255;
dest->a = (src->a * 255 + dest->a * (255 - src->a)) / 255;
}
return true;
}
bool tile::load(const std::string &filename)
{
if (m_pixels)
{
unload();
}
SDL_Surface *img = IMG_Load(filename.c_str());
if (!img)
{
return false;
}
m_width = img->w;
m_height = img->h;
// blow out all formats to non-palettised RGBA.
m_pixels = new tile_colour[m_width * m_height];
unsigned int bpp = img->format->BytesPerPixel;
if (bpp == 1)
{
SDL_Palette *pal = img->format->palette;
assert(pal);
assert(pal->colors);
int src = 0;
int dest = 0;
for (int y = 0; y < img->h; y++)
{
for (int x = 0; x < img->w; x++)
{
int index = ((unsigned char*)img->pixels)[src++];
m_pixels[dest].r = pal->colors[index].r;
m_pixels[dest].g = pal->colors[index].g;
m_pixels[dest].b = pal->colors[index].b;
m_pixels[dest].a = 255;
dest++;
}
}
}
else
{
SDL_LockSurface(img);
int dest = 0;
for (int y = 0; y < img->h; y++)
{
for (int x = 0; x < img->w; x++)
{
unsigned char *p = (unsigned char*)img->pixels
+ y*img->pitch + x*bpp;
unsigned int pixel;
switch (img->format->BytesPerPixel)
{
case 1:
pixel = *p;
break;
case 2:
pixel = *(unsigned short*)p;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
pixel = p[0] << 16 | p[1] << 8 | p[2];
else
pixel = p[0] | p[1] << 8 | p[2] << 16;
break;
case 4:
pixel = *(unsigned int*)p;
break;
default:
assert(!"Invalid bpp");
SDL_UnlockSurface(img);
SDL_FreeSurface(img);
return false;
}
SDL_GetRGBA(pixel, img->format, &m_pixels[dest].r,
&m_pixels[dest].g, &m_pixels[dest].b,
&m_pixels[dest].a);
dest++;
}
}
SDL_UnlockSurface(img);
}
SDL_FreeSurface(img);
replace_colour(tile_colour::background, tile_colour::transparent);
return true;
}
void tile::fill(const tile_colour &fill)
{
for (int y = 0; y < m_height; y++)
{
for (int x = 0; x < m_width; x++)
{
get_pixel(x, y) = fill;
}
}
}
void tile::replace_colour(tile_colour &find, tile_colour &replace)
{
for (int y = 0; y < m_height; y++)
{
for (int x = 0; x < m_width; x++)
{
tile_colour &p = get_pixel(x, y);
if (p == find)
p = replace;
}
}
}
tile_colour &tile::get_pixel(unsigned int x, unsigned int y)
{
assert(m_pixels && x < m_width && y < m_height);
return m_pixels[x + y * m_width];
}
void tile::get_bounding_box(int &x0, int &y0, int &width, int &height)
{
if (!valid())
{
x0 = y0 = width = height = 0;
return;
}
x0 = y0 = 0;
unsigned int x1 = m_width - 1;
unsigned int y1 = m_height - 1;
while (x0 <= x1)
{
bool found = false;
for (unsigned int y = y0; !found && y < y1; y++)
{
found |= (get_pixel(x0, y).a > 0);
}
if (found)
break;
x0++;
}
while (x0 <= x1)
{
bool found = false;
for (unsigned int y = y0; !found && y < y1; y++)
{
found |= (get_pixel(x1, y).a > 0);
}
if (found)
break;
x1--;
}
while (y0 <= y1)
{
bool found = false;
for (unsigned int x = x0; !found && x < x1; x++)
{
found |= (get_pixel(x, y0).a > 0);
}
if (found)
break;
y0++;
}
while (y0 <= y1)
{
bool found = false;
for (unsigned int x = x0; !found && x < x1; x++)
{
found |= (get_pixel(x, y1).a > 0);
}
if (found)
break;
y1--;
}
width = x1 - x0 + 1;
height = y1 - y0 + 1;
}
#include "tile_list_processor.h"
int main(int argc, char **argv)
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s (tile_list.txt)\n", argv[0]);
return -1;
}
tile_list_processor proc;
if (!proc.process_list(argv[1]))
{
fprintf(stderr, "Error: failed to process '%s'\n", argv[1]);
return -2;
}
if (!proc.write_data())
{
fprintf(stderr, "Error: failed to write data for '%s'\n", argv[1]);
return -3;
}
return 0;
}
#ifndef TILEDEF_DEFINES_H
#define TILEDEF_DEFINES_H
#include <assert.h>
class tile_info
{
public:
tile_info(int _width, int _height, int _offset_x, int _offset_y,
int _sx, int _sy, int _ex, int _ey) :
width(_width),
height(_height),
offset_x(_offset_x),
offset_y(_offset_y),
sx(_sx),
sy(_sy),
ex(_ex),
ey(_ey)
{
// verify all params are larger than zero and fit in storage
assert(width == _width);
assert(height == _height);
assert(offset_x == _offset_x);
assert(offset_y == _offset_y);
assert(sx == _sx);
assert(sy == _sy);
assert(ex == _ex);
assert(ey == _ey);
}
// size of the original tile
unsigned char width;
unsigned char height;
// offset to draw this image at (texcoords may be smaller than orig image)
unsigned char offset_x;
unsigned char offset_y;
// texcoords in the tile page
unsigned short sx;
unsigned short sy;
unsigned short ex;
unsigned short ey;
};
#endif
HEADERS = \
tiledef.h \
tiledef-p.h \
tilep-cmt.h \
tiledef-dngn.h \
tilecount-dngn.h \
map.htm
INPUTS := main dngn player demon
INPUTFILES := $(INPUTS:%=dc-%.txt)
HEADERS := $(INPUTS:%=tiledef-%.h)
SOURCE := $(INPUTS:%=tiledef-%.cc)
IMAGES := $(INPUTS:%=%.png)
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.
dngn.bmp: dngn.txt dctile
./dctile dngn.txt
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) $(GENERATEDBMP)
$(DELETE) $(TILEPNG)
$(DELETE) $(HEADERS)
$(TILEGEN): $(OBJECTS)
${CXX} ${LDFLAGS} $(OBJECTS) -o $@
shadow
%rim 1
%sdir player/barding
naga_barding_blue NAGA_BARDING
naga_barding_metal NAGA_BARDING_METAL
naga_barding_magenta NAGA_BARDING_MAGENTA
naga_barding_red NAGA_BARDING_RED
centaur_barding_blue CENTAUR_BARDING
centaur_barding_metal CENTAUR_BARDING_METAL
centaur_barding_magenta CENTAUR_BARDING_MAGENTA
centaur_barding_red CENTAUR_BARDING_RED
shadow SHADOW
%rim 1
%sdir player/barding
naga_barding_blue NAGA_BARDING
naga_barding_metal NAGA_BARDING_METAL
naga_barding_magenta NAGA_BARDING_MAGENTA
naga_barding_red NAGA_BARDING_RED
centaur_barding_blue CENTAUR_BARDING
centaur_barding_metal CENTAUR_BARDING_METAL
centaur_barding_magenta CENTAUR_BARDING_MAGENTA
centaur_barding_red CENTAUR_BARDING_RED
%rim 0
BM6������6���(��� ��� ������������������������```@@@000000 000PPP000000@@@000000000000@@@0�000 000 @@@000@@@ 000 ```@@@@@@@@@0000000000`�PPP000000@@@@@@000@@@0000000�000000000 @@@@@@000000000000000000PPPPPP@@@0000`�000 0`�@@@@@@@@@PPP000PPP@@@000PPP0`�000000000 PPP000000PPP@@@PPP@@@000 0�0�0`�0`�0�0�PPP000@@@@@@0�000@@@@@@0�0`� 000 @@@@@@@@@000000 0�000000 0� ```@@@0000000�000000000000000000000000 PPP000PPP@@@@@@0000�@@@0000000`�000000000 PPP@@@PPP@@@000@@@PPP@@@000000@@@PPP@@@000 @@@000@@@PPP000000@@@@@@@@@@@@0000`�@@@@@@000 0�0�``` 000 000 @@@0�@@@ 000 000@@@@@@000 @@@@@@ 000 PPP000000000000000 @@@0000`�000@@@@@@@@@0�000000000000@@@000 PPP000000@@@@@@000000000```@@@PPP@@@@@@000 PPP@@@0`�PPP@@@@@@PPP000PPP@@@000PPP000000000@@@PPP@@@PPP000@@@PPP000 0`�0�0�``` 0000`�000000 000000 000 000@@@000@@@@@@@@@@@@0`�000 000 0� 000PPP000@@@@@@0�0`�@@@000000@@@@@@000000000 PPP@@@0000000000000`�@@@@@@@@@@@@0000`�000 PPP@@@PPP0000000�@@@@@@PPPPPP000PPP000000 @@@PPP000@@@@@@0000000�@@@0000000000`�000 0�0`�0�PPP 000 000 @@@0�0�000@@@0`� 000 0000`� 000 000@@@000@@@000 000```000000000000000000@@@000000@@@@@@0000`�@@@@@@0000`�0�000000 @@@000000@@@@@@000000000@@@@@@000@@@@@@000 000@@@PPP@@@000PPP0�000@@@000000PPP0�000000@@@PPP@@@PPP0`�@@@@@@000 @�0�0`�0`�@@@000 000 @�0�0�000@@@000000 @@@000 000 000000@@@0`�0�000000 0`� ```000@@@@@@PPP000000 @�0000000�000@@@@@@000000000@@@@@@@@@0000000000�0`�0�000000000000PPP@@@PPP000000@@@PPP@@@ @�@@@000000000@@@@@@@@@@@@@@@000000@@@000@@@000000@@@000000000 0�000000000 0000� PPP000@@@@@@PPP@@@000 000 000000 @@@000 @@@@@@ 000```0000000000000`�0�@@@000000000@@@000000@@@000000PPP@@@000000 PPP@@@000000PPP@@@000 PPP000@@@@@@@@@0000`�000@@@@@@0�PPP000@@@000@@@PPP@@@000000000 000PPP@@@@@@000PPP@@@000 0`�0�0�```000@@@@@@@@@ 000 @�@@@ 0000� PPP000PPP0`�000000 0000000�0� @� 000 PPP@@@000000000000@@@0000000000000`� @�000 @@@0000000`� @�@@@000@@@PPP000@@@ @�@@@@@@000```PPP```PPP```PPPPPP```PPPPPP```PPP``````000000```PPP```PPP```@@@000```PPPPPP``````PPP
BM6������6���(��� ��� ������������������������```@@@000000000PPP000000000 000000000000 000 000@@@ 000 000 ```@@@@@@@@@000@@@000000000000000@@@@@@000@@@000000 @@@000000000000@@@ @@@000000000PPPPPP@@@000@@@@@@PPPPPPPPP@@@@@@000000PPP@@@000PPP000@@@@@@@@@@@@000000000@@@PPP@@@000 PPP000@@@@@@@@@000@@@@@@000000 000 000000 000000 ```@@@000000000000000000000@@@000000000000000000000@@@@@@000@@@@@@000000000000000000 PPP@@@PPP@@@000@@@PPP@@@000@@@PPP@@@@@@000@@@@@@000PPP000000@@@@@@@@@@@@000PPP@@@@@@000 ``` 000 000 @@@000@@@ 000 000@@@@@@000 @@@@@@ 000 PPP000000000000000 @@@000000000@@@@@@@@@000000000000000@@@000 PPP000000@@@@@@000000000```@@@PPP@@@@@@000 PPP@@@000PPP@@@@@@PPP000PPP@@@000PPP000000000@@@PPP@@@PPP000@@@PPP000 ``` 000 000 000000 000 000@@@000000000 000 000 000PPP000@@@@@@@@@@@@000000@@@@@@000000000 PPP@@@000000000 @@@@@@@@@@@@000000000 PPP@@@PPP000000@@@@@@PPPPPP000PPP000000 @@@PPP000@@@@@@000PPP@@@000000000@@@000 PPP 000 000 @@@000@@@000@@@ 000 000000 000 000@@@000 000```000000000000000000@@@000000@@@@@@000000@@@@@@000@@@@@@000000000000 000@@@@@@000000000@@@@@@000@@@@@@000 000@@@PPP@@@000PPP@@@000@@@000000PPP@@@000@@@000@@@@@@PPP000@@@@@@000 @@@000 000 000000 @@@000000 000000 000 000@@@@@@ 000000 000 ```000@@@@@@PPP000000000000000@@@000000000000000000@@@@@@@@@000000000@@@000000000000000PPP@@@PPP000000@@@PPP@@@000@@@000@@@@@@@@@000@@@@@@@@@000000000@@@000000@@@000000000 000000000 000 PPP000@@@@@@PPP@@@000 000 000 000 000 @@@@@@ 000```000000000000000 @@@000000000@@@000000@@@000000@@@000000000000000@@@000000PPP@@@000 PPP000@@@@@@@@@000000PPP@@@@@@000PPP000@@@000@@@PPP000@@@@@@@@@000000PPP@@@@@@000PPP@@@000 ```000@@@@@@@@@ 000@@@@@@ 000@@@000000000000000PPP@@@000000 000000 000 000 PPP@@@000000000000@@@000000000000PPP@@@000000000000000000000@@@000PPP000@@@PPP@@@@@@000```PPP```PPP```PPPPPP```PPPPPP`````````PPPPPPPPP```PPP```PPP```@@@```PPPPPP``````PPP
BM6������6���(��� ��� ������������������������```@@@000000 000PPP000000@@@000000000000@@@PPP000 000000 000 000 ```@@@@@@@@@000000000@@@PPP000000@@@@@@000@@@000000@@@000000000000000@@@000000000000000000PPPPPP@@@000000000 000@@@@@@@@@PPP000PPP@@@000PPPPPP000PPP@@@@@@000@@@000PPP@@@PPP@@@000 PPP000@@@@@@@@@000@@@@@@000 PPP000 000000 000000 ```@@@000000000000000000000000000000000@@@000000000000000@@@000@@@000000000000000000 PPP@@@PPP@@@000@@@PPP@@@000000@@@PPP@@@PPP@@@000@@@@@@@@@000@@@@@@@@@@@@000PPP@@@@@@000 ``` 000 000 @@@000@@@ 000 @@@000 000@@@ 000 PPP000000000000000 @@@000000000@@@@@@@@@000@@@000000@@@000000@@@000000000@@@@@@000000000```@@@PPP@@@@@@000 PPP@@@000PPP@@@@@@PPP000@@@@@@PPP@@@@@@@@@000@@@PPP@@@PPP000@@@PPP000 ``` 000 000000 000000@@@000 000 000 PPP@@@000000 000 000PPP000@@@@@@@@@@@@@@@000000@@@000@@@000@@@000000@@@ @@@000000@@@@@@@@@@@@000000000 PPP@@@PPP000000000@@@@@@PPPPPPPPP@@@PPPPPP@@@000PPP000PPP@@@@@@PPP@@@000000000@@@000 PPP 000 000 @@@000@@@000@@@ 000 000000 000 000@@@000@@@000 000```000000000000000000@@@000000@@@@@@000000@@@@@@000@@@@@@000000 @@@000000@@@@@@000000000@@@@@@000@@@@@@000 000@@@PPP@@@000PPP@@@000@@@000000PPP@@@000000@@@PPP@@@PPP000@@@@@@000 @@@000 000 000000PPP@@@000000 000000 000@@@000@@@@@@ 000000 000 ```000@@@@@@PPP000000000000@@@000@@@000000000000000000@@@PPP000000000@@@000000000000000PPP@@@PPP000000@@@PPP@@@000@@@@@@PPP@@@000000000@@@@@@000PPP@@@PPP@@@000@@@000000000 000000000 000 PPP000@@@@@@PPP@@@000 000 @@@@@@000 000 @@@@@@ 000```000000000000000 @@@000000000@@@000000@@@000000000000@@@000000000000000PPP@@@000 PPP000@@@@@@@@@000000000@@@@@@000PPP000@@@000@@@PPP@@@000@@@PPP@@@@@@PPP@@@000PPP@@@000 ```000 @@@000@@@@@@ 000 PPP000PPP@@@000000 000PPP000000 000 PPP@@@000 @@@000000000000000000000000 @@@000000000000000000@@@@@@000@@@000@@@000```PPP```PPPPPPPPP```PPPPPP```PPP``````000000```PPP```PPP```@@@000PPPPPP``````PPP
BM6������6���(��� ��� ������������������������```@@@000000 000PPP000000@@@000000000000@@@@@@000 000 @@@000@@@ 000 ```@@@@@@@@@000000000@@@PPP000000@@@@@@000@@@000000000000000000 @@@@@@000000000000000000PPPPPP@@@000000000 000@@@@@@@@@PPP000PPP@@@000PPP000000000000 PPP000000PPP@@@PPP@@@000 PPP000@@@@@@@@@000@@@@@@000 000 @@@@@@@@@000000 000000 ```@@@000000000000000000000000000000000 PPP000PPP@@@@@@000@@@@@@000000000000000000 PPP@@@PPP@@@000@@@PPP@@@000000@@@PPP@@@000 @@@000@@@PPP000000@@@@@@@@@@@@000PPP@@@@@@000 ``` 000 000 @@@000@@@ 000 000@@@@@@000 @@@@@@ 000 PPP000000000000000 @@@000000000@@@@@@@@@000000000000000@@@000 PPP000000@@@@@@000000000```@@@PPP@@@@@@000 PPP@@@000PPP@@@@@@PPP000PPP@@@000PPP000000000@@@PPP@@@PPP000@@@PPP000 ``` 000 000000 000000 000 000@@@000@@@@@@@@@@@@000000 000 000PPP000@@@@@@@@@@@@@@@000000@@@@@@000000000 PPP@@@000000000000000@@@@@@@@@@@@000000000 PPP@@@PPP000000000@@@@@@PPPPPP000PPP000000 @@@PPP000@@@@@@000000PPP@@@000000000@@@000 PPP 000 000 @@@000@@@000@@@ 000 000000 000 000@@@000@@@000 000```000000000000000000@@@000000@@@@@@000000@@@@@@000@@@@@@000000 @@@000000@@@@@@000000000@@@@@@000@@@@@@000 000@@@PPP@@@000PPP@@@000@@@000000PPP@@@000000@@@PPP@@@PPP000@@@@@@000 @@@000 000 000000 000@@@000000 @@@000 000 000000@@@@@@ 000000 000 ```000@@@@@@PPP000000000000000000000@@@@@@000000000@@@@@@@@@000000000000@@@000000000000000PPP@@@PPP000000@@@PPP@@@000@@@000000000@@@@@@@@@@@@@@@000000@@@000@@@000000@@@000000000 000 000 PPP000@@@@@@PPP@@@000 000 000000 @@@000 @@@@@@ 000```000000000000000 @@@000000000@@@000000@@@000000PPP@@@000000 PPP@@@000000PPP@@@000 PPP000@@@@@@@@@000000000@@@@@@000PPP000@@@000@@@PPP@@@000000000 000PPP@@@@@@000PPP@@@000 ```000@@@@@@000 000@@@@@@ 000 PPP000@@@@@@000000 000000000 000 000 PPP000000000@@@000@@@000000@@@000@@@000000 @@@000000000@@@000@@@@@@000000@@@000@@@000000```PPP```PPP```PPPPPP```PPPPPP```PPP``````000000```PPP```PPP```@@@000```PPPPPP``````PPP
BM6������6���(��� ��� �������������������������@������������ �� �� �� �0�� �0�0�������������������� �� �� �������� ���0�`������������ �0�� �@�@�@�� �������������0�0�� �� �@�@�� �� �������� �0�@������������ �� �@�� �� ������������������ ���@�@�� �@�� �� �������� �0�`���������������������������������������� �� �� �@�0�@���� ������ �� �@�������������������������������0�������0�0�@�0�� �@���������������� �0�@������ �0�0�0�0�� �� �0�� �0�� ���������� �0�� �� �0�@�����������0�0�@�@�0�0�0�� �� ���� �0�0�� �0�� ������������������ �� �0�@�� �� �����@�� �0�@�� �� �����������0�� �0�� �� ���� ���� �������� ���� �� �0�@�0�0���@���� �� ������ ���������� �0�0�������� �� �0�� �������� �� �@�� �0�@�� ���@�������������� �������� �� �0�������� �0�� �0���������@�@�0�@�@�0���`���������������� �� ������������������ �������������� �0�@�@�0�� ���@������������������ ���� �� �� �� ������������������������������ �� ���`���������������������0�0�0�� �� ���������������� �@���������������@�������� �� �� ���������� �� �@�0�0�� ������������ �@�0�0�� �����������@������ �@�@�@�� �������� �� �@�0�� �� �� ������������ �@�@�� �0������������ ���0�@�0�@�0���������� �@�0�0�0�� ������������ �� �0�0�� ���� �0�������� �� �0�� �0�� �0�������� �� �@�@�@�0�� �������� �� �0�� �� ������ �� �� �0�� �� ���0�� �� ���0���������� �0�@�0�� ���� ���������� �� �������0�0�� �0�����0�� �������������������� �� �0������ �� �������������������� �� �� ���� �0�������� ���� �� ������ ������ �� �������� ���� �� �� ���������� �0�@���0�� ���� �� ���� �0���� �� �������������������� �� �0�@�� �����������@���0���������� �� �0�� �� �������������������0�0�� �� �0�@�� ���������`���0���������0�@�@�@�� �����������������0�@�@�@�0�� �� �@�� �������`�0�� ���������@�� �� �0�@�� ������������ ���@���� �0�� �0�@���� �������@�0�������� �@�� �� �0�� �� �������� �� �� �0�@�0�0�� �� �� �0�� ������������ �0�� �����@������ �� �� �������� �@�0�@�@�@�������� �0�0�������������� �� �� �@�@�0���������������� �� �0�0�0�@�� �� �����0�0�� �������� �� �� �0�� �� �� �� ���� �������������� ���0�0�@�� �� �0���0�0�� ���������0�@�0�� �� �� �� �� ���������������������� �0�0�0�� �����0�������������� �@�0�@�� �� �� ���������0�� �� �@�� ���������� �� ������������������ �� �� �� �0�`�������������� �0�@�0�0�@�� �������������������������������������@�@�`�`�@���� �� �� �0�� �� �0�0�@�@�`�@�@�0�0�@�0�@�`�@�`�`�@�0�@�@
BM6������6���(��� ��� �������������������������0������������ �� �� �� �0�� �0�0�������������������� �� �� �������� ���0�`������������ �0�� �@�@�@�� �������������0�0�� �� �@�@�� �� �������� �0�`�� �� �0�0�� �� �� �@�� �� ������������������ ���@�@�� �0�� �� �������� �0�@�� �@�@�@�@�0�� �� ������������������������ �� �� �@�0�0���� ������ �� ���� �@�`�@�`�@�0�0�����������������������0�0�@�0�� �� ���������������� �`�@�`�@�`�@�0�0������ �0�� �0�� ���������� �0�� �� ������������������ �@�@�@�@�`�@�� �0���� �0�� �0�@�0���������������� �������� �� �����`�� �� �@�@�`�@�`�0�����0�� �0�� �@�@�0���� �������� �������� �0�@�0���@�� �0�� �0�@�@�@�0������ �0�0���� �@�@�@�0�� ���������� ���� �@�`�0���� �� �@�� �� �@�� �@�� �0���� �� �0������ �0�@�� �0�0���������� �0�`�@�0���� ���� �����@�������0�� ���������������� �������������0�@�`�`�0�� ���0�������@�0���������0�� �� �� �� ���������������������0�`�`�0�� �� ���`�����0�@�������������0�0�0�� �� ���������� �������@�@�0�0�@�������@�����@�� �� �� ���������� �� �@�0�0�� ���������� ���@�0�@�� �@���������0�� ���@�0�@�@�� �������� �� �@�0�� �� �� �������� ���� �@�@�� �0�@�0������ �� ���0�@�0�@�0���������� �@�0�0�0�� ������������ �� �0�0�� ���� �@���0���� �� �0�� �0�� �0�������� �� �@�@�@�0�� �������� �� �0�� �� ������ �@�� �� �� �� ���� �� �� �������������� �0�@�0�� ���� ���������� �� �������0�0�� �0������ ���������������������� �� �0������ �� ������������������ �� �� �@���� ���������������� ������ ������ �� ������������ ���������� �� �� �0�0���������������� ������ �� �������������������������������� �������`���������������� �0�� �� �������������� ���� �� ���������� �� ���������`�������������� �@�@�@�� �������������������� �������� �0�����������0���������������� �� �0�@�� ���������� �� ������ ������ �@�@�����������`�������������� �� �0�� �� �������� �� �� �0�� �������� �� �0�0�� ���������0�0�� ������������ �� �� �������� �@�0�@�@�� ������ �� �@�@�� �� ���������0�@�0�� �������������������� �@�`�`�0�@�� ������ �0�@�0�� �� ���� �� �� �`�@�@�� �� ���� �������������@�@�@�`�@�� �� ������ �0�0�@�0�����0�@�0�`�0�@�0�� �����������������@�`�0�� �@�� �� ������ �� �@�0�� ������ �@�0�`�� �� �� ���������0�� �@�@�`�`�@���������������� �@�0�� ���� �� �� �� �0�0�������������� �0�@�0�0�@�� �������������������������������������0�0�`�@�0���� �� �`�`�� �� �0�@�� �0�0�`�@�`�� �� �0�� �� �0�0�� �@�0�@�0
BM6������6���(��� ��� �������������������������0������������ �� �� �� �0�� �0�0�������������������� �� �� �������� ���0�0������������ �0�� �@�@�@�� �������������0�0�� �� �@�@�� �� �������� �0�0������ ������ �� �@�� �� ������������ �0�0�� ���@�@�`�@�@�� �������� �0�@���� �0�� �����������������������0�������� �� �� �@�`�@���� ������ �� �0���0�0�������������������������0�������0�0�@�0�� �� �@�����������0���� �0�� �� �� �� ���������� �0�� �0�� ���������� �0�� �� ���0�@���������0���0�� �0�@�� �0�� ������ �0�� �0�� ������������������ �����0�@�0�����@�� �� �0�@�@�@�� �0�����0�� �0�� �� ���� ���� �������� ���� �@�@�@�0�0���0�� �0�� �0�@�@�� �0������ �0�0�������� �� �0�� �������� �@�@�`�`�@�� ���@�� �@�� �� �� �� �@�� �0���� �� �0�������� �0�� �0�0�������`�@�@�`�@�0���@���� �������������0�� ���������������� �����0�������@�`�`�@�0�� ���0�������������������0�� �� �� �� �������������� �0�����������0�� �� �������������������������0�0�0�� �� �������������0�� �@�����0�0�������0�������� �� �� ���������� �� �@�0�0�� ������������ �@�0�0�0�@���������@������ �@�@�@�0�������� �� ���0�� �� �� ������������ �@�@�0�@�@�0�����@�� ���0�@�0�@�0�0�0�0���������0�0�� ������������ �� �0�0�� ���� �0�������� �� �0�� �0�� �������0�� �������� ���� �������� �� �0�� �� ������ �0�� �0�� �� ���� �� �������������0�� ���� �@�� ���� ���������� �� �������0�0�� �@������ �������������������0�0�@�`�@�� �� �� �������������������� �� �� ���� �������� �� �� �0�� �������� �`�@�`�� ������ ���� �� �� ���������� �0�@������ �� �� �0�0�� �0���� ������ �@�@�0�0�������� �� �0�@�� ������������ ���� �� ������ �0�� �0�� �� �������� �0�� �� �����0�0�� �� �0�@�� ���������� �0�0�0�@�0���� �0�0�@�� �������������������� �� �@�0�� �� �@�� ���������0�@�`�@�@�0���� �� �0�@�� ���������� �� �������� �0�� �0�@���� �������� �0�@�`�`�@�@�0�� �0�� �� �������� �� �� �0�� ������ �� �� �� �� �����������@�0�@�`�@�`�@���� �� �� �������� �@�0�@�@�� ������������ �������������� �@�0�@�@�@�0�������������� �� �@�0�0�@�� �� ���������� �������� �� �� �@�@�0�0�0���@�������������� ���@�@�@�� �� �0�0�� �������������0�@�0�� �0�@�0�� ���� �@�@�0�����������0�� �@�� �� �����0�� ���0�� ������ �@�0�@�� �� �� ���������0�@�� �@�� ���������������������0�0�� ���� �� �� �� �0�0�������������� �0�@�0�0�@�� �������������������������������������0�0�@�0�0���@�@�� �0�� �� �0�0�@�0�0���0�@�0�������@�0�@�0���@�@�0
BM6������6���(��� ��� �������������������������� ������������ �� �� �� �0�� �0�0�������������������� �� �� �������� ���0�@������������ �0�� �@�@�@�� �������������0�0�� �� �@�@�� �� �������� �0�0������������ �� �@�� �@���������������������@�`�`�@�0�� �������� �0�@�������������������0�@�@���������������� �� �`�`�`�`�@�0������ �� �������������������������0�@�������������0�0�@�`�@�0�@�������������������� �� �� �� ���������� �@�� �0�� ���������� �0�� �� ���@���������������� �� �� �@�� �0�� ������ �0�@�0�� ������������������ ���� �@�@�� �����0�� �� �0�@�@�@�� �0�����@�@�0�� �� ���� ���� �������� ���� �� �0�@�0�0���0�� �0�� �0�`�@�� �0�������0�0�������� �� �0�� �������� �� �@�� �0�@�� ���`�� �@�� �� �@�� ������������ �0�������� �0�� �0�0�������@�@�0�@�@�0���`���� �� �@���������������������������� �������������� �0�@�@�0�� ���@�����@�� �����������0�� �� �� �� ������������������������������ �� �������� �`�� �������������0�0�0�� �� �����������������@�������������������� �`�� �� �� ���������� �� �@�0�0�� ������������ �@�0�0�� �����������0���� �@�`�@�@�� �������� �� �@�0�� �� �� ������������ �@�@�� �����������@�� ���0�@�0�@�0���������� �@�0�0�0�� ������������ �� �0�0������ �0���@���� �� ���������0������ �� �� �@�@�@�0�� �������� �� �0�� �� ������ �0�� ���� �� �������� �� ���� ���� ���� �0�@�0�� ���� ���������� �� �������0�@�� �������� �� �� �0�����0�0�������� �� �0������ �� �������������������@�� �0���� �� ���0�@�@�0���0������ ���������������� ���� �� �� �����0�@�@�0�`�������0�� �@�`�@�������� �������������������� �� �0�@�� �@�@�0�����@�������0�0�@�@�`�0���� �������������������0�0�� �� �0�@�� ���������0������ �� �� �0�� �� ���@�� ���������� �0�������� �� �@�0�� �� �@�� �������@������������ ������ �0�@�� ���������� �� �������� �0�� �0�@���� �������0�� ������������ �� �0�� �� �������� �� �� �0�� ������ �� �� �� �� �����������0�� ���� ���������� �� �� �������� �@�0�@�@�� ������������ �������������@���� �� �0�@���������������� �� �@�`�0�@�� �� ���������� �������� �� �� �`�������0�@�@�������������� ���@�@�@�� �� �0�0�� �������������0�@�0�`�������� �� �@�@�0�� ���� �� �����0�� �@�� �� �����0�� ���0�� ������ �@�0�`������������ �� �@�0�� �������������������������0�0�� ���� �� �� �� �0�@���������������������������������������������������������������0�0�0���0�0�`�`�0�0�@�0��0�`�`�0�@�0�0�����0�`�`�0���0�����0�0�0
BM6������6���(��� ��� �������������������������� ������������ �� �� �� �0�� �0�0�������������������� �� �� �������� ���0�@������������ �0�� �@�@�@�� �������������0�0�� �� �@�@�� �� �������� �0�0������������ �� �@�� �� ������������ �0�0�� ���@�@�� �0�� �� �������� �0�`���������������@������������������������ �� �� �@�0�0���� ������ �� �@�������������0�0�����������������������0�0�@�0�� �� �������������0�������� �� �@�� ���������� �0�� �0������������ �0�� �� ���������������0���� �� �����@���� ������ �0�� �0�� ������������������ �������� �� ������ �� �� �����0�@���������0�� �0�� �� ���� ���� �������� ���� �� �0�@�0�0���0�� �0���0�`�@�`�0������ �0�0�������� �� �0�� �������� �� �@�� �0�@�� ���`�� �@�� ���@�`�`�@���������0�������� �0�� �0�0���0�@�@�@�0�@�@�0���`���� �����0�`�`�@�0������������������ ���������@�0�� �0�@�@�0�� ���`���������0�@�@�0���������� �� ���������������0�@������������ �@���@�����������������������0�0�� �� �����������@�0�`�@���������@�`���0�������� �� �� ���������� �� �@�0�0�� ���0�@�@�0�@�0�@�0�� �����`�����@������ �� �`�@�� �������� �� �`�0�� �� �@�@�������0�� �@�@�� �0�@�@�����@�� ���0�@�0�@�0���������� �`�`�0�0�@������������ �� �0�0�� ���� �0���`���� �� �0�� �0�� �0�������� �� �@�`�@�0�� �������� �� �0�� �� ������ �0�� �`�� �� ���� �� �� ���0���������� �0�@�0�� ���� ���������� �� �������0�0�� �@������ ���������0�� ���������� �� �0������ �� �������������������� �� �� ���� �������� �� �� �0�� ������ ������ �� �������� ���� �� �� ���������� �0�`���������� �0�0�� �0���� �� �������0������������ �� �0�@�� �����������0������������ �� �� �0�� �� �������������������0�0�� �� �0�`�� ���������`�������������� �@�@�@�� ���������� ���������� �� �@�0�@�`�@�� �������@���������������� �� �0�@�� ���������� ���������� �@�@�`�@���� ���0���0�������������� �� �0�� �� �������� �� �� �0�� ���@�`�@�`�@�0���@�0�����@���� �����������0�� �� �������� �@�0�@�@�� �@�@�@�`�@�`�0�@�0�@������ ���0�� ���������0�� �������� �� �@�0�0�@�� �@�@�`�@�`�@�0�����0�@�� �@�� �0�@�� �������� �0�������� ���@�@�@�� �� �0�0�@�`�@�0�������0�@�0�`�� �0�@�� ���������������������0�� �@�� �� �����0�@�@�0�� ������ �@�0�`���� �� ���������������������������������������0�0�� ���� �� �� �� �0�0���������������������������������������������������������������0�0�`�`�0�@�0�0�@�0�@�@�0�� �0�0�� �`�`�`�@�0�@�@�0�� �0�`�`�� �� �0
BM6������6���(��� ��� �������������������������� ���������� �� �� �� �� �0�� �0�0�������������������� �� �� �������� ���0�0�������� ���� �0�� �@�@�@�� �������� �0�@�0�0�� �� �@�@�� �� �������� �0�� ������������ �� �@�� �� �������� ���0�@�� �� ���@�@�� �0�� �� �������� �0�@���� �� �����������������0�0�0�@�@�������� �� �� �@�0�0���� ������ �� �@������ �� �������������0�@�0�@�0���������0�0�@�@�0�� �������������`�������� �� �� �� �������@�0�`�`�@�� ���������� �0�@�0���������������`���� �� �� �@�� �0�� �����0�@�`�`�@���������������@�� �������� �� ������ �� �� �0�@�@�@�� �0�����0�`�@�0�� ���� ���� �����@�� ���� �� �0�@�0�0���@�� �0�� �0�@�@�� �0������ �0�@�������� �� �0�� �@�0���� �� �@�� �0�@�� ���� �� �@�� �� �� �� �@�� �0���� �� �0�������� �0�� �0�@�������@�@�0�@�@�0���� ���� �����0�0�0�0�� �� ���������������� ���0�@�0�0���� �0�@�@�0�� ���`�������0�0�@�0�@�@�0�� �� �� �� ���������0�`�`�@�@�0���������� �� ���`�� �������0�@�@�`�@�0�� �0�0�� �� �������0�@�@�`�`�@���������������@�������� �0�@�`�@�`�@�� �� �@�0�0�� �����0�0�@�`�`�0�0�� �����������0������ �@�`�@�@�`�@���� �� �@�0�� �� �� �����0�0�@�@�@�@�� ������������0�� ���0�@�0�@�`�@�`�0���� �@�0�0�0�� ���������0�� �� �0�0�� �����0���@���� �� �0�� �0�� �0�0�0���� �� �@�@�@�0�� �������� �� �0�� �� ������ �0�� ��0�� �� ���� �� �� ���0���������� �0�@�0�� ���� ���������� �� �������0�0�� �`��0���� ���������������������� �� �0������ �� �������������������� �� �`���� �������� �� �� �0�� �����0�0�0�0�0�������� ���� �� �� ���������� �0�@���������� �0�0�� �0���0�� �@�`�@�@�� ���������� �� �0�@�� ������������ ������������ �0�� �0�� �� �@�`�@�`�@�0�� �����0�0�� �� �0�@�� ���������@�������0�0�0�0�@�@�@�� �@�`�@�@�0�� �������� �� �@�0�� �� �@�� �������@�� �0�0�� ���� ���� �� �0�@�� �@�`�@�0�� �� �������� �0�� �0�@���� �������� �������� �� �@�@�� �0�� �� �������� �� �� �0�� ������ �� �� �� �� ������������ �0�� ������ �@�`�@�� �� �������� �@�0�@�@�� ������������ ���������������0�0�� ���@�`�`�@�� �������� �`�@�0�0�@�0�0�� �������� �������� �� �� ���0�@�� �� �� �@�@�@�� �� ������ ���@�`�@�� �� ���0�� �������������0�@�0�� �0�@�0�� ���� �� ���������������0�� �@�� �� �������� �0�0�� ������ �@�0���� �� �� ���������0�� �@�@�� ������������������������ �� �0�0�� �� �� �0�0�������������������0�0�����������������������������������������0�� �0�@�`�`�0�� ��0�0�@���0�@���� �@�0�0�@�0���@�@�`�`�@���0���0��
BM6������6���(��� ��� �������������������������`������������ �� �� �� �0�� �0�0�������������������� �� �� �������� ���0�0������������ �0�� �@�@�@�� �������������0�0�� �� �@�@�� �� �������� �0�`������������ �� �@�� �� ������������ �0�0�� ���@�@�� �0�� �� �������� �0�@�������������������������������0�������� �� �� �@�0�0���� ������ �� �`�������������������������������0�������0�0�@�0�� �� �������������@�������� �� �� �� ���������� �0�� �0�� ���������� �0�� �� ���������������@���� �� �� �@�� �0�� ������ �0�� �0�� ������������������ �������� �� �����`�� �� �0�@�@�@�� �0�����0�� �0�� �� ���� ���� �������� ���� �� �0�@�0�0���`�� �0�� �0�@�@�� �0������ �0�0�������� �� �0�� �������� �� �@�� �0�@�� ���`�� �@�� �� �� �� �@�� �0���� �� �0�������� �0�� �0�0�������@�@�0�@�@�0���0���� �������������0�� ���������������� �����0�������� �0�@�@�0�� �����������������������0�� �� �� �� �������������� �0�������������� �� �������������������������0�0�0�� �� �������������0�� �@���������������@�������� �� �� ���������� �� �@�0�0�� ������������ �@�0�0�� �����������@������ �@�@�@�� �������� �� �@�0�� �� �� ������������ �@�@�� �0�0�0�����`�� ���0�@�0�@�0���������� �@�0�0�0�� ������������ �� �0�0�� ���� �0���`���� �� �0�� �0�� �0�������� �� �@�@�@�0�� �������� �� �0�� �� ������ �0�� �0�� �� ���� �� �� ���0���������� �0�@�0�� ���� ���������� �� �������0�0�� �0������ ���������0�� ���������� �� �0������ �� �������������������� �� �`���� �������� �� �� �0�� ������ ������ �� �������� ���� �� �� ���������� �0�`���������� �0�0�� �0���� �� �������0������������ �� �0�@�� �����������@������������ �� �� �0�� �� ���������0���������0�0�� �� �0�@�� ���������0�������������� �@�@�@�� ���������� �0�������� �� �@�0�� �� �@�� �������@���������������� �� �0�@�� ���������� �� �������� �0�� �0�@���� �������0�������������� �� �0�� �� �������� �� �� �0�� ������ �� �� �� �� �����������@���� ������������ �� �� �������� �@�0�@�@�� ������������ �������������0���0�� �������������������� �� �@�0�0�@�� �� ���������� �������� �� �� �@���@�� �� ���� �������������� ���@�@�@�� �� �0�0�� �������������0�@�0�`���@�0�� ���������������������0�� �@�� �� �����0�� ���0�� ������ �@�0�`���� �� ���������0�� �� �@�� ���������������������0�0�� ���� �� �� �� �0�0�������������� �0�@�0�0�@�� �������������������������������������@�`�`�@�0���� �`�� �`�� �`�0�`���@�0�@�@�0�`�`�`�0�`�@�`�0�@�`�@�0
%name demon
%prefix TILE
%rim 1
%sdir dc-mon/demon
demon_body_fat DEMON_BODY
demon_body_fatter
demon_body_normal
demon_body_spiked
demon_body_spotty
demon_body_thin
demon_head_cthulhu DEMON_HEAD
demon_head_elephant
demon_head_eyeball
demon_head_heads
demon_head_helmet
demon_head_horns
demon_head_horse
demon_head_medusa
demon_head_monkey
demon_head_mouse
demon_head_ram
demon_head_rhino
demon_head_tentacles
demon_wings_bones DEMON_WINGS
demon_wings_butterfly
demon_wings_demonic
demon_wings_large
demon_wings_medium
demon_wings_red
%corpse 0
EXTRA_INCLUDES += -I$(RLTILES)
OBJECTS += $(RLTILES)/tiledef-demon.o $(RLTILES)/tiledef-dngn.o $(RLTILES)/tiledef-main.o $(RLTILES)/tiledef-player.o
TILEFILES = \
main.png \
player.png \
demon.png \
dngn.png
DESTTILEFILES = $(TILEFILES:%=dat/tiles/%)
EXTRA_DEPENDS += $(DESTTILEFILES)
TILEFILES = \
tile.png \
player.png \
title.png \
dngn.png
DESTTILEFILES = $(TILEFILES:%=dat/tiles/%)
EXTRA_DEPENDS += $(TILEHEADERS) $(DESTTILEFILES)
cd $(RLTILES) && make -f makefile.unix all CFLAGS="$(PNG_INCLUDE)" LDFLAGS="$(PNG_LIB)" && cd ..
$(TILEHEADERS): $(ORIGTILEHEADERS)
$(COPY) $(RLTILES)$@ .
cd $(RLTILES) && make -f makefile.unix all
env.tile_flv(c).wall = tile_DNGN_start[IDX_WALL_UNDEAD]
+ random2(tile_DNGN_count[IDX_WALL_UNDEAD]);
env.tile_flv(c).wall = TILE_WALL_UNDEAD
+ random2(tile_dngn_count[TILE_WALL_UNDEAD]);
env.tile_flv(c).floor = tile_DNGN_start[IDX_FLOOR_NERVES]
+ random2(tile_DNGN_count[IDX_FLOOR_NERVES]);
env.tile_flv(c).floor = TILE_FLOOR_NERVES
+ random2(tile_dngn_count[TILE_FLOOR_NERVES]);