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 | }