From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
Subject: Re: Questions relating to direct-to-screen drawing
Organization: Kalamazoo College
Date: Tue, 29 Sep 1992 12:04:52 GMT

dougm@cns.caltech.edu (Doug McNaught) writes:
>
>  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...
>
>His name is Alexei Lebedev and he can be reached at 
>  70534.404@CompuServe.COM
>
>1). ... 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.

The global will not tell you;  disassemble _StripAddress in both 24- and
32-bit mode to see why.  (In 24-bit mode, it ANDs the global like you'd
expect;  in 32-bit mode, it returns and does nothing.)

>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);
>destImage->baseAddr = StripAddress(*destImage->baseH);
>
>Is this the right way to do this?

Looks fine to me.  

>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?

It has an effect on any computer running in 24-bit mode that is capable
of switching into 32-bit mode.  The LC, like most Macs, could fit these
conditions.

>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?

Is it 32-bit clean?  Probably, but why take a chance?  StripAddress is a
very quick call.  Is it the baseAddr of the main screen?  Yes.

>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?

screenBits.rowBytes stays the same for a good reason--it _is_ the same,
at least on your machine.  The standard Apple 8-bit card, for example,
will always have a rowBytes of 1024, no matter how many bytes wide the
image actually is.  If you're in 8-bit mode, 384 bytes per line are
going to waste;  if you're in 1-bit mode, 944.  (That way-cool screen
extender by that European dude, I think it's called MaxApplScreen or
something like that, makes use of the extra ram on the card, by the way.
Except I can never remember the name of the control panel, I always
think "MaxApplZone"...anyway...)

The Right(tm) way of getting a screen's base address is to decide which
screen you want from the device list, and use
(**(**theGDevHndl).gdPMap).baseAddr.  Generally, you should always swap
into 32-bit mode before writing to the screen (or anyplace not in main
RAM).  I say "generally" because if you know for a fact that the screen's
address is a 24-bit address, you don't need to--but why _not_ call
SwapMMUMode()?

>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.

screenBits is a holdover from 9-inch-screen days.  The Right(tm) way to
get a screen's PixMap is to walk the GDevice list, as I said above.
I don't know whether screenBits was upgraded to a PixMap, or what the
story is, because I never use it.  It's a very rare occasion that you
know for sure that the main screen is the one you want.

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

"Concentrate and ask again."  :-)  Seriously, Tech Note #213
("StripAddress: the Untold Story") explains stripping and MMU modes
quite well.

>Also, if I want to write to 
>another screen, do I call SetGDevice? If so, what happens to my screenBits? 

No, you don't have to.  Change the current GDevice and you change the
color environment--for example, I believe the Color Manager call
Color2Index will decide on an index based on the new GDevice's inverse
table.  You won't affect QuickDraw calls (hopefully), because they all
go through DeviceLoop anyway.  I have no idea whether screenBits will
reflect the current GDevice, or always the main one.

>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?

I believe the rule is--always leave the current GDevice where you found
it.  (And I believe that, if others follow the rule, you'll always find
it set to the main device.)  So, do GetGDevice/SetGDevice/.../SetGDevice.

If you need to, that is--when you're drawing direct to screen, there
isn't much reason to change the current GDevice.

>I used to calculate screen width by taking screenBits.rowBytes and multiplying
>it by 8.

This is not a good thing to do.  (Although I must say it's interesting
to try to figure out what's going on inside your computer.)  Trust
rowBytes.  If you want screen width, subtract left from right.

>Also it doesn't make sense that in 
>1 bit mode screenbits.rowBytes is 1024 (!!), while in 8 bit mode it's 512 
>(??).

Makes no sense to me neither--check that value with the 8-bit screen
again.  I'll bet it's still 1024.


Also, I highly recommend Forrest Tanaka's short develop article entitled
"Graphical Truffles" (sorry, I forget which issue, email me if you need
to know).  It cleared a lot of cobwebs out of my Color QuickDraw
paradigm.  Develop is downloadable from ftp.apple.com.
-- 
 Jamie McCarthy      Internet: k044477@kzoo.edu      AppleLink: j.mccarthy
 Was bringt mich nicht um...