[comp.sys.mac.programmer] Smoothly dragging small pictures

TALLEY-J@osu-20.ircc.ohio-state.edu (James T. Talley) (05/10/89)

Can anyone point me to information on dragging small pictures
(not grey outlines) on the screen?  The pictures that need to be
dragged are slightly larger than icons.  I wrote a routine that
uses an offscreen bitmap and copybits to save and restore the
existing screen image while I copybits the picture from place to
place.  The problem is that there is a terrible flicker.  Is
there a trick to getting rid of the flicker?  Is there a better
way that I haven't thought of yet?  Any help is appreciated.

James Talley
talley-j@osu-20.ircc.ohio-state.edu

gandreas@umn-d-ub.D.UMN.EDU (Glenn Andreas) (05/11/89)

In article <12492910881010@osu-20.ircc.ohio-state.edu> TALLEY-J@osu-20.ircc.ohio-state.edu (James T. Talley) writes:
>Can anyone point me to information on dragging small pictures
>(not grey outlines) on the screen?  The pictures that need to be
>dragged are slightly larger than icons.  I wrote a routine that
>uses an offscreen bitmap and copybits to save and restore the
>existing screen image while I copybits the picture from place to
>place.  The problem is that there is a terrible flicker.  Is
>there a trick to getting rid of the flicker?  Is there a better
>way that I haven't thought of yet?  Any help is appreciated.
>
>James Talley
>talley-j@osu-20.ircc.ohio-state.edu


One trick is to use TWO offscreen buffers.  Keep the background screen image
in one, and use the other as a temporary.  What you do is when you want to
move the image, union the rectangles of the old object position and the new
object position, copying that rectangle from the background bitmap to the
temporary.  Draw your object onto the temporary, and then copybits that same
rectangle onto the screen.  The reason that your image flickers is that
there are times that the screen is refreshed between the time you erase and
the time you redraw, but with the two offscreen bitmaps, this is never a
problem.  I've tried it, and it is fast enough (it will be part of Theldrow
version 3).

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= "Whether you like it, or don't like it, sit   | - gandreas@ub.d.umn.edu - =
=  back and take a look at it, because it's the |   Glenn Andreas           =
=  best going today!  WOOOOoooo!" - Ric Flair   |                           =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

stores@unix.SRI.COM (Matt Mora) (05/11/89)

In article <12492910881010@osu-20.ircc.ohio-state.edu> TALLEY-J@osu-20.ircc.ohio-state.edu (James T. Talley) writes:
>Can anyone point me to information on dragging small pictures
>(not grey outlines) on the screen?  The pictures that need to be
>dragged are slightly larger than icons.  I wrote a routine that
>uses an offscreen bitmap and copybits to save and restore the
>existing screen image while I copybits the picture from place to
>place.  The problem is that there is a terrible flicker.  Is
>there a trick to getting rid of the flicker?  Is there a better
>way that I haven't thought of yet?  Any help is appreciated.

The key is to do _all_ the drawing offsceen then copy
the unionrect of the new location and the old location.

First you saved the bits where the image was before it was drawn.

You save the bits of where the image will be moved to.

You replace the bits where the image was.

Draw the image in the new location

Now that the offscreen bitmap is fixed & the image is in the new location
and the old location bits have been restored, you copy a rectangle
from the offscreenbitmap that contains the union of old location rect and 
the new location rect directly to the screen.

No Flicker because the user doesn't see the individual drawing and erasing 
steps. And copybits likes rectangles.

This is what Scott Boyd wrote about in an article in Mactutor Volume 3
called "animated bitmaps"

Hope this helps.



-- 
___________________________________________________________
Matthew Mora
SRI International                       stores@unix.sri.com
___________________________________________________________

news@cs.mu.oz.au (news) (05/12/89)

From: jkjl@munnari.oz (John Lim)
Path: munnari.oz!jkjl

Why not simply  do

do {
	doCopyBits(); /* from offscreen to screen BitMap */
	ticker = TickCount();
	while (ticker == TickCount) /* do some background processing */;
} while (ContinueCopyBits);

The rationale behind it is that the value returned by TickCount() only
changes when the screen refreshing task is moving back to the top
of the screen and not redrawing the screen. Refer to Knaster's first book
(cant remember its title at the moment).

The advantage of this method is that you have time to do some
background processing, and you don't waste memory in allocating a 
second offscreen BitMap (which looks like a bit of a kludge to me).


	john lim

mnkonar@gorby.SRC.Honeywell.COM (Murat N. Konar) (05/13/89)

In article <1488@murtoa.cs.mu.oz.au> jkjl@munmurra.UUCP (John Lim) writes:
(code deleted)
>The rationale behind it is that the value returned by TickCount() only
>changes when the screen refreshing task is moving back to the top
>of the screen and not redrawing the screen. Refer to Knaster's first book
>(cant remember its title at the moment).

"How To Write Macintosh Software"  but it should have been called "How To
Debug Macintosh Software."  Good book.

Anyhow, isn't it true that since the Mac II's video guts are on a seperate
card that the video refresh is no longer strictly synced with the VBL?
Seems like I read this in IM-V somewhere.

____________________________________________________________________
Have a day. :^|
Murat N. Konar        Honeywell Systems & Research Center, Camden, MN
mnkonar@SRC.honeywell.com (internet) {umn-cs,ems,bthpyd}!srcsip!mnkonar(UUCP)

gandreas@umn-d-ub.D.UMN.EDU (Glenn Andreas) (05/13/89)

In article <1488@murtoa.cs.mu.oz.au> jkjl@munmurra.UUCP (John Lim) writes:
>From: jkjl@munnari.oz (John Lim)
>Path: munnari.oz!jkjl
>
>Why not simply  do
>
>do {
>	doCopyBits(); /* from offscreen to screen BitMap */
>	ticker = TickCount();
>	while (ticker == TickCount) /* do some background processing */;
>} while (ContinueCopyBits);
>
>The advantage of this method is that you have time to do some
>background processing, and you don't waste memory in allocating a 
>second offscreen BitMap (which looks like a bit of a kludge to me).
>
>
>	john lim


This won't work based on the original question, since there needs to be
a way to erase where you were, restoring the original background.  Sure, you
can time it for the VBL (which the TickCount wait does), but there are still
problems:
	1) There will be certain areas on the screen that it doesn't work
	at all.  I tried this, waiting for the TickCount, and quickly
	restoring the old background and slapping on the new image.  It
	had an interesting effect - there would be a horizontal band where
	the image would disappear completely.  It just took too long to
	restore the old image and slap up the new one.

	2) This won't work on monitors such as are found a II, etc... which
	do not have a vertical retrace at the same rate as the tick count
	changes.  There are more details in IM V.

All in all, a background image bitmap and a temp intermediate bitmap system
seems to be the best solution (except for the memory price).

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= "Whether you like it, or don't like it, sit   | - gandreas@ub.d.umn.edu - =
=  back and take a look at it, because it's the |   Glenn Andreas           =
=  best going today!  WOOOOoooo!" - Ric Flair   |                           =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

jakob@nada.kth.se (Jakob Cederlund) (05/16/89)

I've done dragging routines in C.  First, I used an offscreen
bitmap containing the "background" for the object and a bitmap
twice the size of the object for drawing the new object.  With
those two bitmaps, the dragging loop needed to do three CopyBits
for each increment of the drag.

However the big, "background" bitmap became too big when dragging
between windows. On my Mac II-system at work, with a large monitor and
a colour ditto, this bitmap would take up 1.5 meg. So I dumped the
background bitmap and used a method which needed five blit's per
drag-step.

I can mail a description of the method (and source if I can dig
it up) if anyone is interested.

/Jakob Cederlund, Royal Institute of Technology Stockholm Sweden
jakob@nada.kth.se