1 /* $Id: bitblt.c,v 1.10 2002-09-07 07:15:50 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * Routines for bitblt's.
20 * Revision 1.29 1995/03/14 12:14:28 john
21 * Added code to double horz/vert bitblts.
23 * Revision 1.28 1995/03/13 09:01:48 john
24 * Fixed bug with VFX1 screen not tall enough.
26 * Revision 1.27 1995/03/01 15:38:10 john
27 * Better ModeX support.
29 * Revision 1.26 1994/12/15 12:19:00 john
30 * Added gr_bm_bitblt (clipped!) function.
32 * Revision 1.25 1994/12/09 18:58:42 matt
33 * Took out include of 3d.h
35 * Revision 1.24 1994/11/28 17:08:32 john
36 * Took out some unused functions in linear.asm, moved
37 * gr_linear_movsd from linear.asm to bitblt.c, made sure that
38 * the code in ibiblt.c sets the direction flags before rep movsing.
40 * Revision 1.22 1994/11/23 16:04:00 john
41 * Fixed generic rle'ing to use new bit method.
43 * Revision 1.21 1994/11/18 22:51:03 john
44 * Changed a bunch of shorts to ints in calls.
46 * Revision 1.20 1994/11/10 15:59:48 john
47 * Fixed bugs with canvas's being created with bogus bm_flags.
49 * Revision 1.19 1994/11/09 21:03:35 john
50 * Added RLE for svga gr_ubitmap.
52 * Revision 1.18 1994/11/09 17:41:29 john
53 * Made a slow version of rle bitblt to svga, modex.
55 * Revision 1.17 1994/11/09 16:35:15 john
56 * First version with working RLE bitmaps.
58 * Revision 1.16 1994/11/04 10:06:58 john
59 * Added fade table for fading fonts. Made font that partially clips
60 * not print a warning message.
62 * Revision 1.15 1994/09/22 16:08:38 john
63 * Fixed some palette stuff.
65 * Revision 1.14 1994/09/19 11:44:27 john
66 * Changed call to allocate selector to the dpmi module.
68 * Revision 1.13 1994/08/08 13:03:00 john
69 * Fixed bug in gr_bitmap in modex
71 * Revision 1.12 1994/07/13 19:47:23 john
72 * Fixed bug with modex bitblt to page 2 not working.
74 * Revision 1.11 1994/05/31 11:10:52 john
75 * *** empty log message ***
77 * Revision 1.10 1994/03/18 15:24:34 matt
78 * Removed interlace stuff
80 * Revision 1.9 1994/02/18 15:32:20 john
81 * *** empty log message ***
83 * Revision 1.8 1994/02/01 13:22:54 john
84 * *** empty log message ***
86 * Revision 1.7 1994/01/13 08:28:25 mike
87 * Modify rect copy to copy alternate scanlines when in interlaced mode.
89 * Revision 1.6 1993/12/28 12:09:46 john
92 * Revision 1.5 1993/10/26 13:18:09 john
93 * *** empty log message ***
95 * Revision 1.4 1993/10/15 16:23:30 john
98 * Revision 1.3 1993/09/13 17:52:58 john
99 * Fixed bug in BitBlt linear to SVGA
101 * Revision 1.2 1993/09/08 14:47:00 john
102 * Made bitmap00 add rowsize instead of bitmap width.
103 * Other routines might have this problem too.
105 * Revision 1.1 1993/09/08 11:43:01 john
114 #include "pa_enabl.h" //$$POLY_ACC
120 #include "byteswap.h" // because of rle code that has short for row offsets
124 #include "ogl_init.h"
127 #if defined(POLY_ACC)
128 #include "poly_acc.h"
131 int gr_bitblt_dest_step_shift = 0;
132 int gr_bitblt_double = 0;
133 ubyte *gr_bitblt_fade_table=NULL;
135 extern void gr_vesa_bitmap( grs_bitmap * source, grs_bitmap * dest, int x, int y );
137 void gr_linear_movsd( ubyte * source, ubyte * dest, unsigned int nbytes);
138 // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
140 #if !defined(NO_ASM) && defined(__WATCOMC__)
142 #pragma aux gr_linear_movsd parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
160 #elif !defined(NO_ASM) && defined(__GNUC__)
162 inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels) {
164 __asm__ __volatile__ (
166 " movl %%ecx, %%ebx;"
167 " movl %%edi, %%eax;"
175 " movl %%ebx, %%ecx;"
178 " movl %%ebx, %%ecx;"
181 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
182 : "0" (src), "1" (dest), "2" (num_pixels)
186 #elif !defined(NO_ASM) && defined(_MSC_VER)
188 __inline void gr_linear_movsd(ubyte *src, ubyte *dest, unsigned int num_pixels)
193 mov ecx, [num_pixels]
213 #else // NO_ASM or unknown compiler
218 #define test_byteblit 0
220 ubyte test_byteblit = 0;
223 void gr_linear_movsd(ubyte * src, ubyte * dest, unsigned int num_pixels )
230 // check to see if we are starting on an even byte boundry
231 // if not, move appropriate number of bytes to even
234 if ( (num_pixels < THRESHOLD) || (((int)src & 0x7) != ((int)dest & 0x7)) || test_byteblit ) {
235 for (i = 0; i < num_pixels; i++)
241 if ((r = (int)src & 0x7)) {
242 for (i = 0; i < 8 - r; i++)
251 for (i = 0; i < n; i++)
255 for (i = 0; i < r; i++)
259 #endif //#ifdef NO_ASM
262 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels );
264 #if !defined(NO_ASM) && defined(__WATCOMC__)
266 #pragma aux gr_linear_rep_movsdm parm [esi] [edi] [ecx] modify exact [ecx esi edi eax] = \
270 "cmp al, " TRANSPARENCY_COLOR_STR \
278 #elif !defined(NO_ASM) && defined(__GNUC__)
280 static inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels ) {
282 __asm__ __volatile__ (
284 " movb (%%esi), %%al;"
286 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
288 " movb %%al,(%%edi);"
293 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
294 : "0" (src), "1" (dest), "2" (num_pixels)
298 #elif !defined(NO_ASM) && defined(_MSC_VER)
300 __inline void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
306 mov ecx, [num_pixels]
309 cmp al, TRANSPARENCY_COLOR
321 static void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, unsigned int num_pixels )
324 for (i=0; i<num_pixels; i++ ) {
325 if (*src != TRANSPARENCY_COLOR )
334 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value );
336 #if !defined(NO_ASM) && defined(__WATCOMC__)
338 #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] = \
344 "cmp al, " TRANSPARENCY_COLOR_STR \
346 "mov al, gr_fade_table[eax]" \
353 #elif !defined(NO_ASM) && defined(__GNUC__)
355 /* #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] */
356 static inline void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value ) {
358 __asm__ __volatile__ (
359 " xorl %%eax, %%eax;"
362 " movb (%%esi), %%al;"
364 " cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
367 " movb gr_fade_table(%%eax), %%al;"
369 " movb _gr_fade_table(%%eax), %%al;"
371 " movb %%al, (%%edi);"
376 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2]), "=b" (dummy[3])
377 : "0" (src), "1" (dest), "2" (num_pixels), "3" (fade_value)
381 #elif !defined(NO_ASM) && defined(_MSC_VER)
383 __inline void gr_linear_rep_movsdm_faded(void * src, void * dest, unsigned int num_pixels, ubyte fade_value )
388 mov ecx, [num_pixels]
389 movzx ebx, byte ptr [fade_value]
395 cmp al, TRANSPARENCY_COLOR
397 mov al, gr_fade_table[eax]
408 static void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, unsigned int num_pixels, ubyte fade_value )
414 fade_base = gr_fade_table + (fade_value * 256);
416 for (i=num_pixels; i != 0; i-- )
419 if (source != (ubyte)TRANSPARENCY_COLOR )
420 *dest = *(fade_base + source);
429 static void gr_linear_rep_movsd_2x(ubyte * src, ubyte * dest, unsigned int num_dest_pixels );
431 #if !defined(NO_ASM) && defined(__WATCOMC__)
433 #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
453 #elif !defined(NO_ASM) && defined (__GNUC__)
455 static inline void gr_linear_rep_movsd_2x(ubyte * src, ubyte * dest, unsigned int num_dest_pixels ) {
456 /* #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] */
458 __asm__ __volatile__ (
461 "movb (%%esi), %%al;"
462 "movb %%al, (%%edi);"
468 "movb (%%esi), %%al;"
470 "movw %%ax, (%%edi);"
477 : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
478 : "0" (src), "1" (dest), "2" (num_dest_pixels)
482 #elif !defined(NO_ASM) && defined(_MSC_VER)
484 __inline void gr_linear_rep_movsd_2x(ubyte * src, ubyte * dest, unsigned int num_dest_pixels )
489 mov ecx, [num_dest_pixels]
513 static void gr_linear_rep_movsd_2x(ubyte *src, ubyte *dest, unsigned int num_pixels)
515 double *d = (double *)dest;
516 uint *s = (uint *)src;
521 if (num_pixels & 0x3) {
522 // not a multiple of 4? do single pixel at a time
523 for (i=0; i<num_pixels; i++) {
530 for (i = 0; i < num_pixels / 4; i++) {
533 temp = ((temp >> 8) & 0x00FFFF00) | (temp & 0xFF0000FF); // 0xABCDEFGH -> 0xABABCDEF
534 temp = ((temp >> 8) & 0x000000FF) | (temp & 0xFFFFFF00); // 0xABABCDEF -> 0xABABCDCD
535 doubletemp[0] = temp;
537 work = ((work << 8) & 0x00FFFF00) | (work & 0xFF0000FF); // 0xABCDEFGH -> 0xABEFGHGH
538 work = ((work << 8) & 0xFF000000) | (work & 0x00FFFFFF); // 0xABEFGHGH -> 0xEFEFGHGH
539 doubletemp[1] = work;
541 *d = *(double *) &(doubletemp[0]);
551 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
553 #if !defined(NO_ASM) && defined(__WATCOMC__)
555 #pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
564 #elif !defined(NO_ASM) && defined(__GNUC__)
566 static inline void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
567 /*#pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
568 __asm__ __volatile__ (
570 "movb (%%esi), %%al;"
572 "movb %%al, (%%edi);"
576 : : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
577 : "%eax", "%ecx", "%esi", "%edi");
582 static void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
586 num_pixels = num_pixels;
587 src_rowsize = src_rowsize;
588 dest_rowsize = dest_rowsize;
595 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
597 #if !defined(NO_ASM) && defined(__WATCOMC__)
599 #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
603 "cmp al, " TRANSPARENCY_COLOR_STR \
611 #elif !defined(NO_ASM) && defined(__GNUC__)
613 static inline void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
614 /* #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
616 __asm__ __volatile__ (
618 "movb (%%esi), %%al;"
620 "cmpb $" TRANSPARENCY_COLOR_STR ", %%al;"
622 "movb %%al, (%%edi);"
627 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
628 : "1" (src), "2" (dest), "0" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
634 static void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize )
638 num_pixels = num_pixels;
639 src_rowsize = src_rowsize;
640 dest_rowsize = dest_rowsize;
646 #endif /* __MSDOS__ */
648 void gr_ubitmap00( int x, int y, grs_bitmap *bm )
653 unsigned char * dest;
656 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
657 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
661 for (y1=0; y1 < bm->bm_h; y1++ ) {
662 if (gr_bitblt_double)
663 gr_linear_rep_movsd_2x( src, dest, bm->bm_w );
665 gr_linear_movsd( src, dest, bm->bm_w );
666 src += bm->bm_rowsize;
667 dest+= (int)(dest_rowsize);
671 void gr_ubitmap00m( int x, int y, grs_bitmap *bm )
676 unsigned char * dest;
679 dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
680 dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
684 if (gr_bitblt_fade_table==NULL) {
685 for (y1=0; y1 < bm->bm_h; y1++ ) {
686 gr_linear_rep_movsdm( src, dest, bm->bm_w );
687 src += bm->bm_rowsize;
688 dest+= (int)(dest_rowsize);
691 for (y1=0; y1 < bm->bm_h; y1++ ) {
692 gr_linear_rep_movsdm_faded( src, dest, bm->bm_w, gr_bitblt_fade_table[y1+y] );
693 src += bm->bm_rowsize;
694 dest+= (int)(dest_rowsize);
719 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels );
721 #if !defined(NO_ASM) && defined(__WATCOMC__)
723 #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
730 " mov al, [esi+8] " \
731 " mov ah, [esi+12] " \
734 " mov ah, [esi+4] " \
739 " jne next4pixels " \
752 #elif !defined (NO_ASM) && defined(__GNUC__)
754 static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) {
755 /* #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] */
757 __asm__ __volatile__ (
758 " movl %%ecx, %%ebx;"
764 " movb 8(%%esi), %%al;"
765 " movb 12(%%esi), %%ah;"
767 " movb (%%esi), %%al;"
768 " movb 4(%%esi), %%ah;"
769 " movl %%eax, (%%edi);"
778 " movb (%%esi), %%al;"
780 " movb %%al, (%%edi);"
785 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
786 : "1" (src), "2" (dest), "0" (npixels)
787 : "%eax", "%ebx", "%edx" );
792 static void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels )
802 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels );
804 #if !defined(NO_ASM) && defined(__WATCOMC__)
806 #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
813 " mov al, [esi+4] " \
814 " mov ah, [esi+6] " \
817 " mov ah, [esi+2] " \
822 " jne next4pixels " \
835 #elif !defined(NO_ASM) && defined(__GNUC__)
837 static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels ) {
838 /* #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = */
840 __asm__ __volatile__ (
841 " movl %%ecx, %%ebx;"
847 " movb 4(%%esi), %%al;"
848 " movb 6(%%esi), %%ah;"
850 " movb (%%esi), %%al;"
851 " movb 2(%%esi), %%ah;"
852 " movl %%eax, (%%edi);"
861 " movb (%%esi),%%al;"
863 " movb %%al, (%%edi);"
868 : "=c" (dummy[0]), "=S" (dummy[1]), "=D" (dummy[2])
869 : "1" (src), "2" (dest), "0" (npixels)
870 : "%eax", "%ebx", "%edx" );
875 static void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels )
886 // From Linear to ModeX
887 void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
897 sstep = src->bm_rowsize;
898 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
900 if (!gr_bitblt_double) {
901 for (plane=0; plane<4; plane++ ) {
902 gr_modex_setplane( (plane+dx)&3 );
903 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane;
904 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
906 if ( (w&3) > plane ) w1++;
907 for (y=dy; y < dy+h; y++ ) {
908 modex_copy_scanline( sbits, dbits, w1 );
914 for (plane=0; plane<4; plane++ ) {
915 gr_modex_setplane( (plane+dx)&3 );
916 sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane/2;
917 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
919 if ( (w&3) > plane ) w1++;
920 for (y=dy; y < dy+h; y++ ) {
921 modex_copy_scanline_2x( sbits, dbits, w1 );
930 // From Linear to ModeX masked
931 void gr_bm_ubitblt01m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
942 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
943 dbits = &gr_video_memory[(dest->bm_rowsize * dy) + dx/4];
945 for (x=dx; x < dx+w; x++ ) {
946 gr_modex_setplane( x&3 );
950 //for (y=0; y < h; y++ ) {
951 // *dbits1 = *sbits1;
952 // sbits1 += src_bm_rowsize;
953 // dbits1 += dest_bm_rowsize;
955 modex_copy_column_m(sbits, dbits, h, src->bm_rowsize, dest->bm_rowsize << gr_bitblt_dest_step_shift );
963 #endif /* __MSDOS__ */
966 void gr_ubitmap012( int x, int y, grs_bitmap *bm )
973 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
974 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
975 gr_setcolor( *src++ );
981 void gr_ubitmap012m( int x, int y, grs_bitmap *bm )
988 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
989 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
990 if ( *src != TRANSPARENCY_COLOR ) {
999 #if defined(POLY_ACC)
1000 void gr_ubitmap05( int x, int y, grs_bitmap *bm )
1002 register int x1, y1;
1009 dst = (short *)(DATA + y * ROWSIZE + x * PA_BPP);
1010 mod = ROWSIZE / 2 - bm->bm_w;
1012 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
1013 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
1014 *dst++ = pa_clut[*src++];
1020 void gr_ubitmap05m( int x, int y, grs_bitmap *bm )
1022 register int x1, y1;
1029 dst = (short *)(DATA + y * ROWSIZE + x * PA_BPP);
1030 mod = ROWSIZE / 2 - bm->bm_w;
1032 for (y1=y; y1 < (y+bm->bm_h); y1++ ) {
1033 for (x1=x; x1 < (x+bm->bm_w); x1++ ) {
1034 if ( *src != TRANSPARENCY_COLOR ) {
1035 *dst = pa_clut[*src];
1044 void gr_bm_ubitblt05_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1046 unsigned short * dbits;
1047 unsigned char * sbits, scanline[640];
1048 int i, data_offset, j, nextrow;
1051 nextrow=dest->bm_rowsize/PA_BPP;
1054 if (src->bm_flags & BM_FLAG_RLE_BIG)
1057 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1058 for (i=0; i<sy; i++ )
1059 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1061 dbits = (unsigned short *)(dest->bm_data + (dest->bm_rowsize * dy) + dx*PA_BPP);
1063 // No interlacing, copy the whole buffer.
1064 for (i=0; i < h; i++ ) {
1065 gr_rle_expand_scanline( scanline, sbits, sx, sx+w-1 );
1066 for(j = 0; j != w; ++j)
1067 dbits[j] = pa_clut[scanline[j]];
1068 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1069 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1071 sbits += (int)(src->bm_data[4+i+sy]);
1076 void gr_bm_ubitblt05m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1078 unsigned short * dbits;
1079 unsigned char * sbits, scanline[640];
1080 int i, data_offset, j, nextrow;
1083 nextrow=dest->bm_rowsize/PA_BPP;
1085 if (src->bm_flags & BM_FLAG_RLE_BIG)
1088 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1089 for (i=0; i<sy; i++ )
1090 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1092 dbits = (unsigned short *)(dest->bm_data + (dest->bm_rowsize * dy) + dx*PA_BPP);
1094 // No interlacing, copy the whole buffer.
1095 for (i=0; i < h; i++ ) {
1096 gr_rle_expand_scanline( scanline, sbits, sx, sx+w-1 );
1097 for(j = 0; j != w; ++j)
1098 if(scanline[j] != TRANSPARENCY_COLOR)
1099 dbits[j] = pa_clut[scanline[j]];
1100 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1101 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1103 sbits += (int)(src->bm_data[4+i+sy]);
1109 void gr_ubitmapGENERIC(int x, int y, grs_bitmap * bm)
1111 register int x1, y1;
1113 for (y1=0; y1 < bm->bm_h; y1++ ) {
1114 for (x1=0; x1 < bm->bm_w; x1++ ) {
1115 gr_setcolor( gr_gpixel(bm,x1,y1) );
1116 gr_upixel( x+x1, y+y1 );
1121 void gr_ubitmapGENERICm(int x, int y, grs_bitmap * bm)
1123 register int x1, y1;
1126 for (y1=0; y1 < bm->bm_h; y1++ ) {
1127 for (x1=0; x1 < bm->bm_w; x1++ ) {
1128 c = gr_gpixel(bm,x1,y1);
1129 if ( c != TRANSPARENCY_COLOR ) {
1131 gr_upixel( x+x1, y+y1 );
1139 // From linear to SVGA
1140 void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1142 unsigned char * sbits;
1144 unsigned int offset, EndingOffset, VideoLocation;
1146 int sbpr, dbpr, y1, page, BytesToMove;
1148 sbpr = src->bm_rowsize;
1150 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1152 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1154 sbits = src->bm_data + ( sbpr*sy ) + sx;
1156 for (y1=0; y1 < h; y1++ ) {
1158 page = VideoLocation >> 16;
1159 offset = VideoLocation & 0xFFFF;
1161 gr_vesa_setpage( page );
1163 EndingOffset = offset+w-1;
1165 if ( EndingOffset <= 0xFFFF )
1167 if ( gr_bitblt_double )
1168 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
1170 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), w );
1172 VideoLocation += dbpr;
1177 BytesToMove = 0xFFFF-offset+1;
1179 if ( gr_bitblt_double )
1180 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1182 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1185 gr_vesa_setpage(page);
1187 if ( gr_bitblt_double )
1188 gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
1190 gr_linear_movsd( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
1192 VideoLocation += dbpr;
1201 void gr_bm_ubitblt02m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1203 unsigned char * sbits;
1205 unsigned int offset, EndingOffset, VideoLocation;
1207 int sbpr, dbpr, y1, page, BytesToMove;
1209 sbpr = src->bm_rowsize;
1211 dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1213 VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1215 sbits = src->bm_data + ( sbpr*sy ) + sx;
1217 for (y1=0; y1 < h; y1++ ) {
1219 page = VideoLocation >> 16;
1220 offset = VideoLocation & 0xFFFF;
1222 gr_vesa_setpage( page );
1224 EndingOffset = offset+w-1;
1226 if ( EndingOffset <= 0xFFFF )
1228 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), w );
1230 VideoLocation += dbpr;
1235 BytesToMove = 0xFFFF-offset+1;
1237 gr_linear_rep_movsdm( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1240 gr_vesa_setpage(page);
1242 gr_linear_rep_movsdm( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
1244 VideoLocation += dbpr;
1251 // From SVGA to linear
1252 void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1254 unsigned char * dbits;
1256 unsigned int offset, offset1, offset2;
1258 int sbpr, dbpr, y1, page;
1260 dbpr = dest->bm_rowsize;
1262 sbpr = src->bm_rowsize;
1264 for (y1=0; y1 < h; y1++ ) {
1266 offset2 = (unsigned int)src->bm_data + (sbpr * (y1+sy)) + sx;
1267 dbits = dest->bm_data + (dbpr * (y1+dy)) + dx;
1269 page = offset2 >> 16;
1270 offset = offset2 & 0xFFFF;
1271 offset1 = offset+w-1;
1272 gr_vesa_setpage( page );
1274 if ( offset1 > 0xFFFF ) {
1275 // Overlaps two pages
1276 while( offset <= 0xFFFF )
1277 *dbits++ = gr_video_memory[offset++];
1278 offset1 -= (0xFFFF+1);
1281 gr_vesa_setpage(page);
1283 while( offset <= offset1 )
1284 *dbits++ = gr_video_memory[offset++];
1291 //@extern int Interlacing_on;
1293 // From Linear to Linear
1294 void gr_bm_ubitblt00(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;
1298 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1303 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1304 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1306 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1308 // No interlacing, copy the whole buffer.
1309 for (i=0; i < h; i++ ) {
1310 if (gr_bitblt_double)
1311 gr_linear_rep_movsd_2x( sbits, dbits, w );
1313 gr_linear_movsd( sbits, dbits, w );
1314 sbits += src->bm_rowsize;
1318 // From Linear to Linear Masked
1319 void gr_bm_ubitblt00m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1321 unsigned char * dbits;
1322 unsigned char * sbits;
1323 //int src_bm_rowsize_2, dest_bm_rowsize_2;
1327 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1328 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1330 // No interlacing, copy the whole buffer.
1332 if (gr_bitblt_fade_table==NULL) {
1333 for (i=0; i < h; i++ ) {
1334 gr_linear_rep_movsdm( sbits, dbits, w );
1335 sbits += src->bm_rowsize;
1336 dbits += dest->bm_rowsize;
1339 for (i=0; i < h; i++ ) {
1340 gr_linear_rep_movsdm_faded( sbits, dbits, w, gr_bitblt_fade_table[dy+i] );
1341 sbits += src->bm_rowsize;
1342 dbits += dest->bm_rowsize;
1348 extern void gr_lbitblt( grs_bitmap * source, grs_bitmap * dest, int height, int width );
1350 #if 1 //def MACINTOSH
1352 // width == number of destination pixels
1354 void gr_linear_movsd_double(ubyte *src, ubyte *dest, int width)
1356 double *d = (double *)dest;
1357 uint *s = (uint *)src;
1362 num_pixels = width / 2;
1363 if ( (num_pixels & 0x3) || (((int)src & 0x7) != ((int)dest & 0x7)) ) {
1364 // not a multiple of 4? do single pixel at a time
1365 for (i=0; i<num_pixels; i++) {
1372 for (i = 0; i < num_pixels / 4; i++) {
1375 temp = ((temp >> 8) & 0x00FFFF00) | (temp & 0xFF0000FF); // 0xABCDEFGH -> 0xABABCDEF
1376 temp = ((temp >> 8) & 0x000000FF) | (temp & 0xFFFFFF00); // 0xABABCDEF -> 0xABABCDCD
1377 doubletemp[0] = temp;
1379 work = ((work << 8) & 0x00FFFF00) | (work & 0xFF0000FF); // 0xABCDEFGH -> 0xABEFGHGH
1380 work = ((work << 8) & 0xFF000000) | (work & 0x00FFFFFF); // 0xABEFGHGH -> 0xEFEFGHGH
1381 doubletemp[1] = work;
1383 *d = *(double *) &(doubletemp[0]);
1388 //extern void BlitLargeAlign(ubyte *draw_buffer, int dstRowBytes, ubyte *dstPtr, int w, int h, int modulus);
1391 asm void BlitLargeAlign(ubyte *rSrcPtr, int rDblDStrd, ubyte *rDst1Ptr, int rWidth, int rHeight, int rModulus)
1393 stw r31,-4(SP) // store non-volatile reg in red zone
1394 addi r5,r5,-8 // subtract 8 from dst
1395 stw r30,-8(SP) // store non-volatile reg in red zone
1397 la r30,-16(SP) // calculate copy of local 8-byte variable
1399 // rSStrd = modulus - w
1400 add r31,r5,r4 // dst2 = dstRowBytes + dst1
1401 sub r4,r4,r6 // r4 = dstRowBytes - w
1402 addi r7,r7,-1 // subtract 1 from height count
1403 srawi r6,r6,2 // rWidth = w >> 2
1404 addi r3,r3,-4 // subtract 4 from src
1405 addi r6,r6,-1 // subtract 1 from width count
1406 add r4,r4,r4 // rDblDStrd = 2 * r4
1408 BlitLargeAlignY: // y count is in r7
1409 lwzu r10,4(r3) // load a long into r10
1410 mr r0,r10 // put a copy in r0
1412 // these are simplified -- can't use 'em inslwi r0,r10,16,8
1413 // these are simplified -- can't use 'em insrwi r11,r10,16,8
1414 rlwimi r0,r10,24,8,31
1415 rlwimi r11,r10,8,8,23
1416 rlwimi r0,r10,16,24,31
1418 rlwimi r11,r10,16,0,7
1420 mtctr r6 // copy x count into the counter
1424 lwzu r10,4(r3) // load a long into r10
1426 mr r0,r10 // put a copy in r0
1428 // simplefied inslwi r0,r10,16,8
1429 // simplefied insrwi r11,r10,16,8
1430 rlwimi r0,r10,24,8,31
1431 rlwimi r11,r10,8,8,23
1432 rlwimi r0,r10,16,24,31
1434 rlwimi r11,r10,16,0,7
1438 bdnz BlitLargeAlignX // loop over all x
1441 addic. r7,r7,-1 // decrement the counter
1449 bne BlitLargeAlignY // loop for all y
1451 lwz r30,-8(SP) // restore non-volatile regs
1452 lwz r31,-4(SP) // restore non-volatile regs
1453 blr // return to caller
1456 void gr_bm_ubitblt_double(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap *src, grs_bitmap *dest)
1462 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1463 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1464 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1465 Assert( !((int)dbits & 0x7) ); // assert to check double word alignment
1466 BlitLargeAlign(sbits, dstep, dbits, src->bm_w, src->bm_h, src->bm_rowsize);
1470 // w and h are the doubled width and height
1472 void gr_bm_ubitblt_double_slow(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap *src, grs_bitmap *dest)
1478 sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1479 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1480 dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1482 for (i=0; i < h; i++ ) {
1484 gr_linear_movsd_double(sbits, dbits, w);
1487 sbits += src->bm_rowsize;
1494 // Clipped bitmap ...
1496 void gr_bitmap( int x, int y, grs_bitmap *bm )
1498 int dx1=x, dx2=x+bm->bm_w-1;
1499 int dy1=y, dy2=y+bm->bm_h-1;
1502 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
1503 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
1504 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
1505 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
1506 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
1507 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
1509 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1511 gr_bm_ubitblt(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
1515 //-NOT-used // From linear to SVGA
1516 //-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)
1518 //-NOT-used unsigned char * sbits;
1520 //-NOT-used unsigned int offset, EndingOffset, VideoLocation;
1522 //-NOT-used int sbpr, dbpr, y1, page, BytesToMove;
1524 //-NOT-used sbpr = src->bm_rowsize;
1526 //-NOT-used dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
1528 //-NOT-used VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
1530 //-NOT-used sbits = src->bm_data + ( sbpr*sy ) + sx;
1532 //-NOT-used for (y1=0; y1 < h; y1++ ) {
1534 //-NOT-used page = VideoLocation >> 16;
1535 //-NOT-used offset = VideoLocation & 0xFFFF;
1537 //-NOT-used gr_vesa_setpage( page );
1539 //-NOT-used EndingOffset = offset+w-1;
1541 //-NOT-used if ( EndingOffset <= 0xFFFF )
1543 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
1545 //-NOT-used VideoLocation += dbpr;
1546 //-NOT-used sbits += sbpr;
1550 //-NOT-used BytesToMove = 0xFFFF-offset+1;
1552 //-NOT-used gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
1555 //-NOT-used gr_vesa_setpage(page);
1557 //-NOT-used gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
1559 //-NOT-used VideoLocation += dbpr;
1560 //-NOT-used sbits += sbpr;
1568 //-NOT-used // From Linear to Linear
1569 //-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)
1571 //-NOT-used unsigned char * dbits;
1572 //-NOT-used unsigned char * sbits;
1573 //-NOT-used //int src_bm_rowsize_2, dest_bm_rowsize_2;
1577 //-NOT-used sbits = src->bm_data + (src->bm_rowsize * sy) + sx;
1578 //-NOT-used dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1580 //-NOT-used // No interlacing, copy the whole buffer.
1581 //-NOT-used for (i=0; i < h; i++ ) {
1582 //-NOT-used gr_linear_rep_movsd_2x( sbits, dbits, w );
1584 //-NOT-used sbits += src->bm_rowsize;
1585 //-NOT-used dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1589 void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1591 unsigned char * dbits;
1592 unsigned char * sbits;
1596 if (src->bm_flags & BM_FLAG_RLE_BIG)
1599 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1601 for (i=0; i<sy; i++ )
1602 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1604 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1606 // No interlacing, copy the whole buffer.
1607 for (i=0; i < h; i++ ) {
1608 gr_rle_expand_scanline( dbits, sbits, sx, sx+w-1 );
1609 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1610 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1612 sbits += (int)(src->bm_data[4+i+sy]);
1613 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1617 void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1619 unsigned char * dbits;
1620 unsigned char * sbits;
1624 if (src->bm_flags & BM_FLAG_RLE_BIG)
1627 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1628 for (i=0; i<sy; i++ )
1629 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1631 dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
1633 // No interlacing, copy the whole buffer.
1634 for (i=0; i < h; i++ ) {
1635 gr_rle_expand_scanline_masked( dbits, sbits, sx, sx+w-1 );
1636 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1637 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((i+sy)*data_offset)])));
1639 sbits += (int)(src->bm_data[4+i+sy]);
1640 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
1646 extern void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1647 extern void gr_rle_expand_scanline_generic_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1648 extern void gr_rle_expand_scanline_svga_masked( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2 );
1650 void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1654 unsigned char * sbits;
1656 //mprintf( 0, "SVGA RLE!\n" );
1659 if (src->bm_flags & BM_FLAG_RLE_BIG)
1662 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1663 for (i=0; i<sy; i++ )
1664 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1666 for (y1=0; y1 < h; y1++ ) {
1667 gr_rle_expand_scanline_generic( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1668 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1669 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1671 sbits += (int)src->bm_data[4+y1+sy];
1676 void gr_bm_ubitblt0xm_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1680 unsigned char * sbits;
1682 //mprintf( 0, "SVGA RLE!\n" );
1685 if (src->bm_flags & BM_FLAG_RLE_BIG)
1688 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1689 for (i=0; i<sy; i++ )
1690 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1692 for (y1=0; y1 < h; y1++ ) {
1693 gr_rle_expand_scanline_generic_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1694 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1695 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1697 sbits += (int)src->bm_data[4+y1+sy];
1703 void gr_bm_ubitblt02m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1707 unsigned char * sbits;
1709 //mprintf( 0, "SVGA RLE!\n" );
1712 if (src->bm_flags & BM_FLAG_RLE_BIG)
1715 sbits = &src->bm_data[4 + (src->bm_h*data_offset)];
1716 for (i=0; i<sy; i++ )
1717 sbits += (int)(INTEL_SHORT(src->bm_data[4+(i*data_offset)]));
1719 for (y1=0; y1 < h; y1++ ) {
1720 gr_rle_expand_scanline_svga_masked( dest, dx, dy+y1, sbits, sx, sx+w-1 );
1721 if ( src->bm_flags & BM_FLAG_RLE_BIG )
1722 sbits += (int)INTEL_SHORT(*((short *)&(src->bm_data[4+((y1+sy)*data_offset)])));
1724 sbits += (int)src->bm_data[4+y1+sy];
1729 void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1731 register int x1, y1;
1733 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR ))
1735 if ( src->bm_flags & BM_FLAG_RLE )
1736 gr_bm_ubitblt00_rle( w, h, dx, dy, sx, sy, src, dest );
1738 gr_bm_ubitblt00( w, h, dx, dy, sx, sy, src, dest );
1743 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
1745 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
1748 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
1750 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
1753 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
1755 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
1761 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
1763 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
1764 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 0);
1767 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_LINEAR ))
1771 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
1777 if ( (src->bm_flags & BM_FLAG_RLE ) && (src->bm_type == BM_LINEAR) ) {
1778 gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest );
1783 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA ))
1785 gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest );
1789 if ( (src->bm_type == BM_SVGA) && (dest->bm_type == BM_LINEAR ))
1791 gr_bm_ubitblt20( w, h, dx, dy, sx, sy, src, dest );
1795 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_MODEX ))
1797 gr_bm_ubitblt01( w, h, dx+XOFFSET, dy+YOFFSET, sx, sy, src, dest );
1802 #if defined(POLY_ACC)
1803 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR15 ))
1805 ubyte *s = src->bm_data + sy * src->bm_rowsize + sx;
1806 ushort *t = (ushort *)(dest->bm_data + dy * dest->bm_rowsize + dx * PA_BPP);
1811 for(x = 0; x < w; x++)
1812 t[x] = pa_clut[s[x]];
1813 s += src->bm_rowsize;
1814 t += dest->bm_rowsize / PA_BPP;
1819 if ( (src->bm_type == BM_LINEAR15) && (dest->bm_type == BM_LINEAR15 ))
1821 pa_blit(dest, dx, dy, src, sx, sy, w, h);
1826 for (y1=0; y1 < h; y1++ ) {
1827 for (x1=0; x1 < w; x1++ ) {
1828 gr_bm_pixel( dest, dx+x1, dy+y1, gr_gpixel(src,sx+x1,sy+y1) );
1833 void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
1835 int dx1=dx, dx2=dx+dest->bm_w-1;
1836 int dy1=dy, dy2=dy+dest->bm_h-1;
1838 int sx1=sx, sx2=sx+src->bm_w-1;
1839 int sy1=sy, sy2=sy+src->bm_h-1;
1841 if ((dx1 >= dest->bm_w ) || (dx2 < 0)) return;
1842 if ((dy1 >= dest->bm_h ) || (dy2 < 0)) return;
1843 if ( dx1 < 0 ) { sx1 += -dx1; dx1 = 0; }
1844 if ( dy1 < 0 ) { sy1 += -dy1; dy1 = 0; }
1845 if ( dx2 >= dest->bm_w ) { dx2 = dest->bm_w-1; }
1846 if ( dy2 >= dest->bm_h ) { dy2 = dest->bm_h-1; }
1848 if ((sx1 >= src->bm_w ) || (sx2 < 0)) return;
1849 if ((sy1 >= src->bm_h ) || (sy2 < 0)) return;
1850 if ( sx1 < 0 ) { dx1 += -sx1; sx1 = 0; }
1851 if ( sy1 < 0 ) { dy1 += -sy1; sy1 = 0; }
1852 if ( sx2 >= src->bm_w ) { sx2 = src->bm_w-1; }
1853 if ( sy2 >= src->bm_h ) { sy2 = src->bm_h-1; }
1855 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
1856 if ( dx2-dx1+1 < w )
1858 if ( dy2-dy1+1 < h )
1860 if ( sx2-sx1+1 < w )
1862 if ( sy2-sy1+1 < h )
1865 gr_bm_ubitblt(w,h, dx1, dy1, sx1, sy1, src, dest );
1868 void gr_ubitmap( int x, int y, grs_bitmap *bm )
1872 source = bm->bm_type;
1875 if (source==BM_LINEAR) {
1879 if ( bm->bm_flags & BM_FLAG_RLE )
1880 gr_bm_ubitblt00_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1882 gr_ubitmap00( x, y, bm );
1886 ogl_ubitmapm(x,y,bm);
1891 Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
1892 Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 0);
1897 if ( bm->bm_flags & BM_FLAG_RLE )
1898 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1900 gr_vesa_bitmap( bm, &grd_curcanv->cv_bitmap, x, y );
1903 gr_bm_ubitblt01(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1906 #if defined(POLY_ACC)
1908 if ( bm->bm_flags & BM_FLAG_RLE )
1909 gr_bm_ubitblt05_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1911 gr_ubitmap05( x, y, bm);
1916 gr_ubitmap012( x, y, bm );
1920 gr_ubitmapGENERIC(x, y, bm);
1925 void gr_ubitmapm( int x, int y, grs_bitmap *bm )
1929 source = bm->bm_type;
1932 Assert(x+bm->bm_w <= grd_curcanv->cv_w);
1933 Assert(y+bm->bm_h <= grd_curcanv->cv_h);
1936 _3dfx_Blit( x, y, bm );
1937 if ( _3dfx_skip_ddraw )
1941 if (source==BM_LINEAR) {
1945 if ( bm->bm_flags & BM_FLAG_RLE )
1946 gr_bm_ubitblt00m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1948 gr_ubitmap00m( x, y, bm );
1952 ogl_ubitmapm(x,y,bm);
1957 if (bm->bm_w < 35 && bm->bm_h < 35) {
1958 // ugly hack needed for reticle
1959 if ( bm->bm_flags & BM_FLAG_RLE )
1960 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap, 1 );
1962 gr_ubitmapGENERICm(x, y, bm);
1965 Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
1966 Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 1);
1971 if (bm->bm_flags & BM_FLAG_RLE)
1972 gr_bm_ubitblt02m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1973 //gr_bm_ubitblt0xm_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1975 gr_bm_ubitblt02m(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
1976 //gr_ubitmapGENERICm(x, y, bm);
1979 gr_bm_ubitblt01m(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
1982 #if defined(POLY_ACC)
1984 if ( bm->bm_flags & BM_FLAG_RLE )
1985 gr_bm_ubitblt05m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
1987 gr_ubitmap05m( x, y, bm );
1992 gr_ubitmap012m( x, y, bm );
1996 gr_ubitmapGENERICm(x, y, bm);
2001 void gr_bitmapm( int x, int y, grs_bitmap *bm )
2003 int dx1=x, dx2=x+bm->bm_w-1;
2004 int dy1=y, dy2=y+bm->bm_h-1;
2007 if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
2008 if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
2009 if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
2010 if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
2011 if ( dx2 >= grd_curcanv->cv_bitmap.bm_w ) { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
2012 if ( dy2 >= grd_curcanv->cv_bitmap.bm_h ) { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
2014 // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
2016 if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_LINEAR ))
2018 if ( bm->bm_flags & BM_FLAG_RLE )
2019 gr_bm_ubitblt00m_rle(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
2021 gr_bm_ubitblt00m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
2025 else if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_SVGA ))
2027 gr_bm_ubitblt02m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
2032 gr_bm_ubitbltm(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
2036 void gr_bm_ubitbltm(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
2038 register int x1, y1;
2042 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
2044 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
2047 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
2049 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
2052 if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
2054 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
2059 if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
2061 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
2062 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 1);
2065 if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
2067 Assert ((int)src->bm_data == BM_D3D_RENDER || (int)src->bm_data == BM_D3D_DISPLAY);
2068 //Win32_BlitDirectXToDirectX (w, h, dx, dy, sx, sy, src->bm_data, dest->bm_data, 0);
2072 #if defined(POLY_ACC)
2073 if(src->bm_type == BM_LINEAR && dest->bm_type == BM_LINEAR15)
2081 s = (ubyte *)(src->bm_data + src->bm_rowsize * sy + sx);
2082 smod = src->bm_rowsize - w;
2083 d = (ushort *)(dest->bm_data + dest->bm_rowsize * dy + dx * PA_BPP);
2084 dmod = dest->bm_rowsize / PA_BPP - w;
2086 for (x1=w; x1--; ) {
2087 if ((u = *s) != TRANSPARENCY_COLOR)
2097 if(src->bm_type == BM_LINEAR15)
2099 Assert(src->bm_type == dest->bm_type); // I don't support 15 to 8 yet.
2100 pa_blit_transparent(dest, dx, dy, src, sx, sy, w, h);
2105 for (y1=0; y1 < h; y1++ ) {
2106 for (x1=0; x1 < w; x1++ ) {
2107 if ((c=gr_gpixel(src,sx+x1,sy+y1))!=TRANSPARENCY_COLOR)
2108 gr_bm_pixel( dest, dx+x1, dy+y1,c );
2114 // rescalling bitmaps, 10/14/99 Jan Bobrowski jb@wizard.ae.krakow.pl
2116 inline void scale_line(byte *in, byte *out, int ilen, int olen)
2118 int a = olen/ilen, b = olen%ilen;
2120 byte *end = out + olen;
2136 void gr_bitmap_scale_to(grs_bitmap *src, grs_bitmap *dst)
2138 byte *s = src->bm_data;
2139 byte *d = dst->bm_data;
2141 int a = dst->bm_h/h, b = dst->bm_h%h;
2144 for(y=0; y<h; y++) {
2153 scale_line(s, d, src->bm_w, dst->bm_w);
2154 d += dst->bm_rowsize;
2156 s += src->bm_rowsize;
2160 void show_fullscr(grs_bitmap *bm)
2162 grs_bitmap * const scr = &grd_curcanv->cv_bitmap;
2165 if(bm->bm_type == BM_LINEAR && scr->bm_type == BM_OGL) {
2166 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
2170 if(scr->bm_type != BM_LINEAR) {
2171 grs_bitmap *tmp = gr_create_bitmap(scr->bm_w, scr->bm_h);
2172 gr_bitmap_scale_to(bm, tmp);
2173 gr_bitmap(0, 0, tmp);
2174 gr_free_bitmap(tmp);
2177 gr_bitmap_scale_to(bm, scr);