2 * $Logfile: /Freespace2/code/Graphics/Bitblt.cpp $
7 * Code to do software bitblt type stuff
10 * Revision 1.3 2002/06/05 08:05:29 relnev
11 * stub/warning removal.
13 * reworked the sound code.
15 * Revision 1.2 2002/05/28 21:36:10 relnev
16 * some more timer junk.
18 * tried to fix software mode.
20 * Revision 1.1.1.1 2002/05/03 03:28:09 root
24 * 3 11/30/98 1:07p Dave
25 * 16 bit conversion, first run.
27 * 2 10/07/98 10:52a Dave
30 * 1 10/07/98 10:48a Dave
32 * 2 4/14/98 12:15p John
33 * Made 16-bpp movies work.
35 * 1 3/25/98 8:07p John
36 * Split software renderer into Win32 and DirectX
48 #include "grinternal.h"
50 // Headers for 2d functions
53 MONITOR( Num2dBitmaps );
55 void gr8_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
64 MONITOR_INC( Num2dBitmaps, 1 );
66 if ( !Current_alphacolor ) return;
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 ));
71 bmp = bm_lock( gr_screen.current_bitmap, 8, BMP_RLE|BMP_NO_PALETTE_MAP );
75 if (bmp->flags & BMP_RLE) {
76 int * offsets = (int *)(bmp->data);
77 ubyte *lookup = &Current_alphacolor->table.lookup[0][0];
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];
91 int run_span = count & 0x80;
93 count = (count & (~0x80))+1;
95 // This span crosses X1.. so skip some and draw some
96 if ( i+count >= x2 ) {
105 // We have 'count' pixels of c
106 ubyte *tmp_lookup = &lookup[c<<8];
109 *dp = tmp_lookup[*dp];
125 // We have 'count' un-rle'd pixels
129 *dp = lookup[(c<<8) | *dp];
152 int run_span = count & 0x80;
154 count = (count & (~0x80))+1;
155 if ( i+count >= x2 ) {
160 ubyte *end_ptr = dp + count;
168 // We have 'count' pixels of c
169 ubyte *tmp_lookup = &lookup[c<<8];
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]];
182 while ( count > 0 ) {
183 *dp = tmp_lookup[*dp];
191 // We have 'count' un-rle'd pixels
194 *dp = lookup[(c<<8) | *dp];
196 } while ( dp < end_ptr );
205 ubyte * sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
206 ubyte *lookup = (ubyte *)&Current_alphacolor->table.lookup[0][0];
208 for (hi=0; hi<h; hi++ ) {
210 ubyte c, * sp = sptr;
211 ubyte * dp = GR_SCREEN_PTR(ubyte,x,hi+y);
212 for (j=0; j<w; j++ ) {
215 *dp = lookup[(c<<8) | *dp];
224 bm_unlock(gr_screen.current_bitmap);
228 void grx_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
235 int dx1=x, dx2=x+w-1;
236 int dy1=y, dy2=y+h-1;
239 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
244 if ( count > 1 ) Int3();
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; }
280 if ( w < 1 ) return; // clipped away!
281 if ( h < 1 ) return; // clipped away!
285 // Make sure clipping algorithm works
289 Assert( w == (dx2-dx1+1) );
290 Assert( h == (dy2-dy1+1) );
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) );
303 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
305 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
307 switch( gr_screen.bits_per_pixel ) {
309 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
313 Error( LOCATION, "Unsupported BPP=%d in grx_aabitmap_ex!\n", gr_screen.bytes_per_pixel );
320 void gr8_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
323 MONITOR_INC( Num2dBitmaps, 1 );
332 bmp = bm_lock( gr_screen.current_bitmap, 8, 0 );
333 sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
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 ));
338 if ( bmp->flags & BMP_XPARENT ) {
339 for (i=0; i<h; i++ ) {
341 ubyte c, * sp = sptr;
342 ubyte * dp = GR_SCREEN_PTR(ubyte,x,i+y);
343 for (j=0; j<w; j++ ) {
345 if (c != 255) *dp = c;
351 for (i=0; i<h; i++ ) {
352 ubyte *dptr = GR_SCREEN_PTR(ubyte,x,i+y);
353 memcpy( dptr, sptr, w );
357 bm_unlock(gr_screen.current_bitmap);
365 void grx_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
372 int dx1=x, dx2=x+w-1;
373 int dy1=y, dy2=y+h-1;
376 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
381 if ( count > 1 ) Int3();
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; }
417 if ( w < 1 ) return; // clipped away!
418 if ( h < 1 ) return; // clipped away!
422 // Make sure clipping algorithm works
426 Assert( w == (dx2-dx1+1) );
427 Assert( h == (dy2-dy1+1) );
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) );
440 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
442 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
444 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
449 void grx_bitmap(int x,int y)
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;
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; }
465 if ( sx < 0 ) return;
466 if ( sy < 0 ) return;
467 if ( sx >= w ) return;
468 if ( sy >= h ) return;
470 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
472 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
475 void grx_aabitmap(int x,int y)
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;
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; }
491 if ( sx < 0 ) return;
492 if ( sy < 0 ) return;
493 if ( sx >= w ) return;
494 if ( sy >= h ) return;
496 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
498 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);