Path: utzoo!utgpu!watmath!clyde!att!rutgers!mailrus!ncar!ames!pasteur!helios.ee.lbl.gov!ux1.lbl.gov!beard
From: beard@ux1.lbl.gov (Patrick C Beard)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Thanks! (was "Question about "GrafPort transfer modes"..)
Keywords: I have another problem/question...
Message-ID: <1377@helios.ee.lbl.gov>
Date: 6 Dec 88 04:40:35 GMT
References: <32993@bbn.COM>
Sender: usenet@helios.ee.lbl.gov
Reply-To: beard@ux1.lbl.gov (Patrick C Beard)
Organization: Lawrence Berkeley Laboratory, Berkeley
Lines: 116

In article <32993@bbn.COM> franco@bbn.com (Frank A. Lonigro) writes:
>First of all I'd like to thank everyone who answered my question about
>grafport transfer modes.
>

>mystone@caen.engin.umich.edu (Dean Yu)
>Randy Carr 
>Eric Pepke 
>David Casseres 
>jskuskin@eleazar.Dartmouth.EDU (Jeffrey Kuskin)
>beard@ux1.lbl.gov
You're welcome!
>chrisj@cup.portal.com
>
>
>Now for my new question:
>
>The effect I am trying to accomplish is to take a picture(a game playing piece)
>and display it on a playing field(a checker board).  What I want to be able
>to do is to grab the playing piece with a mouseDown and move it around on
>the board.  I don't want to drag a gray region of it like in DragWindow.  What
>I want to do is to move it around like when your in MacPaint and you lasso
>some odd shaped piece of your picture and then move it to another part of
>the screen.  I also don't want to drag around the square-ish white rectangle
>that is part of the picture.  Once again, I would like to just drag it around
>as if it had a white polygon frame in the shape of the playing piece, say
>1 or 2 pixels just outside of the piece.
>

There are two Apple provided solutions to this.  One is BitMapRgn, a routine
that calculates regions around arbitrarily shaped bitmaps;  the other is
CalcMask and CopyMask (IM IV-24), which respectively, create a mask in
the shape of the desired bitmap and draw only the bits that are inside
the mask.

I have tried using CopyMask and CalcMask in my own programs and find it
perfectly adequate.  You can only get a srcCopy transfer mode with CopyMask,
but I find find that's all I need.  

BitMapRgn is available from software licensing at Apple an costs to include
in your programs.  Plus, using CopyBits with a region is much slower than
CopyMask with a mask.

>I know this effect is possible, because ChessMaster 2000 uses it, not to
>mention about a 1000 other graphics oriented games.
>
>I'm really trying to get into programming my Mac and I would appreciate any
>help you can give me, sample 'C' code of a simple example would be a great
>help.
>
>Thanks again,
>-franco
>
>franco@bbn.com
>franco%bbn.com@relay.cs.net
>...!harvard!bbn!franco
>

Here is a fragment:

My reasons for doing this type of coding was to replace the standard
cursor with a graphic that had the same flexibility as the cursor but
could be any size.

/*
	BigCursor.h -- Definition of a bigger than standard cursor.
 */

typedef struct BigCursor {
	BitMap		cursor;
	BitMap		mask;
	BitMap		savedBits;
	Rect		savedRect;
	Boolean		saved;		/* a boolean to tell if we need to update */
} BigCursor;				/* a cursor that can be any size. */

I used the above data structure to store the BitMap of the image, its
mask, and a bitmap to save the bits behind wherever the user puts it.
To draw the thing and move it around:

TrackBigCursor(bigC,pt,port)
BigCursor *bigC;
Point pt;
GrafPtr port;	/* grafport to draw in */
{
	Rect r;
	int w, h;
	while(Button()) {
		/* save the bits behind the new location of the cursor */
		r=(*bigC).savedBits.bounds;
		w=r.right-r.left; h=r.bottom-r.top
		topLeft(r)=pt;
		r.bottom=r.top+h; r.right=r.left.w;
		CopyBits(&PSEPort->portBits, &(*bigC).savedBits, &r, 
				&(*bigC).savedBits.bounds, srcCopy, nil);
		(*bigC).saved=true; (*bigC).savedRect=r;
		/* draw the cursor in the new position */
		CopyMask(&(*bigC).cursor, &(*bigC).mask, &port->portBits, 
				&(*bigC).cursor.bounds, &(*bigC).mask.bounds, &r);

		...	code to keep tracking etc...
		GetMouse(&pt);
	}
	/* button released now restore things */
	if((*bigC).saved) {
		CopyBits(&(*bigC).savedBits, &PSEPort->portBits, 
			&(*bigC).savedBits.bounds, &(*bigC).savedRect, srcCopy, nil);
		(*bigC).saved=false;	/* for later */
	}
}

I hope this is helpful.  You'll need to read IM IV carefully to understand
what I am doing.

Patrick Beard
Lawrence Berkeley Laboratory