1 /* $Id: bitblt.c,v 1.18 2005-07-30 01:51:42 chris 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.
30 #include "byteswap.h" // because of rle code that has short for row offsets
37 int gr_bitblt_dest_step_shift = 0;
38 int gr_bitblt_double = 0;
39 ubyte *gr_bitblt_fade_table=NULL;
41 extern void gr_vesa_bitmap( grs_bitmap * source, grs_bitmap * dest, int x, int y );
43 void gr_linear_movsd( ubyte * source, ubyte * dest, unsigned int nbytes);
44 // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
46 #if !defined(NO_ASM) && defined(__WATCOMC__)
48 #pragma aux gr_linear_movsd parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
66 #elif !defined(NO_ASM) && defined(__GNUC__)
68 inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels) {
70 __asm__ __volatile__ (
87 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
88 : "0" (src), "1" (dest), "2" (num_pixels)
92 #elif !defined(NO_ASM) && defined(_MSC_VER)
94 __inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels)
119 #else // NO_ASM or unknown compiler
124 #define test_byteblit 0
126 ubyte test_byteblit = 0;
129 void gr_linear_movsd(ubyte * src, ubyte * dest, unsigned int num_pixels )
136 // check to see if we are starting on an even byte boundry
137 // if not, move appropriate number of bytes to even
140 if ( (num_pixels < THRESHOLD) || (((int)src & 0x7) != ((int)dest & 0x7)) || test_byteblit ) {
141 for (i = 0; i < num_pixels; i++)
147 if ((r = (int)src & 0x7)) {
148 for (i = 0; i < 8 - r; i++)
157 for (i = 0; i < n; i++)
161 for (i = 0; i < r; i++)
165 #endif //#ifdef NO_ASM
168 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels );
170 #if !defined(NO_ASM) && defined(__WATCOMC__)
172 #pragma aux gr_linear_rep_movsdm parm [esi] [edi] [ecx] modify exact [ecx esi edi eax] = \
176 "cmp al, " TRANSPARENCY_COLOR_STR \
184 #elif !defined(NO_ASM) && defined(__GNUC__)
186 static inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels ) {
188 __asm__ __volatile__ (
190 " movb (%%esi), %%al;"
192 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
194 " movb %%al,(%%edi);"
199 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
200 : "0" (src), "1" (dest), "2" (num_pixels)
204 #elif !defined(NO_ASM) && defined(_MSC_VER)
206 __inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
212 mov ecx, [num_pixels]
215 cmp al, TRANSPARENCY_COLOR
227 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
230 for (i=0; i<num_pixels; i++ ) {
231 if (*src != TRANSPARENCY_COLOR )
240 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value );
242 #if !defined(NO_ASM) && defined(__WATCOMC__)
244 #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] = \
250 "cmp al, " TRANSPARENCY_COLOR_STR \
252 "mov al, gr_fade_table[eax]" \
259 #elif !defined(NO_ASM) && defined(__GNUC__)
261 /* #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] */
262 static inline void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value ) {
264 __asm__ __volatile__ (
265 " xorl %%eax, %%eax;"
268 " movb (%%esi), %%al;"
270 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
273 " movb gr_fade_table(%%eax), %%al;"
275 " movb _gr_fade_table(%%eax), %%al;"
277 " movb %%al, (%%edi);"
282 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2]), "=b" (dummy[3])
283 : "0" (src), "1" (dest), "2" (num_pixels), "3" (fade_value)
287 #elif !defined(NO_ASM) && defined(_MSC_VER)
289 __inline void gr_linear_rep_movsdm_faded(void * src, void * dest, unsigned int num_pixels, ubyte fade_value )
294 mov ecx, [num_pixels]
295 movzx ebx, byte ptr [fade_value]
301 cmp al, TRANSPARENCY_COLOR
303 mov al, gr_fade_table[eax]
314 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value )
320 fade_base = gr_fade_table + (fade_value * 256);
322 for (i=num_pixels; i != 0; i-- )
325 if (source != (ubyte)TRANSPARENCY_COLOR )
326 *dest = *(fade_base + source);
335 void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels);
337 #if !defined(NO_ASM) && defined(__WATCOMC__)
339 #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
359 #elif !defined(NO_ASM) && defined (__GNUC__)
361 inline void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels)
363 /* #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] */
365 __asm__ __volatile__ (
368 "movb (%%esi), %%al;"
369 "movb %%al, (%%edi);"
375 "movb (%%esi), %%al;"
377 "movw %%ax, (%%edi);"
384 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
385 : "0" (src), "1" (dest), "2" (num_dest_pixels)
389 #elif !defined(NO_ASM) && defined(_MSC_VER)
391 __inline void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_dest_pixels)
396 mov ecx, [num_dest_pixels]
420 void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_pixels)
422 double *d = (double *)dest;
423 uint *s = (uint *)src;
428 if (num_pixels & 0x3) {
429 // not a multiple of 4? do single pixel at a time
430 for (i=0; i<num_pixels; i++) {
437 for (i = 0; i < num_pixels / 4; i++) {
440 temp = ((temp >> 8) & 0x00FFFF00) | (temp & 0xFF0000FF); // 0xABCDEFGH -> 0xABABCDEF
441 temp = ((temp >> 8) & 0x000000FF) | (temp & 0xFFFFFF00); // 0xABABCDEF -> 0xABABCDCD
442 doubletemp[0] = temp;
444 work = ((work << 8) & 0x00FFFF00) | (work & 0xFF0000FF); // 0xABCDEFGH -> 0xABEFGHGH
445 work = ((work << 8) & 0xFF000000) | (work & 0x00FFFFFF); // 0xABEFGHGH -> 0xEFEFGHGH
446 doubletemp[1] = work;
448 *d = *(double *) &(doubletemp[0]);
458 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
460 #if !defined(NO_ASM) && defined(__WATCOMC__)
462 #pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
471 #elif !defined(NO_ASM) && defined(__GNUC__)
473 static inline void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
474 /*#pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
475 __asm__ __volatile__ (
477 "movb (%%esi), %%al;"
479 "movb %%al, (%%edi);"
483 : : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
484 : "%eax", "%ecx", "%esi", "%edi");
489 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
493 num_pixels = num_pixels;
494 src_rowsize = src_rowsize;
495 dest_rowsize = dest_rowsize;
502 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
504 #if !defined(NO_ASM) && defined(__WATCOMC__)
506 #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
510 "cmp al, " TRANSPARENCY_COLOR_STR \
518 #elif !defined(NO_ASM) && defined(__GNUC__)
520 static inline void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
521 /* #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
523 __asm__ __volatile__ (
525 "movb (%%esi), %%al;"
527 "cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
529 "movb %%al, (%%edi);"
534 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
535 : "1" (src), "2" (dest), "0" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
541 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
545 num_pixels = num_pixels;
546 src_rowsize = src_rowsize;
547 dest_rowsize = dest_rowsize;
553 #endif /* __MSDOS__ */
555 void gr_ubitmap00( int x, int y, grs_bitmap *bm )
560 unsigned char * dest;
563 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
564 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
568 for (y1=0; y1 < bm->bm_h; y1++ ) {
569 if (gr_bitblt_double)
570 gr_linear_rep_movsd_2x( src, dest, bm->bm_w );
572 gr_linear_movsd( src, dest, bm->bm_w );
573 src += bm->bm_rowsize;
574 dest+= (int)(dest_rowsize);
578 void gr_ubitmap00m( int x, int y, grs_bitmap *bm )
583 unsigned char * dest;
586 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
587 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
591 if (gr_bitblt_fade_table==NULL) {
592 for (y1=0; y1 < bm->bm_h; y1++ ) {
593 gr_linear_rep_movsdm( src, dest, bm->bm_w );
594 src += bm->bm_rowsize;
595 dest+= (int)(dest_rowsize);
598 for (y1=0; y1 < bm->bm_h; y1++ ) {
599 gr_linear_rep_movsdm_faded( src, dest, bm->bm_w, gr_bitblt_fade_table[y1+y] );
600 src += bm->bm_rowsize;
601 dest+= (int)(dest_rowsize);
626 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels );
628 #if !defined(NO_ASM) && defined(__WATCOMC__)
630 #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
637 " mov al, [esi+8] " \
638 " mov ah, [esi+12] " \
641 " mov ah, [esi+4] " \
646 " jne next4pixels " \
659 #elif !defined (NO_ASM) && defined(__GNUC__)
661 static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) {
662 /* #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] */
664 __asm__ __volatile__ (
665 " movl %%ecx, %%ebx;"
671 " movb 8(%%esi), %%al;"
672 " movb 12(%%esi), %%ah;"
674 " movb (%%esi), %%al;"
675 " movb 4(%%esi), %%ah;"
676 " movl %%eax, (%%edi);"
685 " movb (%%esi), %%al;"
687 " movb %%al, (%%edi);"
692 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
693 : "1" (src), "2" (dest), "0" (npixels)
694 : "%eax", "%ebx", "%edx" );
699 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels )
709 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels );
711 #if !defined(NO_ASM) && defined(__WATCOMC__)
713 #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
720 " mov al, [esi+4] " \
721 " mov ah, [esi+6] " \
724 " mov ah, [esi+2] " \
729 " jne next4pixels " \
742 #elif !defined(NO_ASM) && defined(__GNUC__)
744 static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels ) {
745 /* #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = */
747 __asm__ __volatile__ (
748 " movl %%ecx, %%ebx;"
754 " movb 4(%%esi), %%al;"
755 " movb 6(%%esi), %%ah;"
757 " movb (%%esi), %%al;"
758 " movb 2(%%esi), %%ah;"
759 " movl %%eax, (%%edi);"
768 " movb (%%esi),%%al;"
770 " movb %%al, (%%edi);"
775 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
776 : "1" (src), "2" (dest), "0" (npixels)
777 : "%eax", "%ebx", "%edx" );
782 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels )
793 // From Linear to ModeX
794 void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
804 sstep = src->bm_rowsize;
805 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
807 if (!gr_bitblt_double) {
808 for (plane=0; plane<4; plane++ ) {
809 gr_modex_setplane( (plane+dx)&3 );
810 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane;
811 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
813 if ( (w&3) > plane ) w1++;
814 for (y=dy; y < dy+h; y++ ) {
815 modex_copy_scanline( sbits, dbits, w1 );
821 for (plane=0; plane<4; plane++ ) {
822 gr_modex_setplane( (plane+dx)&3 );
823 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane/2;
824 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
826 if ( (w&3) > plane ) w1++;
827 for (y=dy; y < dy+h; y++ ) {
828 modex_copy_scanline_2x( sbits, dbits, w1 );
837 // From Linear to ModeX masked
838 void gr_bm_ubitblt01m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
849 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
850 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + dx/4];
852 for (x=dx; x < dx+w; x++ ) {
853 gr_modex_setplane( x&3 );
857 //for (y=0; y < h; y++ ) {
858 // *dbits1 = *sbits1;
859 // sbits1 += src_bm_rowsize;
860 // dbits1 += dest_bm_rowsize;
862 modex_copy_column_m(sbits, dbits, h, src->bm_rowsize, dest->bm_rowsize << gr_bitblt_dest_step_shift );
870 #endif /* __MSDOS__ */
873 void gr_ubitmap012( int x, int y, grs_bitmap *bm )
880 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
881 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
882 gr_setcolor( *src++ );
888 void gr_ubitmap012m( int x, int y, grs_bitmap *bm )
895 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
896 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
897 if ( *src != TRANSPARENCY_COLOR ) {
906 void gr_ubitmapGENERIC(int x, int y, grs_bitmap * bm)
910 for (y1=0; y1 < bm->bm_h; y1++ ) {
911 for (x1=0; x1 < bm->bm_w; x1++ ) {
912 gr_setcolor( gr_gpixel(bm,x1,y1) );
913 gr_upixel( x+x1, y+y1 );
918 void gr_ubitmapGENERICm(int x, int y, grs_bitmap * bm)
923 for (y1=0; y1 < bm->bm_h; y1++ ) {
924 for (x1=0; x1 < bm->bm_w; x1++ ) {
925 c = gr_gpixel(bm,x1,y1);
926 if ( c != TRANSPARENCY_COLOR ) {
928 gr_upixel( x+x1, y+y1 );
936 // From linear to SVGA
937 void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
939 unsigned char * sbits;
941 unsigned int offset, EndingOffset, VideoLocation;
943 int sbpr, dbpr, y1, page, BytesToMove;
945 sbpr = src->bm_rowsize;
947 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
949 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
951 sbits = src->bm_data + ( sbpr*sy ) + sx;
953 for (y1=0; y1 < h; y1++ ) {
955 page = VideoLocation >> 16;
956 offset = VideoLocation & 0xFFFF;
958 gr_vesa_setpage( page );
960 EndingOffset = offset+w-1;
962 if ( EndingOffset <= 0xFFFF )
964 if ( gr_bitblt_double )
965 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
967 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), w );
969 VideoLocation += dbpr;
974 BytesToMove = 0xFFFF-offset+1;
976 if ( gr_bitblt_double )
977 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
979 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
982 gr_vesa_setpage(page);
984 if ( gr_bitblt_double )
985 gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
987 gr_linear_movsd( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
989 VideoLocation += dbpr;
998 void gr_bm_ubitblt02m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1000 unsigned char * sbits;
1002 unsigned int offset, EndingOffset, VideoLocation;
1004 int sbpr, dbpr, y1, page, BytesToMove;
1006 sbpr = src->bm_rowsize;
1008 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1010 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1012 sbits = src->bm_data + ( sbpr*sy ) + sx;
1014 for (y1=0; y1 < h; y1++ ) {
1016 page = VideoLocation >> 16;
1017 offset = VideoLocation & 0xFFFF;
1019 gr_vesa_setpage( page );
1021 EndingOffset = offset+w-1;
1023 if ( EndingOffset <= 0xFFFF )
1025 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), w );
1027 VideoLocation += dbpr;
1032 BytesToMove = 0xFFFF-offset+1;
1034 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1037 gr_vesa_setpage(page);
1039 gr_linear_rep_movsdm( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
1041 VideoLocation += dbpr;
1048 // From SVGA to linear
1049 void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1051 unsigned char * dbits;
1053 unsigned int offset, offset1, offset2;
1055 int sbpr, dbpr, y1, page;
1057 dbpr = dest->bm_rowsize;
1059 sbpr = src->bm_rowsize;
1061 for (y1=0; y1 < h; y1++ ) {
1063 offset2 = (unsigned int)src->bm_data + (sbpr * (y1+sy)) + sx;
1064 dbits = dest->bm_data + (dbpr * (y1+dy)) + dx;
1066 page = offset2 >> 16;
1067 offset = offset2 & 0xFFFF;
1068 offset1 = offset+w-1;
1069 gr_vesa_setpage( page );
1071 if ( offset1 > 0xFFFF ) {
1072 // Overlaps two pages
1073 while( offset <= 0xFFFF )
1074 *dbits++ = gr_video_memory[offset++];
1075 offset1 -= (0xFFFF+1);
1078 gr_vesa_setpage(page);
1080 while( offset <= offset1 )
1081 *dbits++ = gr_video_memory[offset++];
1088 //@extern int Interlacing_on;
1090 // From Linear to Linear
1091 void gr_bm_ubitblt00(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1093 unsigned char * dbits;
1094 unsigned char * sbits;
1095 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1100 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1101 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1103 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1105 // No interlacing, copy the whole buffer.
1106 for (i=0; i < h; i++ ) {
1107 if (gr_bitblt_double)
1108 gr_linear_rep_movsd_2x( sbits, dbits, w );
1110 gr_linear_movsd( sbits, dbits, w );
1111 sbits += src->bm_rowsize;
1115 // From Linear to Linear Masked
1116 void gr_bm_ubitblt00m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1118 unsigned char * dbits;
1119 unsigned char * sbits;
1120 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1124 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1125 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1127 // No interlacing, copy the whole buffer.
1129 if (gr_bitblt_fade_table==NULL) {
1130 for (i=0; i < h; i++ ) {
1131 gr_linear_rep_movsdm( sbits, dbits, w );
1132 sbits += src->bm_rowsize;
1133 dbits += dest->bm_rowsize;
1136 for (i=0; i < h; i++ ) {
1137 gr_linear_rep_movsdm_faded( sbits, dbits, w, gr_bitblt_fade_table[dy+i] );
1138 sbits += src->bm_rowsize;
1139 dbits += dest->bm_rowsize;
1145 extern void gr_lbitblt( grs_bitmap * source, grs_bitmap * dest, int height, int width );
1149 // width == number of destination pixels
1151 void gr_linear_movsd_double(ubyte *src, ubyte *dest, int width)
1153 double *d = (double *)dest;
1154 uint *s = (uint *)src;
1159 num_pixels = width / 2;
1160 if ( (num_pixels & 0x3) || (((int)src & 0x7) != ((int)dest & 0x7)) ) {
1161 // not a multiple of 4? do single pixel at a time
1162 for (i=0; i<num_pixels; i++) {
1169 for (i = 0; i < num_pixels / 4; i++) {
1172 temp = ((temp >> 8) & 0x00FFFF00) | (temp & 0xFF0000FF); // 0xABCDEFGH -> 0xABABCDEF
1173 temp = ((temp >> 8) & 0x000000FF) | (temp & 0xFFFFFF00); // 0xABABCDEF -> 0xABABCDCD
1174 doubletemp[0] = temp;
1176 work = ((work << 8) & 0x00FFFF00) | (work & 0xFF0000FF); // 0xABCDEFGH -> 0xABEFGHGH
1177 work = ((work << 8) & 0xFF000000) | (work & 0x00FFFFFF); // 0xABEFGHGH -> 0xEFEFGHGH
1178 doubletemp[1] = work;
1180 *d = *(double *) &(doubletemp[0]);
1185 //extern void BlitLargeAlign(ubyte *draw_buffer, int dstRowBytes, ubyte *dstPtr, int w, int h, int modulus);
1187 asm void BlitLargeAlign(ubyte *rSrcPtr, int rDblDStrd, ubyte *rDst1Ptr, int rWidth, int rHeight, int rModulus)
1189 stw r31,-4(SP) // store non-volatile reg in red zone
1190 addi r5,r5,-8 // subtract 8 from dst
1191 stw r30,-8(SP) // store non-volatile reg in red zone
1193 la r30,-16(SP) // calculate copy of local 8-byte variable
1195 // rSStrd = modulus - w
1196 add r31,r5,r4 // dst2 = dstRowBytes + dst1
1197 sub r4,r4,r6 // r4 = dstRowBytes - w
1198 addi r7,r7,-1 // subtract 1 from height count
1199 srawi r6,r6,2 // rWidth = w >> 2
1200 addi r3,r3,-4 // subtract 4 from src
1201 addi r6,r6,-1 // subtract 1 from width count
1202 add r4,r4,r4 // rDblDStrd = 2 * r4
1204 BlitLargeAlignY: // y count is in r7
1205 lwzu r10,4(r3) // load a long into r10
1206 mr r0,r10 // put a copy in r0
1208 // these are simplified -- can't use 'em inslwi r0,r10,16,8
1209 // these are simplified -- can't use 'em insrwi r11,r10,16,8
1210 rlwimi r0,r10,24,8,31
1211 rlwimi r11,r10,8,8,23
1212 rlwimi r0,r10,16,24,31
1214 rlwimi r11,r10,16,0,7
1216 mtctr r6 // copy x count into the counter
1220 lwzu r10,4(r3) // load a long into r10
1222 mr r0,r10 // put a copy in r0
1224 // simplefied inslwi r0,r10,16,8
1225 // simplefied insrwi r11,r10,16,8
1226 rlwimi r0,r10,24,8,31
1227 rlwimi r11,r10,8,8,23
1228 rlwimi r0,r10,16,24,31
1230 rlwimi r11,r10,16,0,7
1234 bdnz BlitLargeAlignX // loop over all x
1237 addic. r7,r7,-1 // decrement the counter
1245 bne BlitLargeAlignY // loop for all y
1247 lwz r30,-8(SP) // restore non-volatile regs
1248 lwz r31,-4(SP) // restore non-volatile regs
1249 blr // return to caller
1252 void gr_bm_ubitblt_double(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap *src, grs_bitmap *dest)
1258 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1259 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1260 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1261 Assert( !((int)dbits & 0x7) ); // assert to check double word alignment
1262 BlitLargeAlign(sbits, dstep, dbits, src->bm_w, src->bm_h, src->bm_rowsize);
1265 // w and h are the doubled width and height
1267 void gr_bm_ubitblt_double_slow(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap *src, grs_bitmap *dest)
1273 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1274 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1275 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1277 for (i=0; i < h; i++ ) {
1279 gr_linear_movsd_double(sbits, dbits, w);
1282 sbits += src->bm_rowsize;
1286 #endif /* MACINTOSH */
1289 // Clipped bitmap ...
1291 void gr_bitmap( int x, int y, grs_bitmap *bm )
1293 int dx1=x, dx2=x+bm->bm_w-1;
1294 int dy1=y, dy2=y+bm->bm_h-1;
1297 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1298 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1299 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1300 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1301 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1302 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1304 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1306 gr_bm_ubitblt(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1310 //-NOT-used // From linear to SVGA
1311 //-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)
1313 //-NOT-used unsigned char * sbits;
1315 //-NOT-used unsigned int offset, EndingOffset, VideoLocation;
1317 //-NOT-used int sbpr, dbpr, y1, page, BytesToMove;
1319 //-NOT-used sbpr = src->bm_rowsize;
1321 //-NOT-used dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1323 //-NOT-used VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1325 //-NOT-used sbits = src->bm_data + ( sbpr*sy ) + sx;
1327 //-NOT-used for (y1=0; y1 < h; y1++ ) {
1329 //-NOT-used page = VideoLocation >> 16;
1330 //-NOT-used offset = VideoLocation & 0xFFFF;
1332 //-NOT-used gr_vesa_setpage( page );
1334 //-NOT-used EndingOffset = offset+w-1;
1336 //-NOT-used if ( EndingOffset <= 0xFFFF )
1338 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
1340 //-NOT-used VideoLocation += dbpr;
1341 //-NOT-used sbits += sbpr;
1345 //-NOT-used BytesToMove = 0xFFFF-offset+1;
1347 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1350 //-NOT-used gr_vesa_setpage(page);
1352 //-NOT-used gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
1354 //-NOT-used VideoLocation += dbpr;
1355 //-NOT-used sbits += sbpr;
1363 //-NOT-used // From Linear to Linear
1364 //-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)
1366 //-NOT-used unsigned char * dbits;
1367 //-NOT-used unsigned char * sbits;
1368 //-NOT-used //int src_bm_rowsize_2, dest_bm_rowsize_2;
1372 //-NOT-used sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1373 //-NOT-used dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1375 //-NOT-used // No interlacing, copy the whole buffer.
1376 //-NOT-used for (i=0; i < h; i++ ) {
1377 //-NOT-used gr_linear_rep_movsd_2x( sbits, dbits, w );
1379 //-NOT-used sbits += src->bm_rowsize;
1380 //-NOT-used dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1384 void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1386 unsigned char * dbits;
1387 unsigned char * sbits;
1391 if (src->bm_flags & BM_FLAG_RLE_BIG)
1394 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1396 for (i=0; i<sy; i++ )
1397 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1399 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1401 // No interlacing, copy the whole buffer.
1402 for (i=0; i < h; i++ ) {
1403 gr_rle_expand_scanline( dbits, sbits, sx, sx+w-1 );
1404 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1405 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1407 sbits += (int)(src->bm_data[4+i+sy]);
1408 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1412 void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1414 unsigned char * dbits;
1415 unsigned char * sbits;
1419 if (src->bm_flags & BM_FLAG_RLE_BIG)
1422 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1423 for (i=0; i<sy; i++ )
1424 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1426 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1428 // No interlacing, copy the whole buffer.
1429 for (i=0; i < h; i++ ) {
1430 gr_rle_expand_scanline_masked( dbits, sbits, sx, sx+w-1 );
1431 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1432 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1434 sbits += (int)(src->bm_data[4+i+sy]);
1435 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1441 extern void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1442 extern void gr_rle_expand_scanline_generic_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1443 extern void gr_rle_expand_scanline_svga_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1445 void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1449 unsigned char * sbits;
1451 //mprintf( 0, "SVGA RLE!\n" );
1454 if (src->bm_flags & BM_FLAG_RLE_BIG)
1457 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1458 for (i=0; i<sy; i++ )
1459 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1461 for (y1=0; y1 < h; y1++ ) {
1462 gr_rle_expand_scanline_generic( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1463 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1464 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1466 sbits += (int)src->bm_data[4+y1+sy];
1471 void gr_bm_ubitblt0xm_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1475 unsigned char * sbits;
1477 //mprintf( 0, "SVGA RLE!\n" );
1480 if (src->bm_flags & BM_FLAG_RLE_BIG)
1483 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1484 for (i=0; i<sy; i++ )
1485 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1487 for (y1=0; y1 < h; y1++ ) {
1488 gr_rle_expand_scanline_generic_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1489 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1490 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1492 sbits += (int)src->bm_data[4+y1+sy];
1498 void gr_bm_ubitblt02m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1502 unsigned char * sbits;
1504 //mprintf( 0, "SVGA RLE!\n" );
1507 if (src->bm_flags & BM_FLAG_RLE_BIG)
1510 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 for (y1=0; y1 < h; y1++ ) {
1515 gr_rle_expand_scanline_svga_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1516 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1517 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1519 sbits += (int)src->bm_data[4+y1+sy];
1524 void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1526 register int x1, y1;
1528 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR ))
1530 if ( src->bm_flags & BM_FLAG_RLE )
1531 gr_bm_ubitblt00_rle( w, h, dx, dy, sx, sy, src, dest );
1533 gr_bm_ubitblt00( w, h, dx, dy, sx, sy, src, dest );
1538 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1540 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1543 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1545 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1548 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1550 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1556 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
1558 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
1559 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 0);
1562 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_LINEAR ))
1566 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
1572 if ( (src->bm_flags & BM_FLAG_RLE ) && (src->bm_type == BM_LINEAR) ) {
1573 gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest );
1578 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA ))
1580 gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest );
1584 if ( (src->bm_type == BM_SVGA) && (dest->bm_type == BM_LINEAR ))
1586 gr_bm_ubitblt20( w, h, dx, dy, sx, sy, src, dest );
1590 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_MODEX ))
1592 gr_bm_ubitblt01( w, h, dx+XOFFSET, dy+YOFFSET, sx, sy, src, dest );
1597 for (y1=0; y1 < h; y1++ ) {
1598 for (x1=0; x1 < w; x1++ ) {
1599 gr_bm_pixel( dest, dx+x1, dy+y1, gr_gpixel(src,sx+x1,sy+y1) );
1604 void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1606 int dx1=dx, dx2=dx+dest->bm_w-1;
1607 int dy1=dy, dy2=dy+dest->bm_h-1;
1609 int sx1=sx, sx2=sx+src->bm_w-1;
1610 int sy1=sy, sy2=sy+src->bm_h-1;
1612 if ((dx1 >= dest->bm_w ) || (dx2 < 0)) return;
1613 if ((dy1 >= dest->bm_h ) || (dy2 < 0)) return;
1614 if ( dx1 < 0 ) { sx1 += -dx1; dx1 = 0; }
1615 if ( dy1 < 0 ) { sy1 += -dy1; dy1 = 0; }
1616 if ( dx2 >= dest->bm_w ) { dx2 = dest->bm_w-1; }
1617 if ( dy2 >= dest->bm_h ) { dy2 = dest->bm_h-1; }
1619 if ((sx1 >= src->bm_w ) || (sx2 < 0)) return;
1620 if ((sy1 >= src->bm_h ) || (sy2 < 0)) return;
1621 if ( sx1 < 0 ) { dx1 += -sx1; sx1 = 0; }
1622 if ( sy1 < 0 ) { dy1 += -sy1; sy1 = 0; }
1623 if ( sx2 >= src->bm_w ) { sx2 = src->bm_w-1; }
1624 if ( sy2 >= src->bm_h ) { sy2 = src->bm_h-1; }
1626 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1627 if ( dx2-dx1+1 < w )
1629 if ( dy2-dy1+1 < h )
1631 if ( sx2-sx1+1 < w )
1633 if ( sy2-sy1+1 < h )
1636 gr_bm_ubitblt(w,h, dx1, dy1, sx1, sy1, src, dest );
1639 void gr_ubitmap( int x, int y, grs_bitmap *bm )
1643 source = bm->bm_type;
1646 if (source==BM_LINEAR) {
1650 if ( bm->bm_flags & BM_FLAG_RLE )
1651 gr_bm_ubitblt00_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1653 gr_ubitmap00( x, y, bm );
1657 ogl_ubitmapm(x,y,bm);
1662 Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
1663 Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 0);
1668 if ( bm->bm_flags & BM_FLAG_RLE )
1669 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1671 gr_vesa_bitmap( bm, &grd_curcanv->cv_bitmap, x, y );
1674 gr_bm_ubitblt01(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1678 gr_ubitmap012( x, y, bm );
1682 gr_ubitmapGENERIC(x, y, bm);
1687 void gr_ubitmapm( int x, int y, grs_bitmap *bm )
1691 source = bm->bm_type;
1694 Assert(x+bm->bm_w <= grd_curcanv->cv_w);
1696 Assert(y+bm->bm_h <= grd_curcanv->cv_h);
1700 _3dfx_Blit( x, y, bm );
1701 if ( _3dfx_skip_ddraw )
1705 if (source==BM_LINEAR) {
1709 if ( bm->bm_flags & BM_FLAG_RLE )
1710 gr_bm_ubitblt00m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1712 gr_ubitmap00m( x, y, bm );
1716 ogl_ubitmapm(x,y,bm);
1721 if (bm->bm_w < 35 && bm->bm_h < 35) {
1722 // ugly hack needed for reticle
1723 if ( bm->bm_flags & BM_FLAG_RLE )
1724 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap, 1 );
1726 gr_ubitmapGENERICm(x, y, bm);
1729 Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
1730 Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 1);
1735 if (bm->bm_flags & BM_FLAG_RLE)
1736 gr_bm_ubitblt02m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1737 //gr_bm_ubitblt0xm_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1739 gr_bm_ubitblt02m(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1740 //gr_ubitmapGENERICm(x, y, bm);
1743 gr_bm_ubitblt01m(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1748 gr_ubitmap012m( x, y, bm );
1752 gr_ubitmapGENERICm(x, y, bm);
1757 void gr_bitmapm( int x, int y, grs_bitmap *bm )
1759 int dx1=x, dx2=x+bm->bm_w-1;
1760 int dy1=y, dy2=y+bm->bm_h-1;
1763 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1764 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1765 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1766 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1767 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1768 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1770 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1772 if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_LINEAR ))
1774 if ( bm->bm_flags & BM_FLAG_RLE )
1775 gr_bm_ubitblt00m_rle(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1777 gr_bm_ubitblt00m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1781 else if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_SVGA ))
1783 gr_bm_ubitblt02m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1788 gr_bm_ubitbltm(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1792 void gr_bm_ubitbltm(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1794 register int x1, y1;
1798 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1800 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1803 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1805 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1808 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1810 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1815 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
1817 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
1818 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 1);
1821 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
1823 Assert ((int)src->bm_data == BM_D3D_RENDER || (int)src->bm_data == BM_D3D_DISPLAY);
1824 //Win32_BlitDirectXToDirectX (w, h, dx, dy, sx, sy, src->bm_data, dest->bm_data, 0);
1829 for (y1=0; y1 < h; y1++ ) {
1830 for (x1=0; x1 < w; x1++ ) {
1831 if ((c=gr_gpixel(src,sx+x1,sy+y1))!=TRANSPARENCY_COLOR)
1832 gr_bm_pixel( dest, dx+x1, dy+y1,c );
1838 // rescalling bitmaps, 10/14/99 Jan Bobrowski jb@wizard.ae.krakow.pl
1840 inline void scale_line(unsigned char *in, unsigned char *out, int ilen, int olen)
1842 int a = olen/ilen, b = olen%ilen;
1844 unsigned char *end = out + olen;
1860 void gr_bitmap_scale_to(grs_bitmap *src, grs_bitmap *dst)
1862 unsigned char *s = src->bm_data;
1863 unsigned char *d = dst->bm_data;
1865 int a = dst->bm_h/h, b = dst->bm_h%h;
1868 for(y=0; y<h; y++) {
1877 scale_line(s, d, src->bm_w, dst->bm_w);
1878 d += dst->bm_rowsize;
1880 s += src->bm_rowsize;
1884 void show_fullscr(grs_bitmap *bm)
1886 grs_bitmap * const scr = &grd_curcanv->cv_bitmap;
1889 if(bm->bm_type == BM_LINEAR && scr->bm_type == BM_OGL) {
1890 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
1894 if(scr->bm_type != BM_LINEAR) {
1895 grs_bitmap *tmp = gr_create_bitmap(scr->bm_w, scr->bm_h);
1896 gr_bitmap_scale_to(bm, tmp);
1897 gr_bitmap(0, 0, tmp);
1898 gr_free_bitmap(tmp);
1901 gr_bitmap_scale_to(bm, scr);