home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / 2d / bitblt.c next >
Text File  |  1998-06-08  |  27KB  |  998 lines

  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.  * $Source: f:/miner/source/2d/rcs/bitblt.c $
  15.  * $Revision: 1.29 $
  16.  * $Author: john $
  17.  * $Date: 1995/03/14 12:14:28 $
  18.  *
  19.  * Routines for bitblt's.
  20.  *
  21.  * $Log: bitblt.c $
  22.  * Revision 1.29  1995/03/14  12:14:28  john
  23.  * Added code to double horz/vert bitblts.
  24.  * 
  25.  * Revision 1.28  1995/03/13  09:01:48  john
  26.  * Fixed bug with VFX1 screen not tall enough.
  27.  * 
  28.  * Revision 1.27  1995/03/01  15:38:10  john
  29.  * Better ModeX support.
  30.  * 
  31.  * Revision 1.26  1994/12/15  12:19:00  john
  32.  * Added gr_bm_bitblt (clipped!) function.
  33.  * 
  34.  * Revision 1.25  1994/12/09  18:58:42  matt
  35.  * Took out include of 3d.h
  36.  * 
  37.  * Revision 1.24  1994/11/28  17:08:32  john
  38.  * Took out some unused functions in linear.asm, moved
  39.  * gr_linear_movsd from linear.asm to bitblt.c, made sure that
  40.  * the code in ibiblt.c sets the direction flags before rep movsing.
  41.  * 
  42.  * Revision 1.22  1994/11/23  16:04:00  john
  43.  * Fixed generic rle'ing to use new bit method.
  44.  * 
  45.  * Revision 1.21  1994/11/18  22:51:03  john
  46.  * Changed a bunch of shorts to ints in calls.
  47.  * 
  48.  * Revision 1.20  1994/11/10  15:59:48  john
  49.  * Fixed bugs with canvas's being created with bogus bm_flags.
  50.  * 
  51.  * Revision 1.19  1994/11/09  21:03:35  john
  52.  * Added RLE for svga gr_ubitmap.
  53.  * 
  54.  * Revision 1.18  1994/11/09  17:41:29  john
  55.  * Made a slow version of rle bitblt to svga, modex.
  56.  * 
  57.  * Revision 1.17  1994/11/09  16:35:15  john
  58.  * First version with working RLE bitmaps.
  59.  * 
  60.  * Revision 1.16  1994/11/04  10:06:58  john
  61.  * Added fade table for fading fonts. Made font that partially clips
  62.  * not print a warning message.
  63.  * 
  64.  * Revision 1.15  1994/09/22  16:08:38  john
  65.  * Fixed some palette stuff.
  66.  * 
  67.  * Revision 1.14  1994/09/19  11:44:27  john
  68.  * Changed call to allocate selector to the dpmi module.
  69.  * 
  70.  * Revision 1.13  1994/08/08  13:03:00  john
  71.  * Fixed bug in gr_bitmap in modex 
  72.  * 
  73.  * Revision 1.12  1994/07/13  19:47:23  john
  74.  * Fixed bug with modex bitblt to page 2 not working.
  75.  * 
  76.  * Revision 1.11  1994/05/31  11:10:52  john
  77.  * *** empty log message ***
  78.  * 
  79.  * Revision 1.10  1994/03/18  15:24:34  matt
  80.  * Removed interlace stuff
  81.  * 
  82.  * Revision 1.9  1994/02/18  15:32:20  john
  83.  * *** empty log message ***
  84.  * 
  85.  * Revision 1.8  1994/02/01  13:22:54  john
  86.  * *** empty log message ***
  87.  * 
  88.  * Revision 1.7  1994/01/13  08:28:25  mike
  89.  * Modify rect copy to copy alternate scanlines when in interlaced mode.
  90.  * 
  91.  * Revision 1.6  1993/12/28  12:09:46  john
  92.  * added lbitblt.asm
  93.  * 
  94.  * Revision 1.5  1993/10/26  13:18:09  john
  95.  * *** empty log message ***
  96.  * 
  97.  * Revision 1.4  1993/10/15  16:23:30  john
  98.  * y
  99.  * 
  100.  * Revision 1.3  1993/09/13  17:52:58  john
  101.  * Fixed bug in BitBlt linear to SVGA
  102.  * 
  103.  * Revision 1.2  1993/09/08  14:47:00  john
  104.  * Made bitmap00 add rowsize instead of bitmap width.
  105.  * Other routines might have this problem too.
  106.  * 
  107.  * Revision 1.1  1993/09/08  11:43:01  john
  108.  * Initial revision
  109.  * 
  110.  *
  111.  */
  112.  
  113. #include "mem.h"
  114. #include "gr.h"
  115. #include "grdef.h"
  116. #include "rle.h"
  117. #include "mono.h"
  118.  
  119. int gr_bitblt_dest_step_shift = 0;
  120. int gr_bitblt_double = 0;
  121. ubyte *gr_bitblt_fade_table=NULL;
  122.  
  123. extern void gr_vesa_bitmap( grs_bitmap * source, grs_bitmap * dest, int x, int y );
  124.  
  125. // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
  126. void gr_linear_movsd(ubyte * src, ubyte * dest, int num_pixels );
  127. #pragma aux gr_linear_movsd parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
  128. " cld "                    \
  129. " mov        ebx, ecx    "    \
  130. " mov        eax, edi"    \
  131. " and        eax, 011b"    \
  132. " jz        d_aligned"    \
  133. " mov        ecx, 4"        \
  134. " sub        ecx, eax"    \
  135. " sub        ebx, ecx"    \
  136. " rep        movsb"        \
  137. " d_aligned: "            \
  138. " mov        ecx, ebx"    \
  139. " shr        ecx, 2"        \
  140. " rep     movsd"        \
  141. " mov        ecx, ebx"    \
  142. " and     ecx, 11b"    \
  143. " rep     movsb";
  144.  
  145. void gr_linear_rep_movsdm(ubyte * src, ubyte * dest, int num_pixels );
  146. #pragma aux gr_linear_rep_movsdm parm [esi] [edi] [ecx] modify exact [ecx esi edi eax] = \
  147. "nextpixel:"                    \
  148.     "mov    al,[esi]"            \
  149.     "inc    esi"                    \
  150.     "cmp    al, 255"                \
  151.     "je    skip_it"                \
  152.     "mov    [edi], al"            \
  153. "skip_it:"                        \
  154.     "inc    edi"                    \
  155.     "dec    ecx"                    \
  156.     "jne    nextpixel";
  157.  
  158. void gr_linear_rep_movsdm_faded(ubyte * src, ubyte * dest, int num_pixels, ubyte fade_value );
  159. #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] = \
  160. "  xor eax, eax"    \
  161. "  mov ah, bl"  \
  162. "nextpixel:"                    \
  163.     "mov    al,[esi]"            \
  164.     "inc    esi"                    \
  165.     "cmp    al, 255"                \
  166.     "je    skip_it"                \
  167.     "mov  al, gr_fade_table[eax]"    \
  168.     "mov    [edi], al"            \
  169. "skip_it:"                        \
  170.     "inc    edi"                    \
  171.     "dec    ecx"                    \
  172.     "jne    nextpixel";
  173.  
  174.  
  175. void gr_linear_rep_movsd_2x(ubyte * src, ubyte * dest, int num_dest_pixels );
  176. #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
  177.     "shr    ecx, 1"                \
  178.     "jnc    nextpixel"            \
  179.     "mov    al, [esi]"            \
  180.     "mov    [edi], al"            \
  181.     "inc    esi"                    \
  182.     "inc    edi"                    \
  183.     "cmp    ecx, 0"                \
  184.     "je    done"                    \
  185. "nextpixel:"                    \
  186.     "mov    al,[esi]"            \
  187.     "mov    ah, al"                \
  188.     "mov    [edi], ax"            \
  189.     "inc    esi"                    \
  190.     "inc    edi"                    \
  191.     "inc    edi"                    \
  192.     "dec    ecx"                    \
  193.     "jne    nextpixel"            \
  194. "done:"
  195.  
  196.  
  197.  
  198. void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
  199. #pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
  200. "nextpixel:"                            \
  201.     "mov    al,[esi]"            \
  202.     "add    esi, ebx"    \
  203.     "mov    [edi], al"    \
  204.     "add    edi, edx"    \
  205.     "dec    ecx"            \
  206.     "jne    nextpixel"    
  207.  
  208. void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
  209. #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
  210. "nextpixel:"                            \
  211.     "mov    al,[esi]"            \
  212.     "add    esi, ebx"    \
  213.     "cmp    al, 255"        \
  214.     "je    skip_itx"        \
  215.     "mov    [edi], al"    \
  216. "skip_itx:"                \
  217.     "add    edi, edx"    \
  218.     "dec    ecx"            \
  219.     "jne    nextpixel"    
  220.  
  221.  
  222. void gr_ubitmap00( int x, int y, grs_bitmap *bm )
  223. {
  224.     register int y1;
  225.     int dest_rowsize;
  226.  
  227.     unsigned char * dest;
  228.     unsigned char * src;
  229.  
  230.     dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
  231.     dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
  232.  
  233.     src = bm->bm_data;
  234.  
  235.     for (y1=0; y1 < bm->bm_h; y1++ )    {
  236.         if (gr_bitblt_double)
  237.             gr_linear_rep_movsd_2x( src, dest, bm->bm_w );
  238.         else
  239.             gr_linear_movsd( src, dest, bm->bm_w );
  240.         src += bm->bm_rowsize;
  241.         dest+= (int)(dest_rowsize);
  242.     }
  243. }
  244.  
  245. void gr_ubitmap00m( int x, int y, grs_bitmap *bm )
  246. {
  247.     register int y1;
  248.     int dest_rowsize;
  249.  
  250.     unsigned char * dest;
  251.     unsigned char * src;
  252.  
  253.     dest_rowsize=grd_curcanv->cv_bitmap.bm_rowsize << gr_bitblt_dest_step_shift;
  254.     dest = &(grd_curcanv->cv_bitmap.bm_data[ dest_rowsize*y+x ]);
  255.  
  256.     src = bm->bm_data;
  257.  
  258.     if (gr_bitblt_fade_table==NULL)    {
  259.         for (y1=0; y1 < bm->bm_h; y1++ )    {
  260.             gr_linear_rep_movsdm( src, dest, bm->bm_w );
  261.             src += bm->bm_rowsize;
  262.             dest+= (int)(dest_rowsize);
  263.         }
  264.     } else {
  265.         for (y1=0; y1 < bm->bm_h; y1++ )    {
  266.             gr_linear_rep_movsdm_faded( src, dest, bm->bm_w, gr_bitblt_fade_table[y1+y] );
  267.             src += bm->bm_rowsize;
  268.             dest+= (int)(dest_rowsize);
  269.         }
  270.     }
  271. }
  272.  
  273. //"        jmp     aligned4                "    \
  274. //"        mov    eax, edi                "    \
  275. //"        and    eax, 11b                "    \
  276. //"        jz        aligned4                "    \
  277. //"        mov    ebx, 4                "    \
  278. //"        sub    ebx, eax                "    \
  279. //"        sub    ecx, ebx                "    \
  280. //"alignstart:                        "    \
  281. //"        mov    al, [esi]            "    \
  282. //"        add    esi, 4                "    \
  283. //"        mov    [edi], al            "    \
  284. //"        inc    edi                    "    \
  285. //"        dec    ebx                    "    \
  286. //"        jne    alignstart            "    \
  287. //"aligned4:                            "    \
  288.  
  289. void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels );
  290. #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
  291. "        mov    ebx, ecx                "    \
  292. "        and    ebx, 11b                "    \
  293. "        shr    ecx, 2                "    \
  294. "        cmp    ecx, 0                "    \
  295. "        je        no2group                "    \
  296. "next4pixels:                        "    \
  297. "        mov    al, [esi+8]            "    \
  298. "        mov    ah, [esi+12]        "    \
  299. "        shl    eax, 16                "    \
  300. "        mov    al, [esi]            "    \
  301. "        mov    ah, [esi+4]            "    \
  302. "        mov    [edi], eax            "    \
  303. "        add    esi, 16                "    \
  304. "        add    edi, 4                "    \
  305. "        dec    ecx                    "    \
  306. "        jne    next4pixels            "    \
  307. "no2group:                            "    \
  308. "        cmp    ebx, 0                "    \
  309. "        je        done2                    "    \
  310. "finishend:                            "    \
  311. "        mov    al, [esi]            "    \
  312. "        add    esi, 4                "    \
  313. "        mov    [edi], al            "    \
  314. "        inc    edi                    "    \
  315. "        dec    ebx                    "    \
  316. "        jne    finishend            "    \
  317. "done2:                                ";
  318.  
  319. void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels );
  320. #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
  321. "        mov    ebx, ecx                "    \
  322. "        and    ebx, 11b                "    \
  323. "        shr    ecx, 2                "    \
  324. "        cmp    ecx, 0                "    \
  325. "        je        no2group                "    \
  326. "next4pixels:                        "    \
  327. "        mov    al, [esi+4]            "    \
  328. "        mov    ah, [esi+6]            "    \
  329. "        shl    eax, 16                "    \
  330. "        mov    al, [esi]            "    \
  331. "        mov    ah, [esi+2]            "    \
  332. "        mov    [edi], eax            "    \
  333. "        add    esi, 8                "    \
  334. "        add    edi, 4                "    \
  335. "        dec    ecx                    "    \
  336. "        jne    next4pixels            "    \
  337. "no2group:                            "    \
  338. "        cmp    ebx, 0                "    \
  339. "        je        done2                    "    \
  340. "finishend:                            "    \
  341. "        mov    al, [esi]            "    \
  342. "        add    esi, 2                "    \
  343. "        mov    [edi], al            "    \
  344. "        inc    edi                    "    \
  345. "        dec    ebx                    "    \
  346. "        jne    finishend            "    \
  347. "done2:                                ";
  348.  
  349.  
  350.  
  351. // From Linear to ModeX
  352. void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  353. {
  354.     ubyte * dbits;
  355.     ubyte * sbits;
  356.     int sstep,dstep;
  357.     int y,plane;
  358.     int w1;
  359.  
  360.     if ( w < 4 ) return;
  361.  
  362.     sstep = src->bm_rowsize;
  363.     dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
  364.  
  365.     if (!gr_bitblt_double)    {
  366.         for (plane=0; plane<4; plane++ )    {
  367.             gr_modex_setplane( (plane+dx)&3 );
  368.             sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane;
  369.             dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
  370.             w1 = w >> 2;
  371.             if ( (w&3) > plane ) w1++;
  372.             for (y=dy; y < dy+h; y++ )        {
  373.                 modex_copy_scanline( sbits, dbits, w1 );        
  374.                 dbits += dstep;
  375.                 sbits += sstep;
  376.             }
  377.         }
  378.     } else {
  379.         for (plane=0; plane<4; plane++ )    {
  380.             gr_modex_setplane( (plane+dx)&3 );
  381.             sbits = src->bm_data + (src->bm_rowsize * sy) + sx + plane/2;
  382.             dbits = &gr_video_memory[(dest->bm_rowsize * dy) + ((plane+dx)/4) ];
  383.             w1 = w >> 2;
  384.             if ( (w&3) > plane ) w1++;
  385.             for (y=dy; y < dy+h; y++ )        {
  386.                 modex_copy_scanline_2x( sbits, dbits, w1 );        
  387.                 dbits += dstep;
  388.                 sbits += sstep;
  389.             }
  390.         }
  391.     }
  392. }
  393.  
  394.  
  395. // From Linear to ModeX masked
  396. void gr_bm_ubitblt01m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  397. {
  398.     //ubyte * dbits1;
  399.     //ubyte * sbits1;
  400.     
  401.     ubyte * dbits;
  402.     ubyte * sbits;
  403.  
  404.     int x;
  405. //    int y;
  406.  
  407.     sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
  408.     dbits =   &gr_video_memory[(dest->bm_rowsize * dy) + dx/4];
  409.  
  410.     for (x=dx; x < dx+w; x++ )    {    
  411.         gr_modex_setplane( x&3 );
  412.  
  413.         //sbits1 = sbits;
  414.         //dbits1 = dbits;
  415.         //for (y=0; y < h; y++ )    {
  416.         //    *dbits1 = *sbits1;
  417.         //    sbits1 += src_bm_rowsize;
  418.         //    dbits1 += dest_bm_rowsize;
  419.         //    }
  420.         modex_copy_column_m(sbits, dbits, h, src->bm_rowsize, dest->bm_rowsize << gr_bitblt_dest_step_shift );
  421.  
  422.         sbits++;
  423.         if ( (x&3)==3 )
  424.             dbits++;
  425.     }
  426. }
  427.  
  428.  
  429.  
  430.  
  431. void gr_ubitmap012( int x, int y, grs_bitmap *bm )
  432. {
  433.     register int x1, y1;
  434.     unsigned char * src;
  435.  
  436.     src = bm->bm_data;
  437.  
  438.     for (y1=y; y1 < (y+bm->bm_h); y1++ )    {
  439.         for (x1=x; x1 < (x+bm->bm_w); x1++ )    {
  440.             gr_setcolor( *src++ );
  441.             gr_upixel( x1, y1 );
  442.         }
  443.     }
  444. }
  445.  
  446. void gr_ubitmap012m( int x, int y, grs_bitmap *bm )
  447. {
  448.     register int x1, y1;
  449.     unsigned char * src;
  450.  
  451.     src = bm->bm_data;
  452.  
  453.     for (y1=y; y1 < (y+bm->bm_h); y1++ )    {
  454.         for (x1=x; x1 < (x+bm->bm_w); x1++ )    {
  455.             if ( *src != 255 )    {
  456.                 gr_setcolor( *src );
  457.                 gr_upixel( x1, y1 );
  458.             }
  459.             src++;
  460.         }
  461.     }
  462. }
  463.  
  464.  
  465. void gr_ubitmapGENERIC(int x, int y, grs_bitmap * bm)
  466. {
  467.     register int x1, y1;
  468.  
  469.     for (y1=0; y1 < bm->bm_h; y1++ )    {
  470.         for (x1=0; x1 < bm->bm_w; x1++ )    {
  471.             gr_setcolor( gr_gpixel(bm,x1,y1) );
  472.             gr_upixel( x+x1, y+y1 );
  473.         }
  474.     }
  475. }
  476.  
  477. void gr_ubitmapGENERICm(int x, int y, grs_bitmap * bm)
  478. {
  479.     register int x1, y1;
  480.     ubyte c;
  481.  
  482.     for (y1=0; y1 < bm->bm_h; y1++ )    {
  483.         for (x1=0; x1 < bm->bm_w; x1++ )    {
  484.             c = gr_gpixel(bm,x1,y1);
  485.             if ( c != 255 )    {
  486.                 gr_setcolor( c );
  487.                 gr_upixel( x+x1, y+y1 );
  488.             }
  489.         }
  490.     }
  491. }
  492.  
  493.  
  494. void gr_ubitmap( int x, int y, grs_bitmap *bm )
  495. {   int source, dest;
  496.  
  497.     source = bm->bm_type;
  498.     dest = TYPE;
  499.  
  500.     if (source==BM_LINEAR) {
  501.         switch( dest )
  502.         {
  503.         case BM_LINEAR:
  504.             if ( bm->bm_flags & BM_FLAG_RLE )
  505.                 gr_bm_ubitblt00_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
  506.             else
  507.                 gr_ubitmap00( x, y, bm );
  508.             return;
  509.         case BM_SVGA:
  510.             if ( bm->bm_flags & BM_FLAG_RLE )
  511.                 gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
  512.             else
  513.                 gr_vesa_bitmap( bm, &grd_curcanv->cv_bitmap, x, y );
  514.             return;
  515.         case BM_MODEX:
  516.             gr_bm_ubitblt01(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
  517.             return;
  518.         default:
  519.             gr_ubitmap012( x, y, bm );
  520.             return;
  521.         }
  522.     } else  {
  523.         gr_ubitmapGENERIC(x, y, bm);
  524.     }
  525. }
  526.  
  527. void gr_ubitmapm( int x, int y, grs_bitmap *bm )
  528. {   int source, dest;
  529.  
  530.     source = bm->bm_type;
  531.     dest = TYPE;
  532.  
  533.     if (source==BM_LINEAR) {
  534.         switch( dest )
  535.         {
  536.         case BM_LINEAR:
  537.             if ( bm->bm_flags & BM_FLAG_RLE )
  538.                 gr_bm_ubitblt00m_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap );
  539.             else
  540.                 gr_ubitmap00m( x, y, bm );
  541.             return;
  542.         case BM_SVGA:
  543.             gr_ubitmapGENERICm(x, y, bm);
  544.             return;
  545.         case BM_MODEX:
  546.             gr_bm_ubitblt01m(bm->bm_w, bm->bm_h, x+XOFFSET, y+YOFFSET, 0, 0, bm, &grd_curcanv->cv_bitmap);
  547.             return;
  548.         default:
  549.             gr_ubitmap012m( x, y, bm );
  550.             return;
  551.         }
  552.     } else  {
  553.         gr_ubitmapGENERICm(x, y, bm);
  554.     }
  555. }
  556.  
  557.  
  558.  
  559. // From linear to SVGA
  560. void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  561. {
  562.     unsigned char * sbits;
  563.  
  564.     unsigned int offset, EndingOffset, VideoLocation;
  565.  
  566.     int sbpr, dbpr, y1, page, BytesToMove;
  567.  
  568.     sbpr = src->bm_rowsize;
  569.  
  570.     dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
  571.  
  572.     VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
  573.  
  574.     sbits = src->bm_data + ( sbpr*sy ) + sx;
  575.  
  576.     for (y1=0; y1 < h; y1++ )    {
  577.  
  578.         page    = VideoLocation >> 16;
  579.         offset  = VideoLocation & 0xFFFF;
  580.  
  581.         gr_vesa_setpage( page );
  582.  
  583.         EndingOffset = offset+w-1;
  584.  
  585.         if ( EndingOffset <= 0xFFFF )
  586.         {
  587.             if ( gr_bitblt_double )
  588.                 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
  589.             else
  590.                 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), w );
  591.  
  592.             VideoLocation += dbpr;
  593.             sbits += sbpr;
  594.         }
  595.         else
  596.         {
  597.             BytesToMove = 0xFFFF-offset+1;
  598.  
  599.             if ( gr_bitblt_double )
  600.                 gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
  601.             else
  602.                 gr_linear_movsd( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
  603.  
  604.             page++;
  605.             gr_vesa_setpage(page);
  606.  
  607.             if ( gr_bitblt_double )
  608.                 gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
  609.             else
  610.                 gr_linear_movsd( (void *)(sbits+BytesToMove), (void *)0xA0000, EndingOffset - 0xFFFF );
  611.  
  612.             VideoLocation += dbpr;
  613.             sbits += sbpr;
  614.         }
  615.     }
  616. }
  617.  
  618. // From SVGA to linear
  619. void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  620. {
  621.     unsigned char * dbits;
  622.  
  623.     unsigned int offset, offset1, offset2;
  624.  
  625.     int sbpr, dbpr, y1, page;
  626.  
  627.     dbpr = dest->bm_rowsize;
  628.  
  629.     sbpr = src->bm_rowsize;
  630.  
  631.     for (y1=0; y1 < h; y1++ )    {
  632.  
  633.         offset2 =   (unsigned int)src->bm_data  + (sbpr * (y1+sy)) + sx;
  634.         dbits   =   dest->bm_data + (dbpr * (y1+dy)) + dx;
  635.  
  636.         page = offset2 >> 16;
  637.         offset = offset2 & 0xFFFF;
  638.         offset1 = offset+w-1;
  639.         gr_vesa_setpage( page );
  640.  
  641.         if ( offset1 > 0xFFFF )  {
  642.             // Overlaps two pages
  643.             while( offset <= 0xFFFF )
  644.                 *dbits++ = gr_video_memory[offset++];
  645.             offset1 -= (0xFFFF+1);
  646.             offset = 0;
  647.             page++;
  648.             gr_vesa_setpage(page);
  649.         }
  650.         while( offset <= offset1 )
  651.             *dbits++ = gr_video_memory[offset++];
  652.  
  653.     }
  654. }
  655.  
  656. //@extern int Interlacing_on;
  657.  
  658. // From Linear to Linear
  659. void gr_bm_ubitblt00(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  660. {
  661.     unsigned char * dbits;
  662.     unsigned char * sbits;
  663.     //int    src_bm_rowsize_2, dest_bm_rowsize_2;
  664.     int dstep;
  665.  
  666.     int i;
  667.  
  668.     sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
  669.     dbits =   dest->bm_data + (dest->bm_rowsize * dy) + dx;
  670.  
  671.     dstep = dest->bm_rowsize << gr_bitblt_dest_step_shift;
  672.  
  673.     // No interlacing, copy the whole buffer.
  674.     for (i=0; i < h; i++ )    {
  675.         if (gr_bitblt_double)
  676.             gr_linear_rep_movsd_2x( sbits, dbits, w );
  677.         else
  678.             gr_linear_movsd( sbits, dbits, w );
  679.         sbits += src->bm_rowsize;
  680.         dbits += dstep;
  681.     }
  682. }
  683. // From Linear to Linear Masked
  684. void gr_bm_ubitblt00m(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  685. {
  686.     unsigned char * dbits;
  687.     unsigned char * sbits;
  688.     //int    src_bm_rowsize_2, dest_bm_rowsize_2;
  689.  
  690.     int i;
  691.  
  692.     sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
  693.     dbits =   dest->bm_data + (dest->bm_rowsize * dy) + dx;
  694.  
  695.     // No interlacing, copy the whole buffer.
  696.  
  697.     if (gr_bitblt_fade_table==NULL)    {
  698.         for (i=0; i < h; i++ )    {
  699.             gr_linear_rep_movsdm( sbits, dbits, w );
  700.             sbits += src->bm_rowsize;
  701.             dbits += dest->bm_rowsize;
  702.         }
  703.     } else {
  704.         for (i=0; i < h; i++ )    {
  705.             gr_linear_rep_movsdm_faded( sbits, dbits, w, gr_bitblt_fade_table[dy+i] );
  706.             sbits += src->bm_rowsize;
  707.             dbits += dest->bm_rowsize;
  708.         }
  709.     }
  710. }
  711.  
  712.  
  713. extern void gr_lbitblt( grs_bitmap * source, grs_bitmap * dest, int height, int width );
  714.  
  715. void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  716. {
  717.     int dx1=dx, dx2=dx+dest->bm_w-1;
  718.     int dy1=dy, dy2=dy+dest->bm_h-1;
  719.  
  720.     int sx1=sx, sx2=sx+src->bm_w-1;
  721.     int sy1=sy, sy2=sy+src->bm_h-1;
  722.  
  723.     if ((dx1 >= dest->bm_w ) || (dx2 < 0)) return;
  724.     if ((dy1 >= dest->bm_h ) || (dy2 < 0)) return;
  725.     if ( dx1 < 0 ) { sx1 += -dx1; dx1 = 0; }
  726.     if ( dy1 < 0 ) { sy1 += -dy1; dy1 = 0; }
  727.     if ( dx2 >= dest->bm_w )    { dx2 = dest->bm_w-1; }
  728.     if ( dy2 >= dest->bm_h )    { dy2 = dest->bm_h-1; }
  729.  
  730.     if ((sx1 >= src->bm_w ) || (sx2 < 0)) return;
  731.     if ((sy1 >= src->bm_h ) || (sy2 < 0)) return;
  732.     if ( sx1 < 0 ) { dx1 += -sx1; sx1 = 0; }
  733.     if ( sy1 < 0 ) { dy1 += -sy1; sy1 = 0; }
  734.     if ( sx2 >= src->bm_w )    { sx2 = src->bm_w-1; }
  735.     if ( sy2 >= src->bm_h )    { sy2 = src->bm_h-1; }
  736.  
  737.     // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
  738.     if ( dx2-dx1+1 < w )
  739.         w = dx2-dx1+1;
  740.     if ( dy2-dy1+1 < h )
  741.         h = dy2-dy1+1;
  742.     if ( sx2-sx1+1 < w )
  743.         w = sx2-sx1+1;
  744.     if ( sy2-sy1+1 < h )
  745.         h = sy2-sy1+1;
  746.  
  747.     gr_bm_ubitblt(w,h, dx1, dy1, sx1, sy1, src, dest );
  748. }
  749.  
  750. void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  751. {
  752.     register int x1, y1;
  753.  
  754.     if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_LINEAR ))
  755.     {
  756.         if ( src->bm_flags & BM_FLAG_RLE )    
  757.             gr_bm_ubitblt00_rle( w, h, dx, dy, sx, sy, src, dest );
  758.         else
  759.             gr_bm_ubitblt00( w, h, dx, dy, sx, sy, src, dest );
  760.         return;
  761.     }
  762.  
  763.     if ( (src->bm_flags & BM_FLAG_RLE ) && (src->bm_type == BM_LINEAR) )    {
  764.         gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest );
  765.          return;
  766.     }
  767.  
  768.     if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA ))
  769.     {
  770.         gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest );
  771.         return;
  772.     }
  773.  
  774.     if ( (src->bm_type == BM_SVGA) && (dest->bm_type == BM_LINEAR ))
  775.     {
  776.         gr_bm_ubitblt20( w, h, dx, dy, sx, sy, src, dest );
  777.         return;
  778.     }
  779.  
  780.     if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_MODEX ))
  781.     {
  782.         gr_bm_ubitblt01( w, h, dx+XOFFSET, dy+YOFFSET, sx, sy, src, dest );
  783.         return;
  784.     }
  785.  
  786.     for (y1=0; y1 < h; y1++ )    {
  787.         for (x1=0; x1 < w; x1++ )    {
  788.             gr_bm_pixel( dest, dx+x1, dy+y1, gr_gpixel(src,sx+x1,sy+y1) );
  789.         }
  790.     }
  791. }
  792.  
  793. // Clipped bitmap ... 
  794.  
  795. void gr_bitmap( int x, int y, grs_bitmap *bm )
  796. {
  797.     int dx1=x, dx2=x+bm->bm_w-1;
  798.     int dy1=y, dy2=y+bm->bm_h-1;
  799.     int sx=0, sy=0;
  800.  
  801.     if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
  802.     if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
  803.     if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
  804.     if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
  805.     if ( dx2 >= grd_curcanv->cv_bitmap.bm_w )    { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
  806.     if ( dy2 >= grd_curcanv->cv_bitmap.bm_h )    { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
  807.         
  808.     // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
  809.  
  810.     gr_bm_ubitblt(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
  811.  
  812. }
  813.  
  814. void gr_bitmapm( int x, int y, grs_bitmap *bm )
  815. {
  816.     int dx1=x, dx2=x+bm->bm_w-1;
  817.     int dy1=y, dy2=y+bm->bm_h-1;
  818.     int sx=0, sy=0;
  819.  
  820.     if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
  821.     if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
  822.     if ( dx1 < 0 ) { sx = -dx1; dx1 = 0; }
  823.     if ( dy1 < 0 ) { sy = -dy1; dy1 = 0; }
  824.     if ( dx2 >= grd_curcanv->cv_bitmap.bm_w )    { dx2 = grd_curcanv->cv_bitmap.bm_w-1; }
  825.     if ( dy2 >= grd_curcanv->cv_bitmap.bm_h )    { dy2 = grd_curcanv->cv_bitmap.bm_h-1; }
  826.         
  827.     // Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
  828.  
  829.     if ( (bm->bm_type == BM_LINEAR) && (grd_curcanv->cv_bitmap.bm_type == BM_LINEAR ))
  830.     {
  831.         if ( bm->bm_flags & BM_FLAG_RLE )    
  832.             gr_bm_ubitblt00m_rle(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
  833.         else
  834.             gr_bm_ubitblt00m(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
  835.         return;
  836.     }
  837.  
  838.     gr_bm_ubitbltm(dx2-dx1+1,dy2-dy1+1, dx1, dy1, sx, sy, bm, &grd_curcanv->cv_bitmap );
  839.  
  840. }
  841.  
  842. void gr_bm_ubitbltm(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  843. {
  844.     register int x1, y1;
  845.     ubyte c;
  846.  
  847.     for (y1=0; y1 < h; y1++ )    {
  848.         for (x1=0; x1 < w; x1++ )    {
  849.             if ((c=gr_gpixel(src,sx+x1,sy+y1))!=255)
  850.                 gr_bm_pixel( dest, dx+x1, dy+y1,c  );
  851.         }
  852.     }
  853.  
  854. }
  855.  
  856. //-NOT-used // From linear to SVGA
  857. //-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)
  858. //-NOT-used {
  859. //-NOT-used     unsigned char * sbits;
  860. //-NOT-used 
  861. //-NOT-used     unsigned int offset, EndingOffset, VideoLocation;
  862. //-NOT-used 
  863. //-NOT-used     int sbpr, dbpr, y1, page, BytesToMove;
  864. //-NOT-used 
  865. //-NOT-used     sbpr = src->bm_rowsize;
  866. //-NOT-used 
  867. //-NOT-used     dbpr = dest->bm_rowsize << gr_bitblt_dest_step_shift;
  868. //-NOT-used 
  869. //-NOT-used     VideoLocation = (unsigned int)dest->bm_data + (dest->bm_rowsize * dy) + dx;
  870. //-NOT-used 
  871. //-NOT-used     sbits = src->bm_data + ( sbpr*sy ) + sx;
  872. //-NOT-used 
  873. //-NOT-used     for (y1=0; y1 < h; y1++ )    {
  874. //-NOT-used 
  875. //-NOT-used         page    = VideoLocation >> 16;
  876. //-NOT-used         offset  = VideoLocation & 0xFFFF;
  877. //-NOT-used 
  878. //-NOT-used         gr_vesa_setpage( page );
  879. //-NOT-used 
  880. //-NOT-used         EndingOffset = offset+w-1;
  881. //-NOT-used 
  882. //-NOT-used         if ( EndingOffset <= 0xFFFF )
  883. //-NOT-used         {
  884. //-NOT-used             gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), w );
  885. //-NOT-used 
  886. //-NOT-used             VideoLocation += dbpr;
  887. //-NOT-used             sbits += sbpr;
  888. //-NOT-used         }
  889. //-NOT-used         else
  890. //-NOT-used         {
  891. //-NOT-used             BytesToMove = 0xFFFF-offset+1;
  892. //-NOT-used 
  893. //-NOT-used             gr_linear_rep_movsd_2x( (void *)sbits, (void *)(offset+0xA0000), BytesToMove );
  894. //-NOT-used 
  895. //-NOT-used             page++;
  896. //-NOT-used             gr_vesa_setpage(page);
  897. //-NOT-used 
  898. //-NOT-used             gr_linear_rep_movsd_2x( (void *)(sbits+BytesToMove/2), (void *)0xA0000, EndingOffset - 0xFFFF );
  899. //-NOT-used 
  900. //-NOT-used             VideoLocation += dbpr;
  901. //-NOT-used             sbits += sbpr;
  902. //-NOT-used         }
  903. //-NOT-used 
  904. //-NOT-used 
  905. //-NOT-used     }
  906. //-NOT-used }
  907.  
  908.  
  909. //-NOT-used // From Linear to Linear
  910. //-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)
  911. //-NOT-used {
  912. //-NOT-used     unsigned char * dbits;
  913. //-NOT-used     unsigned char * sbits;
  914. //-NOT-used     //int    src_bm_rowsize_2, dest_bm_rowsize_2;
  915. //-NOT-used 
  916. //-NOT-used     int i;
  917. //-NOT-used 
  918. //-NOT-used     sbits =   src->bm_data  + (src->bm_rowsize * sy) + sx;
  919. //-NOT-used     dbits =   dest->bm_data + (dest->bm_rowsize * dy) + dx;
  920. //-NOT-used 
  921. //-NOT-used     // No interlacing, copy the whole buffer.
  922. //-NOT-used     for (i=0; i < h; i++ )    {
  923. //-NOT-used         gr_linear_rep_movsd_2x( sbits, dbits, w );
  924. //-NOT-used 
  925. //-NOT-used         sbits += src->bm_rowsize;
  926. //-NOT-used         dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
  927. //-NOT-used     }
  928. //-NOT-used }
  929.  
  930. void gr_bm_ubitblt00_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  931. {
  932.     unsigned char * dbits;
  933.     unsigned char * sbits;
  934.  
  935.     int i;
  936.  
  937.     sbits = &src->bm_data[4 + src->bm_h];
  938.     for (i=0; i<sy; i++ )
  939.         sbits += (int)src->bm_data[4+i];
  940.  
  941.     dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
  942.  
  943.     // No interlacing, copy the whole buffer.
  944.     for (i=0; i < h; i++ )    {
  945.         gr_rle_expand_scanline( dbits, sbits, sx, sx+w-1 );
  946.         sbits += (int)src->bm_data[4+i+sy];
  947.         dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
  948.     }
  949. }
  950.  
  951. void gr_bm_ubitblt00m_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  952. {
  953.     unsigned char * dbits;
  954.     unsigned char * sbits;
  955.  
  956.     int i;
  957.  
  958.     sbits = &src->bm_data[4 + src->bm_h];
  959.     for (i=0; i<sy; i++ )
  960.         sbits += (int)src->bm_data[4+i];
  961.  
  962.     dbits = dest->bm_data + (dest->bm_rowsize * dy) + dx;
  963.  
  964.     // No interlacing, copy the whole buffer.
  965.     for (i=0; i < h; i++ )    {
  966.         gr_rle_expand_scanline_masked( dbits, sbits, sx, sx+w-1 );
  967.         sbits += (int)src->bm_data[4+i+sy];
  968.         dbits += dest->bm_rowsize << gr_bitblt_dest_step_shift;
  969.     }
  970. }
  971.  
  972. // in rle.c
  973.  
  974. extern void gr_rle_expand_scanline_generic( grs_bitmap * dest, int dx, int dy, ubyte *src, int x1, int x2  );
  975.  
  976.  
  977. void gr_bm_ubitblt0x_rle(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest)
  978. {
  979.     int i;
  980.     register int y1;
  981.     unsigned char * sbits;
  982.  
  983.     //mprintf( 0, "SVGA RLE!\n" );
  984.  
  985.     sbits = &src->bm_data[4 + src->bm_h];
  986.     for (i=0; i<sy; i++ )
  987.         sbits += (int)src->bm_data[4+i];
  988.  
  989.     for (y1=0; y1 < h; y1++ )    {
  990.         gr_rle_expand_scanline_generic( dest, dx, dy+y1,  sbits, sx, sx+w-1  );
  991.         sbits += (int)src->bm_data[4+y1+sy];
  992.     }
  993.  
  994. }
  995.  
  996.  
  997. 
  998.