OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / win / X11 / tile2x11.c
1 /* $NHDT-Date: 1432512808 2015/05/25 00:13:28 $  $NHDT-Branch: master $:$NHDT-Revision: 1.6 $ */
2
3 /*
4  * Convert the given input files into an output file that is expected
5  * by nethack.
6  *
7  * Assumptions:
8  *      + Two dimensional byte arrays are in row order and are not padded
9  *        between rows (x11_colormap[][]).
10  */
11 #include "hack.h" /* for MAX_GLYPH */
12 #include "tile.h"
13 #include "tile2x11.h" /* x11 output file header structure */
14
15 #define OUTNAME "x11tiles"   /* output file name */
16 /* #define PRINT_COLORMAP */ /* define to print the colormap */
17
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];
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     unsigned i;
29
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;
34     }
35
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);
40     }
41     return (unsigned char) (i & 0xFF);
42 }
43
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 */
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         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;
62         }
63
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;
69     }
70
71     return count;
72 }
73
74 /* Merge the current text colormap (ColorMap) with ours (x11_colormap). */
75 static void
76 merge_text_colormap()
77 {
78     unsigned i, j;
79
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;
86
87         if (j >= MAXCOLORMAPSIZE) {
88             Fprintf(stderr, "colormap overflow\n");
89             exit(1);
90         }
91
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
98
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++;
103         }
104     }
105 }
106
107 /* Open the given file, read & merge the colormap, convert the tiles. */
108 static void
109 process_file(fname)
110 char *fname;
111 {
112     unsigned long count;
113
114     if (!fopen_text_file(fname, RDTMODE)) {
115         Fprintf(stderr, "can't open file \"%s\"\n", fname);
116         exit(1);
117     }
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();
123 }
124
125 #ifdef USE_XPM
126 static int
127 xpm_write(fp)
128 FILE *fp;
129 {
130     int i, j, n;
131
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 */
136     }
137
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]);
147
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);
155         }
156
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 = 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;
178
179     if (argc == 1) {
180         Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...]\n", argv[0]);
181         exit(1);
182     }
183
184     fp = fopen(OUTNAME, "w");
185     if (!fp) {
186         Fprintf(stderr, "can't open output file\n");
187         exit(1);
188     }
189
190     /* don't leave garbage at end of partial row */
191     (void) memset((genericptr_t) tile_bytes, 0, sizeof(tile_bytes));
192
193     for (i = 1; i < argc; i++)
194         process_file(argv[i]);
195     Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
196
197     /* round size up to the end of the row */
198     if ((header.ntiles % header.per_row) != 0) {
199         header.ntiles += header.per_row - (header.ntiles % header.per_row);
200     }
201
202 #ifdef USE_XPM
203     if (xpm_write(fp) == 0) {
204         Fprintf(stderr, "can't write XPM file\n");
205         exit(1);
206     }
207 #else
208     if (fwrite((char *) &header, sizeof(x11_header), 1, fp) == 0) {
209         Fprintf(stderr, "can't open output header\n");
210         exit(1);
211     }
212
213     if (fwrite((char *) x11_colormap, 1, header.ncolors * 3, fp) == 0) {
214         Fprintf(stderr, "can't write output colormap\n");
215         exit(1);
216     }
217
218     if (fwrite((char *) tile_bytes, 1,
219                (int) header.ntiles * header.tile_width * header.tile_height,
220                fp) == 0) {
221         Fprintf(stderr, "can't write tile bytes\n");
222         exit(1);
223     }
224 #endif
225
226     fclose(fp);
227     return 0;
228 }