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