OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / win / share / tiletext.c
1 /* NetHack 3.6  tiletext.c      $NHDT-Date: 1524689272 2018/04/25 20:47:52 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $ */
2 /*      Copyright (c) 2016 by Pasi Kallinen                       */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "config.h"
6 #include "tile.h"
7
8 pixval ColorMap[3][MAXCOLORMAPSIZE];
9 int colorsinmap;
10 pixval MainColorMap[3][MAXCOLORMAPSIZE];
11 int colorsinmainmap;
12
13 static short color_index[MAXCOLORMAPSIZE];
14 static int num_colors;
15 static char charcolors[MAXCOLORMAPSIZE];
16
17 static int placeholder_init = 0;
18 static pixel placeholder[TILE_Y][TILE_X];
19 static FILE *tile_file;
20 static int tile_set, tile_set_indx;
21 #if (TILE_X == 8)
22 static const char *text_sets[] = { "monthin.txt", "objthin.txt",
23                                    "oththin.txt" };
24 #else
25 static const char *text_sets[] = { "monsters.txt", "objects.txt",
26                                    "other.txt" };
27 #endif
28
29 extern const char *FDECL(tilename, (int, int));
30 extern boolean FDECL(acceptable_tilename, (int, const char *, const char *));
31 static void FDECL(read_text_colormap, (FILE *));
32 static boolean FDECL(write_text_colormap, (FILE *));
33 static boolean FDECL(read_txttile, (FILE *, pixel (*)[TILE_X]));
34 static void FDECL(write_txttile, (FILE *, pixel (*)[TILE_X]));
35
36 /* Ugh.  DICE doesn't like %[A-Z], so we have to spell it out... */
37 #define FORMAT_STRING                                                       \
38     "%[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.] = " \
39     "(%d, %d, %d) "
40
41 static int grayscale = 0;
42 /* grayscale color mapping */
43 static const int graymappings[] = {
44  /* .  A  B   C   D   E   F   G   H   I   J   K   L   M   N   O   P */
45     0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14
46 };
47
48 void
49 set_grayscale(g)
50 int g;
51 {
52     grayscale = g;
53 }
54
55 static void
56 read_text_colormap(txtfile)
57 FILE *txtfile;
58 {
59     int i, r, g, b;
60     char c[2];
61
62     for (i = 0; i < MAXCOLORMAPSIZE; i++)
63         color_index[i] = -1;
64
65     num_colors = 0;
66     while (fscanf(txtfile, FORMAT_STRING, c, &r, &g, &b) == 4) {
67         color_index[(int) c[0]] = num_colors;
68         ColorMap[CM_RED][num_colors] = r;
69         ColorMap[CM_GREEN][num_colors] = g;
70         ColorMap[CM_BLUE][num_colors] = b;
71         num_colors++;
72     }
73     colorsinmap = num_colors;
74 }
75
76 #undef FORMAT_STRING
77
78 static boolean
79 write_text_colormap(txtfile)
80 FILE *txtfile;
81 {
82     int i;
83     char c;
84
85     num_colors = colorsinmainmap;
86     if (num_colors > 62) {
87         Fprintf(stderr, "too many colors (%d)\n", num_colors);
88         return FALSE;
89     }
90     for (i = 0; i < num_colors; i++) {
91         if (i < 26)
92             c = 'A' + i;
93         else if (i < 52)
94             c = 'a' + i - 26;
95         else
96             c = '0' + i - 52;
97
98         charcolors[i] = c;
99         Fprintf(
100             txtfile, "%c = (%d, %d, %d)\n", c, (int) MainColorMap[CM_RED][i],
101             (int) MainColorMap[CM_GREEN][i], (int) MainColorMap[CM_BLUE][i]);
102     }
103     return TRUE;
104 }
105
106 static boolean
107 read_txttile(txtfile, pixels)
108 FILE *txtfile;
109 pixel (*pixels)[TILE_X];
110 {
111     int ph, i, j, k;
112     char buf[BUFSZ], ttype[BUFSZ];
113     const char *p;
114     char c[2];
115
116     if (fscanf(txtfile, "# %s %d (%[^)])", ttype, &i, buf) <= 0)
117         return FALSE;
118
119     ph = strcmp(ttype, "placeholder") == 0;
120
121     if (!ph && strcmp(ttype, "tile") != 0)
122         Fprintf(stderr, "Keyword \"%s\" unexpected for entry %d\n", ttype, i);
123
124     if (tile_set != 0) {
125         /* check tile name, but not relative number, which will
126          * change when tiles are added
127          */
128         p = tilename(tile_set, tile_set_indx);
129         if (p && strcmp(p, buf) && !acceptable_tilename(tile_set_indx,buf,p)) {
130             Fprintf(stderr, "warning: for tile %d (numbered %d) of %s,\n",
131                     tile_set_indx, i, text_sets[tile_set - 1]);
132             Fprintf(stderr, "\tfound '%s' while expecting '%s'\n", buf, p);
133         }
134     }
135     tile_set_indx++;
136
137     /* look for non-whitespace at each stage */
138     if (fscanf(txtfile, "%1s", c) < 0) {
139         Fprintf(stderr, "unexpected EOF\n");
140         return FALSE;
141     }
142     if (c[0] != '{') {
143         Fprintf(stderr, "didn't find expected '{'\n");
144         return FALSE;
145     }
146     for (j = 0; j < TILE_Y; j++) {
147         for (i = 0; i < TILE_X; i++) {
148             if (fscanf(txtfile, "%1s", c) < 0) {
149                 Fprintf(stderr, "unexpected EOF\n");
150                 return FALSE;
151             }
152             k = color_index[(int) c[0]];
153             if (grayscale) {
154                 if (k > (SIZE(graymappings) - 1))
155                     Fprintf(stderr, "Gray mapping issue %d > %d.\n", k,
156                             SIZE(graymappings) - 1);
157                 else
158                     k = graymappings[k];
159             }
160             if (k == -1)
161                 Fprintf(stderr, "color %c not in colormap!\n", c[0]);
162             else {
163                 pixels[j][i].r = ColorMap[CM_RED][k];
164                 pixels[j][i].g = ColorMap[CM_GREEN][k];
165                 pixels[j][i].b = ColorMap[CM_BLUE][k];
166             }
167         }
168     }
169     if (ph) {
170         /* remember it for later */
171         memcpy(placeholder, pixels, sizeof(placeholder));
172     }
173     if (fscanf(txtfile, "%1s ", c) < 0) {
174         Fprintf(stderr, "unexpected EOF\n");
175         return FALSE;
176     }
177     if (c[0] != '}') {
178         Fprintf(stderr, "didn't find expected '}'\n");
179         return FALSE;
180     }
181 #ifdef _DCC
182     /* DICE again... it doesn't seem to eat whitespace after the } like
183      * it should, so we have to do so manually.
184      */
185     while ((*c = fgetc(txtfile)) != EOF && isspace((uchar) *c))
186         ;
187     ungetc(*c, txtfile);
188 #endif
189     return TRUE;
190 }
191
192 static void
193 write_txttile(txtfile, pixels)
194 FILE *txtfile;
195 pixel (*pixels)[TILE_X];
196 {
197     const char *p;
198     const char *type;
199     int i, j, k;
200
201     if (memcmp(placeholder, pixels, sizeof(placeholder)) == 0)
202         type = "placeholder";
203     else
204         type = "tile";
205
206     if (tile_set == 0)
207         Fprintf(txtfile, "# %s %d (unknown)\n", type, tile_set_indx);
208     else {
209         p = tilename(tile_set, tile_set_indx);
210         if (p)
211             Fprintf(txtfile, "# %s %d (%s)\n", type, tile_set_indx, p);
212         else
213             Fprintf(txtfile, "# %s %d (null)\n", type, tile_set_indx);
214     }
215     tile_set_indx++;
216
217     Fprintf(txtfile, "{\n");
218     for (j = 0; j < TILE_Y; j++) {
219         Fprintf(txtfile, "  ");
220         for (i = 0; i < TILE_X; i++) {
221             for (k = 0; k < num_colors; k++) {
222                 if (ColorMap[CM_RED][k] == pixels[j][i].r
223                     && ColorMap[CM_GREEN][k] == pixels[j][i].g
224                     && ColorMap[CM_BLUE][k] == pixels[j][i].b)
225                     break;
226             }
227             if (k >= num_colors)
228                 Fprintf(stderr, "color not in colormap!\n");
229             (void) fputc(charcolors[k], txtfile);
230         }
231         Fprintf(txtfile, "\n");
232     }
233     Fprintf(txtfile, "}\n");
234 }
235
236 /* initialize main colormap from globally accessed ColorMap */
237 void
238 init_colormap()
239 {
240     int i;
241
242     colorsinmainmap = colorsinmap;
243     for (i = 0; i < colorsinmap; i++) {
244         MainColorMap[CM_RED][i] = ColorMap[CM_RED][i];
245         MainColorMap[CM_GREEN][i] = ColorMap[CM_GREEN][i];
246         MainColorMap[CM_BLUE][i] = ColorMap[CM_BLUE][i];
247     }
248 }
249
250 /* merge new colors from ColorMap into MainColorMap */
251 void
252 merge_colormap()
253 {
254     int i, j;
255
256     for (i = 0; i < colorsinmap; i++) {
257         for (j = 0; j < colorsinmainmap; j++) {
258             if (MainColorMap[CM_RED][j] == ColorMap[CM_RED][i]
259                 && MainColorMap[CM_GREEN][j] == ColorMap[CM_GREEN][i]
260                 && MainColorMap[CM_BLUE][j] == ColorMap[CM_BLUE][i])
261                 break;
262         }
263         if (j >= colorsinmainmap) { /* new color */
264             if (colorsinmainmap >= MAXCOLORMAPSIZE) {
265                 Fprintf(stderr,
266                         "Too many colors to merge -- excess ignored.\n");
267             }
268             j = colorsinmainmap;
269             MainColorMap[CM_RED][j] = ColorMap[CM_RED][i];
270             MainColorMap[CM_GREEN][j] = ColorMap[CM_GREEN][i];
271             MainColorMap[CM_BLUE][j] = ColorMap[CM_BLUE][i];
272             colorsinmainmap++;
273         }
274     }
275 }
276
277 boolean
278 fopen_text_file(filename, type)
279 const char *filename;
280 const char *type;
281 {
282     const char *p;
283     int i;
284
285     if (tile_file != (FILE *) 0) {
286         Fprintf(stderr, "can only open one text file at at time\n");
287         return FALSE;
288     }
289
290     tile_file = fopen(filename, type);
291     if (tile_file == (FILE *) 0) {
292         Fprintf(stderr, "cannot open text file %s\n", filename);
293         return FALSE;
294     }
295
296     p = rindex(filename, '/');
297     if (p)
298         p++;
299     else
300         p = filename;
301
302     tile_set = 0;
303     for (i = 0; i < SIZE(text_sets); i++) {
304         if (!strcmp(p, text_sets[i]))
305             tile_set = i + 1;
306     }
307     tile_set_indx = 0;
308
309     if (!strcmp(type, RDTMODE)) {
310         /* Fill placeholder with noise */
311         if (!placeholder_init) {
312             placeholder_init++;
313             for (i = 0; i < (int) sizeof placeholder; i++)
314                 ((char *) placeholder)[i] = i % 256;
315         }
316
317         read_text_colormap(tile_file);
318         if (!colorsinmainmap)
319             init_colormap();
320         else
321             merge_colormap();
322         return TRUE;
323     } else if (!strcmp(type, WRTMODE)) {
324         if (!colorsinmainmap) {
325             Fprintf(stderr, "no colormap set yet\n");
326             return FALSE;
327         }
328         return (write_text_colormap(tile_file));
329     } else {
330         Fprintf(stderr, "bad mode (%s) for fopen_text_file\n", type);
331         return FALSE;
332     }
333 }
334
335 boolean
336 read_text_tile(pixels)
337 pixel (*pixels)[TILE_X];
338 {
339     return (read_txttile(tile_file, pixels));
340 }
341
342 boolean
343 write_text_tile(pixels)
344 pixel (*pixels)[TILE_X];
345 {
346     write_txttile(tile_file, pixels);
347     return TRUE;
348 }
349
350 int
351 fclose_text_file()
352 {
353     int ret;
354
355     ret = fclose(tile_file);
356     tile_file = (FILE *) 0;
357     return ret;
358 }