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