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)
421 while (num_pixels--) {
425 unsigned short *sp=(unsigned short *)dest;
427 *sp=((short)c<<8)|(short)c;
438 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
440 #if !defined(NO_ASM) && defined(__WATCOMC__)
442 #pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
451 #elif !defined(NO_ASM) && defined(__GNUC__)
453 static inline void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
454 /*#pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
455 __asm__ __volatile__ (
457 "movb (%%esi), %%al;"
459 "movb %%al, (%%edi);"
463 : : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
464 : "%eax", "%ecx", "%esi", "%edi");
469 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
473 num_pixels = num_pixels;
474 src_rowsize = src_rowsize;
475 dest_rowsize = dest_rowsize;
482 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
484 #if !defined(NO_ASM) && defined(__WATCOMC__)
486 #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
490 "cmp al, " TRANSPARENCY_COLOR_STR \
498 #elif !defined(NO_ASM) && defined(__GNUC__)
500 static inline void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
501 /* #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
503 __asm__ __volatile__ (
505 "movb (%%esi), %%al;"
507 "cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
509 "movb %%al, (%%edi);"
514 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
515 : "1" (src), "2" (dest), "0" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
521 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
525 num_pixels = num_pixels;
526 src_rowsize = src_rowsize;
527 dest_rowsize = dest_rowsize;
533 #endif /* __MSDOS__ */
535 void gr_ubitmap00( int x, int y, grs_bitmap *bm )
540 unsigned char * dest;
543 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
544 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
548 for (y1=0; y1 < bm->bm_h; y1++ ) {
549 if (gr_bitblt_double)
550 gr_linear_rep_movsd_2x( src, dest, bm->bm_w );
552 gr_linear_movsd( src, dest, bm->bm_w );
553 src += bm->bm_rowsize;
554 dest+= (int)(dest_rowsize);
558 void gr_ubitmap00m( int x, int y, grs_bitmap *bm )
563 unsigned char * dest;
566 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
567 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
571 if (gr_bitblt_fade_table==NULL) {
572 for (y1=0; y1 < bm->bm_h; y1++ ) {
573 gr_linear_rep_movsdm( src, dest, bm->bm_w );
574 src += bm->bm_rowsize;
575 dest+= (int)(dest_rowsize);
578 for (y1=0; y1 < bm->bm_h; y1++ ) {
579 gr_linear_rep_movsdm_faded( src, dest, bm->bm_w, gr_bitblt_fade_table[y1+y] );
580 src += bm->bm_rowsize;
581 dest+= (int)(dest_rowsize);
606 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels );
608 #if !defined(NO_ASM) && defined(__WATCOMC__)
610 #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
617 " mov al, [esi+8] " \
618 " mov ah, [esi+12] " \
621 " mov ah, [esi+4] " \
626 " jne next4pixels " \
639 #elif !defined (NO_ASM) && defined(__GNUC__)
641 static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) {
642 /* #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] */
644 __asm__ __volatile__ (
645 " movl %%ecx, %%ebx;"
651 " movb 8(%%esi), %%al;"
652 " movb 12(%%esi), %%ah;"
654 " movb (%%esi), %%al;"
655 " movb 4(%%esi), %%ah;"
656 " movl %%eax, (%%edi);"
665 " movb (%%esi), %%al;"
667 " movb %%al, (%%edi);"
672 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
673 : "1" (src), "2" (dest), "0" (npixels)
674 : "%eax", "%ebx", "%edx" );
679 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels )
689 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels );
691 #if !defined(NO_ASM) && defined(__WATCOMC__)
693 #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
700 " mov al, [esi+4] " \
701 " mov ah, [esi+6] " \
704 " mov ah, [esi+2] " \
709 " jne next4pixels " \
722 #elif !defined(NO_ASM) && defined(__GNUC__)
724 static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels ) {
725 /* #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = */
727 __asm__ __volatile__ (
728 " movl %%ecx, %%ebx;"
734 " movb 4(%%esi), %%al;"
735 " movb 6(%%esi), %%ah;"
737 " movb (%%esi), %%al;"
738 " movb 2(%%esi), %%ah;"
739 " movl %%eax, (%%edi);"
748 " movb (%%esi),%%al;"
750 " movb %%al, (%%edi);"
755 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
756 : "1" (src), "2" (dest), "0" (npixels)
757 : "%eax", "%ebx", "%edx" );
762 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels )
773 // From Linear to ModeX
774 void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
784 sstep = src->bm_rowsize;
785 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
787 if (!gr_bitblt_double) {
788 for (plane=0; plane<4; plane++ ) {
789 gr_modex_setplane( (plane+dx)&3 );
790 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane;
791 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
793 if ( (w&3) > plane ) w1++;
794 for (y=dy; y < dy+h; y++ ) {
795 modex_copy_scanline( sbits, dbits, w1 );
801 for (plane=0; plane<4; plane++ ) {
802 gr_modex_setplane( (plane+dx)&3 );
803 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane/2;
804 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
806 if ( (w&3) > plane ) w1++;
807 for (y=dy; y < dy+h; y++ ) {
808 modex_copy_scanline_2x( sbits, dbits, w1 );
817 // From Linear to ModeX masked
818 void gr_bm_ubitblt01m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
829 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
830 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + dx/4];
832 for (x=dx; x < dx+w; x++ ) {
833 gr_modex_setplane( x&3 );
837 //for (y=0; y < h; y++ ) {
838 // *dbits1 = *sbits1;
839 // sbits1 += src_bm_rowsize;
840 // dbits1 += dest_bm_rowsize;
842 modex_copy_column_m(sbits, dbits, h, src->bm_rowsize, dest->bm_rowsize << gr_bitblt_dest_step_shift );
850 #endif /* __MSDOS__ */
853 void gr_ubitmap012( int x, int y, grs_bitmap *bm )
860 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
861 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
862 gr_setcolor( *src++ );
868 void gr_ubitmap012m( int x, int y, grs_bitmap *bm )
875 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
876 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
877 if ( *src != TRANSPARENCY_COLOR ) {
886 void gr_ubitmapGENERIC(int x, int y, grs_bitmap * bm)
890 for (y1=0; y1 < bm->bm_h; y1++ ) {
891 for (x1=0; x1 < bm->bm_w; x1++ ) {
892 gr_setcolor( gr_gpixel(bm,x1,y1) );
893 gr_upixel( x+x1, y+y1 );
898 void gr_ubitmapGENERICm(int x, int y, grs_bitmap * bm)
903 for (y1=0; y1 < bm->bm_h; y1++ ) {
904 for (x1=0; x1 < bm->bm_w; x1++ ) {
905 c = gr_gpixel(bm,x1,y1);
906 if ( c != TRANSPARENCY_COLOR ) {
908 gr_upixel( x+x1, y+y1 );
916 // From linear to SVGA
917 void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
919 unsigned char * sbits;
921 unsigned int offset, EndingOffset, VideoLocation;
923 int sbpr, dbpr, y1, page, BytesToMove;
925 sbpr = src->bm_rowsize;
927 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
929 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
931 sbits = src->bm_data + ( sbpr*sy ) + sx;
933 for (y1=0; y1 < h; y1++ ) {
935 page = VideoLocation >> 16;
936 offset = VideoLocation & 0xFFFF;
938 gr_vesa_setpage( page );
940 EndingOffset = offset+w-1;
942 if ( EndingOffset <= 0xFFFF )
944 if ( gr_bitblt_double )
945 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
947 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), w );
949 VideoLocation += dbpr;
954 BytesToMove = 0xFFFF-offset+1;
956 if ( gr_bitblt_double )
957 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
959 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
962 gr_vesa_setpage(page);
964 if ( gr_bitblt_double )
965 gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
967 gr_linear_movsd( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
969 VideoLocation += dbpr;
978 void gr_bm_ubitblt02m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
980 unsigned char * sbits;
982 unsigned int offset, EndingOffset, VideoLocation;
984 int sbpr, dbpr, y1, page, BytesToMove;
986 sbpr = src->bm_rowsize;
988 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
990 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
992 sbits = src->bm_data + ( sbpr*sy ) + sx;
994 for (y1=0; y1 < h; y1++ ) {
996 page = VideoLocation >> 16;
997 offset = VideoLocation & 0xFFFF;
999 gr_vesa_setpage( page );
1001 EndingOffset = offset+w-1;
1003 if ( EndingOffset <= 0xFFFF )
1005 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), w );
1007 VideoLocation += dbpr;
1012 BytesToMove = 0xFFFF-offset+1;
1014 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1017 gr_vesa_setpage(page);
1019 gr_linear_rep_movsdm( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
1021 VideoLocation += dbpr;
1028 // From SVGA to linear
1029 void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1031 unsigned char * dbits;
1033 unsigned int offset, offset1, offset2;
1035 int sbpr, dbpr, y1, page;
1037 dbpr = dest->bm_rowsize;
1039 sbpr = src->bm_rowsize;
1041 for (y1=0; y1 < h; y1++ ) {
1043 offset2 = (unsigned int)src->bm_data + (sbpr * (y1+sy)) + sx;
1044 dbits = dest->bm_data + (dbpr * (y1+dy)) + dx;
1046 page = offset2 >> 16;
1047 offset = offset2 & 0xFFFF;
1048 offset1 = offset+w-1;
1049 gr_vesa_setpage( page );
1051 if ( offset1 > 0xFFFF ) {
1052 // Overlaps two pages
1053 while( offset <= 0xFFFF )
1054 *dbits++ = gr_video_memory[offset++];
1055 offset1 -= (0xFFFF+1);
1058 gr_vesa_setpage(page);
1060 while( offset <= offset1 )
1061 *dbits++ = gr_video_memory[offset++];
1068 //@extern int Interlacing_on;
1070 // From Linear to Linear
1071 void gr_bm_ubitblt00(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1073 unsigned char * dbits;
1074 unsigned char * sbits;
1075 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1080 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1081 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1083 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1085 // No interlacing, copy the whole buffer.
1086 for (i=0; i < h; i++ ) {
1087 if (gr_bitblt_double)
1088 gr_linear_rep_movsd_2x( sbits, dbits, w );
1090 gr_linear_movsd( sbits, dbits, w );
1091 sbits += src->bm_rowsize;
1095 // From Linear to Linear Masked
1096 void gr_bm_ubitblt00m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1098 unsigned char * dbits;
1099 unsigned char * sbits;
1100 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1104 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1105 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1107 // No interlacing, copy the whole buffer.
1109 if (gr_bitblt_fade_table==NULL) {
1110 for (i=0; i < h; i++ ) {
1111 gr_linear_rep_movsdm( sbits, dbits, w );
1112 sbits += src->bm_rowsize;
1113 dbits += dest->bm_rowsize;
1116 for (i=0; i < h; i++ ) {
1117 gr_linear_rep_movsdm_faded( sbits, dbits, w, gr_bitblt_fade_table[dy+i] );
1118 sbits += src->bm_rowsize;
1119 dbits += dest->bm_rowsize;
1125 extern void gr_lbitblt( grs_bitmap * source, grs_bitmap * dest, int height, int width );
1129 //extern void BlitLargeAlign(ubyte *draw_buffer, int dstRowBytes, ubyte *dstPtr, int w, int h, int modulus);
1131 asm void BlitLargeAlign(ubyte *rSrcPtr, int rDblDStrd, ubyte *rDst1Ptr, int rWidth, int rHeight, int rModulus)
1133 stw r31,-4(SP) // store non-volatile reg in red zone
1134 addi r5,r5,-8 // subtract 8 from dst
1135 stw r30,-8(SP) // store non-volatile reg in red zone
1137 la r30,-16(SP) // calculate copy of local 8-byte variable
1139 // rSStrd = modulus - w
1140 add r31,r5,r4 // dst2 = dstRowBytes + dst1
1141 sub r4,r4,r6 // r4 = dstRowBytes - w
1142 addi r7,r7,-1 // subtract 1 from height count
1143 srawi r6,r6,2 // rWidth = w >> 2
1144 addi r3,r3,-4 // subtract 4 from src
1145 addi r6,r6,-1 // subtract 1 from width count
1146 add r4,r4,r4 // rDblDStrd = 2 * r4
1148 BlitLargeAlignY: // y count is in r7
1149 lwzu r10,4(r3) // load a long into r10
1150 mr r0,r10 // put a copy in r0
1152 // these are simplified -- can't use 'em inslwi r0,r10,16,8
1153 // these are simplified -- can't use 'em insrwi r11,r10,16,8
1154 rlwimi r0,r10,24,8,31
1155 rlwimi r11,r10,8,8,23
1156 rlwimi r0,r10,16,24,31
1158 rlwimi r11,r10,16,0,7
1160 mtctr r6 // copy x count into the counter
1164 lwzu r10,4(r3) // load a long into r10
1166 mr r0,r10 // put a copy in r0
1168 // simplefied inslwi r0,r10,16,8
1169 // simplefied insrwi r11,r10,16,8
1170 rlwimi r0,r10,24,8,31
1171 rlwimi r11,r10,8,8,23
1172 rlwimi r0,r10,16,24,31
1174 rlwimi r11,r10,16,0,7
1178 bdnz BlitLargeAlignX // loop over all x
1181 addic. r7,r7,-1 // decrement the counter
1189 bne BlitLargeAlignY // loop for all y
1191 lwz r30,-8(SP) // restore non-volatile regs
1192 lwz r31,-4(SP) // restore non-volatile regs
1193 blr // return to caller
1196 #endif /* MACINTOSH */
1199 // Clipped bitmap ...
1201 void gr_bitmap( int x, int y, grs_bitmap *bm )
1203 int dx1=x, dx2=x+bm->bm_w-1;
1204 int dy1=y, dy2=y+bm->bm_h-1;
1207 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1208 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1209 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1210 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1211 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1212 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1214 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1216 gr_bm_ubitblt(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1220 //-NOT-used // From linear to SVGA
1221 //-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)
1223 //-NOT-used unsigned char * sbits;
1225 //-NOT-used unsigned int offset, EndingOffset, VideoLocation;
1227 //-NOT-used int sbpr, dbpr, y1, page, BytesToMove;
1229 //-NOT-used sbpr = src->bm_rowsize;
1231 //-NOT-used dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1233 //-NOT-used VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1235 //-NOT-used sbits = src->bm_data + ( sbpr*sy ) + sx;
1237 //-NOT-used for (y1=0; y1 < h; y1++ ) {
1239 //-NOT-used page = VideoLocation >> 16;
1240 //-NOT-used offset = VideoLocation & 0xFFFF;
1242 //-NOT-used gr_vesa_setpage( page );
1244 //-NOT-used EndingOffset = offset+w-1;
1246 //-NOT-used if ( EndingOffset <= 0xFFFF )
1248 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
1250 //-NOT-used VideoLocation += dbpr;
1251 //-NOT-used sbits += sbpr;
1255 //-NOT-used BytesToMove = 0xFFFF-offset+1;
1257 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1260 //-NOT-used gr_vesa_setpage(page);
1262 //-NOT-used gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
1264 //-NOT-used VideoLocation += dbpr;
1265 //-NOT-used sbits += sbpr;
1273 //-NOT-used // From Linear to Linear
1274 //-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)
1276 //-NOT-used unsigned char * dbits;
1277 //-NOT-used unsigned char * sbits;
1278 //-NOT-used //int src_bm_rowsize_2, dest_bm_rowsize_2;
1282 //-NOT-used sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1283 //-NOT-used dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1285 //-NOT-used // No interlacing, copy the whole buffer.
1286 //-NOT-used for (i=0; i < h; i++ ) {
1287 //-NOT-used gr_linear_rep_movsd_2x( sbits, dbits, w );
1289 //-NOT-used sbits += src->bm_rowsize;
1290 //-NOT-used dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1294 void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1296 unsigned char * dbits;
1297 unsigned char * sbits;
1301 if (src->bm_flags & BM_FLAG_RLE_BIG)
1304 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1306 for (i=0; i<sy; i++ )
1307 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1309 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1311 // No interlacing, copy the whole buffer.
1312 for (i=0; i < h; i++ ) {
1313 gr_rle_expand_scanline( dbits, sbits, sx, sx+w-1 );
1314 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1315 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1317 sbits += (int)(src->bm_data[4+i+sy]);
1318 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1322 void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1324 unsigned char * dbits;
1325 unsigned char * sbits;
1329 if (src->bm_flags & BM_FLAG_RLE_BIG)
1332 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1333 for (i=0; i<sy; i++ )
1334 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1336 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1338 // No interlacing, copy the whole buffer.
1339 for (i=0; i < h; i++ ) {
1340 gr_rle_expand_scanline_masked( dbits, sbits, sx, sx+w-1 );
1341 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1342 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1344 sbits += (int)(src->bm_data[4+i+sy]);
1345 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1351 extern void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1352 extern void gr_rle_expand_scanline_generic_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1353 extern void gr_rle_expand_scanline_svga_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1355 void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1359 unsigned char * sbits;
1361 //mprintf( 0, "SVGA RLE!\n" );
1364 if (src->bm_flags & BM_FLAG_RLE_BIG)
1367 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1368 for (i=0; i<sy; i++ )
1369 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1371 for (y1=0; y1 < h; y1++ ) {
1372 gr_rle_expand_scanline_generic( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1373 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1374 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1376 sbits += (int)src->bm_data[4+y1+sy];
1381 void gr_bm_ubitblt0xm_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1385 unsigned char * sbits;
1387 //mprintf( 0, "SVGA RLE!\n" );
1390 if (src->bm_flags & BM_FLAG_RLE_BIG)
1393 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1394 for (i=0; i<sy; i++ )
1395 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1397 for (y1=0; y1 < h; y1++ ) {
1398 gr_rle_expand_scanline_generic_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1399 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1400 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1402 sbits += (int)src->bm_data[4+y1+sy];
1408 void gr_bm_ubitblt02m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1412 unsigned char * sbits;
1414 //mprintf( 0, "SVGA RLE!\n" );
1417 if (src->bm_flags & BM_FLAG_RLE_BIG)
1420 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1421 for (i=0; i<sy; i++ )
1422 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1424 for (y1=0; y1 < h; y1++ ) {
1425 gr_rle_expand_scanline_svga_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1426 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1427 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1429 sbits += (int)src->bm_data[4+y1+sy];
1434 void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1436 register int x1, y1;
1438 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR ))
1440 if ( src->bm_flags & BM_FLAG_RLE )
1441 gr_bm_ubitblt00_rle( w, h, dx, dy, sx, sy, src, dest );
1443 gr_bm_ubitblt00( w, h, dx, dy, sx, sy, src, dest );
1448 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1450 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1453 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1455 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1458 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1460 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1465 if ( (src->bm_flags & BM_FLAG_RLE ) && (src->bm_type == BM_LINEAR) ) {
1466 gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest );
1471 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA ))
1473 gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest );
1477 if ( (src->bm_type == BM_SVGA) && (dest->bm_type == BM_LINEAR ))
1479 gr_bm_ubitblt20( w, h, dx, dy, sx, sy, src, dest );
1483 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_MODEX ))
1485 gr_bm_ubitblt01( w, h, dx+XOFFSET, dy+YOFFSET, sx, sy, src, dest );
1490 for (y1=0; y1 < h; y1++ ) {
1491 for (x1=0; x1 < w; x1++ ) {
1492 gr_bm_pixel( dest, dx+x1, dy+y1, gr_gpixel(src,sx+x1,sy+y1) );
1497 void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1499 int dx1=dx, dx2=dx+dest->bm_w-1;
1500 int dy1=dy, dy2=dy+dest->bm_h-1;
1502 int sx1=sx, sx2=sx+src->bm_w-1;
1503 int sy1=sy, sy2=sy+src->bm_h-1;
1505 if ((dx1 >= dest->bm_w ) || (dx2 < 0)) return;
1506 if ((dy1 >= dest->bm_h ) || (dy2 < 0)) return;
1507 if ( dx1 < 0 ) { sx1 += -dx1; dx1 = 0; }
1508 if ( dy1 < 0 ) { sy1 += -dy1; dy1 = 0; }
1509 if ( dx2 >= dest->bm_w ) { dx2 = dest->bm_w-1; }
1510 if ( dy2 >= dest->bm_h ) { dy2 = dest->bm_h-1; }
1512 if ((sx1 >= src->bm_w ) || (sx2 < 0)) return;
1513 if ((sy1 >= src->bm_h ) || (sy2 < 0)) return;
1514 if ( sx1 < 0 ) { dx1 += -sx1; sx1 = 0; }
1515 if ( sy1 < 0 ) { dy1 += -sy1; sy1 = 0; }
1516 if ( sx2 >= src->bm_w ) { sx2 = src->bm_w-1; }
1517 if ( sy2 >= src->bm_h ) { sy2 = src->bm_h-1; }
1519 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1520 if ( dx2-dx1+1 < w )
1522 if ( dy2-dy1+1 < h )
1524 if ( sx2-sx1+1 < w )
1526 if ( sy2-sy1+1 < h )
1529 gr_bm_ubitblt(w,h, dx1, dy1, sx1, sy1, src, dest );
1532 void gr_ubitmap( int x, int y, grs_bitmap *bm )
1536 source = bm->bm_type;
1539 if (source==BM_LINEAR) {
1543 if ( bm->bm_flags & BM_FLAG_RLE )
1544 gr_bm_ubitblt00_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1546 gr_ubitmap00( x, y, bm );
1550 ogl_ubitmapm(x,y,bm);
1555 if ( bm->bm_flags & BM_FLAG_RLE )
1556 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1558 gr_vesa_bitmap( bm, &grd_curcanv->cv_bitmap, x, y );
1561 gr_bm_ubitblt01(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1565 gr_ubitmap012( x, y, bm );
1569 gr_ubitmapGENERIC(x, y, bm);
1574 void gr_ubitmapm( int x, int y, grs_bitmap *bm )
1578 source = bm->bm_type;
1581 Assert(x+bm->bm_w <= grd_curcanv->cv_w);
1583 Assert(y+bm->bm_h <= grd_curcanv->cv_h);
1586 if (source==BM_LINEAR) {
1590 if ( bm->bm_flags & BM_FLAG_RLE )
1591 gr_bm_ubitblt00m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1593 gr_ubitmap00m( x, y, bm );
1597 ogl_ubitmapm(x,y,bm);
1602 if (bm->bm_flags & BM_FLAG_RLE)
1603 gr_bm_ubitblt02m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1604 //gr_bm_ubitblt0xm_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1606 gr_bm_ubitblt02m(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1607 //gr_ubitmapGENERICm(x, y, bm);
1610 gr_bm_ubitblt01m(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1615 gr_ubitmap012m( x, y, bm );
1619 gr_ubitmapGENERICm(x, y, bm);
1624 void gr_bitmapm( int x, int y, grs_bitmap *bm )
1626 int dx1=x, dx2=x+bm->bm_w-1;
1627 int dy1=y, dy2=y+bm->bm_h-1;
1630 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1631 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1632 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1633 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1634 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1635 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1637 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1639 if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_LINEAR ))
1641 if ( bm->bm_flags & BM_FLAG_RLE )
1642 gr_bm_ubitblt00m_rle(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1644 gr_bm_ubitblt00m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1648 else if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_SVGA ))
1650 gr_bm_ubitblt02m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1655 gr_bm_ubitbltm(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1659 void gr_bm_ubitbltm(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1661 register int x1, y1;
1665 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1667 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1670 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1672 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1675 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1677 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1682 for (y1=0; y1 < h; y1++ ) {
1683 for (x1=0; x1 < w; x1++ ) {
1684 if ((c=gr_gpixel(src,sx+x1,sy+y1))!=TRANSPARENCY_COLOR)
1685 gr_bm_pixel( dest, dx+x1, dy+y1,c );
1691 // rescalling bitmaps, 10/14/99 Jan Bobrowski jb@wizard.ae.krakow.pl
1692 void gr_bitmap_scale_line(unsigned char *in, unsigned char *out, int ilen, int olen)
1694 int a = olen/ilen, b = olen%ilen;
1696 unsigned char *end = out + olen;
1712 void gr_bitmap_scale_to(grs_bitmap *src, grs_bitmap *dst)
1714 unsigned char *s = src->bm_data;
1715 unsigned char *d = dst->bm_data;
1717 int a = dst->bm_h/h, b = dst->bm_h%h;
1720 if ( src->bm_flags & BM_FLAG_RLE ) {
1721 src = rle_expand_texture(src);
1724 for(y=0; y<h; y++) {
1733 gr_bitmap_scale_line(s, d, src->bm_w, dst->bm_w);
1734 d += dst->bm_rowsize;
1736 s += src->bm_rowsize;
1741 void gr_bitmap_fullscr(grs_bitmap *bm)
1743 grs_bitmap * const scr = &grd_curcanv->cv_bitmap;
1746 if(bm->bm_type == BM_LINEAR && scr->bm_type == BM_OGL) {
1747 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
1751 if(scr->bm_type != BM_LINEAR) {
1752 grs_bitmap *tmp = gr_create_bitmap(scr->bm_w, scr->bm_h);
1753 gr_bitmap_scale_to(bm, tmp);
1754 gr_bitmap(0, 0, tmp);
1755 gr_free_bitmap(tmp);
1758 gr_bitmap_scale_to(bm, scr);