1    | /*
2    |  * Convert the given input files into an output file that is expected
3    |  * by nethack.
4    |  * 
5    |  * Assumptions:
6    |  * 	+ Two dimensional byte arrays are in row order and are not padded
7    |  *	  between rows (x11_colormap[][]).
8    |  */
9    | #include "hack.h"		/* for MAX_GLYPH */
10   | #include "tile.h"
11   | #include "tile2x11.h"		/* x11 output file header structure */
12   | 
13   | #define OUTNAME "x11tiles"	/* output file name */
14   | /* #define PRINT_COLORMAP */	/* define to print the colormap */
15   | 
16   | 
17   | x11_header	header;
18   | unsigned char	tile_bytes[TILE_X*TILE_Y*MAX_GLYPH];
19   | unsigned char	*curr_tb = tile_bytes;
20   | unsigned char	x11_colormap[MAXCOLORMAPSIZE][3];
21   | 
22   | 
23   | /* Look up the given pixel and return its colormap index. */
24   | static unsigned char
25   | pix_to_colormap(pix)
26   |     pixel pix;
27   | {
28   |     int i;
29   | 
30   |     for (i = 0; i < header.ncolors; i++) {
31   | 	if (pix.r == ColorMap[CM_RED][i] &&
32   | 		pix.g == ColorMap[CM_GREEN][i] &&
33   | 		pix.b == ColorMap[CM_BLUE][i])
34   | 	    break;
35   |     }
36   | 
37   |     if (i == header.ncolors) {
38   | 	Fprintf(stderr, "can't find color: [%u,%u,%u]\n", pix.r, pix.g, pix.b);
39   | 	exit(1);
40   |     }
41   |     return (unsigned char) (i & 0xFF);
42   | }
43   | 
44   | 
45   | /* Convert the tiles in the file to our format of bytes. */
46   | static unsigned long
47   | convert_tiles(tb_ptr)
48   |     unsigned char **tb_ptr;	/* pointer to a tile byte pointer */
49   | {
50   |     unsigned char *tb = *tb_ptr;
51   |     unsigned long count = 0;
52   |     pixel tile[TILE_Y][TILE_X];
53   |     int x, y;
54   | 
55   |     while (read_text_tile(tile)) {
56   | 	count++;
57   | 	for (y = 0; y < TILE_Y; y++)
58   | 	    for (x = 0; x < TILE_X; x++)
59   | 		*tb++ = pix_to_colormap(tile[y][x]);
60   |     }
61   | 
62   |     *tb_ptr = tb;	/* update return val */
63   |     return count;
64   | }
65   | 
66   | 
67   | /* Merge the current text colormap (ColorMap) with ours (x11_colormap). */
68   | static void
69   | merge_text_colormap()
70   | {
71   |     int i, j;
72   | 
73   |     for (i = 0; i < colorsinmap; i++) {
74   | 	for (j = 0; j < header.ncolors; j++)
75   | 	    if (x11_colormap[j][CM_RED] == ColorMap[CM_RED][i] &&
76   | 		    x11_colormap[j][CM_GREEN] == ColorMap[CM_GREEN][i] &&
77   | 		    x11_colormap[j][CM_BLUE] == ColorMap[CM_BLUE][i])
78   | 		break;
79   | 
80   | 	if (j >= MAXCOLORMAPSIZE) {
81   | 	    Fprintf(stderr, "colormap overflow\n");
82   | 	    exit(1);
83   | 	}
84   | 
85   | 	if (j == header.ncolors) {	/* couldn't find it */
86   | #ifdef PRINT_COLORMAP
87   | 	    printf("color %2d: %3d %3d %3d\n", header.ncolors,
88   | 	    	ColorMap[CM_RED][i], ColorMap[CM_GREEN][i],
89   | 	    	ColorMap[CM_BLUE][i]);
90   | #endif
91   | 
92   | 	    x11_colormap[j][CM_RED] = ColorMap[CM_RED][i];
93   | 	    x11_colormap[j][CM_GREEN] = ColorMap[CM_GREEN][i];
94   | 	    x11_colormap[j][CM_BLUE] = ColorMap[CM_BLUE][i];
95   | 	    header.ncolors++;
96   | 	}
97   |     }
98   | }
99   | 
100  | 
101  | /* Open the given file, read & merge the colormap, convert the tiles. */
102  | static void
103  | process_file(fname)
104  |     char *fname;
105  | {
106  |     unsigned long count;
107  | 
108  |     if (!fopen_text_file(fname, RDTMODE)) {
109  | 	Fprintf(stderr, "can't open file \"%s\"\n", fname);
110  | 	exit(1);
111  | 	}
112  |     merge_text_colormap();
113  |     count = convert_tiles(&curr_tb);
114  |     Fprintf(stderr, "%s: %lu tiles\n", fname, count);
115  |     header.ntiles += count;
116  |     fclose_text_file();
117  | }
118  | 
119  | 
120  | #ifdef USE_XPM
121  | static int
122  | xpm_write(fp)
123  | FILE *fp;
124  | {
125  |     int i,j,n;
126  | 
127  |     if (header.ncolors > 64) {
128  | 	Fprintf(stderr, "Sorry, only configured for up to 64 colors\n");
129  | 	exit(1);
130  | 	/* All you need to do is add more char per color - below */
131  |     }
132  | 
133  |     fprintf(fp, "/* XPM */\n");
134  |     fprintf(fp, "static char* nhtiles[] = {\n");
135  |     fprintf(fp, "\"%lu %lu %lu %d\",\n",
136  | 		header.tile_width,
137  | 		header.tile_height*header.ntiles,
138  | 		header.ncolors,
139  | 		1 /* char per color */);
140  |     for (i = 0; i < header.ncolors; i++)
141  | 	fprintf(fp, "\"%c  c #%02x%02x%02x\",\n",
142  | 		i+'0', /* just one char per color */
143  | 		x11_colormap[i][0],
144  | 		x11_colormap[i][1],
145  | 		x11_colormap[i][2]);
146  | 
147  |     n=0;
148  |     for (i = 0; i < header.tile_height*header.ntiles; i++) {
149  | 	fprintf(fp, "\"");
150  | 	for (j = 0; j < header.tile_width; j++) {
151  | 	    /* just one char per color */
152  | 	    fputc(tile_bytes[n++]+'0', fp);
153  | 	}
154  | 	if (j==header.tile_width-1)
155  | 	    fprintf(fp, "\"\n");
156  | 	else
157  | 	    fprintf(fp, "\",\n");
158  |     }
159  | 
160  |     return fprintf(fp, "};\n")>=0;
161  | }
162  | #endif	/* USE_XPM */
163  | 
164  | int
165  | main(argc, argv)
166  |     int argc;
167  |     char **argv;
168  | {
169  |     FILE *fp;
170  |     int i;
171  | 
172  |     header.version	= 1;
173  |     header.ncolors	= 0;
174  |     header.tile_width	= TILE_X;
175  |     header.tile_height	= TILE_Y;
176  |     header.ntiles	= 0;		/* updated as we read in files */
177  | 
178  |     if (argc == 1) {
179  | 	Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...]\n", argv[0]);
180  | 	exit(1);
181  |     }
182  | 
183  |     fp = fopen(OUTNAME, "w");
184  |     if (!fp) {
185  | 	Fprintf(stderr, "can't open output file\n");
186  | 	exit(1);
187  | 	}
188  | 
189  |     for (i = 1; i < argc; i++)
190  | 	process_file(argv[i]);
191  |     Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
192  | 
193  | #ifdef USE_XPM
194  |     if (xpm_write(fp) == 0) {
195  | 	Fprintf(stderr, "can't write XPM file\n");
196  | 	exit(1);
197  |     }
198  | #else
199  |     if (fwrite((char *)&header, sizeof(x11_header), 1, fp) == 0) {
200  | 	Fprintf(stderr, "can't open output header\n");
201  | 	exit(1);
202  | 	}
203  | 
204  |     if (fwrite((char *)x11_colormap, 1, header.ncolors*3, fp) == 0) {
205  | 	Fprintf(stderr, "can't write output colormap\n");
206  | 	exit(1);
207  |     }
208  | 
209  |     if (fwrite((char *)tile_bytes, 1,
210  | 	(int) header.ntiles*header.tile_width*header.tile_height, fp) == 0) {
211  | 
212  | 	Fprintf(stderr, "can't write tile bytes\n");
213  | 	exit(1);
214  |     }
215  | #endif
216  | 
217  |     fclose(fp);
218  |     return 0;
219  | }