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