Newsgroups: comp.sys.mac.programmer.games Subject: Re: Direct Memory Access in windows.. Summary: Expires: References: <48ah76$qjp@news.mountain.net> Sender: Followup-To: Distribution: Organization: Helsinki University of Technology Keywords: In article crudolph@direct.ca (Chris Rudolph) writes: >Assuming that you are running under System 7.x, are in 32-bit mode, and >are using a color window, then the following code should get you started. And assuming you only had one screen and the window was completely on that screen. Too many assumptions. Since Macs can have more than one monitor, a window can exist on several different pixel maps in various parts of memory. Accessing memory outside the legal range for a pixel map can be deadly to your system. You are likely to hit video card registers and such and they can change the way interrupts work and really cause problems. Most of the time game programmers do not bother with multiple screens and especially windows spanning multiple screens. For that reason, the way you usually draw directly to the screen is that you first find out about the display devices that you have and then possibly create a window on one of them (GetMainDevice is what most people do). Before you draw, decide on a rectangle that you are going to clobber. Then all ShieldCursor to hide the cursor if it was over that rectangle. Otherwise a moving cursor can destroy all your drawing efforts and you may end up drawing on parts of the cursor. The GDevice gives you access to the device pixmap, so you can ask the system if 32 bit addressing is needed (call PixMap32Bit). If 32 bit addressing is needed (and many people still run in 24 bit addr mode, so it is needed quite often), you call SwapMMuMode. Note that calling SwapMMuMode does no harm in any case, since it is ignored in machines that are in the 32 bit addressing mode and screens that are accessible in 24 bit addressing mode without SwapMMuMode remain accessible in 32 bit addressing mode. Now use the GetPixBaseAddr call to get the base address and then get the rowBytes and pixel depth that you are working with. Always check for the pixel depth and don't keep the rowBytes or baseAddr values for any longer than you absolutely need to, since they can change from under you at any moment. Screens now have a tendency to change size and bit depth when the user wants it. Be ready for it or you will crash. Draw into your pixel map using the informaton you have. Remember to be careful to clip all your drawing so that only memory specified to exist within that pixel map is touched. While drawing, remember that you may need to call StripAddress on all your pointers and handles, because if you were running in 24 bit mode, the top bits of each handle and pointer may be used for flags and so the full 32 bit address is not correct without StripAddress. After you are done drawing, call SwapMMuMode to swap back from 32 bit mode, if you went to 32 bit mode. Then call ShowCursor to bracket the call to ShieldCursor that you made. If you are really nice to the user, you will: - Support all existing screen depths (1, 2, 4, 8, 16 and 24 bit/pixel) - Support multiple screens by going through the device list and drawing on all that intersect your drawing area. - Respect the visRgn of the window you are drawing into. If you don't, even when you think your window is on top, you will end up drawing on a control strip, floating clock display, menu bar or the rounded corners of the screen. Of course supporting the visRgn is a whole new world, because you have to know at least something about regions: either convert them to bitmap masks or maybe even examine the region structure itself. Looking at the region structure directly is the only no-no that I actually do. It is my educated guess that the region data structure will not change in the foreseeable future. Don't take my word for it though.