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