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