[comp.sys.amiga.tech] How Does Workbench Do Dragging?

kim@uts.amdahl.com (Kim DeVaughn) (06/10/89)

[ "All sweet things have one thing in common ... a tendency to make you sick." ]
[                                    --Soolin                                  ]

Yes, I am still around ... just VERY busy ...

I am posting the following for a co-worker of mine who doesn't have
access to the net.  Any replies can be posted or email'd to me at
the address below ...

Thanks ...!

/kim   /\../\


Mike Robinson asks:

  I am trying to write what I thought was going to be a very simple
  Solitaire program which uses the mouse.  That is, by pressing the left
  mouse button you will appear to "pick up" a set of cards, "drag" them
  around the screen and, by releasing the button, "drop" them.  Trouble is,
  I cannot perfect the dragging.
   
  I am rendering to an Intuition window opened up on a 640x200 screen with
  (currently) two bitplanes.  It is neither a GZZ nor a SBM window; there
  are no refresh-type flags specified.
   
  I am working with an in-progress version of the program which only moves
  ONE card image.  So we're talking about a rectangle of about 1" wide to
  1.5" high.
   
  The algorithm captures MOUSEMOVE messages.  When the message port becomes
  empty, it moves the card to the location specified by the last message.
  So the number of moves issued should be substantially less than the total
  number of mouse messages received.  I have used several algorithms to try
  to achieve the drag effect:
   
  (a) Capture the background image.  Then write the foreground.  To move,
      issue 3 blits in a row: old background, capture new background,
      write new foreground.
   
  (b) Use Layers.  Create the foreground image as a SMART layer. (Notice
      that I said that I didn't specify any refresh-types on either window
      or screen.  Hmm...) Move the layer with library calls.
   
   
  Algorithm (a) works very badly.  It flickers on the slightest of moves.
  I surmise that this must be a beam-sync problem because it is noticeable
  at the top of the screen and not at the bottom.  The flickering would be
  better described as 'streaking' since the image is filled with horizontal
  bands of the wrong color.
   
  Algorithm (b) works better.  The streaking effect disappears, but the
  whole image blinks in and out and the edge-clipping effect is very
  pronounced.  In a GIMMEZEROZERO window the image fails to follow the
  mouse at all, but blinks on and off with as much as a quarter-second
  between moves.
   
   
  I feel that I'm getting closer to the answer with the Layers library, but
  I'd be *extremely* grateful if someone could tell me, briefly, how
  Workbench does it.  Window-type, flag settings, what library call, etc.
  If I could achieve dragging as well as Workbench does, for comparably
  sized images, I'd be delighted.  Thanks in advance for your help.
   
   
  -Mike Robinson
   Amdahl Education Center; Santa Clara, CA

-- 
UUCP:  kim@amdahl.amdahl.com
  or:  {sun,decwrl,hplabs,pyramid,uunet,oliveb,ames}!amdahl!kim
DDD:   408-746-8462
USPS:  Amdahl Corp.  M/S 249,  1250 E. Arques Av,  Sunnyvale, CA 94086
BIX:   kdevaughn     GEnie:   K.DEVAUGHN     CIS:   76535,25

ali@polya.Stanford.EDU (Ali T. Ozer) (06/15/89)

>Mike Robinson asks, through Kim DeVaughn:
>
>  I am trying to write what I thought was going to be a very simple
>  Solitaire program which uses the mouse.  That is, by pressing the left
>  mouse button you will appear to "pick up" a set of cards, "drag" them
>  around the screen and, by releasing the button, "drop" them.  Trouble is,
>  I cannot perfect the dragging. ...
>  I'd be *extremely* grateful if someone could tell me, briefly, how
>  Workbench does it.  Window-type, flag settings, what library call, etc.
>  If I could achieve dragging as well as Workbench does, for comparably
>  sized images, I'd be delighted.  Thanks in advance for your help.

Well, whatever the Workbench does isn't perfect either --- just drag
several good sized icons simultaneously and you will get a good amount of 
flicker.

What'll work well in your case is some sort of (fake) double buffering ---
Create all your images in offscreen bitmaps or a secondary screen
and blit them in. 

If the largest piece you are moving is 100x100, create a 200x200 bitmap.
If the user moves the piece by a distance of 30,30, say, all you need
to do is recreate the 130x130 area in this bitmap by first drawing
the background, any other pieces that appear, and finally your piece in
its new location in this offscreen bitmap. Then blit this 130x130 area into 
your actual window.

If the user moves the piece by more than 100,100 (so the new image doesn't
overlap the previous one), then you can do the above just for the two
100x100 areas individually (old and new locations).

Using this method you might end up drawing less frames/second, but 
because there's no flicker it'll probably look much better. 

I used this method in a small program I was working on. I just
used a secondary screen to do my temporary drawing; this allows
you to see both the "offscreen" and onscreen versions at the same time
and makes debugging easier. You probably can also use a offscreen bitmap
with an appropriate rastport; I don't see why it shouldn't work.

Ali Ozer