1 /* SCCS Id: @(#)tile2bmp.c 3.4 2002/03/14 */
2 /* Copyright (c) NetHack PC Development Team 1995 */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 /*
6 * Edit History:
7 *
8 * Initial Creation M.Allison 1994/01/11
9 *
10 */
11
12 /* #pragma warning(4103:disable) */
13
14 #include "hack.h"
15 #include "tile.h"
16 #ifndef __GNUC__
17 #include "win32api.h"
18 #endif
19
20 /* #define COLORS_IN_USE MAXCOLORMAPSIZE /* 256 colors */
21 #if (TILE_X==32)
22 #define COLORS_IN_USE 256
23 #else
24 #define COLORS_IN_USE 16 /* 16 colors */
25 #endif
26
27 #define BITCOUNT 8
28
29 extern char *FDECL(tilename, (int, int));
30
31 #if BITCOUNT==4
32 #define MAX_X 320 /* 2 per byte, 4 bits per pixel */
33 #define MAX_Y 480
34 #else
35 # if (TILE_X==32)
36 #define MAX_X (32 * 40)
37 #define MAX_Y 960
38 # else
39 #define MAX_X 640 /* 1 per byte, 8 bits per pixel */
40 #define MAX_Y 480
41 # endif
42 #endif
43
44 /* GCC fix by Paolo Bonzini 1999/03/28 */
45 #ifdef __GNUC__
46 #define PACK __attribute__((packed))
47 #else
48 #define PACK
49 #endif
50
leshort(short x)51 static short leshort(short x)
52 {
53 #ifdef __BIG_ENDIAN__
54 return ((x&0xff)<<8)|((x>>8)&0xff);
55 #else
56 return x;
57 #endif
58 }
59
60
lelong(long x)61 static long lelong(long x)
62 {
63 #ifdef __BIG_ENDIAN__
64 return ((x&0xff)<<24)|((x&0xff00)<<8)|((x>>8)&0xff00)|((x>>24)&0xff);
65 #else
66 return x;
67 #endif
68 }
69
70 #ifdef __GNUC__
71 typedef struct tagBMIH {
72 unsigned long biSize;
73 long biWidth;
74 long biHeight;
75 unsigned short biPlanes;
76 unsigned short biBitCount;
77 unsigned long biCompression;
78 unsigned long biSizeImage;
79 long biXPelsPerMeter;
80 long biYPelsPerMeter;
81 unsigned long biClrUsed;
82 unsigned long biClrImportant;
83 } PACK BITMAPINFOHEADER;
84
85 typedef struct tagBMFH {
86 unsigned short bfType;
87 unsigned long bfSize;
88 unsigned short bfReserved1;
89 unsigned short bfReserved2;
90 unsigned long bfOffBits;
91 } PACK BITMAPFILEHEADER;
92
93 typedef struct tagRGBQ {
94 unsigned char rgbBlue;
95 unsigned char rgbGreen;
96 unsigned char rgbRed;
97 unsigned char rgbReserved;
98 } PACK RGBQUAD;
99 #define UINT unsigned int
100 #define DWORD unsigned long
101 #define LONG long
102 #define WORD unsigned short
103 #define BI_RGB 0L
104 #define BI_RLE8 1L
105 #define BI_RLE4 2L
106 #define BI_BITFIELDS 3L
107 #endif /* __GNUC__ */
108
109 #pragma pack(1)
110 struct tagBMP{
111 BITMAPFILEHEADER bmfh;
112 BITMAPINFOHEADER bmih;
113 #if BITCOUNT==4
114 #define RGBQUAD_COUNT 16
115 RGBQUAD bmaColors[RGBQUAD_COUNT];
116 #else
117 #if (TILE_X==32)
118 #define RGBQUAD_COUNT 256
119 #else
120 #define RGBQUAD_COUNT 16
121 #endif
122 RGBQUAD bmaColors[RGBQUAD_COUNT];
123 #endif
124 #if (COLORS_IN_USE==16)
125 uchar packtile[MAX_Y][MAX_X];
126 #else
127 uchar packtile[MAX_Y][MAX_X];
128 /* uchar packtile[TILE_Y][TILE_X]; */
129 #endif
130 } PACK bmp;
131 #pragma pack()
132
133 #define BMPFILESIZE (sizeof(struct tagBMP))
134
135 FILE *tibfile2;
136
137 pixel tilepixels[TILE_Y][TILE_X];
138
139 static void FDECL(build_bmfh,(BITMAPFILEHEADER *));
140 static void FDECL(build_bmih,(BITMAPINFOHEADER *));
141 static void FDECL(build_bmptile,(pixel (*)[TILE_X]));
142
143 char *tilefiles[] = {
144 #if (TILE_X == 32)
145 "../win/share/mon32.txt",
146 "../win/share/obj32.txt",
147 "../win/share/oth32.txt"
148 #else
149 "../win/share/monsters.txt",
150 "../win/share/objects.txt",
151 "../win/share/other.txt"
152 #endif
153 };
154
155 int num_colors = 0;
156 int tilecount;
157 int max_tiles_in_row = 40;
158 int tiles_in_row;
159 int filenum;
160 int initflag;
161 int yoffset,xoffset;
162 char bmpname[128];
163 FILE *fp;
164
165 int
main(argc,argv)166 main(argc, argv)
167 int argc;
168 char *argv[];
169 {
170 int i, j;
171
172 if (argc != 2) {
173 Fprintf(stderr, "usage: %s outfile.bmp\n", argv[0]);
174 exit(EXIT_FAILURE);
175 } else
176 strcpy(bmpname, argv[1]);
177
178 #ifdef OBSOLETE
179 bmpfile2 = fopen(NETHACK_PACKED_TILEFILE, WRBMODE);
180 if (bmpfile2 == (FILE *)0) {
181 Fprintf(stderr, "Unable to open output file %s\n",
182 NETHACK_PACKED_TILEFILE);
183 exit(EXIT_FAILURE);
184 }
185 #endif
186
187 tilecount = 0;
188 xoffset = yoffset = 0;
189 initflag = 0;
190 filenum = 0;
191 fp = fopen(bmpname,"wb");
192 if (!fp) {
193 printf("Error creating tile file %s, aborting.\n",bmpname);
194 exit(1);
195 }
196 while (filenum < (sizeof(tilefiles) / sizeof(char *))) {
197 if (!fopen_text_file(tilefiles[filenum], RDTMODE)) {
198 Fprintf(stderr,
199 "usage: tile2bmp (from the util directory)\n");
200 exit(EXIT_FAILURE);
201 }
202 num_colors = colorsinmap;
203 if (num_colors > 62) {
204 Fprintf(stderr, "too many colors (%d)\n", num_colors);
205 exit(EXIT_FAILURE);
206 }
207 if (!initflag) {
208 build_bmfh(&bmp.bmfh);
209 build_bmih(&bmp.bmih);
210 for (i = 0; i < MAX_Y; ++i)
211 for (j = 0; j < MAX_X; ++j)
212 bmp.packtile[i][j] = (uchar)0;
213 for (i = 0; i < num_colors; i++) {
214 bmp.bmaColors[i].rgbRed = ColorMap[CM_RED][i];
215 bmp.bmaColors[i].rgbGreen = ColorMap[CM_GREEN][i];
216 bmp.bmaColors[i].rgbBlue = ColorMap[CM_BLUE][i];
217 bmp.bmaColors[i].rgbReserved = 0;
218 }
219 initflag = 1;
220 }
221 /* printf("Colormap initialized\n"); */
222 while (read_text_tile(tilepixels)) {
223 build_bmptile(tilepixels);
224 tilecount++;
225 #if BITCOUNT==4
226 xoffset += (TILE_X / 2);
227 #else
228 xoffset += TILE_X;
229 #endif
230 if (xoffset >= MAX_X) {
231 yoffset += TILE_Y;
232 xoffset = 0;
233 }
234 }
235 (void) fclose_text_file();
236 ++filenum;
237 }
238 fwrite(&bmp, sizeof(bmp), 1, fp);
239 fclose(fp);
240 Fprintf(stderr, "Total of %d tiles written to %s.\n",
241 tilecount, bmpname);
242
243 exit(EXIT_SUCCESS);
244 /*NOTREACHED*/
245 return 0;
246 }
247
248
249 static void
build_bmfh(pbmfh)250 build_bmfh(pbmfh)
251 BITMAPFILEHEADER *pbmfh;
252 {
253 pbmfh->bfType = leshort(0x4D42);
254 pbmfh->bfSize = lelong(BMPFILESIZE);
255 pbmfh->bfReserved1 = (UINT)0;
256 pbmfh->bfReserved2 = (UINT)0;
257 pbmfh->bfOffBits = lelong(sizeof(bmp.bmfh) + sizeof(bmp.bmih) +
258 (RGBQUAD_COUNT * sizeof(RGBQUAD)));
259 }
260
261 static void
build_bmih(pbmih)262 build_bmih(pbmih)
263 BITMAPINFOHEADER *pbmih;
264 {
265 WORD cClrBits;
266 int w,h;
267 pbmih->biSize = lelong(sizeof(bmp.bmih));
268 #if BITCOUNT==4
269 pbmih->biWidth = lelong(w = MAX_X * 2);
270 #else
271 pbmih->biWidth = lelong(w = MAX_X);
272 #endif
273 pbmih->biHeight = lelong(h = MAX_Y);
274 pbmih->biPlanes = leshort(1);
275 #if BITCOUNT==4
276 pbmih->biBitCount = leshort(4);
277 cClrBits = 4;
278 #else
279 pbmih->biBitCount = leshort(8);
280 cClrBits = 8;
281 #endif
282 if (cClrBits == 1)
283 cClrBits = 1;
284 else if (cClrBits <= 4)
285 cClrBits = 4;
286 else if (cClrBits <= 8)
287 cClrBits = 8;
288 else if (cClrBits <= 16)
289 cClrBits = 16;
290 else if (cClrBits <= 24)
291 cClrBits = 24;
292 else cClrBits = 32;
293 pbmih->biCompression = lelong(BI_RGB);
294 pbmih->biXPelsPerMeter = lelong(0);
295 pbmih->biYPelsPerMeter = lelong(0);
296 #if (TILE_X==32)
297 if (cClrBits < 24)
298 pbmih->biClrUsed = lelong(1<<cClrBits);
299 #else
300 pbmih->biClrUsed = lelong(RGBQUAD_COUNT);
301 #endif
302
303 #if (TILE_X==16)
304 pbmih->biSizeImage = lelong(0);
305 #else
306 pbmih->biSizeImage = lelong(((w * cClrBits +31) & ~31) /8 * h);
307 #endif
308 pbmih->biClrImportant = (DWORD)0;
309 }
310
311 static void
312 build_bmptile(pixels)
313 pixel (*pixels)[TILE_X];
314 {
315 int cur_x, cur_y, cur_color;
316 int x,y;
317
318 for (cur_y = 0; cur_y < TILE_Y; cur_y++) {
319 for (cur_x = 0; cur_x < TILE_X; cur_x++) {
320 for (cur_color = 0; cur_color < num_colors; cur_color++) {
321 if (ColorMap[CM_RED][cur_color] == pixels[cur_y][cur_x].r &&
322 ColorMap[CM_GREEN][cur_color]== pixels[cur_y][cur_x].g &&
323 ColorMap[CM_BLUE][cur_color] == pixels[cur_y][cur_x].b)
324 break;
325 }
326 if (cur_color >= num_colors)
327 Fprintf(stderr, "color not in colormap!\n");
328 y = (MAX_Y - 1) - (cur_y + yoffset);
329 #if BITCOUNT==4
330 x = (cur_x / 2) + xoffset;
331 bmp.packtile[y][x] = cur_x%2 ?
332 (uchar)(bmp.packtile[y][x] | cur_color) :
333 (uchar)(cur_color<<4);
334 #else
335 x = cur_x + xoffset;
336 bmp.packtile[y][x] = (uchar)cur_color;
337 #endif
338 }
339 }
340 }
341