NHDT->ANH, nethack->anethack, nhdat->anhdat
[aNetHack.git] / win / X11 / tile2x11.c
blobb2035cda3d36ab680944edbad191dcec452c038e
1 /* $ANH-Date: 1432512808 2015/05/25 00:13:28 $ $ANH-Branch: master $:$ANH-Revision: 1.6 $ */
3 /*
4 * Convert the given input files into an output file that is expected
5 * by anethack.
7 * Assumptions:
8 * + Two dimensional byte arrays are in row order and are not padded
9 * between rows (x11_colormap[][]).
11 #include "hack.h" /* for MAX_GLYPH */
12 #include "tile.h"
13 #include "tile2x11.h" /* x11 output file header structure */
15 #define OUTNAME "x11tiles" /* output file name */
16 /* #define PRINT_COLORMAP */ /* define to print the colormap */
18 x11_header header;
19 unsigned char tile_bytes[TILE_X * TILE_Y * (MAX_GLYPH + TILES_PER_ROW)];
20 unsigned char *curr_tb = tile_bytes;
21 unsigned char x11_colormap[MAXCOLORMAPSIZE][3];
23 /* Look up the given pixel and return its colormap index. */
24 static unsigned char
25 pix_to_colormap(pix)
26 pixel pix;
28 unsigned i;
30 for (i = 0; i < header.ncolors; i++) {
31 if (pix.r == ColorMap[CM_RED][i] && pix.g == ColorMap[CM_GREEN][i]
32 && pix.b == ColorMap[CM_BLUE][i])
33 break;
36 if (i == header.ncolors) {
37 Fprintf(stderr, "can't find color: [%u,%u,%u]\n", pix.r, pix.g,
38 pix.b);
39 exit(1);
41 return (unsigned char) (i & 0xFF);
44 /* Convert the tiles in the file to our format of bytes. */
45 static unsigned long
46 convert_tiles(tb_ptr, total)
47 unsigned char **tb_ptr; /* pointer to a tile byte pointer */
48 unsigned long total; /* total tiles so far */
50 unsigned char *tb = *tb_ptr;
51 unsigned long count = 0;
52 pixel tile[TILE_Y][TILE_X];
53 int x, y;
55 while (read_text_tile(tile)) {
56 count++;
57 total++;
58 for (y = 0; y < TILE_Y; y++) {
59 for (x = 0; x < TILE_X; x++)
60 tb[x] = pix_to_colormap(tile[y][x]);
61 tb += TILE_X * header.per_row;
64 /* repoint at the upper-left corner of the next tile */
65 *tb_ptr += TILE_X;
66 if (header.per_row == 1 || (total % header.per_row) == 0)
67 *tb_ptr += TILE_X * (TILE_Y - 1) * header.per_row;
68 tb = *tb_ptr;
71 return count;
74 /* Merge the current text colormap (ColorMap) with ours (x11_colormap). */
75 static void
76 merge_text_colormap()
78 unsigned i, j;
80 for (i = 0; i < (unsigned) colorsinmap; i++) {
81 for (j = 0; j < header.ncolors; j++)
82 if (x11_colormap[j][CM_RED] == ColorMap[CM_RED][i]
83 && x11_colormap[j][CM_GREEN] == ColorMap[CM_GREEN][i]
84 && x11_colormap[j][CM_BLUE] == ColorMap[CM_BLUE][i])
85 break;
87 if (j >= MAXCOLORMAPSIZE) {
88 Fprintf(stderr, "colormap overflow\n");
89 exit(1);
92 if (j == header.ncolors) { /* couldn't find it */
93 #ifdef PRINT_COLORMAP
94 printf("color %2d: %3d %3d %3d\n", header.ncolors,
95 ColorMap[CM_RED][i], ColorMap[CM_GREEN][i],
96 ColorMap[CM_BLUE][i]);
97 #endif
99 x11_colormap[j][CM_RED] = ColorMap[CM_RED][i];
100 x11_colormap[j][CM_GREEN] = ColorMap[CM_GREEN][i];
101 x11_colormap[j][CM_BLUE] = ColorMap[CM_BLUE][i];
102 header.ncolors++;
107 /* Open the given file, read & merge the colormap, convert the tiles. */
108 static void
109 process_file(fname)
110 char *fname;
112 unsigned long count;
114 if (!fopen_text_file(fname, RDTMODE)) {
115 Fprintf(stderr, "can't open file \"%s\"\n", fname);
116 exit(1);
118 merge_text_colormap();
119 count = convert_tiles(&curr_tb, header.ntiles);
120 Fprintf(stderr, "%s: %lu tiles\n", fname, count);
121 header.ntiles += count;
122 fclose_text_file();
125 #ifdef USE_XPM
126 static int
127 xpm_write(fp)
128 FILE *fp;
130 int i, j, n;
132 if (header.ncolors > 64) {
133 Fprintf(stderr, "Sorry, only configured for up to 64 colors\n");
134 exit(1);
135 /* All you need to do is add more char per color - below */
138 Fprintf(fp, "/* XPM */\n");
139 Fprintf(fp, "static char* nhtiles[] = {\n");
140 Fprintf(fp, "\"%lu %lu %lu %d\",\n", header.tile_width * header.per_row,
141 (header.tile_height * header.ntiles) / header.per_row,
142 header.ncolors, 1 /* char per color */);
143 for (i = 0; i < header.ncolors; i++)
144 Fprintf(fp, "\"%c c #%02x%02x%02x\",\n",
145 i + '0', /* just one char per color */
146 x11_colormap[i][0], x11_colormap[i][1], x11_colormap[i][2]);
148 n = 0;
149 for (i = 0; i < (header.tile_height * header.ntiles) / header.per_row;
150 i++) {
151 Fprintf(fp, "\"");
152 for (j = 0; j < header.tile_width * header.per_row; j++) {
153 /* just one char per color */
154 fputc(tile_bytes[n++] + '0', fp);
157 Fprintf(fp, "\",\n");
160 return fprintf(fp, "};\n") >= 0;
162 #endif /* USE_XPM */
165 main(argc, argv)
166 int argc;
167 char **argv;
169 FILE *fp;
170 int i;
172 header.version = 2; /* version 1 had no per_row field */
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 header.per_row = TILES_PER_ROW;
179 if (argc == 1) {
180 Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...] [-grayscale txt_fileN]\n", argv[0]);
181 exit(1);
184 fp = fopen(OUTNAME, "w");
185 if (!fp) {
186 Fprintf(stderr, "can't open output file\n");
187 exit(1);
190 /* don't leave garbage at end of partial row */
191 (void) memset((genericptr_t) tile_bytes, 0, sizeof(tile_bytes));
193 for (i = 1; i < argc; i++) {
194 if (!strncmp(argv[i], "-grayscale", 10)) {
195 set_grayscale(TRUE);
196 if (i < (argc - 1)) i++;
197 } else {
198 set_grayscale(FALSE);
200 process_file(argv[i]);
202 Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
204 /* round size up to the end of the row */
205 if ((header.ntiles % header.per_row) != 0) {
206 header.ntiles += header.per_row - (header.ntiles % header.per_row);
209 #ifdef USE_XPM
210 if (xpm_write(fp) == 0) {
211 Fprintf(stderr, "can't write XPM file\n");
212 exit(1);
214 #else
215 if (fwrite((char *) &header, sizeof(x11_header), 1, fp) == 0) {
216 Fprintf(stderr, "can't open output header\n");
217 exit(1);
220 if (fwrite((char *) x11_colormap, 1, header.ncolors * 3, fp) == 0) {
221 Fprintf(stderr, "can't write output colormap\n");
222 exit(1);
225 if (fwrite((char *) tile_bytes, 1,
226 (int) header.ntiles * header.tile_width * header.tile_height,
227 fp) == 0) {
228 Fprintf(stderr, "can't write tile bytes\n");
229 exit(1);
231 #endif
233 fclose(fp);
234 return 0;