2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 * Routines for bitblt's.
27 #include "byteswap.h" // because of rle code that has short for row offsets
35 int gr_bitblt_dest_step_shift = 0;
36 int gr_bitblt_double = 0;
37 ubyte *gr_bitblt_fade_table=NULL;
39 extern void gr_vesa_bitmap( grs_bitmap * source, grs_bitmap * dest, int x, int y );
41 void gr_linear_movsd( ubyte * source, ubyte * dest, unsigned int nbytes);
42 // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
44 #if !defined(NO_ASM) && defined(__WATCOMC__)
46 #pragma aux gr_linear_movsd parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
64 #elif !defined(NO_ASM) && defined(__GNUC__)
66 inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels) {
68 __asm__ __volatile__ (
85 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
86 : "0" (src), "1" (dest), "2" (num_pixels)
90 #elif !defined(NO_ASM) && defined(_MSC_VER)
92 __inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels)
117 #else // NO_ASM or unknown compiler
122 #define test_byteblit 0
124 ubyte test_byteblit = 0;
127 void gr_linear_movsd(ubyte * src, ubyte * dest, unsigned int num_pixels )
134 // check to see if we are starting on an even byte boundry
135 // if not, move appropriate number of bytes to even
138 if ( (num_pixels < THRESHOLD) || (((int)src & 0x7) != ((int)dest & 0x7)) || test_byteblit ) {
139 for (i = 0; i < num_pixels; i++)
145 if ((r = (int)src & 0x7)) {
146 for (i = 0; i < 8 - r; i++)
155 for (i = 0; i < n; i++)
159 for (i = 0; i < r; i++)
163 #endif //#ifdef NO_ASM
166 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels );
168 #if !defined(NO_ASM) && defined(__WATCOMC__)
170 #pragma aux gr_linear_rep_movsdm parm [esi] [edi] [ecx] modify exact [ecx esi edi eax] = \
174 "cmp al, " TRANSPARENCY_COLOR_STR \
182 #elif !defined(NO_ASM) && defined(__GNUC__)
184 static inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels ) {
186 __asm__ __volatile__ (
188 " movb (%%esi), %%al;"
190 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
192 " movb %%al,(%%edi);"
197 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
198 : "0" (src), "1" (dest), "2" (num_pixels)
202 #elif !defined(NO_ASM) && defined(_MSC_VER)
204 __inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
210 mov ecx, [num_pixels]
213 cmp al, TRANSPARENCY_COLOR
225 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
228 for (i=0; i<num_pixels; i++ ) {
229 if (*src != TRANSPARENCY_COLOR )
238 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value );
240 #if !defined(NO_ASM) && defined(__WATCOMC__)
242 #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] = \
248 "cmp al, " TRANSPARENCY_COLOR_STR \
250 "mov al, gr_fade_table[eax]" \
257 #elif !defined(NO_ASM) && defined(__GNUC__)
259 /* #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] */
260 static inline void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value ) {
262 __asm__ __volatile__ (
263 " xorl %%eax, %%eax;"
266 " movb (%%esi), %%al;"
268 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
271 " movb gr_fade_table(%%eax), %%al;"
273 " movb _gr_fade_table(%%eax), %%al;"
275 " movb %%al, (%%edi);"
280 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2]), "=b" (dummy[3])
281 : "0" (src), "1" (dest), "2" (num_pixels), "3" (fade_value)
285 #elif !defined(NO_ASM) && defined(_MSC_VER)
287 __inline void gr_linear_rep_movsdm_faded(void * src, void * dest, unsigned int num_pixels, ubyte fade_value )
292 mov ecx, [num_pixels]
293 movzx ebx, byte ptr [fade_value]
299 cmp al, TRANSPARENCY_COLOR
301 mov al, gr_fade_table[eax]
312 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value )
318 fade_base = gr_fade_table + (fade_value * 256);
320 for (i=num_pixels; i != 0; i-- )
323 if (source != (ubyte)TRANSPARENCY_COLOR )
324 *dest = *(fade_base + source);
333 void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels);
335 #if !defined(NO_ASM) && defined(__WATCOMC__)
337 #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
357 #elif !defined(NO_ASM) && defined (__GNUC__)
359 inline void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels)
361 /* #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] */
363 __asm__ __volatile__ (
366 "movb (%%esi), %%al;"
367 "movb %%al, (%%edi);"
373 "movb (%%esi), %%al;"
375 "movw %%ax, (%%edi);"
382 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
383 : "0" (src), "1" (dest), "2" (num_dest_pixels)
387 #elif !defined(NO_ASM) && defined(_MSC_VER)
389 __inline void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels)
394 mov ecx, [num_dest_pixels]
418 void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_pixels)
420 double *d = (double *)dest;
421 uint *s = (uint *)src;
426 if (num_pixels & 0x3) {
427 // not a multiple of 4? do single pixel at a time
428 for (i=0; i<num_pixels; i++) {
435 for (i = 0; i < num_pixels / 4; i++) {
438 temp = ((temp >> 8) & 0x00FFFF00) | (temp & 0xFF0000FF); // 0xABCDEFGH -> 0xABABCDEF
439 temp = ((temp >> 8) & 0x000000FF) | (temp & 0xFFFFFF00); // 0xABABCDEF -> 0xABABCDCD
440 doubletemp[0] = temp;
442 work = ((work << 8) & 0x00FFFF00) | (work & 0xFF0000FF); // 0xABCDEFGH -> 0xABEFGHGH
443 work = ((work << 8) & 0xFF000000) | (work & 0x00FFFFFF); // 0xABEFGHGH -> 0xEFEFGHGH
444 doubletemp[1] = work;
446 *d = *(double *) &(doubletemp[0]);
456 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
458 #if !defined(NO_ASM) && defined(__WATCOMC__)
460 #pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
469 #elif !defined(NO_ASM) && defined(__GNUC__)
471 static inline void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
472 /*#pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
473 __asm__ __volatile__ (
475 "movb (%%esi), %%al;"
477 "movb %%al, (%%edi);"
481 : : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
482 : "%eax", "%ecx", "%esi", "%edi");
487 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
491 num_pixels = num_pixels;
492 src_rowsize = src_rowsize;
493 dest_rowsize = dest_rowsize;
500 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
502 #if !defined(NO_ASM) && defined(__WATCOMC__)
504 #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
508 "cmp al, " TRANSPARENCY_COLOR_STR \
516 #elif !defined(NO_ASM) && defined(__GNUC__)
518 static inline void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
519 /* #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
521 __asm__ __volatile__ (
523 "movb (%%esi), %%al;"
525 "cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
527 "movb %%al, (%%edi);"
532 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
533 : "1" (src), "2" (dest), "0" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
539 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
543 num_pixels = num_pixels;
544 src_rowsize = src_rowsize;
545 dest_rowsize = dest_rowsize;
551 #endif /* __MSDOS__ */
553 void gr_ubitmap00( int x, int y, grs_bitmap *bm )
558 unsigned char * dest;
561 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
562 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
566 for (y1=0; y1 < bm->bm_h; y1++ ) {
567 if (gr_bitblt_double)
568 gr_linear_rep_movsd_2x( src, dest, bm->bm_w );
570 gr_linear_movsd( src, dest, bm->bm_w );
571 src += bm->bm_rowsize;
572 dest+= (int)(dest_rowsize);
576 void gr_ubitmap00m( int x, int y, grs_bitmap *bm )
581 unsigned char * dest;
584 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
585 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
589 if (gr_bitblt_fade_table==NULL) {
590 for (y1=0; y1 < bm->bm_h; y1++ ) {
591 gr_linear_rep_movsdm( src, dest, bm->bm_w );
592 src += bm->bm_rowsize;
593 dest+= (int)(dest_rowsize);
596 for (y1=0; y1 < bm->bm_h; y1++ ) {
597 gr_linear_rep_movsdm_faded( src, dest, bm->bm_w, gr_bitblt_fade_table[y1+y] );
598 src += bm->bm_rowsize;
599 dest+= (int)(dest_rowsize);
624 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels );
626 #if !defined(NO_ASM) && defined(__WATCOMC__)
628 #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
635 " mov al, [esi+8] " \
636 " mov ah, [esi+12] " \
639 " mov ah, [esi+4] " \
644 " jne next4pixels " \
657 #elif !defined (NO_ASM) && defined(__GNUC__)
659 static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) {
660 /* #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] */
662 __asm__ __volatile__ (
663 " movl %%ecx, %%ebx;"
669 " movb 8(%%esi), %%al;"
670 " movb 12(%%esi), %%ah;"
672 " movb (%%esi), %%al;"
673 " movb 4(%%esi), %%ah;"
674 " movl %%eax, (%%edi);"
683 " movb (%%esi), %%al;"
685 " movb %%al, (%%edi);"
690 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
691 : "1" (src), "2" (dest), "0" (npixels)
692 : "%eax", "%ebx", "%edx" );
697 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels )
707 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels );
709 #if !defined(NO_ASM) && defined(__WATCOMC__)
711 #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
718 " mov al, [esi+4] " \
719 " mov ah, [esi+6] " \
722 " mov ah, [esi+2] " \
727 " jne next4pixels " \
740 #elif !defined(NO_ASM) && defined(__GNUC__)
742 static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels ) {
743 /* #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = */
745 __asm__ __volatile__ (
746 " movl %%ecx, %%ebx;"
752 " movb 4(%%esi), %%al;"
753 " movb 6(%%esi), %%ah;"
755 " movb (%%esi), %%al;"
756 " movb 2(%%esi), %%ah;"
757 " movl %%eax, (%%edi);"
766 " movb (%%esi),%%al;"
768 " movb %%al, (%%edi);"
773 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
774 : "1" (src), "2" (dest), "0" (npixels)
775 : "%eax", "%ebx", "%edx" );
780 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels )
791 // From Linear to ModeX
792 void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
802 sstep = src->bm_rowsize;
803 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
805 if (!gr_bitblt_double) {
806 for (plane=0; plane<4; plane++ ) {
807 gr_modex_setplane( (plane+dx)&3 );
808 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane;
809 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
811 if ( (w&3) > plane ) w1++;
812 for (y=dy; y < dy+h; y++ ) {
813 modex_copy_scanline( sbits, dbits, w1 );
819 for (plane=0; plane<4; plane++ ) {
820 gr_modex_setplane( (plane+dx)&3 );
821 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane/2;
822 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
824 if ( (w&3) > plane ) w1++;
825 for (y=dy; y < dy+h; y++ ) {
826 modex_copy_scanline_2x( sbits, dbits, w1 );
835 // From Linear to ModeX masked
836 void gr_bm_ubitblt01m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
847 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
848 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + dx/4];
850 for (x=dx; x < dx+w; x++ ) {
851 gr_modex_setplane( x&3 );
855 //for (y=0; y < h; y++ ) {
856 // *dbits1 = *sbits1;
857 // sbits1 += src_bm_rowsize;
858 // dbits1 += dest_bm_rowsize;
860 modex_copy_column_m(sbits, dbits, h, src->bm_rowsize, dest->bm_rowsize << gr_bitblt_dest_step_shift );
868 #endif /* __MSDOS__ */
871 void gr_ubitmap012( int x, int y, grs_bitmap *bm )
878 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
879 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
880 gr_setcolor( *src++ );
886 void gr_ubitmap012m( int x, int y, grs_bitmap *bm )
893 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
894 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
895 if ( *src != TRANSPARENCY_COLOR ) {
904 void gr_ubitmapGENERIC(int x, int y, grs_bitmap * bm)
908 for (y1=0; y1 < bm->bm_h; y1++ ) {
909 for (x1=0; x1 < bm->bm_w; x1++ ) {
910 gr_setcolor( gr_gpixel(bm,x1,y1) );
911 gr_upixel( x+x1, y+y1 );
916 void gr_ubitmapGENERICm(int x, int y, grs_bitmap * bm)
921 for (y1=0; y1 < bm->bm_h; y1++ ) {
922 for (x1=0; x1 < bm->bm_w; x1++ ) {
923 c = gr_gpixel(bm,x1,y1);
924 if ( c != TRANSPARENCY_COLOR ) {
926 gr_upixel( x+x1, y+y1 );
934 // From linear to SVGA
935 void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
937 unsigned char * sbits;
939 unsigned int offset, EndingOffset, VideoLocation;
941 int sbpr, dbpr, y1, page, BytesToMove;
943 sbpr = src->bm_rowsize;
945 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
947 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
949 sbits = src->bm_data + ( sbpr*sy ) + sx;
951 for (y1=0; y1 < h; y1++ ) {
953 page = VideoLocation >> 16;
954 offset = VideoLocation & 0xFFFF;
956 gr_vesa_setpage( page );
958 EndingOffset = offset+w-1;
960 if ( EndingOffset <= 0xFFFF )
962 if ( gr_bitblt_double )
963 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
965 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), w );
967 VideoLocation += dbpr;
972 BytesToMove = 0xFFFF-offset+1;
974 if ( gr_bitblt_double )
975 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
977 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
980 gr_vesa_setpage(page);
982 if ( gr_bitblt_double )
983 gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
985 gr_linear_movsd( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
987 VideoLocation += dbpr;
996 void gr_bm_ubitblt02m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
998 unsigned char * sbits;
1000 unsigned int offset, EndingOffset, VideoLocation;
1002 int sbpr, dbpr, y1, page, BytesToMove;
1004 sbpr = src->bm_rowsize;
1006 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1008 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1010 sbits = src->bm_data + ( sbpr*sy ) + sx;
1012 for (y1=0; y1 < h; y1++ ) {
1014 page = VideoLocation >> 16;
1015 offset = VideoLocation & 0xFFFF;
1017 gr_vesa_setpage( page );
1019 EndingOffset = offset+w-1;
1021 if ( EndingOffset <= 0xFFFF )
1023 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), w );
1025 VideoLocation += dbpr;
1030 BytesToMove = 0xFFFF-offset+1;
1032 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1035 gr_vesa_setpage(page);
1037 gr_linear_rep_movsdm( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
1039 VideoLocation += dbpr;
1046 // From SVGA to linear
1047 void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1049 unsigned char * dbits;
1051 unsigned int offset, offset1, offset2;
1053 int sbpr, dbpr, y1, page;
1055 dbpr = dest->bm_rowsize;
1057 sbpr = src->bm_rowsize;
1059 for (y1=0; y1 < h; y1++ ) {
1061 offset2 = (unsigned int)src->bm_data + (sbpr * (y1+sy)) + sx;
1062 dbits = dest->bm_data + (dbpr * (y1+dy)) + dx;
1064 page = offset2 >> 16;
1065 offset = offset2 & 0xFFFF;
1066 offset1 = offset+w-1;
1067 gr_vesa_setpage( page );
1069 if ( offset1 > 0xFFFF ) {
1070 // Overlaps two pages
1071 while( offset <= 0xFFFF )
1072 *dbits++ = gr_video_memory[offset++];
1073 offset1 -= (0xFFFF+1);
1076 gr_vesa_setpage(page);
1078 while( offset <= offset1 )
1079 *dbits++ = gr_video_memory[offset++];
1086 //@extern int Interlacing_on;
1088 // From Linear to Linear
1089 void gr_bm_ubitblt00(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1091 unsigned char * dbits;
1092 unsigned char * sbits;
1093 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1098 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1099 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1101 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1103 // No interlacing, copy the whole buffer.
1104 for (i=0; i < h; i++ ) {
1105 if (gr_bitblt_double)
1106 gr_linear_rep_movsd_2x( sbits, dbits, w );
1108 gr_linear_movsd( sbits, dbits, w );
1109 sbits += src->bm_rowsize;
1113 // From Linear to Linear Masked
1114 void gr_bm_ubitblt00m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1116 unsigned char * dbits;
1117 unsigned char * sbits;
1118 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1122 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1123 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1125 // No interlacing, copy the whole buffer.
1127 if (gr_bitblt_fade_table==NULL) {
1128 for (i=0; i < h; i++ ) {
1129 gr_linear_rep_movsdm( sbits, dbits, w );
1130 sbits += src->bm_rowsize;
1131 dbits += dest->bm_rowsize;
1134 for (i=0; i < h; i++ ) {
1135 gr_linear_rep_movsdm_faded( sbits, dbits, w, gr_bitblt_fade_table[dy+i] );
1136 sbits += src->bm_rowsize;
1137 dbits += dest->bm_rowsize;
1143 extern void gr_lbitblt( grs_bitmap * source, grs_bitmap * dest, int height, int width );
1147 //extern void BlitLargeAlign(ubyte *draw_buffer, int dstRowBytes, ubyte *dstPtr, int w, int h, int modulus);
1149 asm void BlitLargeAlign(ubyte *rSrcPtr, int rDblDStrd, ubyte *rDst1Ptr, int rWidth, int rHeight, int rModulus)
1151 stw r31,-4(SP) // store non-volatile reg in red zone
1152 addi r5,r5,-8 // subtract 8 from dst
1153 stw r30,-8(SP) // store non-volatile reg in red zone
1155 la r30,-16(SP) // calculate copy of local 8-byte variable
1157 // rSStrd = modulus - w
1158 add r31,r5,r4 // dst2 = dstRowBytes + dst1
1159 sub r4,r4,r6 // r4 = dstRowBytes - w
1160 addi r7,r7,-1 // subtract 1 from height count
1161 srawi r6,r6,2 // rWidth = w >> 2
1162 addi r3,r3,-4 // subtract 4 from src
1163 addi r6,r6,-1 // subtract 1 from width count
1164 add r4,r4,r4 // rDblDStrd = 2 * r4
1166 BlitLargeAlignY: // y count is in r7
1167 lwzu r10,4(r3) // load a long into r10
1168 mr r0,r10 // put a copy in r0
1170 // these are simplified -- can't use 'em inslwi r0,r10,16,8
1171 // these are simplified -- can't use 'em insrwi r11,r10,16,8
1172 rlwimi r0,r10,24,8,31
1173 rlwimi r11,r10,8,8,23
1174 rlwimi r0,r10,16,24,31
1176 rlwimi r11,r10,16,0,7
1178 mtctr r6 // copy x count into the counter
1182 lwzu r10,4(r3) // load a long into r10
1184 mr r0,r10 // put a copy in r0
1186 // simplefied inslwi r0,r10,16,8
1187 // simplefied insrwi r11,r10,16,8
1188 rlwimi r0,r10,24,8,31
1189 rlwimi r11,r10,8,8,23
1190 rlwimi r0,r10,16,24,31
1192 rlwimi r11,r10,16,0,7
1196 bdnz BlitLargeAlignX // loop over all x
1199 addic. r7,r7,-1 // decrement the counter
1207 bne BlitLargeAlignY // loop for all y
1209 lwz r30,-8(SP) // restore non-volatile regs
1210 lwz r31,-4(SP) // restore non-volatile regs
1211 blr // return to caller
1214 #endif /* MACINTOSH */
1217 // Clipped bitmap ...
1219 void gr_bitmap( int x, int y, grs_bitmap *bm )
1221 int dx1=x, dx2=x+bm->bm_w-1;
1222 int dy1=y, dy2=y+bm->bm_h-1;
1225 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1226 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1227 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1228 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1229 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1230 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1232 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1234 gr_bm_ubitblt(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1238 //-NOT-used // From linear to SVGA
1239 //-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)
1241 //-NOT-used unsigned char * sbits;
1243 //-NOT-used unsigned int offset, EndingOffset, VideoLocation;
1245 //-NOT-used int sbpr, dbpr, y1, page, BytesToMove;
1247 //-NOT-used sbpr = src->bm_rowsize;
1249 //-NOT-used dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1251 //-NOT-used VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1253 //-NOT-used sbits = src->bm_data + ( sbpr*sy ) + sx;
1255 //-NOT-used for (y1=0; y1 < h; y1++ ) {
1257 //-NOT-used page = VideoLocation >> 16;
1258 //-NOT-used offset = VideoLocation & 0xFFFF;
1260 //-NOT-used gr_vesa_setpage( page );
1262 //-NOT-used EndingOffset = offset+w-1;
1264 //-NOT-used if ( EndingOffset <= 0xFFFF )
1266 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
1268 //-NOT-used VideoLocation += dbpr;
1269 //-NOT-used sbits += sbpr;
1273 //-NOT-used BytesToMove = 0xFFFF-offset+1;
1275 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1278 //-NOT-used gr_vesa_setpage(page);
1280 //-NOT-used gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
1282 //-NOT-used VideoLocation += dbpr;
1283 //-NOT-used sbits += sbpr;
1291 //-NOT-used // From Linear to Linear
1292 //-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)
1294 //-NOT-used unsigned char * dbits;
1295 //-NOT-used unsigned char * sbits;
1296 //-NOT-used //int src_bm_rowsize_2, dest_bm_rowsize_2;
1300 //-NOT-used sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1301 //-NOT-used dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1303 //-NOT-used // No interlacing, copy the whole buffer.
1304 //-NOT-used for (i=0; i < h; i++ ) {
1305 //-NOT-used gr_linear_rep_movsd_2x( sbits, dbits, w );
1307 //-NOT-used sbits += src->bm_rowsize;
1308 //-NOT-used dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1312 void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1314 unsigned char * dbits;
1315 unsigned char * sbits;
1319 if (src->bm_flags & BM_FLAG_RLE_BIG)
1322 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1324 for (i=0; i<sy; i++ )
1325 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1327 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1329 // No interlacing, copy the whole buffer.
1330 for (i=0; i < h; i++ ) {
1331 gr_rle_expand_scanline( dbits, sbits, sx, sx+w-1 );
1332 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1333 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1335 sbits += (int)(src->bm_data[4+i+sy]);
1336 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1340 void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1342 unsigned char * dbits;
1343 unsigned char * sbits;
1347 if (src->bm_flags & BM_FLAG_RLE_BIG)
1350 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1351 for (i=0; i<sy; i++ )
1352 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1354 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1356 // No interlacing, copy the whole buffer.
1357 for (i=0; i < h; i++ ) {
1358 gr_rle_expand_scanline_masked( dbits, sbits, sx, sx+w-1 );
1359 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1360 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1362 sbits += (int)(src->bm_data[4+i+sy]);
1363 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1369 extern void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1370 extern void gr_rle_expand_scanline_generic_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1371 extern void gr_rle_expand_scanline_svga_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1373 void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1377 unsigned char * sbits;
1379 //mprintf( 0, "SVGA RLE!\n" );
1382 if (src->bm_flags & BM_FLAG_RLE_BIG)
1385 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1386 for (i=0; i<sy; i++ )
1387 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1389 for (y1=0; y1 < h; y1++ ) {
1390 gr_rle_expand_scanline_generic( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1391 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1392 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1394 sbits += (int)src->bm_data[4+y1+sy];
1399 void gr_bm_ubitblt0xm_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1403 unsigned char * sbits;
1405 //mprintf( 0, "SVGA RLE!\n" );
1408 if (src->bm_flags & BM_FLAG_RLE_BIG)
1411 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1412 for (i=0; i<sy; i++ )
1413 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1415 for (y1=0; y1 < h; y1++ ) {
1416 gr_rle_expand_scanline_generic_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1417 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1418 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1420 sbits += (int)src->bm_data[4+y1+sy];
1426 void gr_bm_ubitblt02m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1430 unsigned char * sbits;
1432 //mprintf( 0, "SVGA RLE!\n" );
1435 if (src->bm_flags & BM_FLAG_RLE_BIG)
1438 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1439 for (i=0; i<sy; i++ )
1440 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1442 for (y1=0; y1 < h; y1++ ) {
1443 gr_rle_expand_scanline_svga_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1444 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1445 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1447 sbits += (int)src->bm_data[4+y1+sy];
1452 void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1454 register int x1, y1;
1456 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR ))
1458 if ( src->bm_flags & BM_FLAG_RLE )
1459 gr_bm_ubitblt00_rle( w, h, dx, dy, sx, sy, src, dest );
1461 gr_bm_ubitblt00( w, h, dx, dy, sx, sy, src, dest );
1466 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1468 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1471 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1473 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1476 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1478 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1483 if ( (src->bm_flags & BM_FLAG_RLE ) && (src->bm_type == BM_LINEAR) ) {
1484 gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest );
1489 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA ))
1491 gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest );
1495 if ( (src->bm_type == BM_SVGA) && (dest->bm_type == BM_LINEAR ))
1497 gr_bm_ubitblt20( w, h, dx, dy, sx, sy, src, dest );
1501 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_MODEX ))
1503 gr_bm_ubitblt01( w, h, dx+XOFFSET, dy+YOFFSET, sx, sy, src, dest );
1508 for (y1=0; y1 < h; y1++ ) {
1509 for (x1=0; x1 < w; x1++ ) {
1510 gr_bm_pixel( dest, dx+x1, dy+y1, gr_gpixel(src,sx+x1,sy+y1) );
1515 void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1517 int dx1=dx, dx2=dx+dest->bm_w-1;
1518 int dy1=dy, dy2=dy+dest->bm_h-1;
1520 int sx1=sx, sx2=sx+src->bm_w-1;
1521 int sy1=sy, sy2=sy+src->bm_h-1;
1523 if ((dx1 >= dest->bm_w ) || (dx2 < 0)) return;
1524 if ((dy1 >= dest->bm_h ) || (dy2 < 0)) return;
1525 if ( dx1 < 0 ) { sx1 += -dx1; dx1 = 0; }
1526 if ( dy1 < 0 ) { sy1 += -dy1; dy1 = 0; }
1527 if ( dx2 >= dest->bm_w ) { dx2 = dest->bm_w-1; }
1528 if ( dy2 >= dest->bm_h ) { dy2 = dest->bm_h-1; }
1530 if ((sx1 >= src->bm_w ) || (sx2 < 0)) return;
1531 if ((sy1 >= src->bm_h ) || (sy2 < 0)) return;
1532 if ( sx1 < 0 ) { dx1 += -sx1; sx1 = 0; }
1533 if ( sy1 < 0 ) { dy1 += -sy1; sy1 = 0; }
1534 if ( sx2 >= src->bm_w ) { sx2 = src->bm_w-1; }
1535 if ( sy2 >= src->bm_h ) { sy2 = src->bm_h-1; }
1537 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1538 if ( dx2-dx1+1 < w )
1540 if ( dy2-dy1+1 < h )
1542 if ( sx2-sx1+1 < w )
1544 if ( sy2-sy1+1 < h )
1547 gr_bm_ubitblt(w,h, dx1, dy1, sx1, sy1, src, dest );
1550 void gr_ubitmap( int x, int y, grs_bitmap *bm )
1554 source = bm->bm_type;
1557 if (source==BM_LINEAR) {
1561 if ( bm->bm_flags & BM_FLAG_RLE )
1562 gr_bm_ubitblt00_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1564 gr_ubitmap00( x, y, bm );
1568 ogl_ubitmapm(x,y,bm);
1573 if ( bm->bm_flags & BM_FLAG_RLE )
1574 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1576 gr_vesa_bitmap( bm, &grd_curcanv->cv_bitmap, x, y );
1579 gr_bm_ubitblt01(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1583 gr_ubitmap012( x, y, bm );
1587 gr_ubitmapGENERIC(x, y, bm);
1592 void gr_ubitmapm( int x, int y, grs_bitmap *bm )
1596 source = bm->bm_type;
1599 Assert(x+bm->bm_w <= grd_curcanv->cv_w);
1601 Assert(y+bm->bm_h <= grd_curcanv->cv_h);
1604 if (source==BM_LINEAR) {
1608 if ( bm->bm_flags & BM_FLAG_RLE )
1609 gr_bm_ubitblt00m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1611 gr_ubitmap00m( x, y, bm );
1615 ogl_ubitmapm(x,y,bm);
1620 if (bm->bm_flags & BM_FLAG_RLE)
1621 gr_bm_ubitblt02m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1622 //gr_bm_ubitblt0xm_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1624 gr_bm_ubitblt02m(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1625 //gr_ubitmapGENERICm(x, y, bm);
1628 gr_bm_ubitblt01m(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1633 gr_ubitmap012m( x, y, bm );
1637 gr_ubitmapGENERICm(x, y, bm);
1642 void gr_bitmapm( int x, int y, grs_bitmap *bm )
1644 int dx1=x, dx2=x+bm->bm_w-1;
1645 int dy1=y, dy2=y+bm->bm_h-1;
1648 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1649 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1650 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1651 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1652 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1653 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1655 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1657 if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_LINEAR ))
1659 if ( bm->bm_flags & BM_FLAG_RLE )
1660 gr_bm_ubitblt00m_rle(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1662 gr_bm_ubitblt00m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1666 else if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_SVGA ))
1668 gr_bm_ubitblt02m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1673 gr_bm_ubitbltm(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1677 void gr_bm_ubitbltm(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1679 register int x1, y1;
1683 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1685 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1688 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1690 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1693 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1695 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1700 for (y1=0; y1 < h; y1++ ) {
1701 for (x1=0; x1 < w; x1++ ) {
1702 if ((c=gr_gpixel(src,sx+x1,sy+y1))!=TRANSPARENCY_COLOR)
1703 gr_bm_pixel( dest, dx+x1, dy+y1,c );
1709 // rescalling bitmaps, 10/14/99 Jan Bobrowski jb@wizard.ae.krakow.pl
1711 static inline void scale_line(unsigned char *in, unsigned char *out, int ilen, int olen)
1713 int a = olen/ilen, b = olen%ilen;
1715 unsigned char *end = out + olen;
1731 void gr_bitmap_scale_to(grs_bitmap *src, grs_bitmap *dst)
1733 unsigned char *s = src->bm_data;
1734 unsigned char *d = dst->bm_data;
1736 int a = dst->bm_h/h, b = dst->bm_h%h;
1739 if ( src->bm_flags & BM_FLAG_RLE ) {
1740 src = rle_expand_texture(src);
1743 for(y=0; y<h; y++) {
1752 scale_line(s, d, src->bm_w, dst->bm_w);
1753 d += dst->bm_rowsize;
1755 s += src->bm_rowsize;
1759 void show_fullscr(grs_bitmap *bm)
1761 grs_bitmap * const scr = &grd_curcanv->cv_bitmap;
1764 if(bm->bm_type == BM_LINEAR && scr->bm_type == BM_OGL) {
1765 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
1769 if(scr->bm_type != BM_LINEAR) {
1770 grs_bitmap *tmp = gr_create_bitmap(scr->bm_w, scr->bm_h);
1771 gr_bitmap_scale_to(bm, tmp);
1772 gr_bitmap(0, 0, tmp);
1773 gr_free_bitmap(tmp);
1776 gr_bitmap_scale_to(bm, scr);