added cvsignore
[btb/d2x.git] / 2d / bitblt.c
1 /* $Id: bitblt.c,v 1.5 2002-07-17 21:55:19 bradleyb Exp $ */
2 /*
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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include <conf.h>
17 #endif
18
19 #include <string.h>
20 #include "u_mem.h"
21 #include "gr.h"
22 #include "grdef.h"
23 #include "rle.h"
24 #include "error.h"
25
26 #ifdef OGL
27 #include "ogl_init.h"
28 #endif
29
30 int gr_bitblt_dest_step_shift = 0;
31 int gr_bitblt_double = 0;
32 ubyte *gr_bitblt_fade_table=NULL;
33
34 void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest);
35 void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest);
36 void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest, int masked);
37
38 void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest);
39 void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest);
40
41 #include "linear.h"
42 #include "modex.h"
43 #include "vesa.h"
44
45 #ifdef NO_ASM
46 void gr_linear_movsd( ubyte * source, ubyte * dest, unsigned int nbytes) {
47         memcpy(dest,source,nbytes);
48 }
49
50 void gr_linear_rep_movsdm(ubyte *src, ubyte *dest, int num_pixels) {
51         register ubyte c;
52         while (num_pixels--)
53                 if ((c=*src++)!=255)
54                         *dest++=c;
55                 else    dest++;
56 }
57
58 void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, int num_pixels, ubyte fade_value ) {
59         register ubyte c;
60         while (num_pixels--)
61                 if ((c=*src++)!=255)
62                         *dest++=gr_fade_table[((int)fade_value<<8)|(int)c];
63                 else    dest++;
64 }
65 void gr_linear_rep_movsd_2x(ubyte * source, ubyte * dest, uint nbytes ) {
66         register ubyte c;
67         while (nbytes--) {
68                 if (nbytes&1)
69                         *dest++=*source++;
70                 else {
71                         c=*source++;
72                         *((unsigned short *)dest)++=((short)c<<8)|(short)c;
73                 }
74         }
75 }
76 #endif
77 #ifdef D1XD3D
78 #include "d3dhelp.h"
79 #endif
80
81 void gr_ubitmap00( int x, int y, grs_bitmap *bm )
82 {
83         register int y1;
84         int dest_rowsize;
85
86         unsigned char * dest;
87         unsigned char * src;
88
89         dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
90         dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
91
92         src = bm->bm_data;
93
94         for (y1=0; y1 < bm->bm_h; y1++ )    {
95                 if (gr_bitblt_double)
96                         gr_linear_rep_movsd_2x( src, dest, bm->bm_w );
97                 else
98                         gr_linear_movsd( src, dest, bm->bm_w );
99                 src += bm->bm_rowsize;
100                 dest+= (int)(dest_rowsize);
101         }
102 }
103
104 void gr_ubitmap00m( int x, int y, grs_bitmap *bm )
105 {
106         register int y1;
107         int dest_rowsize;
108
109         unsigned char * dest;
110         unsigned char * src;
111
112         dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
113         dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
114
115         src = bm->bm_data;
116
117         if (gr_bitblt_fade_table==NULL) {
118                 for (y1=0; y1 < bm->bm_h; y1++ )    {
119                         gr_linear_rep_movsdm( src, dest, bm->bm_w );
120                         src += bm->bm_rowsize;
121                         dest+= (int)(dest_rowsize);
122                 }
123         } else {
124                 for (y1=0; y1 < bm->bm_h; y1++ )    {
125                         gr_linear_rep_movsdm_faded( src, dest, bm->bm_w, gr_bitblt_fade_table[y1+y] );
126                         src += bm->bm_rowsize;
127                         dest+= (int)(dest_rowsize);
128                 }
129         }
130 }
131
132 //"             jmp     aligned4                                "       
133 //"             mov     eax, edi                                "       
134 //"             and     eax, 11b                                "       
135 //"             jz              aligned4                        "       
136 //"             mov     ebx, 4                                  "       
137 //"             sub     ebx, eax                                "       
138 //"             sub     ecx, ebx                                "       
139 //"alignstart:                                                  "       
140 //"             mov     al, [esi]                               "       
141 //"             add     esi, 4                                  "       
142 //"             mov     [edi], al                               "       
143 //"             inc     edi                                     "       
144 //"             dec     ebx                                     "       
145 //"             jne     alignstart                              "       
146 //"aligned4:                                                    "       
147
148 #ifdef __DJGPP__
149 // From Linear to ModeX
150 void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
151 {
152         ubyte * dbits;
153         ubyte * sbits;
154         int sstep,dstep;
155         int y,plane;
156         int w1;
157
158         if ( w < 4 ) return;
159
160         sstep = src->bm_rowsize;
161         dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
162
163         if (!gr_bitblt_double)  {
164                 for (plane=0; plane<4; plane++ )        {
165                         gr_modex_setplane( (plane+dx)&3 );
166                         sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane;
167                         dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
168                         w1 = w >> 2;
169                         if ( (w&3) > plane ) w1++;
170                         for (y=dy; y < dy+h; y++ )              {
171                                 modex_copy_scanline( sbits, dbits, w1 );                
172                                 dbits += dstep;
173                                 sbits += sstep;
174                         }
175                 }
176         } else {
177                 for (plane=0; plane<4; plane++ )        {
178                         gr_modex_setplane( (plane+dx)&3 );
179                         sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane/2;
180                         dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
181                         w1 = w >> 2;
182                         if ( (w&3) > plane ) w1++;
183                         for (y=dy; y < dy+h; y++ )              {
184                                 modex_copy_scanline_2x( sbits, dbits, w1 );             
185                                 dbits += dstep;
186                                 sbits += sstep;
187                         }
188                 }
189         }
190 }
191
192
193 // From Linear to ModeX masked
194 void gr_bm_ubitblt01m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
195 {
196         //ubyte * dbits1;
197         //ubyte * sbits1;
198         
199         ubyte * dbits;
200         ubyte * sbits;
201
202         int x;
203 //      int y;
204
205         sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
206         dbits =   &gr_video_memory[(dest->bm_rowsize * dy) + dx/4];
207
208         for (x=dx; x < dx+w; x++ )      {       
209                 gr_modex_setplane( x&3 );
210
211                 //sbits1 = sbits;
212                 //dbits1 = dbits;
213                 //for (y=0; y < h; y++ )    {
214                 //      *dbits1 = *sbits1;
215                 //      sbits1 += src_bm_rowsize;
216                 //      dbits1 += dest_bm_rowsize;
217                 //      }
218                 modex_copy_column_m(sbits, dbits, h, src->bm_rowsize, dest->bm_rowsize << gr_bitblt_dest_step_shift );
219
220                 sbits++;
221                 if ( (x&3)==3 )
222                         dbits++;
223         }
224 }
225
226 #endif
227
228
229 void gr_ubitmap012( int x, int y, grs_bitmap *bm )
230 {
231         register int x1, y1;
232         unsigned char * src;
233
234         src = bm->bm_data;
235
236         for (y1=y; y1 < (y+bm->bm_h); y1++ )    {
237                 for (x1=x; x1 < (x+bm->bm_w); x1++ )    {
238                         gr_setcolor( *src++ );
239                         gr_upixel( x1, y1 );
240                 }
241         }
242 }
243
244 void gr_ubitmap012m( int x, int y, grs_bitmap *bm )
245 {
246         register int x1, y1;
247         unsigned char * src;
248
249         src = bm->bm_data;
250
251         for (y1=y; y1 < (y+bm->bm_h); y1++ )    {
252                 for (x1=x; x1 < (x+bm->bm_w); x1++ )    {
253                         if ( *src != 255 )      {
254                                 gr_setcolor( *src );
255                                 gr_upixel( x1, y1 );
256                         }
257                         src++;
258                 }
259         }
260 }
261
262
263 void gr_ubitmapGENERIC(int x, int y, grs_bitmap * bm)
264 {
265         register int x1, y1;
266
267         for (y1=0; y1 < bm->bm_h; y1++ )    {
268                 for (x1=0; x1 < bm->bm_w; x1++ )    {
269                         gr_setcolor( gr_gpixel(bm,x1,y1) );
270                         gr_upixel( x+x1, y+y1 );
271                 }
272         }
273 }
274
275 void gr_ubitmapGENERICm(int x, int y, grs_bitmap * bm)
276 {
277         register int x1, y1;
278         ubyte c;
279
280         for (y1=0; y1 < bm->bm_h; y1++ )    {
281                 for (x1=0; x1 < bm->bm_w; x1++ )    {
282                         c = gr_gpixel(bm,x1,y1);
283                         if ( c != 255 ) {
284                                 gr_setcolor( c );
285                                 gr_upixel( x+x1, y+y1 );
286                         }
287                 }
288         }
289 }
290
291 void gr_ubitmap( int x, int y, grs_bitmap *bm )
292 {   int source, dest;
293
294         source = bm->bm_type;
295         dest = TYPE;
296
297         if (source==BM_LINEAR) {
298                 switch( dest )
299                 {
300                 case BM_LINEAR:
301                         if ( bm->bm_flags & BM_FLAG_RLE )
302                                 gr_bm_ubitblt00_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
303                         else
304                                 gr_ubitmap00( x, y, bm );
305                         return;
306 #ifdef OGL
307                 case BM_OGL:
308                         ogl_ubitmapm(x,y,bm);
309                         return;
310 #endif
311 #ifdef D1XD3D
312                 case BM_DIRECTX:
313                         Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
314                         Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 0);
315                         return;
316 #endif
317 #ifdef __DJGPP__
318                 case BM_SVGA:
319                         if ( bm->bm_flags & BM_FLAG_RLE )
320                                 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap, 0 );
321                         else
322                                 gr_bm_ubitblt02( bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap);
323                         return;
324                 case BM_MODEX:
325                         gr_bm_ubitblt01(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
326                         return;
327 #endif
328                 default:
329                         gr_ubitmap012( x, y, bm );
330                         return;
331                 }
332         } else  {
333                 gr_ubitmapGENERIC(x, y, bm);
334         }
335 }
336
337 void gr_ubitmapm( int x, int y, grs_bitmap *bm )
338 {   int source, dest;
339
340
341         source = bm->bm_type;
342         dest = TYPE;
343
344         if (source==BM_LINEAR) {
345                 switch( dest )
346                 {
347                 case BM_LINEAR:
348                         if ( bm->bm_flags & BM_FLAG_RLE )
349                                 gr_bm_ubitblt00m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
350                         else
351                                 gr_ubitmap00m( x, y, bm );
352                         return;
353 #ifdef OGL
354                 case BM_OGL:
355                         ogl_ubitmapm(x,y,bm);
356                         return;
357 #endif
358 #ifdef D1XD3D
359                 case BM_DIRECTX:
360                         if (bm->bm_w < 35 && bm->bm_h < 35) {
361                                 // ugly hack needed for reticle
362                                 if ( bm->bm_flags & BM_FLAG_RLE )
363                                         gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap, 1 );
364                                 else
365                                         gr_ubitmapGENERICm(x, y, bm);
366                                 return;
367                         }
368                         Assert ((int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_RENDER || (int)grd_curcanv->cv_bitmap.bm_data == BM_D3D_DISPLAY);
369                         Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 1);
370                         return;
371 #endif
372 #ifdef __DJGPP__
373                 case BM_SVGA:
374                         gr_ubitmapGENERICm(x, y, bm);
375                         return;
376                 case BM_MODEX:
377                         gr_bm_ubitblt01m(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
378                         return;
379 #endif
380                 default:
381                         gr_ubitmap012m( x, y, bm );
382                         return;
383                 }
384         } else  {
385                 gr_ubitmapGENERICm(x, y, bm);
386         }
387 }
388
389
390 #ifdef __DJGPP__
391 // From linear to SVGA
392 void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
393 {
394         unsigned char * sbits;
395
396         unsigned int offset, EndingOffset, VideoLocation;
397
398         int sbpr, dbpr, y1, page, BytesToMove;
399
400         sbpr = src->bm_rowsize;
401
402         dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
403
404         VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
405
406         sbits = src->bm_data + ( sbpr*sy ) + sx;
407
408         for (y1=0; y1 < h; y1++ )    {
409
410                 page    = VideoLocation >> 16;
411                 offset  = VideoLocation & 0xFFFF;
412
413                 gr_vesa_setpage( page );
414
415                 EndingOffset = offset+w-1;
416
417                 if ( EndingOffset <= 0xFFFF )
418                 {
419                         if ( gr_bitblt_double )
420                                 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+gr_video_memory), w );
421                         else
422                                 gr_linear_movsd( (void *)sbits, (void *)(offset+gr_video_memory), w );
423
424                         VideoLocation += dbpr;
425                         sbits += sbpr;
426                 }
427                 else
428                 {
429                         BytesToMove = 0xFFFF-offset+1;
430
431                         if ( gr_bitblt_double )
432                                 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+gr_video_memory), BytesToMove );
433                         else
434                                 gr_linear_movsd( (void *)sbits, (void *)(offset+gr_video_memory), BytesToMove );
435
436                         page++;
437                         gr_vesa_setpage(page);
438
439                         if ( gr_bitblt_double )
440                                 gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)gr_video_memory, EndingOffset - 0xFFFF );
441                         else
442                                 gr_linear_movsd( (void *)(sbits+BytesToMove), (void *)gr_video_memory, EndingOffset - 0xFFFF );
443
444                         VideoLocation += dbpr;
445                         sbits += sbpr;
446                 }
447         }
448 }
449
450 // From SVGA to linear
451 void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
452 {
453         unsigned char * dbits;
454
455         unsigned int offset, offset1, offset2;
456
457         int sbpr, dbpr, y1, page;
458
459         dbpr = dest->bm_rowsize;
460
461         sbpr = src->bm_rowsize;
462
463         for (y1=0; y1 < h; y1++ )    {
464
465                 offset2 =   (unsigned int)src->bm_data  + (sbpr * (y1+sy)) + sx;
466                 dbits   =   dest->bm_data + (dbpr * (y1+dy)) + dx;
467
468                 page = offset2 >> 16;
469                 offset = offset2 & 0xFFFF;
470                 offset1 = offset+w-1;
471                 gr_vesa_setpage( page );
472
473                 if ( offset1 > 0xFFFF )  {
474                         // Overlaps two pages
475                         while( offset <= 0xFFFF )
476                                 *dbits++ = gr_video_memory[offset++];
477                         offset1 -= (0xFFFF+1);
478                         offset = 0;
479                         page++;
480                         gr_vesa_setpage(page);
481                 }
482                 while( offset <= offset1 )
483                         *dbits++ = gr_video_memory[offset++];
484
485         }
486 }
487 #endif // __DJGPP__
488 //@extern int Interlacing_on;
489
490 // From Linear to Linear
491 void gr_bm_ubitblt00(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
492 {
493         unsigned char * dbits;
494         unsigned char * sbits;
495         //int   src_bm_rowsize_2, dest_bm_rowsize_2;
496         int dstep;
497
498         int i;
499
500         sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
501         dbits =   dest->bm_data + (dest->bm_rowsize * dy) + dx;
502
503         dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
504
505         // No interlacing, copy the whole buffer.
506         if (gr_bitblt_double)
507             for (i=0; i < h; i++ )    {
508                 gr_linear_rep_movsd_2x( sbits, dbits, w );
509                 sbits += src->bm_rowsize;
510                 dbits += dstep;
511             }
512         else
513             for (i=0; i < h; i++ )    {
514                 gr_linear_movsd( sbits, dbits, w );
515                 //memcpy(dbits, sbits, w);
516                 sbits += src->bm_rowsize;
517                 dbits += dstep;
518             }
519 }
520
521 // From Linear to Linear Masked
522 void gr_bm_ubitblt00m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
523 {
524         unsigned char * dbits;
525         unsigned char * sbits;
526         //int   src_bm_rowsize_2, dest_bm_rowsize_2;
527
528         int i;
529
530         sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
531         dbits =   dest->bm_data + (dest->bm_rowsize * dy) + dx;
532
533         // No interlacing, copy the whole buffer.
534
535         if (gr_bitblt_fade_table==NULL) {
536                 for (i=0; i < h; i++ )    {
537                         gr_linear_rep_movsdm( sbits, dbits, w );
538                         sbits += src->bm_rowsize;
539                         dbits += dest->bm_rowsize;
540                 }
541         } else {
542                 for (i=0; i < h; i++ )    {
543                         gr_linear_rep_movsdm_faded( sbits, dbits, w, gr_bitblt_fade_table[dy+i] );
544                         sbits += src->bm_rowsize;
545                         dbits += dest->bm_rowsize;
546                 }
547         }
548 }
549
550
551 void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
552 {
553         int dx1=dx, dx2=dx+dest->bm_w-1;
554         int dy1=dy, dy2=dy+dest->bm_h-1;
555
556         int sx1=sx, sx2=sx+src->bm_w-1;
557         int sy1=sy, sy2=sy+src->bm_h-1;
558
559         if ((dx1 >= dest->bm_w ) || (dx2 < 0)) return;
560         if ((dy1 >= dest->bm_h ) || (dy2 < 0)) return;
561         if ( dx1 < 0 ) { sx1 += -dx1; dx1 = 0; }
562         if ( dy1 < 0 ) { sy1 += -dy1; dy1 = 0; }
563         if ( dx2 >= dest->bm_w )        { dx2 = dest->bm_w-1; }
564         if ( dy2 >= dest->bm_h )        { dy2 = dest->bm_h-1; }
565
566         if ((sx1 >= src->bm_w ) || (sx2 < 0)) return;
567         if ((sy1 >= src->bm_h ) || (sy2 < 0)) return;
568         if ( sx1 < 0 ) { dx1 += -sx1; sx1 = 0; }
569         if ( sy1 < 0 ) { dy1 += -sy1; sy1 = 0; }
570         if ( sx2 >= src->bm_w ) { sx2 = src->bm_w-1; }
571         if ( sy2 >= src->bm_h ) { sy2 = src->bm_h-1; }
572
573         // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
574         if ( dx2-dx1+1 < w )
575                 w = dx2-dx1+1;
576         if ( dy2-dy1+1 < h )
577                 h = dy2-dy1+1;
578         if ( sx2-sx1+1 < w )
579                 w = sx2-sx1+1;
580         if ( sy2-sy1+1 < h )
581                 h = sy2-sy1+1;
582
583         gr_bm_ubitblt(w,h, dx1, dy1, sx1, sy1, src, dest );
584 }
585
586 void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
587 {
588         register int x1, y1;
589
590         if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR ))
591         {
592                 if ( src->bm_flags & BM_FLAG_RLE )      
593                         gr_bm_ubitblt00_rle( w, h, dx, dy, sx, sy, src, dest );
594                 else
595                         gr_bm_ubitblt00( w, h, dx, dy, sx, sy, src, dest );
596                 return;
597         }
598
599 #ifdef OGL
600         if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
601         {
602                 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
603                 return;
604         }
605         if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
606         {
607                 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
608                 return;
609         }
610         if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
611         {
612                 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
613                 return;
614         }
615 #endif
616
617 #ifdef D1XD3D
618         if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
619         {
620                 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
621                 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 0);
622                 return;
623         }
624         if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_LINEAR ))
625         {
626                 return;
627         }
628         if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
629         {
630                 return;
631         }
632 #endif
633
634         if ( (src->bm_flags & BM_FLAG_RLE ) && (src->bm_type == BM_LINEAR) )    {
635                 gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest, 0 );
636                 return;
637         }
638 #ifdef __DJGPP__
639         if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA ))
640         {
641                 gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest );
642                 return;
643         }
644
645         if ( (src->bm_type == BM_SVGA) && (dest->bm_type == BM_LINEAR ))
646         {
647                 gr_bm_ubitblt20( w, h, dx, dy, sx, sy, src, dest );
648                 return;
649         }
650
651         if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_MODEX ))
652         {
653                 gr_bm_ubitblt01( w, h, dx+XOFFSET, dy+YOFFSET, sx, sy, src, dest );
654                 return;
655         }
656 #endif
657         for (y1=0; y1 < h; y1++ )    {
658                 for (x1=0; x1 < w; x1++ )    {
659                         gr_bm_pixel( dest, dx+x1, dy+y1, gr_gpixel(src,sx+x1,sy+y1) );
660                 }
661         }
662 }
663
664 // Clipped bitmap ... 
665
666 void gr_bitmap( int x, int y, grs_bitmap *bm )
667 {
668         int dx1=x, dx2=x+bm->bm_w-1;
669         int dy1=y, dy2=y+bm->bm_h-1;
670         int sx=0, sy=0;
671
672         if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
673         if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
674         if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
675         if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
676         if ( dx2 >= grd_curcanv->cv_bitmap.bm_w )       { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
677         if ( dy2 >= grd_curcanv->cv_bitmap.bm_h )       { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
678                 
679         // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
680
681         gr_bm_ubitblt(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
682
683 }
684
685 void gr_bitmapm( int x, int y, grs_bitmap *bm )
686 {
687         int dx1=x, dx2=x+bm->bm_w-1;
688         int dy1=y, dy2=y+bm->bm_h-1;
689         int sx=0, sy=0;
690
691         if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
692         if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
693         if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
694         if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
695         if ( dx2 >= grd_curcanv->cv_bitmap.bm_w )       { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
696         if ( dy2 >= grd_curcanv->cv_bitmap.bm_h )       { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
697                 
698         // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
699
700         if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_LINEAR ))
701         {
702                 if ( bm->bm_flags & BM_FLAG_RLE )       
703                         gr_bm_ubitblt00m_rle(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
704                 else
705                         gr_bm_ubitblt00m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
706                 return;
707         }
708
709         gr_bm_ubitbltm(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
710
711 }
712
713 void gr_bm_ubitbltm(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
714 {
715         register int x1, y1;
716         ubyte c;
717
718 #ifdef OGL
719         if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_OGL ))
720         {
721                 ogl_ubitblt(w, h, dx, dy, sx, sy, src, dest);
722                 return;
723         }
724         if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_LINEAR ))
725         {
726                 ogl_ubitblt_tolinear(w, h, dx, dy, sx, sy, src, dest);
727                 return;
728         }
729         if ( (src->bm_type == BM_OGL) && (dest->bm_type == BM_OGL ))
730         {
731                 ogl_ubitblt_copy(w, h, dx, dy, sx, sy, src, dest);
732                 return;
733         }
734 #endif
735 #ifdef D1XD3D
736         if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_DIRECTX ))
737         {
738                 Assert ((int)dest->bm_data == BM_D3D_RENDER || (int)dest->bm_data == BM_D3D_DISPLAY);
739                 Win32_BlitLinearToDirectX_bm (src, sx, sy, w, h, dx, dy, 1);
740                 return;
741         }
742         if ( (src->bm_type == BM_DIRECTX) && (dest->bm_type == BM_DIRECTX ))
743         {
744                 Assert ((int)src->bm_data == BM_D3D_RENDER || (int)src->bm_data == BM_D3D_DISPLAY);
745 //              Win32_BlitDirectXToDirectX (w, h, dx, dy, sx, sy, src->bm_data, dest->bm_data, 0);
746                 return;
747         }
748 #endif
749
750
751         for (y1=0; y1 < h; y1++ )    {
752                 for (x1=0; x1 < w; x1++ )    {
753                         if ((c=gr_gpixel(src,sx+x1,sy+y1))!=255)
754                                 gr_bm_pixel( dest, dx+x1, dy+y1,c  );
755                 }
756         }
757
758 }
759
760 //-NOT-used // From linear to SVGA
761 //-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)
762 //-NOT-used {
763 //-NOT-used     unsigned char * sbits;
764 //-NOT-used 
765 //-NOT-used     unsigned int offset, EndingOffset, VideoLocation;
766 //-NOT-used 
767 //-NOT-used     int sbpr, dbpr, y1, page, BytesToMove;
768 //-NOT-used 
769 //-NOT-used     sbpr = src->bm_rowsize;
770 //-NOT-used 
771 //-NOT-used     dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
772 //-NOT-used 
773 //-NOT-used     VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
774 //-NOT-used 
775 //-NOT-used     sbits = src->bm_data + ( sbpr*sy ) + sx;
776 //-NOT-used 
777 //-NOT-used     for (y1=0; y1 < h; y1++ )    {
778 //-NOT-used 
779 //-NOT-used             page    = VideoLocation >> 16;
780 //-NOT-used             offset  = VideoLocation & 0xFFFF;
781 //-NOT-used 
782 //-NOT-used             gr_vesa_setpage( page );
783 //-NOT-used 
784 //-NOT-used             EndingOffset = offset+w-1;
785 //-NOT-used 
786 //-NOT-used             if ( EndingOffset <= 0xFFFF )
787 //-NOT-used             {
788 //-NOT-used                     gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+gr_video_memory), w );
789 //-NOT-used 
790 //-NOT-used                     VideoLocation += dbpr;
791 //-NOT-used                     sbits += sbpr;
792 //-NOT-used             }
793 //-NOT-used             else
794 //-NOT-used             {
795 //-NOT-used                     BytesToMove = 0xFFFF-offset+1;
796 //-NOT-used 
797 //-NOT-used                     gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+gr_video_memory), BytesToMove );
798 //-NOT-used 
799 //-NOT-used                     page++;
800 //-NOT-used                     gr_vesa_setpage(page);
801 //-NOT-used 
802 //-NOT-used                     gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)gr_video_memory, EndingOffset - 0xFFFF );
803 //-NOT-used 
804 //-NOT-used                     VideoLocation += dbpr;
805 //-NOT-used                     sbits += sbpr;
806 //-NOT-used             }
807 //-NOT-used 
808 //-NOT-used 
809 //-NOT-used     }
810 //-NOT-used }
811
812
813 //-NOT-used // From Linear to Linear
814 //-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)
815 //-NOT-used {
816 //-NOT-used     unsigned char * dbits;
817 //-NOT-used     unsigned char * sbits;
818 //-NOT-used     //int   src_bm_rowsize_2, dest_bm_rowsize_2;
819 //-NOT-used 
820 //-NOT-used     int i;
821 //-NOT-used 
822 //-NOT-used     sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
823 //-NOT-used     dbits =   dest->bm_data + (dest->bm_rowsize * dy) + dx;
824 //-NOT-used 
825 //-NOT-used     // No interlacing, copy the whole buffer.
826 //-NOT-used     for (i=0; i < h; i++ )    {
827 //-NOT-used             gr_linear_rep_movsd_2x( sbits, dbits, w );
828 //-NOT-used 
829 //-NOT-used             sbits += src->bm_rowsize;
830 //-NOT-used             dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
831 //-NOT-used     }
832 //-NOT-used }
833
834 void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
835 {
836         unsigned char * dbits;
837         unsigned char * sbits;
838
839         int i;
840
841         sbits = &src->bm_data[4 + src->bm_h];
842         for (i=0; i<sy; i++ )
843                 sbits += (int)src->bm_data[4+i];
844
845         dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
846
847         // No interlacing, copy the whole buffer.
848         for (i=0; i < h; i++ )    {
849                 gr_rle_expand_scanline( dbits, sbits, sx, sx+w-1 );
850                 sbits += (int)src->bm_data[4+i+sy];
851                 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
852         }
853 }
854
855 void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
856 {
857         unsigned char * dbits;
858         unsigned char * sbits;
859
860         int i;
861
862         sbits = &src->bm_data[4 + src->bm_h];
863         for (i=0; i<sy; i++ )
864                 sbits += (int)src->bm_data[4+i];
865
866         dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
867
868         // No interlacing, copy the whole buffer.
869         for (i=0; i < h; i++ )    {
870                 gr_rle_expand_scanline_masked( dbits, sbits, sx, sx+w-1 );
871                 sbits += (int)src->bm_data[4+i+sy];
872                 dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
873         }
874 }
875
876 // in rle.c
877
878 extern void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, 
879         int x1, int x2, int masked );
880
881
882 void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, 
883         grs_bitmap * dest, int masked )
884 {
885         int i;
886         register int y1;
887         unsigned char * sbits;
888
889         sbits = &src->bm_data[4 + src->bm_h];
890         for (i=0; i<sy; i++ )
891                 sbits += (int)src->bm_data[4+i];
892
893         for (y1=0; y1 < h; y1++ )    {
894                 gr_rle_expand_scanline_generic( dest, dx, dy+y1,  sbits, sx, sx+w-1, 
895                         masked );
896                 sbits += (int)src->bm_data[4+y1+sy];
897         }
898 }
899
900 // rescalling bitmaps, 10/14/99 Jan Bobrowski jb@wizard.ae.krakow.pl
901
902 inline void scale_line(byte *in, byte *out, int ilen, int olen)
903 {
904         int a = olen/ilen, b = olen%ilen;
905         int c = 0, i;
906         byte *end = out + olen;
907         while(out<end) {
908                 i = a;
909                 c += b;
910                 if(c >= ilen) {
911                         c -= ilen;
912                         goto inside;
913                 }
914                 while(--i>=0) {
915 inside:
916                         *out++ = *in;
917                 }
918                 in++;
919         }
920 }
921
922 void gr_bitmap_scale_to(grs_bitmap *src, grs_bitmap *dst)
923 {
924         byte *s = src->bm_data;
925         byte *d = dst->bm_data;
926         int h = src->bm_h;
927         int a = dst->bm_h/h, b = dst->bm_h%h;
928         int c = 0, i, y;
929
930         for(y=0; y<h; y++) {
931                 i = a;
932                 c += b;
933                 if(c >= h) {
934                         c -= h;
935                         goto inside;
936                 }
937                 while(--i>=0) {
938 inside:
939                         scale_line(s, d, src->bm_w, dst->bm_w);
940                         d += dst->bm_rowsize;
941                 }
942                 s += src->bm_rowsize;
943         }
944 }
945
946 void show_fullscr(grs_bitmap *bm)
947 {
948         grs_bitmap * const scr = &grd_curcanv->cv_bitmap;
949
950 #ifdef OGL
951         if(bm->bm_type == BM_LINEAR && scr->bm_type == BM_OGL) {
952                 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
953                 return;
954         }
955 #endif
956         if(scr->bm_type != BM_LINEAR) {
957                 grs_bitmap *tmp = gr_create_bitmap(scr->bm_w, scr->bm_h);
958                 gr_bitmap_scale_to(bm, tmp);
959                 gr_bitmap(0, 0, tmp);
960                 gr_free_bitmap(tmp);
961                 return;
962         }
963         gr_bitmap_scale_to(bm, scr);
964 }