1 /* $Id: bitblt.c,v 1.17 2004-11-26 09:50:32 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * Routines for bitblt's.
25 #include "pa_enabl.h" //$$POLY_ACC
31 #include "byteswap.h" // because of rle code that has short for row offsets
42 int gr_bitblt_dest_step_shift = 0;
43 int gr_bitblt_double = 0;
44 ubyte *gr_bitblt_fade_table=NULL;
46 extern void gr_vesa_bitmap( grs_bitmap * source, grs_bitmap * dest, int x, int y );
48 void gr_linear_movsd( ubyte * source, ubyte * dest, unsigned int nbytes);
49 // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
51 #if !defined(NO_ASM) && defined(__WATCOMC__)
53 #pragma aux gr_linear_movsd parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
71 #elif !defined(NO_ASM) && defined(__GNUC__)
73 inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels) {
75 __asm__ __volatile__ (
92 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
93 : "0" (src), "1" (dest), "2" (num_pixels)
97 #elif !defined(NO_ASM) && defined(_MSC_VER)
99 __inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels)
104 mov ecx, [num_pixels]
124 #else // NO_ASM or unknown compiler
129 #define test_byteblit 0
131 ubyte test_byteblit = 0;
134 void gr_linear_movsd(ubyte * src, ubyte * dest, unsigned int num_pixels )
141 // check to see if we are starting on an even byte boundry
142 // if not, move appropriate number of bytes to even
145 if ( (num_pixels < THRESHOLD) || (((int)src & 0x7) != ((int)dest & 0x7)) || test_byteblit ) {
146 for (i = 0; i < num_pixels; i++)
152 if ((r = (int)src & 0x7)) {
153 for (i = 0; i < 8 - r; i++)
162 for (i = 0; i < n; i++)
166 for (i = 0; i < r; i++)
170 #endif //#ifdef NO_ASM
173 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels );
175 #if !defined(NO_ASM) && defined(__WATCOMC__)
177 #pragma aux gr_linear_rep_movsdm parm [esi] [edi] [ecx] modify exact [ecx esi edi eax] = \
181 "cmp al, " TRANSPARENCY_COLOR_STR \
189 #elif !defined(NO_ASM) && defined(__GNUC__)
191 static inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels ) {
193 __asm__ __volatile__ (
195 " movb (%%esi), %%al;"
197 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
199 " movb %%al,(%%edi);"
204 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
205 : "0" (src), "1" (dest), "2" (num_pixels)
209 #elif !defined(NO_ASM) && defined(_MSC_VER)
211 __inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
217 mov ecx, [num_pixels]
220 cmp al, TRANSPARENCY_COLOR
232 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
235 for (i=0; i<num_pixels; i++ ) {
236 if (*src != TRANSPARENCY_COLOR )
245 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value );
247 #if !defined(NO_ASM) && defined(__WATCOMC__)
249 #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] = \
255 "cmp al, " TRANSPARENCY_COLOR_STR \
257 "mov al, gr_fade_table[eax]" \
264 #elif !defined(NO_ASM) && defined(__GNUC__)
266 /* #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] */
267 static inline void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value ) {
269 __asm__ __volatile__ (
270 " xorl %%eax, %%eax;"
273 " movb (%%esi), %%al;"
275 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
278 " movb gr_fade_table(%%eax), %%al;"
280 " movb _gr_fade_table(%%eax), %%al;"
282 " movb %%al, (%%edi);"
287 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2]), "=b" (dummy[3])
288 : "0" (src), "1" (dest), "2" (num_pixels), "3" (fade_value)
292 #elif !defined(NO_ASM) && defined(_MSC_VER)
294 __inline void gr_linear_rep_movsdm_faded(void * src, void * dest, unsigned int num_pixels, ubyte fade_value )
299 mov ecx, [num_pixels]
300 movzx ebx, byte ptr [fade_value]
306 cmp al, TRANSPARENCY_COLOR
308 mov al, gr_fade_table[eax]
319 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value )
325 fade_base = gr_fade_table + (fade_value * 256);
327 for (i=num_pixels; i != 0; i-- )
330 if (source != (ubyte)TRANSPARENCY_COLOR )
331 *dest = *(fade_base + source);
340 void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels);
342 #if !defined(NO_ASM) && defined(__WATCOMC__)
344 #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
364 #elif !defined(NO_ASM) && defined (__GNUC__)
366 inline void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels)
368 /* #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] */
370 __asm__ __volatile__ (
373 "movb (%%esi), %%al;"
374 "movb %%al, (%%edi);"
380 "movb (%%esi), %%al;"
382 "movw %%ax, (%%edi);"
389 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
390 : "0" (src), "1" (dest), "2" (num_dest_pixels)
394 #elif !defined(NO_ASM) && defined(_MSC_VER)
396 __inline void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels)
401 mov ecx, [num_dest_pixels]
425 void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_pixels)
427 double *d = (double *)dest;
428 uint *s = (uint *)src;
433 if (num_pixels & 0x3) {
434 // not a multiple of 4? do single pixel at a time
435 for (i=0; i<num_pixels; i++) {
442 for (i = 0; i < num_pixels / 4; i++) {
445 temp = ((temp >> 8) & 0x00FFFF00) | (temp & 0xFF0000FF); // 0xABCDEFGH -> 0xABABCDEF
446 temp = ((temp >> 8) & 0x000000FF) | (temp & 0xFFFFFF00); // 0xABABCDEF -> 0xABABCDCD
447 doubletemp[0] = temp;
449 work = ((work << 8) & 0x00FFFF00) | (work & 0xFF0000FF); // 0xABCDEFGH -> 0xABEFGHGH
450 work = ((work << 8) & 0xFF000000) | (work & 0x00FFFFFF); // 0xABEFGHGH -> 0xEFEFGHGH
451 doubletemp[1] = work;
453 *d = *(double *) &(doubletemp[0]);
463 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
465 #if !defined(NO_ASM) && defined(__WATCOMC__)
467 #pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
476 #elif !defined(NO_ASM) && defined(__GNUC__)
478 static inline void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
479 /*#pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
480 __asm__ __volatile__ (
482 "movb (%%esi), %%al;"
484 "movb %%al, (%%edi);"
488 : : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
489 : "%eax", "%ecx", "%esi", "%edi");
494 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
498 num_pixels = num_pixels;
499 src_rowsize = src_rowsize;
500 dest_rowsize = dest_rowsize;
507 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
509 #if !defined(NO_ASM) && defined(__WATCOMC__)
511 #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
515 "cmp al, " TRANSPARENCY_COLOR_STR \
523 #elif !defined(NO_ASM) && defined(__GNUC__)
525 static inline void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
526 /* #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
528 __asm__ __volatile__ (
530 "movb (%%esi), %%al;"
532 "cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
534 "movb %%al, (%%edi);"
539 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
540 : "1" (src), "2" (dest), "0" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
546 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
550 num_pixels = num_pixels;
551 src_rowsize = src_rowsize;
552 dest_rowsize = dest_rowsize;
558 #endif /* __MSDOS__ */
560 void gr_ubitmap00( int x, int y, grs_bitmap *bm )
565 unsigned char * dest;
568 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
569 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
573 for (y1=0; y1 < bm->bm_h; y1++ ) {
574 if (gr_bitblt_double)
575 gr_linear_rep_movsd_2x( src, dest, bm->bm_w );
577 gr_linear_movsd( src, dest, bm->bm_w );
578 src += bm->bm_rowsize;
579 dest+= (int)(dest_rowsize);
583 void gr_ubitmap00m( int x, int y, grs_bitmap *bm )
588 unsigned char * dest;
591 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
592 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
596 if (gr_bitblt_fade_table==NULL) {
597 for (y1=0; y1 < bm->bm_h; y1++ ) {
598 gr_linear_rep_movsdm( src, dest, bm->bm_w );
599 src += bm->bm_rowsize;
600 dest+= (int)(dest_rowsize);
603 for (y1=0; y1 < bm->bm_h; y1++ ) {
604 gr_linear_rep_movsdm_faded( src, dest, bm->bm_w, gr_bitblt_fade_table[y1+y] );
605 src += bm->bm_rowsize;
606 dest+= (int)(dest_rowsize);
631 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels );
633 #if !defined(NO_ASM) && defined(__WATCOMC__)
635 #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
642 " mov al, [esi+8] " \
643 " mov ah, [esi+12] " \
646 " mov ah, [esi+4] " \
651 " jne next4pixels " \
664 #elif !defined (NO_ASM) && defined(__GNUC__)
666 static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) {
667 /* #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] */
669 __asm__ __volatile__ (
670 " movl %%ecx, %%ebx;"
676 " movb 8(%%esi), %%al;"
677 " movb 12(%%esi), %%ah;"
679 " movb (%%esi), %%al;"
680 " movb 4(%%esi), %%ah;"
681 " movl %%eax, (%%edi);"
690 " movb (%%esi), %%al;"
692 " movb %%al, (%%edi);"
697 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
698 : "1" (src), "2" (dest), "0" (npixels)
699 : "%eax", "%ebx", "%edx" );
704 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels )
714 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels );
716 #if !defined(NO_ASM) && defined(__WATCOMC__)
718 #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
725 " mov al, [esi+4] " \
726 " mov ah, [esi+6] " \
729 " mov ah, [esi+2] " \
734 " jne next4pixels " \
747 #elif !defined(NO_ASM) && defined(__GNUC__)
749 static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels ) {
750 /* #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = */
752 __asm__ __volatile__ (
753 " movl %%ecx, %%ebx;"
759 " movb 4(%%esi), %%al;"
760 " movb 6(%%esi), %%ah;"
762 " movb (%%esi), %%al;"
763 " movb 2(%%esi), %%ah;"
764 " movl %%eax, (%%edi);"
773 " movb (%%esi),%%al;"
775 " movb %%al, (%%edi);"
780 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
781 : "1" (src), "2" (dest), "0" (npixels)
782 : "%eax", "%ebx", "%edx" );
787 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels )
798 // From Linear to ModeX
799 void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
809 sstep = src->bm_rowsize;
810 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
812 if (!gr_bitblt_double) {
813 for (plane=0; plane<4; plane++ ) {
814 gr_modex_setplane( (plane+dx)&3 );
815 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane;
816 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
818 if ( (w&3) > plane ) w1++;
819 for (y=dy; y < dy+h; y++ ) {
820 modex_copy_scanline( sbits, dbits, w1 );
826 for (plane=0; plane<4; plane++ ) {
827 gr_modex_setplane( (plane+dx)&3 );
828 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane/2;
829 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
831 if ( (w&3) > plane ) w1++;
832 for (y=dy; y < dy+h; y++ ) {
833 modex_copy_scanline_2x( sbits, dbits, w1 );
842 // From Linear to ModeX masked
843 void gr_bm_ubitblt01m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
854 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
855 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + dx/4];
857 for (x=dx; x < dx+w; x++ ) {
858 gr_modex_setplane( x&3 );
862 //for (y=0; y < h; y++ ) {
863 // *dbits1 = *sbits1;
864 // sbits1 += src_bm_rowsize;
865 // dbits1 += dest_bm_rowsize;
867 modex_copy_column_m(sbits, dbits, h, src->bm_rowsize, dest->bm_rowsize << gr_bitblt_dest_step_shift );
875 #endif /* __MSDOS__ */
878 void gr_ubitmap012( int x, int y, grs_bitmap *bm )
885 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
886 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
887 gr_setcolor( *src++ );
893 void gr_ubitmap012m( int x, int y, grs_bitmap *bm )
900 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
901 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
902 if ( *src != TRANSPARENCY_COLOR ) {
911 #if defined(POLY_ACC)
912 void gr_ubitmap05( int x, int y, grs_bitmap *bm )
921 dst = (short *)(DATA + y * ROWSIZE + x * PA_BPP);
922 mod = ROWSIZE / 2 - bm->bm_w;
924 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
925 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
926 *dst++ = pa_clut[*src++];
932 void gr_ubitmap05m( int x, int y, grs_bitmap *bm )
941 dst = (short *)(DATA + y * ROWSIZE + x * PA_BPP);
942 mod = ROWSIZE / 2 - bm->bm_w;
944 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
945 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
946 if ( *src != TRANSPARENCY_COLOR ) {
947 *dst = pa_clut[*src];
956 void gr_bm_ubitblt05_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
958 unsigned short * dbits;
959 unsigned char * sbits, scanline[640];
960 int i, data_offset, j, nextrow;
963 nextrow=dest->bm_rowsize/PA_BPP;
966 if (src->bm_flags & BM_FLAG_RLE_BIG)
969 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
970 for (i=0; i<sy; i++ )
971 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
973 dbits = (unsigned short *)(dest->bm_data + (dest->bm_rowsize * dy) + dx*PA_BPP);
975 // No interlacing, copy the whole buffer.
976 for (i=0; i < h; i++ ) {
977 gr_rle_expand_scanline( scanline, sbits, sx, sx+w-1 );
978 for(j = 0; j != w; ++j)
979 dbits[j] = pa_clut[scanline[j]];
980 if ( src->bm_flags & BM_FLAG_RLE_BIG )
981 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
983 sbits += (int)(src->bm_data[4+i+sy]);
988 void gr_bm_ubitblt05m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
990 unsigned short * dbits;
991 unsigned char * sbits, scanline[640];
992 int i, data_offset, j, nextrow;
995 nextrow=dest->bm_rowsize/PA_BPP;
997 if (src->bm_flags & BM_FLAG_RLE_BIG)
1000 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1001 for (i=0; i<sy; i++ )
1002 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1004 dbits = (unsigned short *)(dest->bm_data + (dest->bm_rowsize * dy) + dx*PA_BPP);
1006 // No interlacing, copy the whole buffer.
1007 for (i=0; i < h; i++ ) {
1008 gr_rle_expand_scanline( scanline, sbits, sx, sx+w-1 );
1009 for(j = 0; j != w; ++j)
1010 if(scanline[j] != TRANSPARENCY_COLOR)
1011 dbits[j] = pa_clut[scanline[j]];
1012 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1013 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1015 sbits += (int)(src->bm_data[4+i+sy]);
1021 void gr_ubitmapGENERIC(int x, int y, grs_bitmap * bm)
1023 register int x1, y1;
1025 for (y1=0; y1 < bm->bm_h; y1++ ) {
1026 for (x1=0; x1 < bm->bm_w; x1++ ) {
1027 gr_setcolor( gr_gpixel(bm,x1,y1) );
1028 gr_upixel( x+x1, y+y1 );
1033 void gr_ubitmapGENERICm(int x, int y, grs_bitmap * bm)
1035 register int x1, y1;
1038 for (y1=0; y1 < bm->bm_h; y1++ ) {
1039 for (x1=0; x1 < bm->bm_w; x1++ ) {
1040 c = gr_gpixel(bm,x1,y1);
1041 if ( c != TRANSPARENCY_COLOR ) {
1043 gr_upixel( x+x1, y+y1 );
1051 // From linear to SVGA
1052 void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1054 unsigned char * sbits;
1056 unsigned int offset, EndingOffset, VideoLocation;
1058 int sbpr, dbpr, y1, page, BytesToMove;
1060 sbpr = src->bm_rowsize;
1062 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1064 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1066 sbits = src->bm_data + ( sbpr*sy ) + sx;
1068 for (y1=0; y1 < h; y1++ ) {
1070 page = VideoLocation >> 16;
1071 offset = VideoLocation & 0xFFFF;
1073 gr_vesa_setpage( page );
1075 EndingOffset = offset+w-1;
1077 if ( EndingOffset <= 0xFFFF )
1079 if ( gr_bitblt_double )
1080 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
1082 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), w );
1084 VideoLocation += dbpr;
1089 BytesToMove = 0xFFFF-offset+1;
1091 if ( gr_bitblt_double )
1092 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1094 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1097 gr_vesa_setpage(page);
1099 if ( gr_bitblt_double )
1100 gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
1102 gr_linear_movsd( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
1104 VideoLocation += dbpr;
1113 void gr_bm_ubitblt02m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1115 unsigned char * sbits;
1117 unsigned int offset, EndingOffset, VideoLocation;
1119 int sbpr, dbpr, y1, page, BytesToMove;
1121 sbpr = src->bm_rowsize;
1123 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1125 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1127 sbits = src->bm_data + ( sbpr*sy ) + sx;
1129 for (y1=0; y1 < h; y1++ ) {
1131 page = VideoLocation >> 16;
1132 offset = VideoLocation & 0xFFFF;
1134 gr_vesa_setpage( page );
1136 EndingOffset = offset+w-1;
1138 if ( EndingOffset <= 0xFFFF )
1140 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), w );
1142 VideoLocation += dbpr;
1147 BytesToMove = 0xFFFF-offset+1;
1149 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1152 gr_vesa_setpage(page);
1154 gr_linear_rep_movsdm( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
1156 VideoLocation += dbpr;
1163 // From SVGA to linear
1164 void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1166 unsigned char * dbits;
1168 unsigned int offset, offset1, offset2;
1170 int sbpr, dbpr, y1, page;
1172 dbpr = dest->bm_rowsize;
1174 sbpr = src->bm_rowsize;
1176 for (y1=0; y1 < h; y1++ ) {
1178 offset2 = (unsigned int)src->bm_data + (sbpr * (y1+sy)) + sx;
1179 dbits = dest->bm_data + (dbpr * (y1+dy)) + dx;
1181 page = offset2 >> 16;
1182 offset = offset2 & 0xFFFF;
1183 offset1 = offset+w-1;
1184 gr_vesa_setpage( page );
1186 if ( offset1 > 0xFFFF ) {
1187 // Overlaps two pages
1188 while( offset <= 0xFFFF )
1189 *dbits++ = gr_video_memory[offset++];
1190 offset1 -= (0xFFFF+1);
1193 gr_vesa_setpage(page);
1195 while( offset <= offset1 )
1196 *dbits++ = gr_video_memory[offset++];
1203 //@extern int Interlacing_on;
1205 // From Linear to Linear
1206 void gr_bm_ubitblt00(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1208 unsigned char * dbits;
1209 unsigned char * sbits;
1210 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1215 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1216 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1218 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1220 // No interlacing, copy the whole buffer.
1221 for (i=0; i < h; i++ ) {
1222 if (gr_bitblt_double)
1223 gr_linear_rep_movsd_2x( sbits, dbits, w );
1225 gr_linear_movsd( sbits, dbits, w );
1226 sbits += src->bm_rowsize;
1230 // From Linear to Linear Masked
1231 void gr_bm_ubitblt00m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1233 unsigned char * dbits;
1234 unsigned char * sbits;
1235 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1239 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1240 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1242 // No interlacing, copy the whole buffer.
1244 if (gr_bitblt_fade_table==NULL) {
1245 for (i=0; i < h; i++ ) {
1246 gr_linear_rep_movsdm( sbits, dbits, w );
1247 sbits += src->bm_rowsize;
1248 dbits += dest->bm_rowsize;
1251 for (i=0; i < h; i++ ) {
1252 gr_linear_rep_movsdm_faded( sbits, dbits, w, gr_bitblt_fade_table[dy+i] );
1253 sbits += src->bm_rowsize;
1254 dbits += dest->bm_rowsize;
1260 extern void gr_lbitblt( grs_bitmap * source, grs_bitmap * dest, int height, int width );
1264 // width == number of destination pixels
1266 void gr_linear_movsd_double(ubyte *src, ubyte *dest, int width)
1268 double *d = (double *)dest;
1269 uint *s = (uint *)src;
1274 num_pixels = width / 2;
1275 if ( (num_pixels & 0x3) || (((int)src & 0x7) != ((int)dest & 0x7)) ) {
1276 // not a multiple of 4? do single pixel at a time
1277 for (i=0; i<num_pixels; i++) {
1284 for (i = 0; i < num_pixels / 4; i++) {
1287 temp = ((temp >> 8) & 0x00FFFF00) | (temp & 0xFF0000FF); // 0xABCDEFGH -> 0xABABCDEF
1288 temp = ((temp >> 8) & 0x000000FF) | (temp & 0xFFFFFF00); // 0xABABCDEF -> 0xABABCDCD
1289 doubletemp[0] = temp;
1291 work = ((work << 8) & 0x00FFFF00) | (work & 0xFF0000FF); // 0xABCDEFGH -> 0xABEFGHGH
1292 work = ((work << 8) & 0xFF000000) | (work & 0x00FFFFFF); // 0xABEFGHGH -> 0xEFEFGHGH
1293 doubletemp[1] = work;
1295 *d = *(double *) &(doubletemp[0]);
1300 //extern void BlitLargeAlign(ubyte *draw_buffer, int dstRowBytes, ubyte *dstPtr, int w, int h, int modulus);
1302 asm void BlitLargeAlign(ubyte *rSrcPtr, int rDblDStrd, ubyte *rDst1Ptr, int rWidth, int rHeight, int rModulus)
1304 stw r31,-4(SP) // store non-volatile reg in red zone
1305 addi r5,r5,-8 // subtract 8 from dst
1306 stw r30,-8(SP) // store non-volatile reg in red zone
1308 la r30,-16(SP) // calculate copy of local 8-byte variable
1310 // rSStrd = modulus - w
1311 add r31,r5,r4 // dst2 = dstRowBytes + dst1
1312 sub r4,r4,r6 // r4 = dstRowBytes - w
1313 addi r7,r7,-1 // subtract 1 from height count
1314 srawi r6,r6,2 // rWidth = w >> 2
1315 addi r3,r3,-4 // subtract 4 from src
1316 addi r6,r6,-1 // subtract 1 from width count
1317 add r4,r4,r4 // rDblDStrd = 2 * r4
1319 BlitLargeAlignY: // y count is in r7
1320 lwzu r10,4(r3) // load a long into r10
1321 mr r0,r10 // put a copy in r0
1323 // these are simplified -- can't use 'em inslwi r0,r10,16,8
1324 // these are simplified -- can't use 'em insrwi r11,r10,16,8
1325 rlwimi r0,r10,24,8,31
1326 rlwimi r11,r10,8,8,23
1327 rlwimi r0,r10,16,24,31
1329 rlwimi r11,r10,16,0,7
1331 mtctr r6 // copy x count into the counter
1335 lwzu r10,4(r3) // load a long into r10
1337 mr r0,r10 // put a copy in r0
1339 // simplefied inslwi r0,r10,16,8
1340 // simplefied insrwi r11,r10,16,8
1341 rlwimi r0,r10,24,8,31
1342 rlwimi r11,r10,8,8,23
1343 rlwimi r0,r10,16,24,31
1345 rlwimi r11,r10,16,0,7
1349 bdnz BlitLargeAlignX // loop over all x
1352 addic. r7,r7,-1 // decrement the counter
1360 bne BlitLargeAlignY // loop for all y
1362 lwz r30,-8(SP) // restore non-volatile regs
1363 lwz r31,-4(SP) // restore non-volatile regs
1364 blr // return to caller
1367 void gr_bm_ubitblt_double(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap *src, grs_bitmap *dest)
1373 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1374 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1375 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1376 Assert( !((int)dbits & 0x7) ); // assert to check double word alignment
1377 BlitLargeAlign(sbits, dstep, dbits, src->bm_w, src->bm_h, src->bm_rowsize);
1380 // w and h are the doubled width and height
1382 void gr_bm_ubitblt_double_slow(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap *src, grs_bitmap *dest)
1388 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1389 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1390 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1392 for (i=0; i < h; i++ ) {
1394 gr_linear_movsd_double(sbits, dbits, w);
1397 sbits += src->bm_rowsize;
1401 #endif /* MACINTOSH */
1404 // Clipped bitmap ...
1406 void gr_bitmap( int x, int y, grs_bitmap *bm )
1408 int dx1=x, dx2=x+bm->bm_w-1;
1409 int dy1=y, dy2=y+bm->bm_h-1;
1412 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1413 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1414 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1415 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1416 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1417 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1419 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1421 gr_bm_ubitblt(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1425 //-NOT-used // From linear to SVGA
1426 //-NOT-used void gr_bm_ubitblt02_2x(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1428 //-NOT-used unsigned char * sbits;
1430 //-NOT-used unsigned int offset, EndingOffset, VideoLocation;
1432 //-NOT-used int sbpr, dbpr, y1, page, BytesToMove;
1434 //-NOT-used sbpr = src->bm_rowsize;
1436 //-NOT-used dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1438 //-NOT-used VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1440 //-NOT-used sbits = src->bm_data + ( sbpr*sy ) + sx;
1442 //-NOT-used for (y1=0; y1 < h; y1++ ) {
1444 //-NOT-used page = VideoLocation >> 16;
1445 //-NOT-used offset = VideoLocation & 0xFFFF;
1447 //-NOT-used gr_vesa_setpage( page );
1449 //-NOT-used EndingOffset = offset+w-1;
1451 //-NOT-used if ( EndingOffset <= 0xFFFF )
1453 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
1455 //-NOT-used VideoLocation += dbpr;
1456 //-NOT-used sbits += sbpr;
1460 //-NOT-used BytesToMove = 0xFFFF-offset+1;
1462 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1465 //-NOT-used gr_vesa_setpage(page);
1467 //-NOT-used gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
1469 //-NOT-used VideoLocation += dbpr;
1470 //-NOT-used sbits += sbpr;
1478 //-NOT-used // From Linear to Linear
1479 //-NOT-used void gr_bm_ubitblt00_2x(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1481 //-NOT-used unsigned char * dbits;
1482 //-NOT-used unsigned char * sbits;
1483 //-NOT-used //int src_bm_rowsize_2, dest_bm_rowsize_2;
1487 //-NOT-used sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1488 //-NOT-used dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1490 //-NOT-used // No interlacing, copy the whole buffer.
1491 //-NOT-used for (i=0; i < h; i++ ) {
1492 //-NOT-used gr_linear_rep_movsd_2x( sbits, dbits, w );
1494 //-NOT-used sbits += src->bm_rowsize;
1495 //-NOT-used dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1499 void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1501 unsigned char * dbits;
1502 unsigned char * sbits;
1506 if (src->bm_flags & BM_FLAG_RLE_BIG)
1509 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1511 for (i=0; i<sy; i++ )
1512 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1514 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1516 // No interlacing, copy the whole buffer.
1517 for (i=0; i < h; i++ ) {
1518 gr_rle_expand_scanline( dbits, sbits, sx, sx+w-1 );
1519 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1520 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1522 sbits += (int)(src->bm_data[4+i+sy]);
1523 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1527 void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1529 unsigned char * dbits;
1530 unsigned char * sbits;
1534 if (src->bm_flags & BM_FLAG_RLE_BIG)
1537 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1538 for (i=0; i<sy; i++ )
1539 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1541 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1543 // No interlacing, copy the whole buffer.
1544 for (i=0; i < h; i++ ) {
1545 gr_rle_expand_scanline_masked( dbits, sbits, sx, sx+w-1 );
1546 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1547 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1549 sbits += (int)(src->bm_data[4+i+sy]);
1550 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1556 extern void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1557 extern void gr_rle_expand_scanline_generic_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1558 extern void gr_rle_expand_scanline_svga_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1560 void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1564 unsigned char * sbits;
1566 //mprintf( 0, "SVGA RLE!\n" );
1569 if (src->bm_flags & BM_FLAG_RLE_BIG)
1572 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1573 for (i=0; i<sy; i++ )
1574 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1576 for (y1=0; y1 < h; y1++ ) {
1577 gr_rle_expand_scanline_generic( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1578 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1579 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1581 sbits += (int)src->bm_data[4+y1+sy];
1586 void gr_bm_ubitblt0xm_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1590 unsigned char * sbits;
1592 //mprintf( 0, "SVGA RLE!\n" );
1595 if (src->bm_flags & BM_FLAG_RLE_BIG)
1598 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1599 for (i=0; i<sy; i++ )
1600 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1602 for (y1=0; y1 < h; y1++ ) {
1603 gr_rle_expand_scanline_generic_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1604 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1605 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1607 sbits += (int)src->bm_data[4+y1+sy];
1613 void gr_bm_ubitblt02m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1617 unsigned char * sbits;
1619 //mprintf( 0, "SVGA RLE!\n" );
1622 if (src->bm_flags & BM_FLAG_RLE_BIG)
1625 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1626 for (i=0; i<sy; i++ )
1627 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1629 for (y1=0; y1 < h; y1++ ) {
1630 gr_rle_expand_scanline_svga_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1631 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1632 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1634 sbits += (int)src->bm_data[4+y1+sy];
1639 void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1641 register int x1, y1;
1643 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR ))
1645 if ( src->bm_flags & BM_FLAG_RLE )
1646 gr_bm_ubitblt00_rle( w, h, dx, dy, sx, sy, src, dest );
1648 gr_bm_ubitblt00( w, h, dx, dy, sx, sy, src, dest );
1653 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1655 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1658 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1660 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1663 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1665 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1671 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
1673 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
1674 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 0);
1677 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_LINEAR ))
1681 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
1687 if ( (src->bm_flags & BM_FLAG_RLE ) && (src->bm_type == BM_LINEAR) ) {
1688 gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest );
1693 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA ))
1695 gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest );
1699 if ( (src->bm_type == BM_SVGA) && (dest->bm_type == BM_LINEAR ))
1701 gr_bm_ubitblt20( w, h, dx, dy, sx, sy, src, dest );
1705 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_MODEX ))
1707 gr_bm_ubitblt01( w, h, dx+XOFFSET, dy+YOFFSET, sx, sy, src, dest );
1712 #if defined(POLY_ACC)
1713 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR15 ))
1715 ubyte *s = src->bm_data + sy * src->bm_rowsize + sx;
1716 ushort *t = (ushort *)(dest->bm_data + dy * dest->bm_rowsize + dx * PA_BPP);
1721 for(x = 0; x < w; x++)
1722 t[x] = pa_clut[s[x]];
1723 s += src->bm_rowsize;
1724 t += dest->bm_rowsize / PA_BPP;
1729 if ( (src->bm_type == BM_LINEAR15) && (dest->bm_type == BM_LINEAR15 ))
1731 pa_blit(dest, dx, dy, src, sx, sy, w, h);
1736 for (y1=0; y1 < h; y1++ ) {
1737 for (x1=0; x1 < w; x1++ ) {
1738 gr_bm_pixel( dest, dx+x1, dy+y1, gr_gpixel(src,sx+x1,sy+y1) );
1743 void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1745 int dx1=dx, dx2=dx+dest->bm_w-1;
1746 int dy1=dy, dy2=dy+dest->bm_h-1;
1748 int sx1=sx, sx2=sx+src->bm_w-1;
1749 int sy1=sy, sy2=sy+src->bm_h-1;
1751 if ((dx1 >= dest->bm_w ) || (dx2 < 0)) return;
1752 if ((dy1 >= dest->bm_h ) || (dy2 < 0)) return;
1753 if ( dx1 < 0 ) { sx1 += -dx1; dx1 = 0; }
1754 if ( dy1 < 0 ) { sy1 += -dy1; dy1 = 0; }
1755 if ( dx2 >= dest->bm_w ) { dx2 = dest->bm_w-1; }
1756 if ( dy2 >= dest->bm_h ) { dy2 = dest->bm_h-1; }
1758 if ((sx1 >= src->bm_w ) || (sx2 < 0)) return;
1759 if ((sy1 >= src->bm_h ) || (sy2 < 0)) return;
1760 if ( sx1 < 0 ) { dx1 += -sx1; sx1 = 0; }
1761 if ( sy1 < 0 ) { dy1 += -sy1; sy1 = 0; }
1762 if ( sx2 >= src->bm_w ) { sx2 = src->bm_w-1; }
1763 if ( sy2 >= src->bm_h ) { sy2 = src->bm_h-1; }
1765 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1766 if ( dx2-dx1+1 < w )
1768 if ( dy2-dy1+1 < h )
1770 if ( sx2-sx1+1 < w )
1772 if ( sy2-sy1+1 < h )
1775 gr_bm_ubitblt(w,h, dx1, dy1, sx1, sy1, src, dest );
1778 void gr_ubitmap( int x, int y, grs_bitmap *bm )
1782 source = bm->bm_type;
1785 if (source==BM_LINEAR) {
1789 if ( bm->bm_flags & BM_FLAG_RLE )
1790 gr_bm_ubitblt00_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1792 gr_ubitmap00( x, y, bm );
1796 ogl_ubitmapm(x,y,bm);
1801 Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
1802 Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 0);
1807 if ( bm->bm_flags & BM_FLAG_RLE )
1808 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1810 gr_vesa_bitmap( bm, &grd_curcanv->cv_bitmap, x, y );
1813 gr_bm_ubitblt01(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1816 #if defined(POLY_ACC)
1818 if ( bm->bm_flags & BM_FLAG_RLE )
1819 gr_bm_ubitblt05_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1821 gr_ubitmap05( x, y, bm);
1826 gr_ubitmap012( x, y, bm );
1830 gr_ubitmapGENERIC(x, y, bm);
1835 void gr_ubitmapm( int x, int y, grs_bitmap *bm )
1839 source = bm->bm_type;
1842 Assert(x+bm->bm_w <= grd_curcanv->cv_w);
1844 Assert(y+bm->bm_h <= grd_curcanv->cv_h);
1848 _3dfx_Blit( x, y, bm );
1849 if ( _3dfx_skip_ddraw )
1853 if (source==BM_LINEAR) {
1857 if ( bm->bm_flags & BM_FLAG_RLE )
1858 gr_bm_ubitblt00m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1860 gr_ubitmap00m( x, y, bm );
1864 ogl_ubitmapm(x,y,bm);
1869 if (bm->bm_w < 35 && bm->bm_h < 35) {
1870 // ugly hack needed for reticle
1871 if ( bm->bm_flags & BM_FLAG_RLE )
1872 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap, 1 );
1874 gr_ubitmapGENERICm(x, y, bm);
1877 Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
1878 Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 1);
1883 if (bm->bm_flags & BM_FLAG_RLE)
1884 gr_bm_ubitblt02m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1885 //gr_bm_ubitblt0xm_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1887 gr_bm_ubitblt02m(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1888 //gr_ubitmapGENERICm(x, y, bm);
1891 gr_bm_ubitblt01m(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1894 #if defined(POLY_ACC)
1896 if ( bm->bm_flags & BM_FLAG_RLE )
1897 gr_bm_ubitblt05m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1899 gr_ubitmap05m( x, y, bm );
1904 gr_ubitmap012m( x, y, bm );
1908 gr_ubitmapGENERICm(x, y, bm);
1913 void gr_bitmapm( int x, int y, grs_bitmap *bm )
1915 int dx1=x, dx2=x+bm->bm_w-1;
1916 int dy1=y, dy2=y+bm->bm_h-1;
1919 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1920 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1921 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1922 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1923 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1924 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1926 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1928 if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_LINEAR ))
1930 if ( bm->bm_flags & BM_FLAG_RLE )
1931 gr_bm_ubitblt00m_rle(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1933 gr_bm_ubitblt00m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1937 else if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_SVGA ))
1939 gr_bm_ubitblt02m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1944 gr_bm_ubitbltm(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1948 void gr_bm_ubitbltm(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1950 register int x1, y1;
1954 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1956 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1959 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1961 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1964 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1966 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1971 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
1973 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
1974 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 1);
1977 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
1979 Assert ((int)src->bm_data == BM_D3D_RENDER || (int)src->bm_data == BM_D3D_DISPLAY);
1980 //Win32_BlitDirectXToDirectX (w, h, dx, dy, sx, sy, src->bm_data, dest->bm_data, 0);
1984 #if defined(POLY_ACC)
1985 if(src->bm_type == BM_LINEAR && dest->bm_type == BM_LINEAR15)
1993 s = (ubyte *)(src->bm_data + src->bm_rowsize * sy + sx);
1994 smod = src->bm_rowsize - w;
1995 d = (ushort *)(dest->bm_data + dest->bm_rowsize * dy + dx * PA_BPP);
1996 dmod = dest->bm_rowsize / PA_BPP - w;
1998 for (x1=w; x1--; ) {
1999 if ((u = *s) != TRANSPARENCY_COLOR)
2009 if(src->bm_type == BM_LINEAR15)
2011 Assert(src->bm_type == dest->bm_type); // I don't support 15 to 8 yet.
2012 pa_blit_transparent(dest, dx, dy, src, sx, sy, w, h);
2017 for (y1=0; y1 < h; y1++ ) {
2018 for (x1=0; x1 < w; x1++ ) {
2019 if ((c=gr_gpixel(src,sx+x1,sy+y1))!=TRANSPARENCY_COLOR)
2020 gr_bm_pixel( dest, dx+x1, dy+y1,c );
2026 // rescalling bitmaps, 10/14/99 Jan Bobrowski jb@wizard.ae.krakow.pl
2028 inline void scale_line(unsigned char *in, unsigned char *out, int ilen, int olen)
2030 int a = olen/ilen, b = olen%ilen;
2032 unsigned char *end = out + olen;
2048 void gr_bitmap_scale_to(grs_bitmap *src, grs_bitmap *dst)
2050 unsigned char *s = src->bm_data;
2051 unsigned char *d = dst->bm_data;
2053 int a = dst->bm_h/h, b = dst->bm_h%h;
2056 for(y=0; y<h; y++) {
2065 scale_line(s, d, src->bm_w, dst->bm_w);
2066 d += dst->bm_rowsize;
2068 s += src->bm_rowsize;
2072 void show_fullscr(grs_bitmap *bm)
2074 grs_bitmap * const scr = &grd_curcanv->cv_bitmap;
2077 if(bm->bm_type == BM_LINEAR && scr->bm_type == BM_OGL) {
2078 ogl_ubitblt_i(scr->bm_w,scr->bm_h,0,0,bm->bm_w,bm->bm_h,0,0,bm,scr);//use opengl to scale, faster and saves ram. -MPM
2082 if(scr->bm_type != BM_LINEAR) {
2083 grs_bitmap *tmp = gr_create_bitmap(scr->bm_w, scr->bm_h);
2084 gr_bitmap_scale_to(bm, tmp);
2085 gr_bitmap(0, 0, tmp);
2086 gr_free_bitmap(tmp);
2089 gr_bitmap_scale_to(bm, scr);