2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/Graphics/Bitblt.cpp $
15 * Code to do software bitblt type stuff
18 * Revision 1.4 2002/06/09 04:41:17 relnev
19 * added copyright header
21 * Revision 1.3 2002/06/05 08:05:29 relnev
22 * stub/warning removal.
24 * reworked the sound code.
26 * Revision 1.2 2002/05/28 21:36:10 relnev
27 * some more timer junk.
29 * tried to fix software mode.
31 * Revision 1.1.1.1 2002/05/03 03:28:09 root
35 * 3 11/30/98 1:07p Dave
36 * 16 bit conversion, first run.
38 * 2 10/07/98 10:52a Dave
41 * 1 10/07/98 10:48a Dave
43 * 2 4/14/98 12:15p John
44 * Made 16-bpp movies work.
46 * 1 3/25/98 8:07p John
47 * Split software renderer into Win32 and DirectX
59 #include "grinternal.h"
61 // Headers for 2d functions
64 MONITOR( Num2dBitmaps );
66 void gr8_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
75 MONITOR_INC( Num2dBitmaps, 1 );
77 if ( !Current_alphacolor ) return;
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 ));
82 bmp = bm_lock( gr_screen.current_bitmap, 8, BMP_RLE|BMP_NO_PALETTE_MAP );
86 if (bmp->flags & BMP_RLE) {
87 int * offsets = (int *)(bmp->data);
88 ubyte *lookup = &Current_alphacolor->table.lookup[0][0];
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];
102 int run_span = count & 0x80;
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 ) {
116 // We have 'count' pixels of c
117 ubyte *tmp_lookup = &lookup[c<<8];
120 *dp = tmp_lookup[*dp];
136 // We have 'count' un-rle'd pixels
140 *dp = lookup[(c<<8) | *dp];
163 int run_span = count & 0x80;
165 count = (count & (~0x80))+1;
166 if ( i+count >= x2 ) {
171 ubyte *end_ptr = dp + count;
179 // We have 'count' pixels of c
180 ubyte *tmp_lookup = &lookup[c<<8];
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]];
193 while ( count > 0 ) {
194 *dp = tmp_lookup[*dp];
202 // We have 'count' un-rle'd pixels
205 *dp = lookup[(c<<8) | *dp];
207 } while ( dp < end_ptr );
216 ubyte * sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
217 ubyte *lookup = (ubyte *)&Current_alphacolor->table.lookup[0][0];
219 for (hi=0; hi<h; hi++ ) {
221 ubyte c, * sp = sptr;
222 ubyte * dp = GR_SCREEN_PTR(ubyte,x,hi+y);
223 for (j=0; j<w; j++ ) {
226 *dp = lookup[(c<<8) | *dp];
235 bm_unlock(gr_screen.current_bitmap);
239 void grx_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
246 int dx1=x, dx2=x+w-1;
247 int dy1=y, dy2=y+h-1;
250 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
255 if ( count > 1 ) Int3();
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; }
291 if ( w < 1 ) return; // clipped away!
292 if ( h < 1 ) return; // clipped away!
296 // Make sure clipping algorithm works
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) );
314 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
316 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
318 switch( gr_screen.bits_per_pixel ) {
320 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
324 Error( LOCATION, "Unsupported BPP=%d in grx_aabitmap_ex!\n", gr_screen.bytes_per_pixel );
331 void gr8_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
334 MONITOR_INC( Num2dBitmaps, 1 );
343 bmp = bm_lock( gr_screen.current_bitmap, 8, 0 );
344 sptr = (ubyte *)( bmp->data + (sy*bmp->w+sx) );
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 ));
349 if ( bmp->flags & BMP_XPARENT ) {
350 for (i=0; i<h; i++ ) {
352 ubyte c, * sp = sptr;
353 ubyte * dp = GR_SCREEN_PTR(ubyte,x,i+y);
354 for (j=0; j<w; j++ ) {
356 if (c != 255) *dp = c;
362 for (i=0; i<h; i++ ) {
363 ubyte *dptr = GR_SCREEN_PTR(ubyte,x,i+y);
364 memcpy( dptr, sptr, w );
368 bm_unlock(gr_screen.current_bitmap);
376 void grx_bitmap_ex(int x,int y,int w,int h,int sx,int sy)
383 int dx1=x, dx2=x+w-1;
384 int dy1=y, dy2=y+h-1;
387 bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
392 if ( count > 1 ) Int3();
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; }
428 if ( w < 1 ) return; // clipped away!
429 if ( h < 1 ) return; // clipped away!
433 // Make sure clipping algorithm works
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) );
451 // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions.
453 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
455 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
460 void grx_bitmap(int x,int y)
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;
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; }
476 if ( sx < 0 ) return;
477 if ( sy < 0 ) return;
478 if ( sx >= w ) return;
479 if ( sy >= h ) return;
481 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
483 gr8_bitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);
486 void grx_aabitmap(int x,int y)
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;
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; }
502 if ( sx < 0 ) return;
503 if ( sy < 0 ) return;
504 if ( sx >= w ) return;
505 if ( sy >= h ) return;
507 // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2)
509 gr8_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy);