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. */
6 * Convert the given input files into an output file that is expected
10 * + Two dimensional byte arrays are in row order and are not padded
11 * between rows (x11_colormap[][]).
13 #include "hack.h" /* for MAX_GLYPH */
15 #include "tile2x11.h" /* x11 output file header structure */
17 #define OUTNAME "x11tiles" /* output file name */
18 /* #define PRINT_COLORMAP */ /* define to print the colormap */
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];
25 /* Look up the given pixel and return its colormap index. */
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])
38 if (i == header.ncolors) {
39 Fprintf(stderr, "can't find color: [%u,%u,%u]\n", pix.r, pix.g,
43 return (unsigned char) (i & 0xFF);
46 /* Convert the tiles in the file to our format of bytes. */
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 */
52 unsigned char *tb = *tb_ptr;
53 unsigned long count = 0;
54 pixel tile[TILE_Y][TILE_X];
57 while (read_text_tile(tile)) {
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;
66 /* repoint at the upper-left corner of the next tile */
68 if (header.per_row == 1 || (total % header.per_row) == 0)
69 *tb_ptr += TILE_X * (TILE_Y - 1) * header.per_row;
76 /* Merge the current text colormap (ColorMap) with ours (x11_colormap). */
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])
89 if (j >= MAXCOLORMAPSIZE) {
90 Fprintf(stderr, "colormap overflow\n");
94 if (j == header.ncolors) { /* couldn't find it */
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]);
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];
109 /* Open the given file, read & merge the colormap, convert the tiles. */
116 if (!fopen_text_file(fname, RDTMODE)) {
117 Fprintf(stderr, "can't open file \"%s\"\n", fname);
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;
134 if (header.ncolors > 64) {
135 Fprintf(stderr, "Sorry, only configured for up to 64 colors\n");
137 /* All you need to do is add more char per color - below */
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]);
151 for (i = 0; i < (header.tile_height * header.ntiles) / header.per_row;
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);
159 Fprintf(fp, "\",\n");
162 return fprintf(fp, "};\n") >= 0;
174 header.version = 2; /* version 1 had no per_row field */
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;
182 Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...] [-grayscale txt_fileN]\n", argv[0]);
186 fp = fopen(OUTNAME, "w");
188 Fprintf(stderr, "can't open output file\n");
192 /* don't leave garbage at end of partial row */
193 (void) memset((genericptr_t) tile_bytes, 0, sizeof(tile_bytes));
195 for (i = 1; i < argc; i++) {
196 if (!strncmp(argv[i], "-grayscale", 10)) {
198 if (i < (argc - 1)) i++;
200 set_grayscale(FALSE);
202 process_file(argv[i]);
204 Fprintf(stdout, "Total tiles: %ld\n", header.ntiles);
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);
212 if (xpm_write(fp) == 0) {
213 Fprintf(stderr, "can't write XPM file\n");
217 if (fwrite((char *) &header, sizeof(x11_header), 1, fp) == 0) {
218 Fprintf(stderr, "can't open output header\n");
222 if (fwrite((char *) x11_colormap, 1, header.ncolors * 3, fp) == 0) {
223 Fprintf(stderr, "can't write output colormap\n");
227 if (fwrite((char *) tile_bytes, 1,
228 (int) header.ntiles * header.tile_width * header.tile_height,
230 Fprintf(stderr, "can't write tile bytes\n");