OSDN Git Service

Initial Import
[nethackexpress/trunk.git] / win / share / tile2bmp.c
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
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
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
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
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
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 }