make gr_remap_font just reload the whole thing
[btb/d2x.git] / 2d / bitmap.c
1 /* $Id: bitmap.c,v 1.3 2002-07-17 21:55:19 bradleyb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include <conf.h>
17 #endif
18
19 #include <stdlib.h>
20 #include <stdio.h>
21
22 #include "u_mem.h"
23
24
25 #include "gr.h"
26 #include "grdef.h"
27 #include "u_dpmi.h"
28 #include "bitmap.h"
29 #include "error.h"
30
31 #ifdef OGL
32 #include "ogl_init.h"
33 #endif
34
35 void build_colormap_good( ubyte * palette, ubyte * colormap, int * freq );
36
37 void gr_set_bitmap_data (grs_bitmap *bm, unsigned char *data)
38 {
39 #ifdef OGL
40 //      if (bm->bm_data!=data)
41                 ogl_freebmtexture(bm);
42 #endif
43         bm->bm_data = data;
44 #ifdef D1XD3D
45         Assert (bm->iMagic == BM_MAGIC_NUMBER);
46         Win32_SetTextureBits (bm, data, bm->bm_flags & BM_FLAG_RLE);
47 #endif
48 }
49
50 void gr_init_bitmap( grs_bitmap *bm, int mode, int x, int y, int w, int h, int bytesperline, unsigned char * data ) // TODO: virtualize
51 {
52 #ifdef D1XD3D
53         Assert (bm->iMagic != BM_MAGIC_NUMBER || bm->pvSurface == NULL);
54 #endif
55
56         bm->bm_x = x;
57         bm->bm_y = y;
58         bm->bm_w = w;
59         bm->bm_h = h;
60         bm->bm_flags = 0;
61         bm->bm_type = mode;
62         bm->bm_rowsize = bytesperline;
63
64         bm->bm_data = NULL;
65 #ifdef D1XD3D
66         bm->iMagic = BM_MAGIC_NUMBER;
67         bm->pvSurface = NULL;
68 #endif
69
70 #ifdef D1XD3D
71         Win32_CreateTexture (bm);
72 #endif
73 #ifdef OGL
74         bm->bm_parent=NULL;bm->gltexture=NULL;
75 #endif
76
77 //      if (data != 0)
78                 gr_set_bitmap_data (bm, data);
79 /*
80         else
81                 gr_set_bitmap_data (bm, d_malloc (w * h));
82 */
83
84 #ifdef BITMAP_SELECTOR
85         bm->bm_selector = 0;
86 #endif
87 }
88
89 void gr_init_bitmap_alloc( grs_bitmap *bm, int mode, int x, int y, int w, int h, int bytesperline)
90 {
91         gr_init_bitmap(bm, mode, x, y, w, h, bytesperline, 0);
92         gr_set_bitmap_data(bm, d_malloc(w * h));
93 }
94
95 void gr_init_bitmap_data (grs_bitmap *bm) // TODO: virtulize
96 {
97         bm->bm_data = NULL;
98 #ifdef D1XD3D
99         Assert (bm->iMagic != BM_MAGIC_NUMBER);
100         bm->iMagic = BM_MAGIC_NUMBER;
101         bm->pvSurface = NULL;
102 #endif
103 #ifdef OGL
104 //      ogl_freebmtexture(bm);//not what we want here.
105         bm->bm_parent=NULL;bm->gltexture=NULL;
106 #endif
107 }
108
109 void gr_free_bitmap(grs_bitmap *bm )
110 {
111         gr_free_bitmap_data (bm);
112         if (bm!=NULL)
113                 d_free(bm);
114 }
115
116 void gr_free_bitmap_data (grs_bitmap *bm) // TODO: virtulize
117 {
118 #ifdef D1XD3D
119         Assert (bm->iMagic == BM_MAGIC_NUMBER);
120
121         Win32_FreeTexture (bm);
122         bm->iMagic = 0;
123         if (bm->bm_data == BM_D3D_RENDER)
124                 bm->bm_data = NULL;
125 #endif
126 #ifdef OGL
127         ogl_freebmtexture(bm);
128 #endif
129         if (bm->bm_data != NULL)
130                 d_free (bm->bm_data);
131         bm->bm_data = NULL;
132 }
133
134 void gr_init_sub_bitmap (grs_bitmap *bm, grs_bitmap *bmParent, int x, int y, int w, int h )     // TODO: virtualize
135 {
136         bm->bm_x = x + bmParent->bm_x;
137         bm->bm_y = y + bmParent->bm_y;
138         bm->bm_w = w;
139         bm->bm_h = h;
140         bm->bm_flags = bmParent->bm_flags;
141         bm->bm_type = bmParent->bm_type;
142         bm->bm_rowsize = bmParent->bm_rowsize;
143
144 #ifdef OGL
145         bm->gltexture=bmParent->gltexture;
146         bm->bm_parent=bmParent;
147 #endif
148 #ifdef D1XD3D
149         Assert (bmParent->iMagic == BM_MAGIC_NUMBER);
150         bm->iMagic = BM_MAGIC_NUMBER;
151         bm->pvSurface = bmParent->pvSurface;
152         if (bm->bm_type == BM_DIRECTX)
153         {
154                 bm->bm_data = bmParent->bm_data;
155         }
156         else
157 #endif
158         {
159                 bm->bm_data = bmParent->bm_data+(unsigned int)((y*bmParent->bm_rowsize)+x);
160         }
161
162 }
163
164 void gr_free_sub_bitmap(grs_bitmap *bm )
165 {
166         if (bm!=NULL)
167         {
168 #ifdef D1XD3D
169                 bm->iMagic = 0;
170 #endif
171                 d_free(bm);
172         }
173 }
174
175
176 grs_bitmap *gr_create_bitmap(int w, int h )
177 {
178         return gr_create_bitmap_raw (w, h, d_malloc(w * h));
179 }
180
181 grs_bitmap *gr_create_bitmap_raw(int w, int h, unsigned char * raw_data )
182 {
183     grs_bitmap *new;
184
185     new = (grs_bitmap *)d_malloc( sizeof(grs_bitmap) );
186         gr_init_bitmap (new, 0, 0, 0, w, h, w, raw_data);
187
188     return new;
189 }
190
191
192 grs_bitmap *gr_create_sub_bitmap(grs_bitmap *bm, int x, int y, int w, int h )
193 {
194     grs_bitmap *new;
195
196     new = (grs_bitmap *)d_malloc( sizeof(grs_bitmap) );
197         gr_init_sub_bitmap (new, bm, x, y, w, h);
198
199         return new;
200 }
201
202 void gr_set_bitmap_flags (grs_bitmap *pbm, int flags)
203 {
204 #ifdef D1XD3D
205         Assert (pbm->iMagic == BM_MAGIC_NUMBER);
206
207         if (pbm->pvSurface)
208         {
209                 if ((flags & BM_FLAG_TRANSPARENT) != (pbm->bm_flags & BM_FLAG_TRANSPARENT))
210                 {
211                         Win32_SetTransparent (pbm->pvSurface, flags & BM_FLAG_TRANSPARENT);
212                 }
213         }
214 #endif
215         pbm->bm_flags = flags;
216 }
217
218 void gr_set_transparent (grs_bitmap *pbm, int bTransparent)
219 {
220         if (bTransparent)
221         {
222                 gr_set_bitmap_flags (pbm, pbm->bm_flags | BM_FLAG_TRANSPARENT);
223         }
224         else
225         {
226                 gr_set_bitmap_flags (pbm, pbm->bm_flags & ~BM_FLAG_TRANSPARENT);
227         }
228 }
229
230 void gr_set_super_transparent (grs_bitmap *pbm, int bTransparent)
231 {
232         if (bTransparent)
233         {
234                 gr_set_bitmap_flags (pbm, pbm->bm_flags & ~BM_FLAG_SUPER_TRANSPARENT);
235         }
236         else
237         {
238                 gr_set_bitmap_flags (pbm, pbm->bm_flags | BM_FLAG_SUPER_TRANSPARENT);
239         }
240 }
241
242 void gr_remap_bitmap( grs_bitmap * bmp, ubyte * palette, int transparent_color, int super_transparent_color )
243 {
244         ubyte colormap[256];
245         int freq[256];
246
247         // This should be build_colormap_asm, but we're not using invert table, so...
248         build_colormap_good( palette, colormap, freq );
249
250         if ( (super_transparent_color>=0) && (super_transparent_color<=255))
251                 colormap[super_transparent_color] = 254;
252
253         if ( (transparent_color>=0) && (transparent_color<=255))
254                 colormap[transparent_color] = 255;
255
256         decode_data_asm(bmp->bm_data, bmp->bm_w * bmp->bm_h, colormap, freq );
257
258         if ( (transparent_color>=0) && (transparent_color<=255) && (freq[transparent_color]>0) )
259                 gr_set_transparent (bmp, 1);
260
261         if ( (super_transparent_color>=0) && (super_transparent_color<=255) && (freq[super_transparent_color]>0) )
262                 gr_set_super_transparent (bmp, 0);
263 }
264
265 void build_colormap_good( ubyte * palette, ubyte * colormap, int * freq )
266 {
267         int i, r, g, b;
268
269         for (i=0; i<256; i++ )  {
270                 r = *palette++;         
271                 g = *palette++;         
272                 b = *palette++;         
273                 *colormap++ = gr_find_closest_color( r, g, b );
274                 *freq++ = 0;
275         }
276 }
277
278
279 void gr_remap_bitmap_good( grs_bitmap * bmp, ubyte * palette, int transparent_color, int super_transparent_color )
280 {
281         ubyte colormap[256];
282         int freq[256];
283    
284         build_colormap_good( palette, colormap, freq );
285
286         if ( (super_transparent_color>=0) && (super_transparent_color<=255))
287                 colormap[super_transparent_color] = 254;
288
289         if ( (transparent_color>=0) && (transparent_color<=255))
290                 colormap[transparent_color] = 255;
291
292         decode_data_asm(bmp->bm_data, bmp->bm_w * bmp->bm_h, colormap, freq );
293
294         if ( (transparent_color>=0) && (transparent_color<=255) && (freq[transparent_color]>0) )
295                 gr_set_transparent (bmp, 1);
296
297         if ( (super_transparent_color>=0) && (super_transparent_color<=255) && (freq[super_transparent_color]>0) )
298                 gr_set_super_transparent (bmp, 1);
299 }
300
301 #ifdef BITMAP_SELECTOR
302 int gr_bitmap_assign_selector( grs_bitmap * bmp )
303 {
304         if (!dpmi_allocate_selector( bmp->bm_data, bmp->bm_w*bmp->bm_h, &bmp->bm_selector )) {
305                 bmp->bm_selector = 0;
306                 return 1;
307         }
308         return 0;
309 }
310 #endif
311
312 void gr_bitmap_check_transparency( grs_bitmap * bmp )
313 {
314         int x, y;
315         ubyte * data;
316
317         data = bmp->bm_data;
318         
319         for (y=0; y<bmp->bm_h; y++ )    {
320                 for (x=0; x<bmp->bm_w; x++ )    {
321                         if (*data++ == 255 )    {
322                                 gr_set_transparent (bmp, 1);
323                                 return;
324                         }
325                 }
326                 data += bmp->bm_rowsize - bmp->bm_w;
327         }
328
329         bmp->bm_flags = 0;
330
331 }