]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/bitblt.cpp
stub/warning removal.
[taylor/freespace2.git] / src / graphics / bitblt.cpp
1 /*
2  * $Logfile: /Freespace2/code/Graphics/Bitblt.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Code to do software bitblt type stuff
8  *
9  * $Log$
10  * Revision 1.3  2002/06/05 08:05:29  relnev
11  * stub/warning removal.
12  *
13  * reworked the sound code.
14  *
15  * Revision 1.2  2002/05/28 21:36:10  relnev
16  * some more timer junk.
17  *
18  * tried to fix software mode.
19  *
20  * Revision 1.1.1.1  2002/05/03 03:28:09  root
21  * Initial import.
22  *
23  * 
24  * 3     11/30/98 1:07p Dave
25  * 16 bit conversion, first run.
26  * 
27  * 2     10/07/98 10:52a Dave
28  * Initial checkin.
29  * 
30  * 1     10/07/98 10:48a Dave
31  * 
32  * 2     4/14/98 12:15p John
33  * Made 16-bpp movies work.
34  * 
35  * 1     3/25/98 8:07p John
36  * Split software renderer into Win32 and DirectX
37  *
38  * $NoKeywords: $
39  */
40
41 #include "osapi.h"
42 #include "2d.h"
43 #include "bmpman.h"
44 #include "key.h"
45 #include "floating.h"
46 #include "palman.h"
47 #include "grsoft.h"
48 #include "grinternal.h"
49
50 // Headers for 2d functions
51 #include "bitblt.h"
52
53 MONITOR( Num2dBitmaps );        
54
55 void gr8_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
56 {
57 #if 0
58         int hi;
59         bitmap * bmp;
60
61         if ( w < 1 ) return;
62         if ( h < 1 ) return;
63
64         MONITOR_INC( Num2dBitmaps, 1 ); 
65
66         if ( !Current_alphacolor )      return;
67
68         //      mprintf(( "x=%d, y=%d, w=%d, h=%d\n", x, y, w, h ));
69         //      mprintf(( "sx=%d, sy=%d, bw=%d, bh=%d\n", sx, sy, bmp->w, bmp->h ));
70
71         bmp = bm_lock( gr_screen.current_bitmap, 8, BMP_RLE|BMP_NO_PALETTE_MAP );        
72
73         gr_lock();
74
75         if (bmp->flags & BMP_RLE)       {
76                 int * offsets = (int *)(bmp->data);
77                 ubyte *lookup = &Current_alphacolor->table.lookup[0][0];
78                         
79                 for (hi=0; hi < h; hi++ )    {
80                         ubyte * dp = GR_SCREEN_PTR(ubyte,x,y+hi);
81                         ubyte * sp = (ubyte *)bmp->data + offsets[sy+hi];
82
83                         int x1 = sx;
84                         int x2 = sx+w;
85                         int i = 0;                      
86
87                         while(i<x1)     {                       
88                                 int count;
89
90                                 count = int(*sp++);
91                                 int run_span = count & 0x80;
92
93                                 count = (count & (~0x80))+1;            
94                                 if ( i+count > x1 ) {
95                                         // This span crosses X1.. so skip some and draw some
96                                         if ( i+count >= x2 ) {
97                                                 count = x2 - i;
98                                         }
99
100                                         if ( run_span ) {
101                                                 // RLE'd data
102                                                 ubyte c = *sp++;
103
104                                                 if ( c > 0 )    {                                       
105                                                         // We have 'count' pixels of c
106                                                         ubyte *tmp_lookup = &lookup[c<<8];
107                                                         while( count-- ) {
108                                                                 if ( i >= x1 )  {
109                                                                         *dp = tmp_lookup[*dp];
110                                                                         dp++;
111                                                                 }
112                                                                 i++;
113                                                         }       
114                                                 } else {
115                                                         while( count-- ) {
116                                                                 if ( i >= x1 )  {
117                                                                         dp++;
118                                                                 }
119                                                                 i++;
120                                                         }       
121                                                 }
122                                         } else {
123                                                 // non RLE'd data
124
125                                                 // We have 'count' un-rle'd pixels
126                                                 while( count-- ) {
127                                                         if ( i >= x1 )  {
128                                                                 ubyte c = *sp;
129                                                                 *dp = lookup[(c<<8) | *dp];
130                                                                 dp++;
131                                                         }
132                                                         sp++;
133                                                         i++;
134                                                 }       
135                                         }
136
137                                 } else {
138                                         i += count;
139                                         if ( run_span ) {
140                                                 // RLE'd data
141                                                 sp++; 
142                                         } else {
143                                                 sp += count;
144                                         }
145                                 }
146                         }
147
148                         while(i<x2)     {                       
149                                 int count;
150
151                                 count = int(*sp++);
152                                 int run_span = count & 0x80;
153
154                                 count = (count & (~0x80))+1;            
155                                 if ( i+count >= x2 ) {
156                                         count = x2 - i;
157                                 }
158                                 i += count;
159
160                                 ubyte *end_ptr = dp + count;
161                                 
162                                 if ( count > 0 )        {
163                                         if ( run_span ) {
164                                                 // RLE'd data
165                                                 ubyte c = *sp++;
166
167                                                 if ( c > 0 )    {                                       
168                                                         // We have 'count' pixels of c
169                                                         ubyte *tmp_lookup = &lookup[c<<8];
170
171                                                         while( count >= 4 )     {
172                                                                 // We have to plot at least 4 pixels of constant color starting at 'dp'
173                                                                 dp[0] = tmp_lookup[dp[0]];
174                                                                 dp[1] = tmp_lookup[dp[1]];
175                                                                 dp[2] = tmp_lookup[dp[2]];
176                                                                 dp[3] = tmp_lookup[dp[3]];
177
178                                                                 count -= 4;
179                                                                 dp += 4;
180                                                         } 
181
182                                                         while ( count > 0 )     {
183                                                                 *dp = tmp_lookup[*dp];
184                                                                 dp++;
185                                                                 count--;
186                                                         }
187                                                 } 
188                                         } else {
189                                                 // non RLE'd data
190
191                                                 // We have 'count' un-rle'd pixels
192                                                 do {
193                                                         ubyte c = *sp++;
194                                                         *dp = lookup[(c<<8) | *dp];
195                                                         dp++;
196                                                 } while ( dp < end_ptr );
197                                         }
198                                 }
199
200                                 dp = end_ptr;
201                         }
202
203                 }
204         } else {
205                 ubyte * sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
206                 ubyte *lookup = (ubyte *)&Current_alphacolor->table.lookup[0][0];
207
208                 for (hi=0; hi<h; hi++ ) {
209                         int j;
210                         ubyte c, * sp = sptr;   
211                         ubyte * dp = GR_SCREEN_PTR(ubyte,x,hi+y);
212                         for (j=0; j<w; j++ )    {
213                                 c = *sp++;
214                                 if ( c > 0 ) {
215                                         *dp = lookup[(c<<8) | *dp];
216                                 }
217                                 dp++;
218                         }
219                         sptr += bmp->w;
220                 }
221         }
222
223         gr_unlock();
224         bm_unlock(gr_screen.current_bitmap);
225 #endif
226 }
227
228 void grx_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
229 {
230         int reclip;
231         #ifndef NDEBUG
232         int count = 0;
233         #endif
234
235         int dx1=x, dx2=x+w-1;
236         int dy1=y, dy2=y+h-1;
237
238         int bw, bh;
239         bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
240
241         do {
242                 reclip = 0;
243                 #ifndef NDEBUG
244                         if ( count > 1 ) Int3();
245                         count++;
246                 #endif
247         
248                 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
249                 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
250                 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
251                 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
252                 if ( dx2 > gr_screen.clip_right )       { dx2 = gr_screen.clip_right; }
253                 if ( dy2 > gr_screen.clip_bottom )      { dy2 = gr_screen.clip_bottom; }
254
255                 if ( sx < 0 ) {
256                         dx1 -= sx;
257                         sx = 0;
258                         reclip = 1;
259                 }
260
261                 if ( sy < 0 ) {
262                         dy1 -= sy;
263                         sy = 0;
264                         reclip = 1;
265                 }
266
267                 w = dx2-dx1+1;
268                 h = dy2-dy1+1;
269
270                 if ( sx + w > bw ) {
271                         w = bw - sx;
272                         dx2 = dx1 + w - 1;
273                 }
274
275                 if ( sy + h > bh ) {
276                         h = bh - sy;
277                         dy2 = dy1 + h - 1;
278                 }
279
280                 if ( w < 1 ) return;            // clipped away!
281                 if ( h < 1 ) return;            // clipped away!
282
283         } while (reclip);
284
285         // Make sure clipping algorithm works
286         #ifndef NDEBUG
287                 Assert( w > 0 );
288                 Assert( h > 0 );
289                 Assert( w == (dx2-dx1+1) );
290                 Assert( h == (dy2-dy1+1) );
291                 Assert( sx >= 0 );
292                 Assert( sy >= 0 );
293                 Assert( sx+w <= bw );
294                 Assert( sy+h <= bh );
295                 Assert( dx2 >= dx1 );
296                 Assert( dy2 >= dy1 );
297                 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
298                 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
299                 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
300                 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
301         #endif
302
303         // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
304
305         // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
306
307         switch( gr_screen.bits_per_pixel )      {
308         case 8: 
309                 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
310                 break;
311
312         default:
313                 Error( LOCATION, "Unsupported BPP=%d in grx_aabitmap_ex!\n", gr_screen.bytes_per_pixel );
314         }
315
316
317 }
318
319
320 void gr8_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
321 {
322 #if 0
323         MONITOR_INC( Num2dBitmaps, 1 ); 
324
325         gr_lock();
326
327         // Normal bitblt
328         int i;
329         bitmap * bmp;
330         ubyte * sptr;
331
332         bmp = bm_lock( gr_screen.current_bitmap, 8, 0 );
333         sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
334
335         //mprintf(( "x=%d, y=%d, w=%d, h=%d\n", x, y, w, h ));
336         //mprintf(( "sx=%d, sy=%d, bw=%d, bh=%d\n", sx, sy, bmp->w, bmp->h ));
337
338         if ( bmp->flags & BMP_XPARENT ) {
339                 for (i=0; i<h; i++ )    {
340                         int j;
341                         ubyte c, * sp = sptr;   
342                         ubyte * dp = GR_SCREEN_PTR(ubyte,x,i+y);
343                         for (j=0; j<w; j++ )    {
344                                 c = *sp++;
345                                 if (c != 255) *dp = c;
346                                 dp++;
347                         }
348                         sptr += bmp->w;
349                 }
350         } else {
351                 for (i=0; i<h; i++ )    {
352                         ubyte *dptr = GR_SCREEN_PTR(ubyte,x,i+y);
353                         memcpy( dptr, sptr, w );
354                         sptr += bmp->w;
355                 }
356         }
357         bm_unlock(gr_screen.current_bitmap);
358
359         gr_unlock();
360 #endif
361 }
362
363
364
365 void grx_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
366 {
367         int reclip;
368         #ifndef NDEBUG
369         int count = 0;
370         #endif
371
372         int dx1=x, dx2=x+w-1;
373         int dy1=y, dy2=y+h-1;
374
375         int bw, bh;
376         bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
377
378         do {
379                 reclip = 0;
380                 #ifndef NDEBUG
381                         if ( count > 1 ) Int3();
382                         count++;
383                 #endif
384         
385                 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
386                 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
387                 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
388                 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
389                 if ( dx2 > gr_screen.clip_right )       { dx2 = gr_screen.clip_right; }
390                 if ( dy2 > gr_screen.clip_bottom )      { dy2 = gr_screen.clip_bottom; }
391
392                 if ( sx < 0 ) {
393                         dx1 -= sx;
394                         sx = 0;
395                         reclip = 1;
396                 }
397
398                 if ( sy < 0 ) {
399                         dy1 -= sy;
400                         sy = 0;
401                         reclip = 1;
402                 }
403
404                 w = dx2-dx1+1;
405                 h = dy2-dy1+1;
406
407                 if ( sx + w > bw ) {
408                         w = bw - sx;
409                         dx2 = dx1 + w - 1;
410                 }
411
412                 if ( sy + h > bh ) {
413                         h = bh - sy;
414                         dy2 = dy1 + h - 1;
415                 }
416
417                 if ( w < 1 ) return;            // clipped away!
418                 if ( h < 1 ) return;            // clipped away!
419
420         } while (reclip);
421
422         // Make sure clipping algorithm works
423         #ifndef NDEBUG
424                 Assert( w > 0 );
425                 Assert( h > 0 );
426                 Assert( w == (dx2-dx1+1) );
427                 Assert( h == (dy2-dy1+1) );
428                 Assert( sx >= 0 );
429                 Assert( sy >= 0 );
430                 Assert( sx+w <= bw );
431                 Assert( sy+h <= bh );
432                 Assert( dx2 >= dx1 );
433                 Assert( dy2 >= dy1 );
434                 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
435                 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
436                 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
437                 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
438         #endif
439
440         // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
441
442         // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
443
444         gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
445 }
446
447
448
449 void grx_bitmap(int x,int y)
450 {
451         int w, h;
452
453         bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
454         int dx1=x, dx2=x+w-1;
455         int dy1=y, dy2=y+h-1;
456         int sx=0, sy=0;
457
458         if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
459         if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
460         if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
461         if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
462         if ( dx2 > gr_screen.clip_right )       { dx2 = gr_screen.clip_right; }
463         if ( dy2 > gr_screen.clip_bottom )      { dy2 = gr_screen.clip_bottom; }
464
465         if ( sx < 0 ) return;
466         if ( sy < 0 ) return;
467         if ( sx >= w ) return;
468         if ( sy >= h ) return;
469
470         // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
471
472         gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
473 }
474
475 void grx_aabitmap(int x,int y)
476 {
477         int w, h;
478
479         bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
480         int dx1=x, dx2=x+w-1;
481         int dy1=y, dy2=y+h-1;
482         int sx=0, sy=0;
483
484         if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
485         if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
486         if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
487         if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
488         if ( dx2 > gr_screen.clip_right )       { dx2 = gr_screen.clip_right; }
489         if ( dy2 > gr_screen.clip_bottom )      { dy2 = gr_screen.clip_bottom; }
490
491         if ( sx < 0 ) return;
492         if ( sy < 0 ) return;
493         if ( sx >= w ) return;
494         if ( sy >= h ) return;
495
496         // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
497
498         gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
499 }
500