2 * $Logfile: /Freespace2/code/Graphics/Bitblt.cpp $
7 * Code to do software bitblt type stuff
10 * Revision 1.1 2002/05/03 03:28:09 root
14 * 3 11/30/98 1:07p Dave
15 * 16 bit conversion, first run.
17 * 2 10/07/98 10:52a Dave
20 * 1 10/07/98 10:48a Dave
22 * 2 4/14/98 12:15p John
23 * Made 16-bpp movies work.
25 * 1 3/25/98 8:07p John
26 * Split software renderer into Win32 and DirectX
38 #include "grinternal.h"
40 // Headers for 2d functions
43 MONITOR( Num2dBitmaps );
45 void gr8_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
54 MONITOR_INC( Num2dBitmaps, 1 );
56 if ( !Current_alphacolor ) return;
58 // mprintf(( "x=%d, y=%d, w=%d, h=%d\n", x, y, w, h ));
59 // mprintf(( "sx=%d, sy=%d, bw=%d, bh=%d\n", sx, sy, bmp->w, bmp->h ));
61 bmp = bm_lock( gr_screen.current_bitmap, 8, BMP_RLE|BMP_NO_PALETTE_MAP );
65 if (bmp->flags & BMP_RLE) {
66 int * offsets = (int *)(bmp->data);
67 ubyte *lookup = &Current_alphacolor->table.lookup[0][0];
69 for (hi=0; hi < h; hi++ ) {
70 ubyte * dp = GR_SCREEN_PTR(ubyte,x,y+hi);
71 ubyte * sp = (ubyte *)bmp->data + offsets[sy+hi];
81 int run_span = count & 0x80;
83 count = (count & (~0x80))+1;
85 // This span crosses X1.. so skip some and draw some
86 if ( i+count >= x2 ) {
95 // We have 'count' pixels of c
96 ubyte *tmp_lookup = &lookup[c<<8];
99 *dp = tmp_lookup[*dp];
115 // We have 'count' un-rle'd pixels
119 *dp = lookup[(c<<8) | *dp];
142 int run_span = count & 0x80;
144 count = (count & (~0x80))+1;
145 if ( i+count >= x2 ) {
150 ubyte *end_ptr = dp + count;
158 // We have 'count' pixels of c
159 ubyte *tmp_lookup = &lookup[c<<8];
161 while( count >= 4 ) {
162 // We have to plot at least 4 pixels of constant color starting at 'dp'
163 dp[0] = tmp_lookup[dp[0]];
164 dp[1] = tmp_lookup[dp[1]];
165 dp[2] = tmp_lookup[dp[2]];
166 dp[3] = tmp_lookup[dp[3]];
172 while ( count > 0 ) {
173 *dp = tmp_lookup[*dp];
181 // We have 'count' un-rle'd pixels
184 *dp = lookup[(c<<8) | *dp];
186 } while ( dp < end_ptr );
195 ubyte * sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
196 ubyte *lookup = (ubyte *)&Current_alphacolor->table.lookup[0][0];
198 for (hi=0; hi<h; hi++ ) {
200 ubyte c, * sp = sptr;
201 ubyte * dp = GR_SCREEN_PTR(ubyte,x,hi+y);
202 for (j=0; j<w; j++ ) {
205 *dp = lookup[(c<<8) | *dp];
214 bm_unlock(gr_screen.current_bitmap);
218 void grx_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
225 int dx1=x, dx2=x+w-1;
226 int dy1=y, dy2=y+h-1;
229 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
234 if ( count > 1 ) Int3();
238 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
239 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
240 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
241 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
242 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
243 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
270 if ( w < 1 ) return; // clipped away!
271 if ( h < 1 ) return; // clipped away!
275 // Make sure clipping algorithm works
279 Assert( w == (dx2-dx1+1) );
280 Assert( h == (dy2-dy1+1) );
283 Assert( sx+w <= bw );
284 Assert( sy+h <= bh );
285 Assert( dx2 >= dx1 );
286 Assert( dy2 >= dy1 );
287 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
288 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
289 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
290 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
293 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
295 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
297 switch( gr_screen.bits_per_pixel ) {
299 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
303 Error( LOCATION, "Unsupported BPP=%d in grx_aabitmap_ex!\n", gr_screen.bytes_per_pixel );
310 void gr8_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
313 MONITOR_INC( Num2dBitmaps, 1 );
322 bmp = bm_lock( gr_screen.current_bitmap, 8, 0 );
323 sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
325 //mprintf(( "x=%d, y=%d, w=%d, h=%d\n", x, y, w, h ));
326 //mprintf(( "sx=%d, sy=%d, bw=%d, bh=%d\n", sx, sy, bmp->w, bmp->h ));
328 if ( bmp->flags & BMP_XPARENT ) {
329 for (i=0; i<h; i++ ) {
331 ubyte c, * sp = sptr;
332 ubyte * dp = GR_SCREEN_PTR(ubyte,x,i+y);
333 for (j=0; j<w; j++ ) {
335 if (c != 255) *dp = c;
341 for (i=0; i<h; i++ ) {
342 ubyte *dptr = GR_SCREEN_PTR(ubyte,x,i+y);
343 memcpy( dptr, sptr, w );
347 bm_unlock(gr_screen.current_bitmap);
355 void grx_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
362 int dx1=x, dx2=x+w-1;
363 int dy1=y, dy2=y+h-1;
366 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
371 if ( count > 1 ) Int3();
375 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
376 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
377 if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
378 if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
379 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
380 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
407 if ( w < 1 ) return; // clipped away!
408 if ( h < 1 ) return; // clipped away!
412 // Make sure clipping algorithm works
416 Assert( w == (dx2-dx1+1) );
417 Assert( h == (dy2-dy1+1) );
420 Assert( sx+w <= bw );
421 Assert( sy+h <= bh );
422 Assert( dx2 >= dx1 );
423 Assert( dy2 >= dy1 );
424 Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) );
425 Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) );
426 Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) );
427 Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) );
430 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
432 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
434 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
439 void grx_bitmap(int x,int y)
443 bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
444 int dx1=x, dx2=x+w-1;
445 int dy1=y, dy2=y+h-1;
448 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
449 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
450 if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
451 if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
452 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
453 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
455 if ( sx < 0 ) return;
456 if ( sy < 0 ) return;
457 if ( sx >= w ) return;
458 if ( sy >= h ) return;
460 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
462 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
465 void grx_aabitmap(int x,int y)
469 bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
470 int dx1=x, dx2=x+w-1;
471 int dy1=y, dy2=y+h-1;
474 if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return;
475 if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return;
476 if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; }
477 if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; }
478 if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; }
479 if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; }
481 if ( sx < 0 ) return;
482 if ( sy < 0 ) return;
483 if ( sx >= w ) return;
484 if ( sy >= h ) return;
486 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
488 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);