1 /* NetHack 3.6	tile2bin.c	$NHDT-Date: 1457207041 2016/03/05 19:44:01 $  $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */
2 /*   Copyright (c) NetHack PC Development Team 1993, 1994, 1995     */
3 /*   NetHack may be freely redistributed.  See license for details. */
4 
5 /*
6  * Edit History:
7  *
8  *	Initial Creation			M.Allison	93/10/21
9  *	ifndef MONITOR_HEAP for heaputil.c	P.Winner	94/03/12
10  *      added Borland C _stklen variable	Y.Sapir		94/05/01
11  *	fixed to use text tiles from win/share	M.Allison	95/01/31
12  *
13  */
14 
15 #include "hack.h"
16 #include "pcvideo.h"
17 #include "tile.h"
18 #include "pctiles.h"
19 
20 #include <dos.h>
21 #ifndef MONITOR_HEAP
22 #include <stdlib.h>
23 #endif
24 #include <time.h>
25 
26 #ifdef __GO32__
27 #include <unistd.h>
28 #endif
29 
30 #if defined(_MSC_VER) && _MSC_VER >= 700
31 #pragma warning(disable : 4309) /* initializing */
32 #pragma warning(disable : 4018) /* signed/unsigned mismatch */
33 #pragma warning(disable : 4131) /* old style declarator */
34 #pragma warning(disable : 4127) /* conditional express. is constant */
35 #endif
36 
37 #ifdef __BORLANDC__
38 extern unsigned _stklen = STKSIZ;
39 #endif
40 
41 /* Produce only a planar file if building the overview file; with packed
42    files, we can make overview-size tiles on the fly */
43 #if defined(OVERVIEW_FILE) && defined(PACKED_FILE)
44 #undef PACKED_FILE
45 #endif
46 
47 extern char *FDECL(tilename, (int, int));
48 
49 #ifdef PLANAR_FILE
50 char masktable[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
51 char charcolors[MAXCOLORMAPSIZE];
52 #ifdef OVERVIEW_FILE
53 struct overview_planar_cell_struct planetile;
54 #else
55 struct planar_cell_struct planetile;
56 #endif
57 FILE *tibfile1;
58 #endif
59 
60 #ifdef PACKED_FILE
61 char packtile[TILE_Y][TILE_X];
62 FILE *tibfile2;
63 #endif
64 
65 int num_colors;
66 pixel pixels[TILE_Y][TILE_X];
67 struct tibhdr_struct tibheader;
68 
69 static void FDECL(write_tibtile, (int));
70 static void FDECL(write_tibheader, (FILE *, struct tibhdr_struct *));
71 static void FDECL(build_tibtile, (pixel(*) [TILE_X], BOOLEAN_P));
72 static void NDECL(remap_colors);
73 
74 #ifndef OVERVIEW_FILE
75 char *tilefiles[] = { "../win/share/monsters.txt", "../win/share/objects.txt",
76                       "../win/share/other.txt" };
77 #else
78 char *tilefiles[] = { "../win/share/monthin.txt", "../win/share/objthin.txt",
79                       "../win/share/oththin.txt" };
80 #endif
81 
82 int tilecount;
83 int filenum;
84 int paletteflag;
85 
86 int
main(argc,argv)87 main(argc, argv)
88 int argc;
89 char *argv[];
90 {
91     int i;
92     struct tm *newtime;
93     time_t aclock;
94     char *paletteptr;
95     unsigned num_monsters = 0;
96 
97     if (argc != 1) {
98         Fprintf(stderr, "usage: tile2bin (from the util directory)\n");
99         exit(EXIT_FAILURE);
100     }
101 
102 #ifdef PLANAR_FILE
103 #ifndef OVERVIEW_FILE
104     tibfile1 = fopen(NETHACK_PLANAR_TILEFILE, WRBMODE);
105 #else
106     tibfile1 = fopen(NETHACK_OVERVIEW_TILEFILE, WRBMODE);
107 #endif
108     if (tibfile1 == (FILE *) 0) {
109         Fprintf(stderr, "Unable to open output file %s\n",
110 #ifndef OVERVIEW_FILE
111                 NETHACK_PLANAR_TILEFILE);
112 #else
113                 NETHACK_OVERVIEW_TILEFILE);
114 #endif
115         exit(EXIT_FAILURE);
116     }
117 #endif
118 
119 #ifdef PACKED_FILE
120     tibfile2 = fopen(NETHACK_PACKED_TILEFILE, WRBMODE);
121     if (tibfile2 == (FILE *) 0) {
122         Fprintf(stderr, "Unable to open output file %s\n",
123                 NETHACK_PACKED_TILEFILE);
124         exit(EXIT_FAILURE);
125     }
126 #endif
127     time(&aclock);
128     newtime = localtime(&aclock);
129 
130     tilecount = 0;
131     paletteflag = 0;
132     filenum = 0;
133     while (filenum < 3) {
134         if (!fopen_text_file(tilefiles[filenum], RDTMODE)) {
135             Fprintf(stderr,
136                     "usage: tile2bin (from the util or src directory)\n");
137             exit(EXIT_FAILURE);
138         }
139         num_colors = colorsinmap;
140         if (num_colors > 62) {
141             Fprintf(stderr, "too many colors (%d)\n", num_colors);
142             exit(EXIT_FAILURE);
143         }
144 
145         if (!paletteflag) {
146             remap_colors();
147             paletteptr = tibheader.palette;
148             for (i = 0; i < num_colors; i++) {
149                 *paletteptr++ = ColorMap[CM_RED][i],
150                 *paletteptr++ = ColorMap[CM_GREEN][i],
151                 *paletteptr++ = ColorMap[CM_BLUE][i];
152             }
153             paletteflag++;
154         }
155 
156         while (read_text_tile(pixels)) {
157             build_tibtile(pixels, FALSE);
158             write_tibtile(tilecount);
159             tilecount++;
160         }
161 
162         (void) fclose_text_file();
163         if (filenum == 0) {
164             num_monsters = tilecount;
165         }
166         ++filenum;
167     }
168 
169     /* Build the statue glyphs */
170     if (!fopen_text_file(tilefiles[0], RDTMODE)) {
171         Fprintf(stderr,
172                 "usage: tile2bin (from the util or src directory)\n");
173         exit(EXIT_FAILURE);
174     }
175 
176     while (read_text_tile(pixels)) {
177         build_tibtile(pixels, TRUE);
178         write_tibtile(tilecount);
179         tilecount++;
180     }
181 
182     (void) fclose_text_file();
183 
184 #if defined(_MSC_VER)
185     tibheader.compiler = MSC_COMP;
186 #elif defined(__BORLANDC__)
187     tibheader.compiler = BC_COMP;
188 #elif defined(__GO32__)
189     tibheader.compiler = DJGPP_COMP;
190 #else
191     tibheader.compiler = OTHER_COMP;
192 #endif
193 
194     strncpy(tibheader.ident, "NetHack 3.6 MSDOS Port binary tile file", 80);
195     strncpy(tibheader.timestamp, asctime(newtime), 24);
196     tibheader.timestamp[25] = '\0';
197     tibheader.tilecount = tilecount;
198     tibheader.numcolors = num_colors;
199 #ifdef PLANAR_FILE
200     tibheader.tilestyle = PLANAR_STYLE;
201     write_tibheader(tibfile1, &tibheader);
202     (void) fclose(tibfile1);
203 #ifndef OVERVIEW_FILE
204     Fprintf(stderr, "Total of %d planar tiles written to %s.\n", tilecount,
205             NETHACK_PLANAR_TILEFILE);
206 #else
207     Fprintf(stderr, "Total of %d planar tiles written to %s.\n", tilecount,
208             NETHACK_OVERVIEW_TILEFILE);
209 #endif
210 #endif
211 
212 #ifdef PACKED_FILE
213     tibheader.tilestyle = PACKED_STYLE;
214     write_tibheader(tibfile2, &tibheader);
215     Fprintf(stderr, "Total of %d packed tiles written to %s.\n", tilecount,
216             NETHACK_PACKED_TILEFILE);
217     (void) fclose(tibfile2);
218 #endif
219 
220     exit(EXIT_SUCCESS);
221     /*NOTREACHED*/
222     return 0;
223 }
224 
225 static void
write_tibheader(fileptr,tibhdr)226 write_tibheader(fileptr, tibhdr)
227 FILE *fileptr;
228 struct tibhdr_struct *tibhdr;
229 {
230     if (fseek(fileptr, 0L, SEEK_SET)) {
231         Fprintf(stderr, "Error writing header to tile file\n");
232     }
233     fwrite(tibhdr, sizeof(struct tibhdr_struct), 1, fileptr);
234 }
235 
236 static void
237 build_tibtile(pixels, statues)
238 pixel (*pixels)[TILE_X];
239 boolean statues;
240 {
241     static int graymappings[] = {
242         /* .  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  */
243         0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14
244     };
245     int i, j, k, co_off;
246     unsigned char co_mask, tmp;
247 
248 #ifdef PLANAR_FILE
249 #ifndef OVERVIEW_FILE
250     memset((void *) &planetile, 0, sizeof(struct planar_cell_struct));
251 #else
252     memset((void *) &planetile, 0,
253            sizeof(struct overview_planar_cell_struct));
254 #endif
255 #endif
256     for (j = 0; j < TILE_Y; j++) {
257         for (i = 0; i < TILE_X; i++) {
258             for (k = 0; k < num_colors; k++) {
259                 if (ColorMap[CM_RED][k] == pixels[j][i].r
260                     && ColorMap[CM_GREEN][k] == pixels[j][i].g
261                     && ColorMap[CM_BLUE][k] == pixels[j][i].b)
262                     break;
263             }
264             if (k >= num_colors)
265                 Fprintf(stderr, "color not in colormap!\n");
266             if (statues) {
267                 k = graymappings[k];
268             } else {
269                 if (k == 16) {
270                     k = 13;
271                 } else if (k == 13) {
272                     k = 16;
273                 }
274             }
275 #ifdef PACKED_FILE
276             packtile[j][i] = k;
277 #endif
278 
279 #ifdef PLANAR_FILE
280             if (i > 7) {
281                 co_off = 1;
282                 co_mask = masktable[i - 8];
283             } else {
284                 co_off = 0;
285                 co_mask = masktable[i];
286             }
287 
288             if (!statues) {
289                 if (k == 28) {
290                     k = 0;
291                 }
292                 if (k >= 16) {
293                     fprintf(stderr, "Warning: pixel value %d in 16 color bitmap\n", k);
294                 }
295             }
296             tmp = planetile.plane[0].image[j][co_off];
297             planetile.plane[0].image[j][co_off] =
298                 (k & 0x0008) ? (tmp | co_mask) : (tmp & ~co_mask);
299 
300             tmp = planetile.plane[1].image[j][co_off];
301             planetile.plane[1].image[j][co_off] =
302                 (k & 0x0004) ? (tmp | co_mask) : (tmp & ~co_mask);
303 
304             tmp = planetile.plane[2].image[j][co_off];
305             planetile.plane[2].image[j][co_off] =
306                 (k & 0x0002) ? (tmp | co_mask) : (tmp & ~co_mask);
307 
308             tmp = planetile.plane[3].image[j][co_off];
309             planetile.plane[3].image[j][co_off] =
310                 (k & 0x0001) ? (tmp | co_mask) : (tmp & ~co_mask);
311 #endif /* PLANAR_FILE */
312         }
313     }
314 }
315 
316 static void
write_tibtile(recnum)317 write_tibtile(recnum)
318 int recnum;
319 {
320     long fpos;
321 
322 #ifdef PLANAR_FILE
323 #ifndef OVERVIEW_FILE
324     fpos = ((long) (recnum) * (long) sizeof(struct planar_cell_struct))
325            + (long) TIBHEADER_SIZE;
326 #else
327     fpos =
328         ((long) (recnum) * (long) sizeof(struct overview_planar_cell_struct))
329         + (long) TIBHEADER_SIZE;
330 #endif
331     if (fseek(tibfile1, fpos, SEEK_SET)) {
332         Fprintf(stderr, "Error seeking before planar tile write %d\n",
333                 recnum);
334     }
335 #ifndef OVERVIEW_FILE
336     fwrite(&planetile, sizeof(struct planar_cell_struct), 1, tibfile1);
337 #else
338     fwrite(&planetile, sizeof(struct overview_planar_cell_struct), 1,
339            tibfile1);
340 #endif
341 #endif
342 
343 #ifdef PACKED_FILE
344     fpos =
345         ((long) (recnum) * (long) sizeof(packtile)) + (long) TIBHEADER_SIZE;
346     if (fseek(tibfile2, fpos, SEEK_SET)) {
347         Fprintf(stderr, "Error seeking before packed tile write %d\n",
348                 recnum);
349     }
350     fwrite(&packtile, sizeof(packtile), 1, tibfile2);
351 #endif
352 }
353 
354 static void
remap_colors()355 remap_colors()
356 {
357     char swap;
358 
359     swap = ColorMap[CM_RED][13];
360     ColorMap[CM_RED][13] = ColorMap[CM_RED][16];
361     ColorMap[CM_RED][16] = swap;
362     swap = ColorMap[CM_GREEN][13];
363     ColorMap[CM_GREEN][13] = ColorMap[CM_GREEN][16];
364     ColorMap[CM_GREEN][16] = swap;
365     swap = ColorMap[CM_BLUE][13];
366     ColorMap[CM_BLUE][13] = ColorMap[CM_BLUE][16];
367     ColorMap[CM_BLUE][16] = swap;
368 }
369