[comp.sys.amiga] Blit Question Response

asaph@TAURUS.BITNET (01/04/90)

/*        Email bounced so I had to post. Sorry for the bandwidth   */

Hi,
  You ask:

>The Problem:
>
>  I want to copy a portion of one RastPort and put into another one.
>  I want only the non-zero bits to transfer. It should work exactly
>  like a brush in Deluxe Paint.
>
>  Wherever the source rastport is non-zero, i want a complete
>  duplication in the destination rastport. It doesn't seem like it
>  should be that hard, but the minterm eludes me.
>
>The Solution:
>
>  Hopefully one of you amazing amiga programmers will know this.
>  (I'm writing in C, using Manx 3.6a)....

>Replies to:
>Nick Tanner (lizard @ blake.acs.washingto.edu)
>Grateful thanks will be forthcoming.

I reply:
  Unfortunately I cannot give you a perferct answer, as I too feel there
should be a 1-blit method to do this, however, I do have a method which
for me has worked flawlessly. This method requires n+1 blits, where n is
the number of bit planes you are bliting to/from.
  As luck would have it, a friend just yesterday asked me this very same
question so I have prepared a small file describing my solution. I will
include it here. If you get a better solution please inform me.
  The method is this: first set the A pen to 0.
  Now blit each plane of the source to the destination as a pattern, this
will cause all the 1 bits of the source to become 0 at the destination.
finaly blit the whole source - all the blit planes - to the destination
using one blitter command, with the mintern 0x60 - cookie-cut.

                                        Hope this helps,
                                                Asaph.
asaph@taurus.bitnet                     asaph@math.tau.ac.il

----------- example code follows -------------------------------------------

     /* set the A pen to the back-ground color so the pattern will
     /* "cut out" an area from the display
      */
     SetAPen(window->RPort,0);
     /* for each plane of the image use it as a pattern to blit all 0's
     /* into the places where the pattern has 1's, and leave the places
     /* where the pattern has 0's untouched
      */
    for (i=0; i<SCREENDEPTH; i++)
       BltPattern(window->RPort,BitMap.Planes[i],
        dx,dy,dx+IMAGEWIDTH,dy+IMAGEHEIGHT,IMAGEWIDTH/8+1);
     /* after clearing the place under the image we are ready to blit
     /* it into the desired location, this time we blit the entire image.
     /* BitMap is a BitMap structure that hold my image - the planes
     /* point to chip-mem buffers that hold the data. For bliting
     /* from an existing rastport youll probably need to do some
     /* more calculations.
      */
     BltBitMapRastPort(&BitMap,0,0,window->RPort,
        dx,dy,IMAGEWIDTH,IMAGEHEIGHT,0x60);


/* example of use, torn out of my CS workshop project */
/* This routine displays a tile on the screen. The tile
/* will either be empty or will contain: an ellipse,  a picture of
/* a bug, or a picture of a bug on an ellipse
 */
DispTile(tile,x,y,window)
Tile *tile;
int x,y;
struct Window *window;
{
 int dx,dy,i;
 /* clear area where tile is to be draw
 ClearTileDisp(x,y,window);
 dx = GRIDLEFT+x*BOXWIDTH;
 dy = GRIDTOP+y*BOXHEIGHT;
 /* if there is an ellipe here*/
 if (tile->pixel[x][y]) {
        SetAPen(window->RPort, FOODCOLOR );
        Preview(window,x,y,-1); /* not important */
        /* draw the ellipse */
        AreaEllipse(window->RPort,dx+BOXWIDTH/2,dy+BOXHEIGHT/2,
                BOXWIDTH/2-1,BOXHEIGHT/2-1);
        AreaEnd(window->RPort);
 }
 if (tile->CreatureX==x && tile->CreatureY==y) {
     /* see above for explanation */
     SetAPen(window->RPort,0);
     for (i=0; i<SCREENDEPTH; i++)
       BltPattern(window->RPort,BugMaps[tile->CreatureD].Planes[i],
        dx+3,dy+1,dx+3+BUGIMAGEWIDTH,dy+1+BUGIMAGEHEIGHT,
        BUGIMAGEWIDTH/8+1);
     BltBitMapRastPort(&BugMaps[tile->CreatureD],0,0,window->RPort,
        dx+3,dy+1,BUGIMAGEWIDTH,BUGIMAGEHEIGHT,0x60);
     Preview(window,x,y,tile->CreatureD); /* not important */
 }
}