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