From: absurd@applelink.apple.com (Tim Dierks, software saboteur)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Questions relating to direct-to-screen drawing
Date: 29 Sep 92 22:21:09 GMT
Followup-To: comp.sys.mac.programmer
Organization: MacDTS Marauders

In article <DOUGM.92Sep28215037@bradbury.cns.caltech.edu>,
dougm@cns.caltech.edu (Doug McNaught) wrote:
> 
> 
> Hey friendly netters,
>   A friend of mine is working on a program that draws directly to the
> screen in a window, and he has some questions about StripAddress and
> maintaining as much compatibility as possible with various models. The
> program runs in 8-bit mode and requires Color QuickDraw. I'm going to
> append the message he sent me and you can reply to him, myself, or the
> net--I'll make sure he gets any useful responses. 
> 
> His name is Alexei Lebedev and he can be reached at 
>   70534.404@CompuServe.COM
> 
> ------here we go!!!------
> 
> Doug,- 
> 
> I'd be very grateful if you posted my problem on UseNet. In particular, I need
> to know the following:
> 
> 1). IM says "strip when the system may be running 24 bit mem manager". I guess
> any system can run 24 bit memory manager. Also, no my global MaskBC variable 
> is always 0x00FFFFFF, even when I'm in 32 bit mode. That means I'm always 
> running 24 bit mem manager.

No; when you're in 32-bit mode, you're using the 32-bit memory manager.
The proper way to check your memory mode is to use Gestalt with the
gestaltAddressingModeAttr selector ('addr').  If bit 0 is set
(the gestalt32BitAddressing flag), then you're in 32-bit mode.  You
probably don't need to know this; see below.

> 2). How do you tell the hardware to operate in 32 bits? Should I use stripped 
> addresses right away, or can I keep a variable that's a stripped address? In 
> particular, when I lock my Image data structure, I do the following:
> 
> HLock(destImage->baseH);
> CheckOS(MemError(), "LOCK");    /* last parameter is a routine name */
> destImage->baseAddr = StripAddress(*destImage->baseH);
> 
> Is this the right way to do this?

This is OK; you can cache a stripped address safely, however, because
the "stripping" doesn't ever change; if you're in 24-bit mode, it
will always mask off the top byte; if you're in 32-bit mode, it
will always leave the address unchanged.  Stripping an address
so you can use it after switching to 32-bit mode is always an OK 
thing to do; it will do the right thing, regardless of the memory
manager mode you are in previously.

> 3). When I start writing to the screen, I switch to 32 bit addressing with 
> SwapMMUMode. Does this have any effect on a computer like LC?

On the LC, this has neither good nor bad effect, because the hardware is
24-bit; stripping it has no effect, but there's no reason to take it
out, either.

> 4). I use screenbits.baseAddr to get screen memory's base address. Is this 
> address 32 bit clean no matter what? (I guess it should be, since it doesn't 
> point to a memory manager block.) Is this a base address of the main screen?
>
> 5). When I switch pixel depth, screenBits.rowBytes remains the same. This is 
> very nasty. What is the right way of getting screen's base address, and should
> I always switch machine to 32 bit addressing mode before writing to the 
> screen?
> 
> 6). How come screenBits is a bit map, but the screen is color? since 
> screenbits is a bitmap, the high bit of its rowBytes should be cleared. This 
> means using copyBits on the screen will produce b/w images, if not nonsense.

If you're attempting to draw on a color machine, you should look
through the GDevices to determine the size, depth and location of screens.
See the "Graphic Devices" chapters in Inside Mac V and VI.

> 7). At what times EXACTLY should strip address be used, and at what times 
> EXACTLY should SwapMMUMode be used?

You should use SwapMMUMode any time you access the frame buffer for a
video device.  You should use StripAddress() to clean any other addresses
you wish to use while switched into 32-bit mode.  For example, if I wanted
to copy an image from a handle to the screen, I would first call
StripAddress on a pointer to the image data; this produces a clean
pointer I can use while in 32-bit mode.  I then call SwapMMUMode(); I'm
now in 32-bit mode, so I can access the screen's memory safely.  I can
then copy the data from the stripped address to the screen.  I then
call SwapMMUMode() to switch back to the mode I was in before.

> These are just some of the questions that bug me. Also, if I want to write to 
> another screen, do I call SetGDevice? If so, what happens to my screenBits? 
> Can the device be changed when I call WaitNextEvent? I mean, when I return 
> from WaitNextEvent, should I always switch to the my own device, like I do 
> with ports?

If you want to draw on another screen, find its GDevice and use the
depth and base address from that structure.  You do not need to change
the devicew, because that's a QuickDraw call, and you're not using
QuickDraw.  (Not that you would use it to draw on the screen if you
were using QuickDraw- it is intended solely for switching to offscreen
GDevices).

> I used to calculate screen width by taking screenBits.rowBytes and multiplying
> it by 8. However, when I start up in 4 bits and then switch to 8 bits (by 
> using SetDepth), the cube becomes twice as large, instead of being twice as 
> small. This doesn't make much sense to me. Also it doesn't make sense that in 
> 1 bit mode screenbits.rowBytes is 1024 (!!), while in 8 bit mode it's 512 
> (??).

Once again, use GDevices (and their associated PixMaps) to get rowBytes
and everything else.

> Hope some of them get answered.
> Have fun.
> -Alexei
> 
> --
> Doug McNaught              |"Sadder still to watch it die/ Then never to have
> dougm@cns.caltech.edu      | known it/ For you, the blind who once could see/
> doug@midget.towson.edu     | The bell tolls for thee..." --Neil Peart
>   Nobody approves my opinions! Not even me, sometimes. Read at your own risk.

Tim Dierks
MacDTS, but I speak for my knees.
Newsgroups: comp.sys.mac.programmer,comp.sys.mac.system