[comp.sys.amiga] Double Buffering and the Menu Strip

iphwk%MTSUNIX1.BITNET@cunyvm.cuny.edu (Bill Kinnersley) (09/20/88)

I'm attempting to write a program that needs to use both menus and
double buffered animation.  That is, there will be well-defined periods of
menu selection interspersed with periods of double buffering.  The problem
is that I keep losing the menu.

Here is (schematically) how I open things:

        bm[0] = AllocMem();
        bm[1] = AllocMem();
        ns.Flags = CUSTOMSCREEN | CUSTOMBITMAP;
        ns.CustomBitMap = bm[0];
        s = OpenScreen(&ns);
        vp = &s->ViewPort;
        nw.Screen = s;
        w = OpenWindow(&nw);
        rp = w->RPort;
        SetMenuStrip(w,&menu[0]);

and here is how I double buffer:

        vp->RasInfo->BitMap = bm[tog];
        WaitTOF();
        ScrollVPort(vp);
        tog ^= 1;
        rp->BitMap = bm[tog];

It looks like the menu wants to remain attached to the original bitmap bm[0].
When bm[0] is being displayed, the menu works OK.  When bm[1] is being
displayed, pressing the right mouse button has no apparent effect.

The thing I tried was to put in a ClearMenuStrip() and SetMenuStrip()
each time the double buffering was finished, but this didn't help.

Is there something else I should be toggling (in the Layer_Info perhaps?)
to keep the menu system informed which bitmap is the current one?

--

Bill Kinnersley
  Physics Department            BITNET: iphwk@mtsunix1
  Montana State University      INTERNET: iphwk%mtsunix1.bitnet@cunyvm.cuny.edu
  Bozeman, MT 59717             CSNET: iphwk%mtsunix1.bitnet@relay.cs.net
  (406)994-3614                 UUCP: ...ucbvax!mtsunix1.bitnet!iphwk
"This message was packed as full as practicable by modern electronic
equipment.  Some settling of contents may have occurred during transmission."

bmacintyre@watsol.waterloo.edu (Blair MacIntyre) (09/21/88)

In article <4148@louie.udel.EDU> iphwk%MTSUNIX1.BITNET@cunyvm.cuny.edu (Bill Kinnersley) writes:
>
>and here is how I double buffer:
>
>        vp->RasInfo->BitMap = bm[tog];
>        WaitTOF();
>        ScrollVPort(vp);
         ^^^^^^^^^^^
>        tog ^= 1;
>        rp->BitMap = bm[tog];

I don't think this is an intelligent way of doing this.  What you should be
doing is ( this is from memory, I'm at work doncha' know )

	Makescreen(s);
	RethinkDisplay();	<-- there are two different Intuition functions
				    to redo the display.  You want to use the
				    less encompasing, faster one here ...
 
>Is there something else I should be toggling (in the Layer_Info perhaps?)
>to keep the menu system informed which bitmap is the current one?

This should do it.  The Rethinkdisplay ( or ReMakeDisplay ... I can't remember
which is the more appropriate ) should redo everything.  I've been playing
with double buffering lately and this is the *only* Intuition compatible way
of doing it ... as far as I can tell.

Course, I've been using it for my 3D graphics package (which is coming along
fine, thank-you-very-much) so I haven't been using menus.  This had better
work though, or Intuition is severely brain-dead ... :-) :-)

Blair "next ... surface mesh's ..."

--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= Mr. Blair MacIntyre (bmacintyre@watsol.waterloo.edu)                        =
= Using computers is like parachuting ... if you don't get it the first time, =
= chances are you won't try it again.                                         =

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (09/24/88)

In article <8597@watdragon.waterloo.edu> bmacintyre@watsol.waterloo.edu (Blair MacIntyre) writes:
>In article <4148@louie.udel.EDU> iphwk%MTSUNIX1.BITNET@cunyvm.cuny.edu (Bill Kinnersley) writes:
>>and here is how I double buffer:
>>        ScrollVPort(vp);
>         ^^^^^^^^^^^
>
>I don't think this is an intelligent way of doing this.  What you should be
>doing is ( this is from memory, I'm at work doncha' know )
>
>	Makescreen(s);
>	RethinkDisplay();
> 
	Eeuuuaaahhh!!  Ick!  RethinkDisplay() is very slow, as it invokes
MrgCop(), which assembles a brand new copper list for the display.  The time
required to do this is non-trivial.  Therefore, if you're doing anything
remotely speed-sensitive, you should avoid RethinkDisplay().

	ScrollVPort() does work with Intuition screens.  As an example,
check out the source code to Ing, the window bouncer.

	To answer the original question, you're probably best off dealing
with the menus via the MENUVERIFY IDCMP class.  When Intuition asks you to
MENUVERIFY, you pull forward the screen you want, confirm the MENUVERIFY
event, and wait for the menu event to happen.  You cannot (easily) have
Intuition menus over a *running* double-buffered display; you must halt
double-buffering and bring the "menu'd" screen to the front to permit the
user to interact with them.

>>Is there something else I should be toggling (in the Layer_Info perhaps?)
>>to keep the menu system informed which bitmap is the current one?
>
	You might possibly be able to spoof the system by fiddling with the
BitMap pointers in the layer structures, but this could easily lead to hairy
bananas.  You're better off pulling the menu'd screen to the front.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	INET: well!ewhac@ucbvax.Berkeley.EDU
 \_ -_		Recumbent Bikes:	UUCP: pacbell > !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

iphwk%MTSUNIX1.BITNET@cunyvm.cuny.edu (Bill Kinnersley) (09/25/88)

[In "Double Buffering and the Menu Strip", I said:]
:
: I'm attempting to write a program that needs to use both menus and
: double buffered animation.  That is, there will be well-defined periods of
: menu selection interspersed with periods of double buffering.
: The problem is that I keep losing the menu.

To make that clearer;
  1) The user makes a menu selection
  2) He then "picks up" an image on the screen and moves it around.
     (This will be a double-buffered Bob)
  3) He then "drops" the thing, and double buffering stops.
  4) When next he tries to make a menu selection, the menu will not appear.

:
: Here is (schematically) how I open things:
:
:         bm[0] = AllocMem();
:         bm[1] = AllocMem();
:         ns.Flags = CUSTOMSCREEN | CUSTOMBITMAP;
:         ns.CustomBitMap = bm[0];
:         s = OpenScreen(&ns);
:         vp = &s->ViewPort;
:         nw.Screen = s;
:         w = OpenWindow(&nw);
:         rp = w->RPort;
:         SetMenuStrip(w,&menu[0]);
:
: and here is how I double buffer:
:
:         vp->RasInfo->BitMap = bm[tog];
:         WaitTOF();
:         ScrollVPort(vp);
:         tog ^= 1;
:         rp->BitMap = bm[tog];
:
The Screen structure comes equipped with its own instance of a BitMap.
Normally both vp->RasInfo->BitMap and rp->BitMap point to s.BitMap.
vp->RasInfo controls what you display, and rp->BitMap controls where
you draw.  We're supposed to be drawing to one BitMap while displaying
the other.

My first impression was that the menu was not being activated--that somehow
Intuition was not picking up the MENUDOWN event, or not associating it with
my window.  This was wrong: the menu was being activated, it just wasn't
being displayed.  By blindly making the proper motions with the mouse I
*could* select menu items, I just couldn't see anything happening.  The
menu was just not being rendered.

OK, menus are handled outside of the Layer system.  They're not rendered
into a layer but directly into the screen's BitMap.  Even though I'm using
a window, Intuition is drawing the menus using the screen's own "naked"
RastPort.  Hah, that's the mistake, I should also be toggling that:

        s->BitMap = bm[tog];

Now the menus appear, sure enough they do. But without the menu STRIP!
Well, I'm on the right track.  How are the menu strips rendered?

When you first open a screen, its LayerInfo structure comes with one layer
10 pixels tall for the menu strip.  Pushing the menu button brings this
layer to the front.  This layer has a RastPort, and the RastPort has a
BitMap, and, and...by golly I should toggle that too!

        s = OpenScreen(&ns);
        lrp = s->LayerInfo.top_layer->RastPort;
        ...
        ...
        lrp->BitMap = bm[tog];

Now it should work, right?  Nope.  The menu strip still does funny tricks.
It appears and forgets to go away.  Then the Window title appears with
little sections hightlighted.  You name it, it happens.  It's cute!

Don't get me wrong..it's BETTER.  It *ALMOST* works.  But somewhere in the
bowels of the menu system, there must be a line of code that does not follow
these BitMap pointers like it should.  It ignores the pointers and does its
rendering on s.BitMap directly.  I think that's a bug.

At any rate, my conclusion at this point is that I can think of nothing
else to toggle, or nothing else I should HAVE to toggle.  I think the only
way that you can double buffer without losing much of the functionality of
Intuition is to abandon this approach completely.

I suggest letting the screen have its precious BitMap.  Instead I will
have to double buffer by using just one BitMap and redirecting the
PlanePtrs in that BitMap.

Am I wrong?  Will doing it that way screw up my double-buffered Bob??

--

Bill Kinnersley
  Physics Department            BITNET: iphwk@mtsunix1
  Montana State University      INTERNET: iphwk%mtsunix1.bitnet@cunyvm.cuny.edu
  Bozeman, MT 59717             CSNET: iphwk%mtsunix1.bitnet@relay.cs.net
  (406)994-3614                 UUCP: ...ucbvax!mtsunix1.bitnet!iphwk
"This message was packed as full as practicable by modern electronic
equipment.  Some settling of contents may have occurred during transmission."