OSDN Git Service

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