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