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