2 * $Logfile: /Freespace2/code/Graphics/Bitblt.cpp $
7 * Code to do software bitblt type stuff
10 * Revision 1.2 2002/05/28 21:36:10 relnev
11 * some more timer junk.
13 * tried to fix software mode.
15 * Revision 1.1.1.1 2002/05/03 03:28:09 root
19 * 3 11/30/98 1:07p Dave
20 * 16 bit conversion, first run.
22 * 2 10/07/98 10:52a Dave
25 * 1 10/07/98 10:48a Dave
27 * 2 4/14/98 12:15p John
28 * Made 16-bpp movies work.
30 * 1 3/25/98 8:07p John
31 * Split software renderer into Win32 and DirectX
43 #include "grinternal.h"
45 // Headers for 2d functions
48 MONITOR( Num2dBitmaps );
50 void gr8_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
59 MONITOR_INC( Num2dBitmaps, 1 );
61 if ( !Current_alphacolor ) return;
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 ));
66 bmp = bm_lock( gr_screen.current_bitmap, 8, BMP_RLE|BMP_NO_PALETTE_MAP );
70 if (bmp->flags & BMP_RLE) {
71 int * offsets = (int *)(bmp->data);
72 ubyte *lookup = &Current_alphacolor->table.lookup[0][0];
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];
86 int run_span = count & 0x80;
88 count = (count & (~0x80))+1;
90 // This span crosses X1.. so skip some and draw some
91 if ( i+count >= x2 ) {
100 // We have 'count' pixels of c
101 ubyte *tmp_lookup = &lookup[c<<8];
104 *dp = tmp_lookup[*dp];
120 // We have 'count' un-rle'd pixels
124 *dp = lookup[(c<<8) | *dp];
147 int run_span = count & 0x80;
149 count = (count & (~0x80))+1;
150 if ( i+count >= x2 ) {
155 ubyte *end_ptr = dp + count;
163 // We have 'count' pixels of c
164 ubyte *tmp_lookup = &lookup[c<<8];
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]];
177 while ( count > 0 ) {
178 *dp = tmp_lookup[*dp];
186 // We have 'count' un-rle'd pixels
189 *dp = lookup[(c<<8) | *dp];
191 } while ( dp < end_ptr );
200 ubyte * sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
201 ubyte *lookup = (ubyte *)&Current_alphacolor->table.lookup[0][0];
203 for (hi=0; hi<h; hi++ ) {
205 ubyte c, * sp = sptr;
206 ubyte * dp = GR_SCREEN_PTR(ubyte,x,hi+y);
207 for (j=0; j<w; j++ ) {
210 *dp = lookup[(c<<8) | *dp];
219 bm_unlock(gr_screen.current_bitmap);
223 void grx_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
230 int dx1=x, dx2=x+w-1;
231 int dy1=y, dy2=y+h-1;
234 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
239 if ( count > 1 ) Int3();
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; }
275 if ( w < 1 ) return; // clipped away!
276 if ( h < 1 ) return; // clipped away!
280 // Make sure clipping algorithm works
284 Assert( w == (dx2-dx1+1) );
285 Assert( h == (dy2-dy1+1) );
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) );
298 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
300 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
302 switch( gr_screen.bits_per_pixel ) {
304 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
308 Error( LOCATION, "Unsupported BPP=%d in grx_aabitmap_ex!\n", gr_screen.bytes_per_pixel );
315 void gr8_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
318 MONITOR_INC( Num2dBitmaps, 1 );
327 bmp = bm_lock( gr_screen.current_bitmap, 8, 0 );
328 sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
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++ ) {
336 ubyte c, * sp = sptr;
337 ubyte * dp = GR_SCREEN_PTR(ubyte,x,i+y);
338 for (j=0; j<w; j++ ) {
340 if (c != 255) *dp = c;
346 for (i=0; i<h; i++ ) {
347 ubyte *dptr = GR_SCREEN_PTR(ubyte,x,i+y);
348 memcpy( dptr, sptr, w );
352 bm_unlock(gr_screen.current_bitmap);
360 void grx_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
367 int dx1=x, dx2=x+w-1;
368 int dy1=y, dy2=y+h-1;
371 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
376 if ( count > 1 ) Int3();
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; }
412 if ( w < 1 ) return; // clipped away!
413 if ( h < 1 ) return; // clipped away!
417 // Make sure clipping algorithm works
421 Assert( w == (dx2-dx1+1) );
422 Assert( h == (dy2-dy1+1) );
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) );
435 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
437 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
439 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
444 void grx_bitmap(int x,int y)
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;
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; }
460 if ( sx < 0 ) return;
461 if ( sy < 0 ) return;
462 if ( sx >= w ) return;
463 if ( sy >= h ) return;
465 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
467 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
470 void grx_aabitmap(int x,int y)
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;
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; }
486 if ( sx < 0 ) return;
487 if ( sy < 0 ) return;
488 if ( sx >= w ) return;
489 if ( sy >= h ) return;
491 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
493 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);