summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/rltiles/tool
diff options
context:
space:
mode:
authorennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-05 01:33:53 +0000
committerennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-05 01:33:53 +0000
commit62f7040f14b39e67042be98f951575fbc819e84e (patch)
treed4fa0598a1bee1d34fff81e2c150de08c2256753 /crawl-ref/source/rltiles/tool
parent19155f1f85058ef9d65d11e60c63cc69c36d4e8a (diff)
downloadcrawl-ref-62f7040f14b39e67042be98f951575fbc819e84e.tar.gz
crawl-ref-62f7040f14b39e67042be98f951575fbc819e84e.zip
Tiles!
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3194 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/rltiles/tool')
-rw-r--r--crawl-ref/source/rltiles/tool/bm.c558
-rw-r--r--crawl-ref/source/rltiles/tool/bm.h26
-rw-r--r--crawl-ref/source/rltiles/tool/dcpl.c581
-rw-r--r--crawl-ref/source/rltiles/tool/dcqv.c847
-rw-r--r--crawl-ref/source/rltiles/tool/dcreverse.c216
-rw-r--r--crawl-ref/source/rltiles/tool/dctile.c642
-rw-r--r--crawl-ref/source/rltiles/tool/mkmap.c408
-rw-r--r--crawl-ref/source/rltiles/tool/mkmapq.c783
-rw-r--r--crawl-ref/source/rltiles/tool/palette.h355
-rw-r--r--crawl-ref/source/rltiles/tool/shade.c254
10 files changed, 4670 insertions, 0 deletions
diff --git a/crawl-ref/source/rltiles/tool/bm.c b/crawl-ref/source/rltiles/tool/bm.c
new file mode 100644
index 0000000000..cd208cecb2
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/bm.c
@@ -0,0 +1,558 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "palette.h"
+
+char cpath[1024];
+/*** PATH separator ***/
+
+#if defined(_WIN32)|| defined(WINDOWS)
+#define PATHSEP '\\'
+#else
+#define PATHSEP '/'
+#endif
+
+void process_cpath(char *path){
+ int i, pos;
+#ifdef LINUX
+ cpath[0]=0;
+ return;
+#endif
+ pos = 0;
+ cpath[0]=0;
+ printf("path=%s\n",path);
+ for(i=0;i<strlen(path);i++)if(path[i]==PATHSEP)pos=i;
+
+ if(pos!=0){
+ pos++;
+ strncpy(cpath,path,pos);
+ cpath[pos]=0;
+ printf("pos=%d\n",pos);
+ }
+}
+
+void fixalloc(char *buf[3], int size)
+{
+ buf[0]=malloc(size);
+ buf[1]=malloc(size);
+ buf[2]=malloc(size);
+}
+
+#if 0
+#define WORD unsigned short
+#define DWORD unsigned int
+
+ typedef struct tagBITMAPFILEHEADER {
+ WORD bfType; // 常に"BM"
+ DWORD bfSize; // ファイルサイズ
+ WORD bfReserved1; // 0に設定
+ WORD bfReserved2; // 0に設定
+ DWORD bfOffBits; // DIB形式ファイルの先頭からピクセルデータ領
+ } BITMAPFILEHEADER;
+
+ typedef struct tagBITMAPINFOHEADER {
+ DWORD biSize; // この構造体のサイズ
+ DWORD biWidth; // 幅(ピクセル単位)
+ DWORD biHeight; // 高さ(ピクセル単位)
+ WORD biPlanes; // 常に1
+ WORD biBitCount; // 1ピクセルあたりのカラービットの数
+ DWORD biCompression; // BI_RGB, BI_RLE8, BI_RLE4のいずれか
+ DWORD biSizeImage; // イメージの全バイト数
+ DWORD biXPelsPerMeter; // 0または水平解像度
+ DWORD biYPelsPerMeter; // 0または垂直解像度
+ DWORD biClrUsed; // 通常は0、biBitCount以下のカラー数に設定可
+ DWORD biClrImportant; // 通常は0
+ } BITMAPINFOHEADER;
+#endif
+
+#define NHASH 512
+#define HASHMAX 100
+int hashflag;
+
+int hashn[NHASH];
+int hashtab[NHASH][HASHMAX][4];
+#define RGB2H(r,g,b) ( ((r)>>5)|(((b)>>5)<<3)|(((g)>>5)<<6) )
+int palr[256],palg[256],palb[256];
+
+unsigned int rev16(unsigned char *x)
+{
+ int r=x[1];
+ r = (r<<8)|x[0];
+ return r;
+}
+unsigned int rev32(unsigned char *x)
+{
+ int r=x[3];
+ r = (r<<8)|x[2];
+ r = (r<<8)|x[1];
+ r = (r<<8)|x[0];
+ return r;
+}
+
+/***** BMP read *****/
+int bmread(char *fn, int *x, int *y, unsigned char *buf3[3])
+{
+unsigned char bmHead[14];
+unsigned char bmInfo[40];
+
+unsigned char pbuf[1024];
+int i,j,k;
+int xx,yy,x0,y0;
+FILE *fp;
+unsigned char *b0;
+int bits, ofbits;
+
+if(NULL==(fp=fopen(fn,"rb")))
+{
+ //printf("no file %s:",fn);
+ return(1);
+}
+ fread(&bmHead,1,14,fp);
+ fread(&bmInfo,1,40,fp);
+
+xx=rev32(&bmInfo[4]);
+yy=rev32(&bmInfo[8]);
+bits=rev16(&bmInfo[14]);
+
+//fprintf(stderr, "wx = %d wy = %d\n",xx,yy);
+
+if(!buf3[0])buf3[0]=malloc(xx*yy);
+if(!buf3[1])buf3[1]=malloc(xx*yy);
+if(!buf3[2])buf3[2]=malloc(xx*yy);
+
+ofbits = rev32(&bmHead[10]);
+
+if(bits==24){
+fseek(fp, ofbits, SEEK_SET);
+
+b0=malloc(xx*yy*3);
+fread(b0,1,3*xx*yy,fp);
+fclose(fp);
+j=0;
+ for(y0=yy-1;y0>=0;y0--){
+ for(x0=0;x0<xx;x0++){
+ i=y0*xx+x0;
+ k=b0[j];j++; buf3[2][i]=k;
+ k=b0[j];j++; buf3[1][i]=k;
+ k=b0[j];j++; buf3[0][i]=k;
+ }}
+free(b0);
+*x=xx;*y=yy;
+return(0);
+}
+
+ if(bits==4){
+b0=malloc(xx*yy/2);
+k=ofbits -54;
+k/=4;
+fread(pbuf,1,k*4,fp);
+fread(b0,1,xx*yy/2,fp);
+fclose(fp);
+
+j=0;
+for(y0=yy-1;y0>=0;y0--){
+for(x0=0;x0<xx;x0++){i=y0*xx+x0;
+if(j&1) k=b0[j/2]&0x0f;
+ else k=b0[j/2]>>4;
+j++;
+
+
+buf3[0][i]=pbuf[ k*4+2 ];
+buf3[1][i]=pbuf[ k*4+1 ];
+buf3[2][i]=pbuf[ k*4+0 ];
+}}
+free(b0);
+*x=xx;*y=yy;
+return(0);
+
+ }
+
+
+
+b0=malloc(xx*yy);
+//k=buf[46]+buf[47]*256;
+k=ofbits -54;
+fread(pbuf,1,k,fp);
+fread(b0,1,xx*yy,fp);
+fclose(fp);
+
+j=0;
+for(y0=yy-1;y0>=0;y0--){
+for(x0=0;x0<xx;x0++){i=y0*xx+x0;
+k=b0[j];j++;
+buf3[0][i]=pbuf[ k*4+2 ];
+buf3[1][i]=pbuf[ k*4+1 ];
+buf3[2][i]=pbuf[ k*4+0 ];
+}}
+free(b0);
+*x=xx;*y=yy;
+return(0);
+}
+
+
+void forcereg(i) int i;{
+int h,n,r,g,b;
+r=palr[i];
+g=palg[i];
+b=palb[i];
+
+h=RGB2H(r,g,b);
+n=hashn[h];
+hashtab[h][n][0]=i;
+hashtab[h][n][1]=r;
+hashtab[h][n][2]=g;
+hashtab[h][n][3]=b;
+n++;
+hashn[h]=n;
+}
+
+void reg_rgb(int i, int r, int g, int b)
+{
+int h,n;
+
+h=RGB2H(r,g,b);
+n=hashn[h];
+hashtab[h][n][0]=i;
+hashtab[h][n][1]=r;
+hashtab[h][n][2]=g;
+hashtab[h][n][3]=b;
+n++;
+hashn[h]=n;
+}
+
+int cidx(r,g,b) int r,g,b;{
+int r2,r2min,i,h,n,ix,dr,dg,db;
+
+ ix = -1;
+ if(hashflag){
+ h=RGB2H(r,g,b);
+ n=hashn[h];
+ for(i=0;i<n;i++)
+ {
+ if( (r==hashtab[h][i][1])&&(g==hashtab[h][i][2])&&(b==hashtab[h][i][3]) )
+ {
+ ix=hashtab[h][i][0];
+ break;
+ }
+ }
+ }
+
+ if(ix==-1){
+ r2min=100000000;
+ for(i=0;i<256;i++)
+ {
+ dr=palr[i]-r;
+ dg=palg[i]-g;
+ db=palb[i]-b;
+ r2=(dr*dr+dg*dg+db*db);
+ //r2+=(dr+dg+db)*(dr+dg+db);
+ if(r2<r2min){ ix=i;r2min=r2;}
+ }
+
+ if(hashflag==1){
+ fprintf(stderr,"Color %02x%02x%02xapproximated\n",r,g,b);
+
+ hashtab[h][n][0]=ix;
+ hashtab[h][n][1]=r;
+ hashtab[h][n][2]=g;
+ hashtab[h][n][3]=b;
+ n++;
+ hashn[h]=n;
+ if(n==HASHMAX)
+ {
+ fprintf(stderr,"HASHMAX exceed! Turning hash off\n");
+ hashflag=0;
+ }
+ }
+ }
+return(ix);
+}
+
+void put4(i,fp) int i;FILE *fp;{
+fputc( ((i>> 0)&0xff) ,fp);
+fputc( ((i>> 8)&0xff) ,fp);
+fputc( ((i>>16)&0xff) ,fp);
+fputc( ((i>>24)&0xff) ,fp);
+}
+
+void put2(i,fp) int i;FILE *fp;{
+fputc( ((i>> 0)&0xff) ,fp);
+fputc( ((i>> 8)&0xff) ,fp); }
+
+void bmwrite(char *fn, int x, int y, unsigned char *buf3[3])
+{
+FILE *fp;
+int i,j,k,xx,yy;
+
+hashflag=1;
+if(fn[0]==0) fp=stdout; else fp=fopen(fn,"wb");
+if (!fp)
+{
+ printf("Error opening %s.\n", fn);
+ exit(-1);
+}
+fputc('B',fp);fputc('M',fp);
+put4(1024+54+x*y,fp);
+put4(0,fp);
+put4(0x436,fp);
+put4(0x28,fp);
+put4(x,fp); put4(y,fp);
+put2(1,fp);put2(8,fp);
+put4(0,fp);put4(x*y,fp);put4(0xb6d,fp);put4(0xb6d,fp);
+put4(256,fp);put4(256,fp);
+fwrite(pbuf,1,1024,fp);
+for(yy=y-1;yy>=0;yy--){
+for(xx=0;xx<x;xx++){i=yy*x+xx;
+k=cidx( buf3[0][i],buf3[1][i],buf3[2][i] );fputc(k,fp);}}
+fclose(fp);}
+
+void bmwrite24(char *fn, int x, int y, unsigned char *buf3[3])
+{
+FILE *fp;
+int i,xx,yy;
+
+if(fn[0]==0) fp=stdout; else fp=fopen(fn,"wb");
+
+fputc('B',fp);fputc('M',fp);
+put4(54+3*x*y,fp);
+put4(0,fp);
+put4(54,fp);
+put4(0x28,fp);
+put4(x,fp); put4(y,fp);
+put2(1,fp);put2(24,fp);
+put4(0,fp);put4(x*y*3,fp);put4(0xb6d,fp);put4(0xb6d,fp);
+put4(0,fp);put4(0,fp);
+for(yy=y-1;yy>=0;yy--){
+for(xx=0;xx<x;xx++){i=yy*x+xx;
+fputc(buf3[2][i],fp);
+fputc(buf3[1][i],fp);
+fputc(buf3[0][i],fp);
+}}
+fclose(fp);}
+
+
+void bmwrite_dither(char *fn, int x, int y, unsigned char *buf3[3],
+ unsigned char *flag)
+{
+ FILE *fp;
+ int i,j,k,xx,yy;
+ int *err_c[3], *err_n[3];
+ unsigned char *buf;
+ int dx,idat[3],udat[3],putdat[3],err[3];
+
+ fprintf(stderr,"Saving %s x=%d y=%d\n",fn,x,y);
+
+ for(i=0;i<3;i++){
+ err_c[i]=malloc(sizeof(int)*(x+2));
+ err_n[i]=malloc(sizeof(int)*(x+2));
+ for(j=0;j<x+2;j++)err_c[i][j]=err_n[i][j]=0;
+ }
+ buf=malloc(x*y);
+
+for(yy=0;yy<y;yy++){
+//fprintf(stderr,"Y=%d x=%d\n",yy,x);
+
+ for(i=0;i<3;i++){
+ for(j=0;j<x+2;j++){err_c[i][j]=err_n[i][j];err_n[i][j]=0;}}
+
+
+if((yy&1)==0){//even
+
+for(xx=0;xx<x;xx++){
+int do_ep = 1;
+idat[0] = buf3[0][ xx+yy*x];
+idat[1] = buf3[1][ xx+yy*x];
+idat[2] = buf3[2][ xx+yy*x];
+for(i=0;i<3;i++) {idat[i] += err_c[i][xx+1];
+udat[i]=idat[i];if(udat[i]<0)udat[i]=0;
+if(udat[i]>255)udat[i]=255;}
+
+if(buf3[0][xx+yy*x]==0x47 && buf3[1][xx+yy*x]==0x6c && buf3[2][xx+yy*x]==0x6c)
+ do_ep=0;
+if (flag!=NULL)
+{
+ if (flag[xx+yy*x]==0) do_ep=0;
+}
+if (do_ep == 0)
+k=cidx( buf3[0][xx+yy*x],buf3[1][xx+yy*x],buf3[2][xx+yy*x]);
+else
+k=cidx( udat[0],udat[1],udat[2]);
+
+buf[xx+yy*x]=k;
+//fprintf(stderr,"Y=%d xx=%d\n",yy,xx);
+
+putdat[0]=palr[k];
+putdat[1]=palg[k];
+putdat[2]=palb[k];
+for(i=0;i<3;i++) {
+ err[i]=(idat[i]-putdat[i]+8)/16;
+ //if(flag[xx+yy*x]!=1)err[i]=0;
+ err_c[i][xx+1+1] += err[i]*7;
+ err_n[i][xx-1+1] += err[i]*3;
+ err_n[i][xx+0+1] += err[i]*5;
+ err_n[i][xx+1+1] += err[i];
+}/**i**/
+}/**x**/
+}else{
+for(xx=x-1;xx>=0;xx--){
+int do_ep=1;
+idat[0] = buf3[0][ xx+yy*x];
+idat[1] = buf3[1][ xx+yy*x];
+idat[2] = buf3[2][ xx+yy*x];
+for(i=0;i<3;i++) {idat[i] += err_c[i][xx+1];
+udat[i]=idat[i];if(udat[i]<0)udat[i]=0;
+if(udat[i]>255)udat[i]=255;}
+
+if(buf3[0][xx+yy*x]==0x47 && buf3[1][xx+yy*x]==0x6c && buf3[2][xx+yy*x]==0x6c)
+ do_ep=0;
+if (flag!=NULL)
+{
+ if (flag[xx+yy*x]==0) do_ep=0;
+}
+if (do_ep == 0)
+k=cidx( buf3[0][xx+yy*x],buf3[1][xx+yy*x],buf3[2][xx+yy*x]);
+else
+k=cidx( udat[0],udat[1],udat[2]);
+
+buf[xx+yy*x]=(unsigned char)k;
+putdat[0]=palr[k];
+putdat[1]=palg[k];
+putdat[2]=palb[k];
+for(i=0;i<3;i++) {
+ err[i]=(idat[i]-putdat[i]+8)/16;
+ //if(flag[xx+yy*x]!=1)err[i]=0;
+
+ err_c[i][xx-1+1] += err[i]*7;
+ err_n[i][xx+1+1] += err[i]*3;
+ err_n[i][xx+0+1] += err[i]*5;
+ err_n[i][xx-1+1] += err[i];
+}/*i*/
+}/*x*/
+
+}/*else*/
+}/*y*/
+
+for(i=0;i<3;i++){
+free(err_c[i]);
+free(err_n[i]);}
+
+if(fn[0]==0) fp=stdout; else fp=fopen(fn,"wb");
+fputc('B',fp);fputc('M',fp);
+put4(1024+54+x*y,fp);
+put4(0,fp);
+put4(0x436,fp);
+put4(0x28,fp);
+put4(x,fp);put4(y,fp);
+put2(1,fp);put2(8,fp);
+put4(0,fp);put4(x*y,fp);put4(0xb6d,fp);put4(0xb6d,fp);
+put4(256,fp);put4(256,fp);
+fwrite(pbuf,1,1024,fp);
+for(yy=y-1;yy>=0;yy--){
+for(xx=0;xx<x;xx++){i=yy*x+xx; fputc(buf[i],fp);}}
+fclose(fp);
+free(buf);
+
+}/** exit**/
+
+
+void myfget(ss,fp) char *ss;FILE *fp;{
+#define STRMAX 200
+/****
+int ix=1;
+while(1){ ss[0]=getc(fp);
+ if( ((ss[0]!=32)&&(ss[0]!='#'))||(feof(fp)))break;
+ if(ss[0]=='#') fgets(ss,99,fp);}
+
+while(1){
+ ss[ix]=getc(fp);ix++;
+ if( (ss[ix-1]<33)||(ix==STRMAX)||(feof(fp)) )break;}
+ss[ix-1]=0;printf("%s\n",ss);
+****/
+int l;
+while(1){
+ fgets(ss,STRMAX,fp);
+ if(feof(fp)){fprintf(stderr,"FILE EOF\n");return;}
+ if(ss[0]=='#')continue;
+ if(ss[0]<32)continue;
+ break;
+}
+ l=strlen(ss);ss[l-1]=0;
+}
+
+void oldcolors()
+{
+int coldat[] = {
+ // Old gold
+ 0xE6, 0x68541f,
+ 0xE7, 0x807020,
+ 0xE8, 0xaa8834,
+ 0xEA, 0xf2c44d,
+ 0xEC, 0xfcfc99,
+
+ 0xe6, 0x604818,
+ 0xe7, 0x806020,
+ 0xe8, 0xa07828,
+ 0xe9, 0xc09030,
+ 0xea, 0xe0a838,
+ 0xeb, 0xffc040,
+ //Old zombie
+ 0xee, 0x756958,
+ 0xef, 0x91876e,
+ 0xf0, 0xab9a81,
+ //Old brass
+ 0xf1, 0xe0c0a0,
+ 0xe9, 0xd0a850
+ -1, -1
+};
+
+ int i=0;
+
+ while(coldat[i]!= -1)
+ {
+ int ix = coldat[i+0];
+ int col= coldat[i+1];
+ int r= col>>16;
+ int g= (col>>8)&0xff;
+ int b= (col)&0xff;
+
+ reg_rgb( ix,r,g,b);
+ palr[ix]=r;
+ palg[ix]=g;
+ palb[ix]=b;
+ i+=2;
+ }
+}
+
+void stdpal(){
+int i;
+
+ for(i=0;i<256;i++){
+ palr[i]=pbuf[i*4+2];
+ palg[i]=pbuf[i*4+1];
+ palb[i]=pbuf[i*4+0];
+ }
+ for(i=0;i<NHASH;i++)hashn[i]=0;
+ for(i=0;i<256;i++)forcereg(i);
+
+ oldcolors();
+}
+
+
+int getval(char *buf, char *tag, int *val)
+{
+ int len = strlen(tag);
+ if(buf[0]!='%') return 0;
+ if (strncmp(&buf[1], tag, len)!=0) return 0;
+ *val = atoi(&buf[len+2]);
+ return 1;
+}
+
+int getname(char *buf, char *tag, char *name)
+{
+ int len = strlen(tag);
+ if(buf[0]!='%') return 0;
+ if (strncmp(&buf[1], tag, len)!=0) return 0;
+ strcpy(name, &buf[len+2]);
+ return 1;
+}
+
diff --git a/crawl-ref/source/rltiles/tool/bm.h b/crawl-ref/source/rltiles/tool/bm.h
new file mode 100644
index 0000000000..8197dd5d4f
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/bm.h
@@ -0,0 +1,26 @@
+#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
+
diff --git a/crawl-ref/source/rltiles/tool/dcpl.c b/crawl-ref/source/rltiles/tool/dcpl.c
new file mode 100644
index 0000000000..ef9b59fb31
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/dcpl.c
@@ -0,0 +1,581 @@
+#include "bm.h"
+
+/** Some global **/
+//Flags
+int corpse, mesh, slant,rim;
+// Files
+FILE *mfp,*sfp;
+//Strings
+char outname[1024], subsname[200], sdir[200];
+char realname[1024];
+
+/** Parts related **/
+int parts_n;
+#define MAXPARTS 20
+int parts_nx[MAXPARTS], parts_ny[MAXPARTS];
+int parts_ox[MAXPARTS], parts_oy[MAXPARTS];
+int parts_start[MAXPARTS], parts_number[MAXPARTS];
+
+char parts_names[MAXPARTS][64];
+
+int parts_comment_ofs[MAXPARTS];
+int n_comments, pos_comment;
+#define MAXTOTAL 1000
+int part_comment_ofs[MAXTOTAL];
+char comment[MAXTOTAL*60];
+
+int part_x,part_y;
+int part_n;
+int part_nx,part_ny;
+char part_name[32];
+int part_wx, part_wy, part_ox, part_oy;
+
+/*** BUFFER MEMORY ***/
+#define XX 30
+int xx0;
+#define LX (XX)
+
+
+/*** tmp buffer, floor , final output, final queue ***/
+unsigned char *tbuf[3],*fbuf[3],*dbuf[3], *obuf[3];
+
+/*** normal floor*/
+#define WOADR(x,y,xx,yy) \
+((x)*32+xx+ xx0*32*((y)*32+yy))
+
+#define ADR(x,y) ((x)+(y)*32)
+
+/*** output width/height in block ***/
+int bx,by;
+
+/****************************/
+/* Wrapper routines ********/
+/**************************/
+int load_pxxx(fnam)
+ char *fnam;
+{
+ int x,y;
+
+ sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,fnam);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+
+ sprintf(realname,"%s%s.bmp",cpath,fnam);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+
+ if(subsname[0])
+ {
+ sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,subsname);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+
+ sprintf(realname,"%s%s.bmp",cpath,subsname);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+ }
+
+ return 1;
+}
+
+
+void clr_buf()
+{
+int xx,yy;
+
+ for(xx=0;xx<32;xx++)
+ {
+ for(yy=0;yy<32;yy++)
+ {
+ dbuf[0][ ADR(xx,yy) ]=0x47;
+ dbuf[1][ ADR(xx,yy) ]=0x6c;
+ dbuf[2][ ADR(xx,yy) ]=0x6c;
+ }
+ }
+}
+
+void cp_floor()
+{
+ int xx,yy,c;
+ for(xx=0;xx<32;xx++)
+ for(yy=0;yy<32;yy++)
+ for(c=0;c<3;c++)
+ dbuf[c][ ADR(xx,yy) ]=fbuf[c][ ADR(xx,yy)];
+}
+
+void cp_monst_32()
+{
+ int xx,yy,c,dd[3],ad;
+ char dflag[33][32];
+ int xmin,xmax,ymin,ymax,ox,oy;
+
+ if(corpse==1 )
+ {
+ xmin=ymin=31;
+ xmax=ymax=0;
+ for(xx=0;xx<32;xx++){
+ for(yy=0;yy<32;yy++){
+ ad=ADR(xx,yy);
+ for(c=0;c<3;c++)dd[c]=tbuf[c][ad];
+ if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
+ if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
+ if(xx<xmin)xmin=xx;
+ if(xx>xmax)xmax=xx;
+ if(yy<ymin)ymin=yy;
+ if(yy>ymax)ymax=yy;
+ }
+ }
+ ox=(xmax+xmin)/2-16;
+ oy=(ymax+ymin)/2-16;
+ }
+
+ /** copy loop **/
+ for(xx=0;xx<32;xx++){
+ for(yy=0;yy<32;yy++){
+ dflag[xx][yy]=0;
+ ad=ADR(xx,yy);
+
+ if(corpse==1)
+ {
+ int x1=xx+ox;
+ int y1=(yy+oy)*2-16;
+ int cy=18;
+ if(xx<4 || xx>=28)cy+=2;else
+ if(xx<12 || xx>=20) cy+=1;
+
+ if(yy>=cy-1 && yy<=cy+0)continue;
+ x1 += (y1-16)/4;
+ if(y1>=cy){y1-=2;x1-=3;}else {y1 +=2;x1+=3;}
+ if(x1<0 || x1>=32 || y1<0 || y1>=32)continue;
+ ad=ADR(x1,y1);
+ }
+
+ /*** normal***/
+ for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
+
+ if(mesh==2)
+ {
+ if( (dd[0]!=0x47)||(dd[1]!=0x6c)|| (dd[2]!=0x6c))
+ {
+ if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
+ }
+ }
+ if(mesh==1)
+ {
+ if((((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
+ }
+
+ if( (dd[0]==0x47)&&(dd[1]==0x6c)&& (dd[2]==0x6c))continue;
+ if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
+
+ for(c=0;c<3;c++) {dbuf[c][ADR(xx,yy)]=dd[c];}
+ dflag[xx][yy]=1;
+ }
+ }/*XY*/
+
+#if 1
+ if(corpse==1)
+ {
+ for(xx=0;xx<32;xx++)
+ {
+ int cy=18;
+ if(xx<4 || xx>=28)cy+=2;else
+ if(xx<12 || xx>=20) cy+=1;
+ if(dflag[xx][cy-2]==1 && dflag[xx][cy+1]==1 )
+ {
+ for(yy=cy-1;yy<=cy-0;yy++)
+ {
+ dbuf[0][ADR(xx,yy)]=32;
+ dbuf[1][ADR(xx,yy)]=0;
+ dbuf[2][ADR(xx,yy)]=0;
+ dflag[xx][yy]=1;
+ }
+ }
+ }
+
+ /** shade**/
+ for(xx=1;xx<32;xx++){
+ for(yy=1;yy<32;yy++){
+ if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==1)
+ {
+ dbuf[0][ADR(xx,yy)]=0;
+ dbuf[1][ADR(xx,yy)]=0;
+ dbuf[2][ADR(xx,yy)]=0;
+ }
+ }
+ }
+
+ for(xx=3;xx<32;xx++){
+ for(yy=3;yy<32;yy++){
+ if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==0
+ && dflag[xx-2][yy-2]==1 && dflag[xx-3][yy-3]==1)
+ {
+ dbuf[0][ADR(xx,yy)]=0;
+ dbuf[1][ADR(xx,yy)]=0;
+ dbuf[2][ADR(xx,yy)]=0;
+ }
+ }
+ }
+
+ }
+#endif
+}
+
+
+void bflush()
+{
+ int xx,yy,c;
+ for(xx=part_ox;xx<part_ox+part_wx;xx++){
+ for(yy=part_oy;yy<part_oy+part_wy;yy++){
+ for(c=0;c<3;c++){
+ obuf[c][WOADR(bx,by,part_x*part_wx+xx-part_ox,part_y*part_wy+yy-part_oy)]
+ = dbuf[c][ADR(xx,yy)];
+ }
+ }
+ }
+}
+
+
+void load_monst(fnam) char *fnam;{
+ if( load_pxxx(fnam)){
+ printf("no file %s.bmp\n",fnam);
+ getchar();
+ exit(1);
+ }
+ cp_monst_32();
+ bflush();
+}
+
+void flush_part()
+{
+
+ if(part_x!=0 || part_y!=0)
+ {
+ part_x=part_y=0;
+ bx++;if(bx==xx0){bx=0;by++;;}
+ }
+ parts_number[parts_n]=part_n;
+ parts_n++;
+
+}
+
+void process_config(char *fname)
+{
+ int i,j;
+ char tmp[100],st[1024];
+ char *nuke;
+ FILE *fp=fopen(fname,"r");
+ if(fp==NULL)
+ {
+ printf("Error no config file %s\nHit return",fname);
+ getchar();
+ exit(1);
+ }
+
+
+ while(1){
+ fgets(tmp,99,fp);
+ if(feof(fp))break;
+ i=0;
+ while(i<99 && tmp[i]>=32) i++;
+ tmp[i]=0;
+
+ if(getname(tmp,"back",st))
+ {
+ /*** Set Background BMP (format "%back bmpname") ***/
+ if(strncmp(st,"none",4)==0)
+ {
+ /** clear **/
+ for(i=0;i<32*32;i++){fbuf[0][i]=0x47;fbuf[1][i]=fbuf[2][i]=0x6c;}
+ }
+ else
+ {
+ load_pxxx(st);
+ for(i=0;i<32*32;i++)for(j=0;j<3;j++)fbuf[j][i]=tbuf[j][i];
+ }
+ continue;
+ }
+
+ if (getname(tmp,"include",st)){
+ char fn2[200];
+ sprintf(fn2,"%s%s",cpath, st);
+ if(strcmp(fname,fn2)!=0) process_config(fn2);
+ continue;
+ }
+
+ if (getval(tmp,"slant",&slant)) continue;
+ if (getval(tmp,"rim",&rim)) continue;
+ if (getval(tmp,"mesh",&mesh)) continue;
+ if (getval(tmp,"corpse",&corpse)) continue;
+ if (getname(tmp,"subst",subsname)) continue;
+ if (getname(tmp,"sdir",sdir)) continue;
+ if (getname(tmp,"name", outname)) continue;
+ if (getval(tmp,"width",&xx0)) continue;
+ /****/
+ if (getname(tmp,"parts_ctg",part_name))
+ {
+ if(part_n!=0)
+ flush_part();
+ part_n=0;
+ strcpy(parts_names[parts_n],part_name);
+ parts_comment_ofs[parts_n] = n_comments;
+ parts_start[parts_n]=bx+by*xx0;
+ fprintf(sfp,"#define TILEP_PART_%s %d\n",part_name, parts_n);
+ fprintf(sfp,"enum %s {\n",part_name);
+ fprintf(sfp," TILEP_%s_000,\n",part_name);
+
+ continue;
+ }
+
+ if (getval(tmp,"parts_wx",&part_wx))
+ {
+ parts_nx[parts_n]=part_nx=32/part_wx;
+ continue;
+ }
+
+ if (getval(tmp,"parts_wy",&part_wy))
+ {
+ parts_ny[parts_n]=part_ny=32/part_wy;
+ continue;
+ }
+
+ if (getval(tmp,"parts_ox", &part_ox))
+ {
+ parts_ox[parts_n]=part_ox;
+ continue;
+ }
+
+ if (getval(tmp,"parts_oy", &part_oy))
+ {
+ parts_oy[parts_n]=part_oy;
+ continue;
+ }
+
+ /****/
+ if (tmp[0]=='#' || tmp[0]<32){
+ if(tmp[0]=='#') fprintf(sfp,"//%s\n",tmp);
+ continue;
+ }
+
+ if (strcmp(tmp, "%end") == 0)
+ {
+ fprintf(sfp," N_PART_%s};\n\n",part_name);
+ continue;
+ }
+ /*** normal bitmap ***/
+#define WID 32
+ clr_buf();
+ cp_floor();
+
+ i=0;
+ while(i<99 && tmp[i]>32)i++;
+ tmp[i]=0; strcpy(st, &tmp[i+1]);
+ load_monst(tmp);
+
+ fprintf(mfp,
+ "<area shape=\"rect\" coords=\"%d,%d,%d,%d\" alt=\"%s\" href=%s>\n",
+ bx*WID + part_x*part_wx,
+ by*WID + part_y*part_wy,
+ bx*WID + part_x*part_wx + part_wx-1,
+ by*WID + part_y*part_wy + part_wy-1,
+ st, realname);
+
+ if(!strstr(st,"IGNORE_COMMENT")){
+ nuke=strstr(st,"/*");if(nuke)*nuke=0;
+ if (st && strcmp(st,"") != 0 && strcmp(st, "\n") != 0)
+ {
+ fprintf(sfp," TILEP_%s_%s,\n", part_name, st);
+ }
+ else
+ {
+ fprintf(sfp," FILLER_%s_%d,\n", part_name, part_n);
+ }
+
+ i=strlen(st);
+ strncpy(&comment[pos_comment],st,i);
+ part_comment_ofs[n_comments]=pos_comment;
+ pos_comment += i;
+ n_comments++;
+
+ // n_comments = pos_comment=0;
+ //int parts_comment_ofs[];
+ //int part_comment_ofs[MAXTOTAL];
+ //char comment[MAXTOTAL*60];
+ }
+ else
+ {
+ i=0;
+ part_comment_ofs[n_comments]=pos_comment;
+ pos_comment += i;
+ n_comments++;
+ }
+
+ part_n++;
+ part_x++;
+ if(part_x==part_nx)
+ {
+ part_x=0;
+ part_y++;
+ if(part_y==part_ny)
+ {
+ part_y=0;
+ bx++;
+ if(bx==xx0)
+ {
+ bx=0;
+ by++;
+ }
+ }
+ }
+
+ /* normal */
+
+ }/* while */
+ fclose(fp);
+}
+
+/********************************************/
+
+int main(int argc, char **argv)
+{
+
+ int i,j,k,l,m,n,fl;
+ char fn[100],st2[100];
+
+ slant=corpse=mesh=rim=0;
+
+ bx=by=0;
+
+ /* parts related */
+ parts_n=0;
+
+ part_x=part_y=0;
+ part_n=0;
+ part_wx=part_wy=32;
+ part_ox=part_oy=0;
+
+ /* comments */
+ n_comments = pos_comment=0;
+ //int parts_comment_ofs[];
+ //int part_comment_ofs[MAXTOTAL];
+ //char comment[MAXTOTAL*60];
+
+
+ process_cpath(argv[0]);
+
+ xx0=XX;
+ subsname[0]=0;
+ sdir[0]=0;
+ realname[0]=0;
+
+ stdpal();
+ fixalloc(tbuf,64*64);
+ fixalloc(dbuf,64*64);
+ fixalloc(fbuf,64*64);
+ fixalloc(obuf, 32*64*(64)*64);
+
+
+ strcpy(outname,"tile");
+
+ sprintf(fn,"%smap.htm",cpath);
+ mfp=fopen(fn,"w");
+ if(mfp==NULL){
+ printf("Error could not open %s\nHit return",fn);
+ getchar();
+ exit(1);
+ }
+
+ sprintf(fn,"%stiledef-p.h",cpath);
+ sfp=fopen(fn,"w");
+ if(sfp==NULL){
+ printf("Error could not open %s\nHit return",fn);
+ getchar();
+ exit(1);
+ }
+ fprintf(sfp,"/* Automatically generated by tile generator. */\n");
+
+ fprintf(mfp,"<HTML>\n");
+ fprintf(mfp,"<MAP NAME=\"nhmap\">\n");
+
+ printf("%s\ncpath=%s\n",argv[0],cpath);
+ if(argc==1)
+ sprintf(fn,"%sdc-pl.txt",cpath);
+ else
+ strcpy(fn,argv[1]);
+ process_config(fn);
+
+ if(part_n!=0)flush_part();
+
+ fprintf(sfp,"\n#define TILEP_TOTAL %d\n",bx+by*xx0);
+ fprintf(sfp,"#define TILEP_PER_ROW %d\n\n",xx0);
+
+ fprintf(sfp,"#define TILEP_PARTS_TOTAL %d\n\n",parts_n);
+
+ fprintf(sfp,"const int tilep_parts_start[TILEP_PARTS_TOTAL]=\n {");
+ for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_start[i]);
+ fprintf(sfp," %d};\n",parts_start[parts_n-1]);
+
+ fprintf(sfp,"const int tilep_parts_total[TILEP_PARTS_TOTAL]=\n {");
+ for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_number[i]);
+ fprintf(sfp," %d};\n",parts_number[parts_n-1]);
+
+ fprintf(sfp,"const int tilep_parts_ox[TILEP_PARTS_TOTAL]=\n {");
+ for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_ox[i]);
+ fprintf(sfp," %d};\n",parts_ox[parts_n-1]);
+
+ fprintf(sfp,"const int tilep_parts_oy[TILEP_PARTS_TOTAL]=\n {");
+ for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_oy[i]);
+ fprintf(sfp," %d};\n",parts_oy[parts_n-1]);
+
+ fprintf(sfp,"const int tilep_parts_nx[TILEP_PARTS_TOTAL]=\n {");
+ for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_nx[i]);
+ fprintf(sfp," %d};\n",parts_nx[parts_n-1]);
+
+ fprintf(sfp,"const int tilep_parts_ny[TILEP_PARTS_TOTAL]=\n {");
+ for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_ny[i]);
+ fprintf(sfp," %d};\n",parts_ny[parts_n-1]);
+
+ fclose(sfp);
+
+ sprintf(fn,"%stilep-cmt.h",cpath);
+ sfp=fopen(fn,"w");
+ if(sfp==NULL){
+ printf("Error could not open %s\nHit return",fn);
+ getchar();
+ exit(1);
+ }
+ fprintf(sfp,"/* Automatically generated by tile generator. */\n");
+
+ fprintf(sfp,"static const char *tilep_parts_name[%d]={\n",parts_n);
+ for(i=0;i<parts_n-1;i++)
+ {
+ fprintf(sfp," \"%s\",\n",parts_names[i]);
+ }
+ i=parts_n-1;
+ fprintf(sfp," \"%s\"\n};\n",parts_names[i]);
+
+
+ fprintf(sfp,"const int tilep_comment_ofs[TILEP_PARTS_TOTAL]= {\n");
+ for(i=0;i<parts_n-1;i++)fprintf(sfp," %d,",parts_comment_ofs[i]);
+ fprintf(sfp," %d};\n",parts_comment_ofs[parts_n-1]);
+
+ fprintf(sfp,"static const char *tilep_comment[%d]={\n",n_comments);
+ for(i=0;i<n_comments-1;i++)
+ {
+ int len=part_comment_ofs[i+1]-part_comment_ofs[i];
+ strncpy(st2, &comment[part_comment_ofs[i]],len);
+ st2[len]=0;
+ fprintf(sfp," \"%s\",\n",st2);
+ }
+ i=pos_comment-part_comment_ofs[n_comments-1];
+ strncpy(st2, &comment[part_comment_ofs[n_comments-1]],i);
+ st2[i]=0;
+ fprintf(sfp," \"%s\" };\n",st2);
+ fclose(sfp);
+
+ fprintf(mfp,"<IMG SRC=%s.bmp USEMAP=\"#nhmap\" >\n", outname);
+
+
+ fclose(mfp);
+ i=by*32;if(bx!=0)i+=32;
+
+ sprintf(fn,"%s%s.bmp",cpath,outname);
+ bmwrite(fn,xx0*32,i,obuf);
+
+}
diff --git a/crawl-ref/source/rltiles/tool/dcqv.c b/crawl-ref/source/rltiles/tool/dcqv.c
new file mode 100644
index 0000000000..88fe9cbbc1
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/dcqv.c
@@ -0,0 +1,847 @@
+#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;
+}
diff --git a/crawl-ref/source/rltiles/tool/dcreverse.c b/crawl-ref/source/rltiles/tool/dcreverse.c
new file mode 100644
index 0000000000..66e69685b7
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/dcreverse.c
@@ -0,0 +1,216 @@
+#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]);
+}
diff --git a/crawl-ref/source/rltiles/tool/dctile.c b/crawl-ref/source/rltiles/tool/dctile.c
new file mode 100644
index 0000000000..aaadeca911
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/dctile.c
@@ -0,0 +1,642 @@
+#include "bm.h"
+
+/** Some global **/
+int corpse=0;
+int mesh=0;
+int slant=0;
+int rim=0;
+FILE *mfp=NULL; // map html
+FILE *sfp=NULL; // "tiledef.h"
+FILE *tfp=NULL; // tiles.txt
+FILE *cfp=NULL; // lengths of tile counts
+int tilecount = 0;
+int tilecountidx = -1;
+int counts[1024];
+int countnames[100][100];
+
+char outname[1024], ctgname[100], subsname[100];
+char sdir[300];
+char realname[1024];
+char imgname[1024];
+char tiledefname[1024];
+char enumprefix[100];
+const int read_size = 2048;
+
+/*** BUFFER MEMORY ***/
+#define XX 30
+int xx0;
+#define YY 90
+#define LX (XX)
+
+/*** tmp buffer, floor , final output, final queue ***/
+unsigned char *tbuf[3],fbuf[3][32*32],*obuf[3], dbuf[3][32*32];
+
+/*** compose buffer */
+unsigned char cbuf[3][32*32];
+
+/*** normal floor*/
+#define WOADR(x,y,xx,yy) ((x)*32+xx+ xx0*32*((y)*32+yy))
+#define ADR(x,y) ((x)+(y)*32)
+
+/*** output width/height in block ***/
+int bx,by;
+int filler = 0;
+
+unsigned char bkg[3] = { 0x47, 0x6c, 0x6c };
+
+#define WID 32
+
+/****************************************/
+/* Wrapper routines **************/
+/**************************/
+
+int load_pxxx(fnam) char *fnam;{
+ int x,y;
+
+ sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,fnam);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+
+ sprintf(realname,"%s%s.bmp",cpath,fnam);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+
+ if(subsname[0]){
+ sprintf(realname,"%s%s%c%s.bmp",cpath,sdir,PATHSEP,subsname);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+
+ sprintf(realname,"%s%s.bmp",cpath,subsname);
+ if(bmread(realname,&x,&y,tbuf)==0) return 0;
+ }
+
+
+ return 1;
+}
+
+
+void clr_buf() {
+ int xx,yy;
+
+ for(xx=0;xx<32;xx++){
+ for(yy=0;yy<32;yy++){
+ dbuf[0][ ADR(xx,yy) ]=bkg[0];
+ dbuf[1][ ADR(xx,yy) ]=bkg[1];
+ dbuf[2][ ADR(xx,yy) ]=bkg[2];
+ }
+ }
+}
+
+void cp_floor(){
+ int xx,yy,c;
+ for(xx=0;xx<32;xx++)
+ for(yy=0;yy<32;yy++)
+ for(c=0;c<3;c++)
+ dbuf[c][ ADR(xx,yy) ]=fbuf[c][ ADR(xx,yy)];
+}
+
+#define TILEX 32
+#define TILEY 32
+
+void make_rim(){
+ static unsigned char dflag[TILEX][TILEY];
+ int x,y,c,dd[3],ad;
+ int n0,n1,n2;
+
+ // dflag:
+ // 0 = background
+ // 1 = tile
+ // 2 = black
+
+ for(y=0;y<TILEY;y++){
+ for(x=0;x<TILEX;x++){
+ dflag[x][y]=1;
+ ad=ADR(x,y);
+ for(c=0;c<3;c++)dd[c]=dbuf[c][ad];
+ if( (dd[0]==bkg[0])&&(dd[1]==bkg[1])&& (dd[2]==bkg[2])) dflag[x][y]=0;
+ if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0)) dflag[x][y]=2;
+ }
+ }
+
+ for(x=0;x<TILEX;x++){
+ for(y=0;y<TILEY;y++){
+ ad=x+y*TILEX;
+ if(dflag[x][y]==2 || dflag[x][y]==0){
+ n0=n1=n2=0;
+ if(x>0){
+ if(dflag[x-1][y]==0) n0++;
+ if(dflag[x-1][y]==1) n1++;
+ if(dflag[x-1][y]==2) n2++;
+ }
+
+ if(y>0){
+ if(dflag[x][y-1]==0) n0++;
+ if(dflag[x][y-1]==1) n1++;
+ if(dflag[x][y-1]==2) n2++;
+ }
+
+ if(x<31){
+ if(dflag[x+1][y]==0) n0++;
+ if(dflag[x+1][y]==1) n1++;
+ if(dflag[x+1][y]==2) n2++;
+ }
+ if(y<31){
+ if(dflag[x][y+1]==0) n0++;
+ if(dflag[x][y+1]==1) n1++;
+ if(dflag[x][y+1]==2) n2++;
+ }
+ // n1 = tiles adjacent but not diagonal that are tile pixels
+ if(n1!=0 )
+ dbuf[0][x+y*32]=dbuf[1][x+y*32]=dbuf[2][x+y*32]=0x10;
+ }
+ }
+ }
+
+}
+
+void cp_monst_32(){
+ int xx,yy,c,dd[3],ad;
+ char dflag[32][32];
+ int xmin,xmax,ymin,ymax,ox,oy;
+
+ if(corpse==1)
+ {
+ xmin=ymin=31;
+ xmax=ymax=0;
+ for(xx=0;xx<32;xx++){
+ for(yy=0;yy<32;yy++){
+ ad=ADR(xx,yy);
+ for(c=0;c<3;c++)dd[c]=tbuf[c][ad];
+ if( (dd[0]==bkg[0])&&(dd[1]==bkg[1])&& (dd[2]==bkg[2]))continue;
+ if( (dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
+ if(xx<xmin)xmin=xx;
+ if(xx>xmax)xmax=xx;
+ if(yy<ymin)ymin=yy;
+ if(yy>ymax)ymax=yy;
+ }
+ }
+ ox=(xmax+xmin)/2-16;
+ oy=(ymax+ymin)/2-16;
+ }
+
+ for(xx=0;xx<32;xx++){
+ for(yy=0;yy<32;yy++){
+ dflag[xx][yy]=0;
+ ad=ADR(xx,yy);
+ if(corpse==1){
+ int x1=xx+ox;
+ int y1=(yy+oy)*2-16;
+ int cy=18;
+ if(xx<4 || xx>=28)cy+=2;else
+ if(xx<12 || xx>=20) cy+=1;
+
+ if(yy>=cy-1 && yy<=cy+0)continue;
+ x1 += (y1-16)/4;
+ if(y1>=cy){y1-=2;x1-=3;}else {y1 +=2;x1+=3;}
+ if(x1<0 || x1>=32 || y1<0 || y1>=32)continue;
+ ad=ADR(x1,y1);
+ }
+
+ /*** normal***/
+ for(c=0;c<3;c++){dd[c]=tbuf[c][ad];}
+ if(mesh==2){
+ if( (dd[0]!=bkg[0])||(dd[1]!=bkg[1])|| (dd[2]!=bkg[2])){
+ if( ((xx+yy)&1) ==0)dd[0]=dd[1]=dd[2]=0;
+ }
+ }
+ if(mesh==1){
+ if( (((xx/2)+(yy/2))&1) ==1)dd[0]=dd[1]=dd[2]=0;
+ }
+
+ if( (dd[0]==bkg[0])&&(dd[1]==bkg[1])&& (dd[2]==bkg[2]))continue;
+ if( (corpse==1) &&(dd[0]==0)&&(dd[1]==0)&& (dd[2]==0))continue;
+
+ for(c=0;c<3;c++) {dbuf[c][ADR(xx,yy)]=dd[c];}
+ dflag[xx][yy]=1;
+ }
+ }
+
+
+#if 1
+if(corpse==1){
+for(xx=0;xx<32;xx++){
+int cy=18;
+if(xx<4 || xx>=28)cy+=2;else
+if(xx<12 || xx>=20) cy+=1;
+if(dflag[xx][cy-2]==1 && dflag[xx][cy+1]==1 ){
+for(yy=cy-1;yy<=cy-0;yy++){ dbuf[0][ADR(xx,yy)]=32;
+dbuf[1][ADR(xx,yy)]=0;dbuf[2][ADR(xx,yy)]=0;
+dflag[xx][yy]=1;
+}}
+}
+
+/** shade**/
+for(xx=1;xx<32;xx++){
+for(yy=1;yy<32;yy++){
+if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==1){
+dbuf[0][ADR(xx,yy)]=0;
+dbuf[1][ADR(xx,yy)]=0;
+dbuf[2][ADR(xx,yy)]=0;
+}
+}}
+
+for(xx=3;xx<32;xx++){
+for(yy=3;yy<32;yy++){
+if(dflag[xx][yy]==0 && dflag[xx-1][yy-1]==0
+ && dflag[xx-2][yy-2]==1 && dflag[xx-3][yy-3]==1){
+dbuf[0][ADR(xx,yy)]=0;
+dbuf[1][ADR(xx,yy)]=0;
+dbuf[2][ADR(xx,yy)]=0;
+}
+}}
+
+
+
+
+}
+#endif
+if(rim==1)make_rim();
+}
+
+
+void bflush(){
+int xx,yy,c;
+for(xx=0;xx<32;xx++){
+for(yy=0;yy<32;yy++){
+for(c=0;c<3;c++){
+obuf[c][WOADR(bx,by,xx,yy)]= dbuf[c][ADR(xx,yy)];
+}}}
+}
+
+
+void load_monst(fnam) char *fnam;{
+ if( load_pxxx(fnam)){
+ printf("no file pxxx/%s.bmp or %s/%s.bmp\n",fnam,sdir,fnam);
+ getchar();
+ exit(1);
+ }
+ cp_monst_32();
+ bflush();
+}
+
+void process_config(char *fname)
+{
+ int x,y;
+ int i,j;
+ char tmp[read_size],st[read_size];
+ char *nuke;
+ FILE *fp=fopen(fname,"r");
+ if(fp==NULL){
+ printf("Error no config file %s\nHit return",fname);
+ getchar();
+ exit(1);
+ }
+
+ while(1){
+ fgets(tmp,read_size,fp);
+ if(feof(fp))break;
+ i=0;while(i<read_size && tmp[i]>=32)i++;
+ tmp[i]=0;
+
+ if(getname(tmp,"back",st))
+ {
+ /*** Set Background BMP (format "%back bmpname") ***/
+ if(strncmp(st,"none",4)==0)
+ {
+ /** clear **/
+ for(i=0;i<32*32;i++){fbuf[0][i]=bkg[0];fbuf[1][i]=bkg[1];fbuf[2][i]=bkg[2];}
+ }
+ else
+ {
+ load_pxxx(st);
+ for(i=0;i<32*32;i++)for(j=0;j<3;j++)fbuf[j][i]=tbuf[j][i];
+ }
+ continue;
+ }
+
+ if (getname(tmp,"include",st)){
+ char fn2[read_size];
+ sprintf(fn2,"%s%s",cpath, st);
+ if(strcmp(fname,fn2)!=0) process_config(fn2);
+ continue;
+ }
+
+ if (getname(tmp,"htmlfile",st))
+ {
+ char fn2[read_size];
+ sprintf(fn2,"%s%s",cpath, st);
+ mfp=fopen(fn2,"w");
+ if(mfp==NULL)
+ {
+ printf("Error could not open %s\nHit return",fn2);
+ getchar();
+ exit(1);
+ }
+ fprintf(mfp,"<HTML><head>\n");
+ continue;
+ }
+
+ if (getname(tmp,"tilelist",st))
+ {
+ char fn2[read_size];
+ sprintf(fn2,"%s%s",cpath, st);
+ tfp=fopen(fn2,"w");
+ if(tfp==NULL)
+ {
+ printf("Error could not open %s\nHit return",fn2);
+ getchar();
+ exit(1);
+ }
+ fprintf(tfp,"%%tilefile %s\n", imgname);
+ fprintf(tfp,"%%rim %d\n", rim);
+ continue;
+ }
+
+ if (getname(tmp,"tiledef",st))
+ {
+ char fn[read_size];
+ sprintf(fn,"%s%s",cpath,st);
+ strcpy(tiledefname, st);;
+ sfp=fopen(fn,"w");
+ if(sfp==NULL)
+ {
+ printf("Error could not open %s\nHit return",fn);
+ getchar();
+ exit(1);
+ }
+ fprintf(sfp,"/* Automatically generated by tile generator. */\n");
+ fprintf(sfp, "enum TILE_%sIDX {\n", enumprefix);
+ continue;
+ }
+
+ if (getname(tmp,"tilecount",st))
+ {
+ char fn[read_size];
+ sprintf(fn,"%s%s",cpath,st);
+ cfp=fopen(fn,"w");
+ if(cfp==NULL)
+ {
+ printf("Error could not open %s\nHit return",fn);
+ getchar();
+ exit(1);
+ }
+ fprintf(cfp,"/* Automatically generated by tile generator. */\n");
+ fprintf(cfp,"#include \"%s\"\n", tiledefname);
+ fprintf(cfp, "enum TILE_%sCOUNT_IDX {\n", enumprefix);
+ continue;
+ }
+
+ if (getname(tmp,"enumprefix",st))
+ {
+ strcpy(enumprefix, st);
+ continue;
+ }
+
+ if (getname(tmp,"htmlhead",st))
+ {
+ if(mfp)fprintf(mfp,"%s\n",st);
+ continue;
+ }
+
+ if (getname(tmp,"htmlbody",st))
+ {
+ if(mfp)fprintf(mfp,"</head><body>\n<map name=\"nhmap\">\n");
+ continue;
+ }
+
+ if (getval(tmp,"slant",&slant)) continue;
+ if (getval(tmp,"rim",&rim))
+ {
+ if (tfp) fprintf(tfp, "%%rim %d\n", rim);
+ continue;
+ }
+ if (getval(tmp,"mesh",&mesh)) continue;
+ if (getval(tmp,"corpse",&corpse)) continue;
+
+ if (getname(tmp,"ctg",ctgname)) continue;
+ if (getname(tmp,"subst",subsname)) continue;
+ if (getname(tmp,"sdir",sdir)) continue;
+ if (getname(tmp,"name", outname))
+ {
+ sprintf(imgname, "%s.bmp", outname);
+ continue;
+ }
+ if (getname(tmp,"htmlimg",imgname)) continue;
+ if (getval(tmp,"width",&xx0)) continue;
+ if (tmp[0]=='#' || tmp[0]<32){
+ if(tmp[0]<32) fprintf(sfp,"\n");
+ if(tmp[0]=='#')fprintf(sfp,"//%s\n",tmp);
+ continue;
+ }
+
+ // begin a 32x32 composing sequence
+ if (getname(tmp,"start",st))
+ {
+ clr_buf();
+ for (i = 0; i < 32*32; i++)
+ {
+ cbuf[0][i] = fbuf[0][i];
+ cbuf[1][i] = fbuf[1][i];
+ cbuf[2][i] = fbuf[2][i];
+ }
+ continue;
+ }
+
+ // compose an image onto the current buffer
+ if (getname(tmp,"compose",st))
+ {
+ if(load_pxxx(st)){
+ printf("no file pxxx/%s.bmp or %s/%s.bmp\n",st,sdir,st);
+ getchar();
+ exit(1);
+ }
+ for(i=0;i<32*32;i++)
+ {
+ if (tbuf[0][i] != bkg[0] ||
+ tbuf[1][i] != bkg[1] ||
+ tbuf[2][i] != bkg[2])
+ {
+ cbuf[0][i] = tbuf[0][i];
+ cbuf[1][i] = tbuf[1][i];
+ cbuf[2][i] = tbuf[2][i];
+ }
+ }
+ continue;
+ }
+
+ if (getname(tmp,"nextrow",st))
+ {
+ if (bx == 0)
+ continue;
+
+ while (bx != xx0)
+ {
+ fprintf(sfp, " TILE_%sFILLER%d,\n", enumprefix, filler++);
+ bx++;
+ }
+
+ bx = 0;
+ by ++;
+ continue;
+ }
+
+ // finish composing
+ if (getname(tmp,"finish",st))
+ {
+ realname[0] = 0;
+ for (i=0;i<32*32;i++)
+ {
+ tbuf[0][i] = cbuf[0][i];
+ tbuf[1][i] = cbuf[1][i];
+ tbuf[2][i] = cbuf[2][i];
+ }
+ cp_monst_32();
+ bflush();
+ }
+ else
+ {
+ /*** normal bitmap ***/
+ clr_buf();cp_floor();
+ i=0;while(i<read_size && tmp[i]>32)i++;
+ tmp[i]=0; strcpy(st, &tmp[i+1]);
+
+ if (tfp)
+ {
+ fprintf(tfp,"%%sx %d\n%%sy %d\n%%ex %d\n%%ey %d\n",
+ bx*WID,by*WID,bx*WID+WID-1,by*WID+WID-1);
+ }
+
+ load_monst(tmp);
+ }
+
+ if(mfp)
+ {
+ fprintf(
+ mfp,"<area shape=\"rect\" coords=\"%d,%d,%d,%d\" alt=\"%s\" href=\"%s\">\n",
+ bx*WID,by*WID,bx*WID+WID-1,by*WID+WID-1,
+ st,realname);
+ }
+
+ if (tfp)
+ {
+ if (corpse)
+ fprintf(tfp,"%%skip\n");
+ else
+ fprintf(tfp,"%%file %s\n", realname);
+ }
+
+ if(!strstr(st,"IGNORE_COMMENT")){
+ nuke=strstr(st,"/*");if(nuke)*nuke=0;
+ if (st && strcmp(st, "") != 0 && strcmp(st, "\n") != 0)
+ {
+ fprintf(sfp," TILE_%s,\n",st);
+ if (cfp)
+ {
+ if (tilecountidx == -1)
+ tilecountidx++;
+ else
+ counts[tilecountidx++] = tilecount;
+ fprintf(cfp, " IDX_%s,\n",st);
+ sprintf(countnames[tilecountidx], "TILE_%s", st);
+ tilecount = 1;
+ }
+ }
+ else
+ {
+ fprintf(sfp, " TILE_%sFILLER%d,\n", enumprefix, filler++);
+ tilecount++;
+ }
+ }
+
+ bx++;if(bx==xx0){bx=0;by++;;}
+
+ }/* while */
+ fclose(fp);
+}
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+ int i;
+ char fn[100];
+
+ bx=by=0;
+ process_cpath(argv[0]);
+
+ xx0=XX;
+ ctgname[0]=0;
+ subsname[0]=0;
+ sdir[0]=0;
+ enumprefix[0] = 0;
+
+ stdpal();
+ fixalloc(tbuf,256*256);
+ fixalloc(obuf, LX*64*(YY)*64);
+
+
+ strcpy(outname,"tile");
+ strcpy(imgname,"tile.bmp");
+
+
+ printf("%s\ncpath=%s\n",argv[0],cpath);
+ if(argc==1)
+ sprintf(fn,"%sdc-2d.txt",cpath);
+ else
+ strcpy(fn,argv[1]);
+ process_config(fn);
+
+ if (sfp)
+ {
+ fprintf(sfp, "TILE_%sTOTAL};\n\n", enumprefix);
+ fprintf(sfp,"#define TILE_%sPER_ROW %d\n", enumprefix, xx0);
+ fclose(sfp);
+ }
+
+ if(mfp)
+ {
+ fprintf(mfp,"</map>\n<img src=%s usemap=\"#nhmap\" >\n", imgname);
+ fprintf(mfp,"</body></html>\n");
+ fclose(mfp);
+ }
+
+ if (cfp)
+ {
+ int i;
+
+ fprintf(cfp, " IDX_%sTOTAL\n};\n\n", enumprefix);
+
+ counts[tilecountidx++] = tilecount;
+
+ fprintf(cfp, "int tile_%scount[IDX_%sTOTAL] =\n{\n",
+ enumprefix, enumprefix);
+
+ for (i = 0; i < tilecountidx; i++)
+ {
+ fprintf(cfp, (i < tilecountidx - 1) ? " %d,\n" : " %d\n",
+ counts[i]);
+ }
+
+ fprintf(cfp, "};\n\n");
+
+ fprintf(cfp, "int tile_%sstart[IDX_%sTOTAL] = \n{\n",
+ enumprefix, enumprefix);
+
+ for (i = 0; i < tilecountidx; i++)
+ {
+ fprintf(cfp, (i < tilecountidx - 1) ? " %s,\n" : " %s\n",
+ countnames[i]);
+ }
+
+ fprintf(cfp, "};\n\n");
+ close(cfp);
+ }
+
+ if(tfp)
+ {
+ fclose(tfp);
+ }
+
+ i=by*32;
+ if(bx!=0)i+=32;
+ sprintf(fn,"%s%s.bmp",cpath,outname);
+ bmwrite(fn,xx0*32,i,obuf);
+ return 0;
+}
diff --git a/crawl-ref/source/rltiles/tool/mkmap.c b/crawl-ref/source/rltiles/tool/mkmap.c
new file mode 100644
index 0000000000..f07ce369ea
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/mkmap.c
@@ -0,0 +1,408 @@
+#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);
+
+}
diff --git a/crawl-ref/source/rltiles/tool/mkmapq.c b/crawl-ref/source/rltiles/tool/mkmapq.c
new file mode 100644
index 0000000000..ad92344267
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/mkmapq.c
@@ -0,0 +1,783 @@
+#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;
+}
diff --git a/crawl-ref/source/rltiles/tool/palette.h b/crawl-ref/source/rltiles/tool/palette.h
new file mode 100644
index 0000000000..c94b0d66f7
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/palette.h
@@ -0,0 +1,355 @@
+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
+};
diff --git a/crawl-ref/source/rltiles/tool/shade.c b/crawl-ref/source/rltiles/tool/shade.c
new file mode 100644
index 0000000000..3e7d7f715b
--- /dev/null
+++ b/crawl-ref/source/rltiles/tool/shade.c
@@ -0,0 +1,254 @@
+#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);
+
+}