davet@cmi.com (David Temkin) (04/11/91)
I'm developing an animated game for for the Mac which, because of performance requirements, doesn't use QuickDraw. It works in 1-bit (black and white) mode, as well as 2-bit mode. In black and white everything is pretty much fine. But in 2-bit mode things sometimes get a bit flaky, and I've been having problems with a variety of obscure (read non-sanctioned) Mac graphics techniques. Would some kind (and knowledgeable) souls in netland please read on and pass on any info they might have? 1. The most serious problem I have manifests itself in 2-bit mode on some machines, but not on others. The problem seems to be that my program writes directly into the video buffer. This only works properly on SOME configurations. On the Mac IIsi and the IIci and some fx configurations, there is no apparent problem writing directly to video memory. But on other machines, notably the vanilla Mac II, IIx, IIcx (each with the standard video cards) and the LC, my program produces a distorted image (multiply overlaid copies of the image, separated horizontally) on the top two-thirds of the screen, and nothing below it. I'm using 24-bit addressing, but even if I use 32-bit addressing (with SwapMMUMode) the result is the same. (Incidentally, the new calls provided with 32-bit QuickDraw -- GetPixBaseAddr and PixMap32Bit -- do not help. The addresses in question are unchanged and apparently do not need to be addressed in 32 bit mode). I considered the possibility that the problem may have something to do with 32-bit clean ROMs, but (1) I have seen it work on a IIcx with a different video card, and (2) there are no ROM calls involved -- all of the graphics code is mine. What is going on? Is the memory mapping following a non-linear or discontinuous model with the 2-bit video screen? Does anybody out there have any experience with this? I assume that the 2-bit screen is mapped essentially like the black and white screen, except that each pixel takes two bits. Is this not universally true? Or am I simply missing some initialization procedure? 2. For some reason, I have been unable to communicate with the video drivers as specified in Designing Cards and Drivers. I'm interested in using the second video page in Macs that have them (apparently Mac IIs and SE/30s may have them as well as the originals), and to determine whether such a beast exists, I need to query the video driver using a Status call. But it comes up nonsense. Here's the code in question (Think C): void this() { GDHandle gdev; short refNum; OSErr err; VDPageInfo csParam; InitToolbox(); gdev = GetMainDevice(); refNum = (**gdev).gdRefNum; err = Status(refNum, cscGetMode, &csParam); } Following the status call, err is 0 (noErr) but csParam contains garbage. What am I missing? One odd aspect of this problem is that on the machine I'm currently using (IIci w/built-in video), the device refNum is -49, even though IM says reference numbers range from -1 to -32. Is this significant? Along these lines, I am currently using the alternate screen buffers on the old (compact) macs using the old segment loader techniques (relaunch if I don't have the alternate screen allocated): if (CurPageOption != -1) { GetAppParms(ApplName, &ref, &aHandle); Launch(-1, ApplName); } There are a number of problems with this method. First, relaunching in this manner does not seem to be supported in System 7 or under Multifinder. Second, I can't figure out from inside the program whether or not the program has already been launched. The problem here is that if I'm running under Multifinder or whatever and I cannot get possession of the second screen, the program continues to launch itself, over and over, without notifying the user (or itself) that there has been a problem. I'd like to be able to take some intelligent action if I cannot gain possession of the second screen. Ideas? (In fact, I'd really like to know a way to get at the old Mac alternate screen under Multifinder and System 7. What exactly is preventing it from being used under these systems? Is there a workaround? It would improve the performance of my program by about 20 percent if I could reliably access the alternate screen buffer. And on 68000-based systems, that 20 percent is significant.) Also -- on the SE/30, one does not flip video pages in the same way as it is done on older compact Macs (using the VIA register A, bit 6). Is it done using the video driver SetMode control call? A tech note said in plain English that the SE/30 has two video buffers, but I haven't been able to get at the alternate screen. How is this done? And how is it done on the Classic? Is it the same as the Plus/SE? 3. How do you invalidate the whole screen? Because my program takes over an entire monitor, and because the pallete manager "hard-wires" black and white into the color table (I don't use white), I've resorted to the color manager to set the colors directly for the given device, and after running, I restore the colors which were present prior to running my program. This works fine, but sometimes when the program exits, the text in underlying windows is drawn improperly (white on black -- it seems that something happens to the QuickDraw background/foreground colors). However, if the screen is then blanked using a screen saver and then restored, everything comes back to normal. So, the question is: what can I do to correct this? How does one invalidate the whole screen in the same manner as the screen saver? Anyway, thanks for reading this far. I would truly appreciate some answers to these questions; I've been dealing with these problems for some time now. If there's anyone out there who's knowledgeable about low-level Mac graphics, I'd appreaciate it if they could give me some pointers. David Temkin Center for Machine Intelligence, EDS Corp. davet@cmi.com
jmunkki@hila.hut.fi (Juri Munkki) (04/14/91)
In article <9822@etsu.CMI.COM> davet@cmi.com (David Temkin) writes: >notably the vanilla Mac II, IIx, IIcx (each with the standard video cards) >and the LC, my program produces a distorted image (multiply overlaid >copies of the image, separated horizontally) on the top two-thirds of the >screen, and nothing below it. You are probably assuming that rowBytes is related to the width of the screen. This isn't so. A 640 pixel screen actually has a rowBytes that accomodates 1024 on most Macintosh video cards. 640/1024 probably looks like two thirds of the screen and results in overlaid graphics. > I'm using 24-bit addressing, but even if I >use 32-bit addressing (with SwapMMUMode) the result is the same. You should be using 32-bit addressing no matter what machine you are using. It never hurts and if you fail to use it in the right place, you'll just a crash or something even worse. >have any experience with this? I assume that the 2-bit screen is mapped >essentially like the black and white screen, except that each pixel takes >two bits. Is this not universally true? As I said above, this is not true. Never assume anything. Dig it out from Inside Macintosh. Inside Macintosh says that each row is rowBytes wide, so that's how you have to write software. >2. For some reason, I have been unable to communicate with the video >drivers as specified in Designing Cards and Drivers. I'm interested in >using >the second video page in Macs that have them (apparently Mac IIs and >SE/30s may have them as well as the originals), and to determine whether >such a beast exists, I need to query the video driver using a Status call. I just wrote something that seems to work quite well. I was thinking about doing this with the Sega 3D glasses, so this seemed like a good time to try it out. Project STORM uses a different approach (it plays with color tables). You have to have a valid mode in the mode parameter, so I first get the current mode. You then find out how many pages there are. With MaxAppleZoom, the 16 color mode doesn't allow two pages. This was a surprise, but it also explains why the Oids demo behaves the way it does. You have to remember that video cards are not required to support multiple pages. Most of them just happen to have that capability. Palette animation is a more reliable method of obtaining double buffering. Here's some Think C code that works: #include <video.h> GDHandle Device; CntrlParam VideoParam; VDPageInfo ModeRecord; int NumPages=1; /* At least one page, I assume */ void GetMainInfo() { Device=GetMainDevice(); VideoParam.ioCompletion = 0; VideoParam.ioRefNum = (*Device)->gdRefNum; } int ReadCurrentMode() { int theErr; VDPageInfo ThisModeRecord; *(void **)(&VideoParam.csParam) = &ThisModeRecord; VideoParam.csCode = cscGetMode; theErr = PBStatus(&VideoParam,0); if(theErr) return theErr; ModeRecord = ThisModeRecord; VideoParam.csCode = cscGetPageCnt; theErr = PBStatus(&VideoParam,0); NumPages = ThisModeRecord.csPage; return theErr; } int SetCurrentPage(n) int n; { int theErr; VDPageInfo NewModeRecord; NewModeRecord = ModeRecord; NewModeRecord.csPage = n; *(void **)(&VideoParam.csParam) = &NewModeRecord; VideoParam.csCode = cscSetMode; theErr = PBControl(&VideoParam,0); return theErr; } void main() { int i; long j; GetMainInfo(); ReadCurrentMode(); for(i=0;i<NumPages;i++) { SetCurrentPage(i); Delay(60,&j); } SetCurrentPage(ModeRecord.csPage); } >There are a number of problems with this method. First, relaunching in >this manner does not seem to be supported in System 7 or under >Multifinder. Second, I can't figure out from inside the program whether or >not the program has already been launched. The problem here is that if I'm >running under Multifinder or whatever and I cannot get possession of the >second screen, the program continues to launch itself, over and over, >without notifying the user (or itself) that there has been a problem. I'd >like to be able to take some intelligent action if I cannot gain >possession of the second screen. Ideas? Leave yourself an event that identifies your application. You can put an application specific event in the event queue and look for it at startup. I don't know how well this is supported with System 7.0, but at least I think it should work on anything newer than that. Another way is to use a file to mark your startup. Of course the system folder might be locked... >(In fact, I'd really like to know a way to get at the old Mac alternate >screen under Multifinder and System 7. What exactly is preventing it from >being used under these systems? Is there a workaround? It would improve >the performance of my program by about 20 percent if I could reliably >access the alternate screen buffer. And on 68000-based systems, that 20 >percent is significant.) As far as I know it isn't supported. Just write your program so that it can do without the alternate buffer if it has to and notify the user that there will be a 20% improvement if the game is booted from a disk containing an older system. A boot time init that reserves this RAM area might work. I remember seeing something like this posted on the net a few years ago... >Also -- on the SE/30, one does not flip video pages in the same way as it >is done on older compact Macs (using the VIA register A, bit 6). Is it >done using the video driver SetMode control call? A tech note said in >plain English that the SE/30 has two video buffers, but I haven't been >able to get at the alternate screen. How is this done? And how is it done >on the Classic? Is it the same as the Plus/SE? Try it, now that you have working code. It might work. Let us know if it does. I don't have a machine to try it on. >This works fine, but sometimes when the program exits, the text >in underlying windows is drawn improperly (white on black -- it seems that >something happens to the QuickDraw background/foreground colors). I assume that you are using SetEntries to restore the screen contents. A Develop magazine issue specifically warns about this (it was an article about the palette manager). I haven't had any problems with a pair of SaveEntries and RestoreEntries. Just remember that the color count is not the actual count but the count-1 (I was bitten by that feature). ____________________________________________________________________________ / Juri Munkki / Helsinki University of Technology / Wind / Project / / jmunkki@hut.fi / Computing Center Macintosh Support / Surf / STORM / ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
deadman@garnet.berkeley.edu (Ben Haller) (04/21/91)
In article <1991Apr14.011556.23504@santra.uucp> jmunkki@hila.hut.fi (Juri Munkki) writes: >In article <9822@etsu.CMI.COM> davet@cmi.com (David Temkin) writes: >> I'm using 24-bit addressing, but even if I >>use 32-bit addressing (with SwapMMUMode) the result is the same. > >You should be using 32-bit addressing no matter what machine you are >using. It never hurts and if you fail to use it in the right place, >you'll just a crash or something even worse. Wrong. Switching processor modes is slow, because the SwapMMUMode routine is slow. So you only want to call it if you have to. People with 24-bit boards tend to be people with fast machines, so they can afford the call, whereas people with vanilla Mac IIs (or an LC, even worse) haven't got much processor to spare, and probably don't have 24-bit boards. >>have any experience with this? I assume that the 2-bit screen is mapped >>essentially like the black and white screen, except that each pixel takes >>two bits. Is this not universally true? > >As I said above, this is not true. Never assume anything. Dig it out from >Inside Macintosh. Inside Macintosh says that each row is rowBytes wide, so >that's how you have to write software. Um, he was asking about 2-bit graphics, not about rowBytes. In answer, yes, in two-bit mode each pixels takes two consecutive bits, and is otherwise mapped the same as in 1-bit mode. This may not be true in the future, but it's true now. >>This works fine, but sometimes when the program exits, the text >>in underlying windows is drawn improperly (white on black -- it seems that >>something happens to the QuickDraw background/foreground colors). > >I assume that you are using SetEntries to restore the screen contents. >A Develop magazine issue specifically warns about this (it was an article >about the palette manager). I haven't had any problems with a pair of >SaveEntries and RestoreEntries. Just remember that the color count is >not the actual count but the count-1 (I was bitten by that feature). Interesting. Could you give a more specific reference? Is there a TN on this, or is this Develop article the only reference? I've been having a fair bit of trouble with QuickDraw's color matching scheme lately, and I'm pretty sure I've found some outright bugs, so I'd like to see this article. -Ben Haller (deadman@garnet.berkeley.edu) "Wave after wave, each mightier than the last 'Til last, a ninth one, gathering half the deep And full of voices, slowly rose and plunged Roaring, and all the wave was in a flame" -Tennyson, "The Coming of Arthur"
jmunkki@hila.hut.fi (Juri Munkki) (04/21/91)
In article <1991Apr20.200229.805@agate.berkeley.edu> deadman@garnet.berkeley.edu (Ben Haller) writes: >In article <1991Apr14.011556.23504@santra.uucp> jmunkki@hila.hut.fi (Juri Munkki) writes: >>> I'm using 24-bit addressing, but even if I >>>use 32-bit addressing (with SwapMMUMode) the result is the same. >> >>You should be using 32-bit addressing no matter what machine you are >>using. It never hurts and if you fail to use it in the right place, >>you'll just a crash or something even worse. > >Wrong. Switching processor modes is slow, because the SwapMMUMode routine >is slow. So you only want to call it if you have to. People with 24-bit >boards tend to be people with fast machines, so they can afford the call, >whereas people with vanilla Mac IIs (or an LC, even worse) haven't got much >processor to spare, and probably don't have 24-bit boards. Assuming that you group all your drawing between two calls to SwapMMUMode, the overhead is not noticeable. Of course, I was just giving my opinion and you are quite free to disagree. I just dropped into TMON to look at the ROM code from SwapMMUMode and it's 27 assembly instructions long. Of course there's the overhead from the trap dispatcher that you might be worried about. If you would like to be useful, how about showing us how to find out which cards need the call to SwapMMUMode? I have no idea how this could be done unless one has full documentation for 32 bit QD. Usually when people try to find out about machine features that they really do not need to know about, they end up shooting themselves in the foot. Just think of all those programs that checked for a Mac II and failed to work if they were run on a IIx. I spent a few hours fixing their code with TMON to prove my clients that a Mac IIx really was compatible with the software. >>In article <9822@etsu.CMI.COM> davet@cmi.com (David Temkin) writes: >>>have any experience with this? I assume that the 2-bit screen is mapped >>>essentially like the black and white screen, except that each pixel takes >>>two bits. Is this not universally true? >> >>As I said above, this is not true. Never assume anything. Dig it out from >>Inside Macintosh. Inside Macintosh says that each row is rowBytes wide, so >>that's how you have to write software. > >Um, he was asking about 2-bit graphics, not about rowBytes. In answer, >yes, in two-bit mode each pixels takes two consecutive bits, and is >otherwise mapped the same as in 1-bit mode. This may not be true in >the future, but it's true now. Actually what I said fixed the problem. David contacted me with E-mail to thank for solving the problems he had problems with. He really did assume that with a 640 pixel wide screen the rowBytes value would be something like 160. If you read the symptoms that he wrote about, you'll see why I answered the way I did. [The above quote from David isn't complete and as such is slightly misleading.] >>I assume that you are using SetEntries to restore the screen contents. >>A Develop magazine issue specifically warns about this (it was an article >>about the palette manager). I haven't had any problems with a pair of >>SaveEntries and RestoreEntries. Just remember that the color count is >>not the actual count but the count-1 (I was bitten by that feature). > >Interesting. Could you give a more specific reference? Is there a TN on >this, or is this Develop article the only reference? I've been having a >fair bit of trouble with QuickDraw's color matching scheme lately, and >I'm pretty sure I've found some outright bugs, so I'd like to see this >article. Develop, volume 2, issue 1, Palette Manager Animation, by Rich Collyer. ____________________________________________________________________________ / Juri Munkki / Helsinki University of Technology / Wind / Project / / jmunkki@hut.fi / Computing Center Macintosh Support / Surf / STORM / ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
deadman@garnet.berkeley.edu (Ben Haller) (04/28/91)
In article <1991Apr21.073551.14802@santra.uucp> jmunkki@hila.hut.fi (Juri Munkki) writes: >In article <1991Apr20.200229.805@agate.berkeley.edu> deadman@garnet.berkeley.edu (Ben Haller) writes: >>Wrong. Switching processor modes is slow, because the SwapMMUMode routine >>is slow. So you only want to call it if you have to. > >If you would like to be useful, how about showing us how to find out which >cards need the call to SwapMMUMode? I have no idea how this could be done >unless one has full documentation for 32 bit QD. > >Usually when people try to find out about machine features that they really >do not need to know about, they end up shooting themselves in the foot. OK, I'll bite. First you check if color QuickDraw is available. This can be done like: SysEnvRec worldRec; SysEnvirons(1, &worldRec); if (worldRec.hasColorQD) ...CQD is available... else ...CQD is not available... If CQD is available, then you should find out monitor information from the GDevice list, check for 32-Bit QuickDraw, etc. If it's not, then you may find out the monitor information from screenBits and GrayRgn, and you need not check for 32-Bit QuickDraw, swap MMU modes, etc. - all that is guaranteed not to be necessary. So, the next step is checking for 32-Bit QuickDraw. This can be done as follows: #define QD32Trap 0xAB03 #define UnImplTrap 0xA89F if (NGetTrapAddress(QD32Trap, ToolTrap) != NGetTrapAddress(UnImplTrap, ToolTrap)) ...32-Bit QD is available... else ...32-Bit QD is not available... If 32-Bit CQD is available, then you need to check whether you should swap MMU modes or not. If 32-Bit CQD is not available, then you never need to swap the MMU. So the next step is, given that 32-Bit CQD is available, how do you check whether you need to swap the MMU for a given PixMap? I haven't done this yet (I'll be doing it when I get around to the next revision of Solarian II). I believe there is a call in the 32-Bit QuickDraw suite that tells you whether a given PixMap needs to be swapped. But I don't think that's strictly necessary. What I would do is get the base address from the GDevice's PixMap (it *must* be the GDevice's, other PixMaps will probably have the main GDevice's baseAddr, or may even have 0 if I recall correctly). Then do the following comparison: if ((long)baseAddr != StripAddress(baseAddr)) ...need to swap the MMU to write directly to the screen... else ...don't need to swap the MMU... I'm providing this information because it was requested. I do not vouch for it's complete accuracy (such as on strange third-party color monitors for the Plus or SE that hack into QuickDraw in strange ways, etc.) Also, Apple may be recommending other ways of checking for some of these things nowadays, in particular there may be Gestalt calls that Apple recommends using instead of SysEnvirons and comparing trap addresses. But I really doubt that Apple will break these method of checking, since may programs use them. On a slightly different note, I keep posting things like this relating to going direct to screen. I hope someone somewhere is keeping these posts for future integration into a UMPG-type thing, or a FAQ post. I spend a lot of time telling people how to go direct to screen. It's a popular topic. -Ben Haller (deadman@garnet.berkeley.edu) "Soy el galan de las penas Llorando Sin compasion." - David Byrne
mxmora@unix.SRI.COM (Matt Mora) (05/02/91)
In article <1991Apr27.193509.19020@agate.berkeley.edu> deadman@garnet.berkeley.edu (Ben Haller) writes: > On a slightly different note, I keep posting things like this relating to >going direct to screen. I hope someone somewhere is keeping these posts >for future integration into a UMPG-type thing, or a FAQ post. I spend a >lot of time telling people how to go direct to screen. It's a popular >topic. Don't worry, I got it all. It will be in volume II of the UMPG. By the way, how about posting (or mail it to me so I can include it in the UMPG) some of the actual direct to screen drawing code you have. Or is it only available for a nominal fee? I know you mentioned something about your sorce code was for sale for $25. >-Ben Haller (deadman@garnet.berkeley.edu) -- ___________________________________________________________ Matthew Mora | my Mac Matt_Mora@sri.com SRI International | my unix mxmora@unix.sri.com ___________________________________________________________
deadman@garnet.berkeley.edu (Ben Haller) (05/05/91)
In article <23841@unix.SRI.COM> mxmora@unix.sri.com (Matt Mora) writes: (in what perhaps should have been a personal letter, but since it wasn't I'll reply...since everybody else keeps asking me too... :-> ) >how about posting (or mail it to me so I can include it in the UMPG) >some of the actual direct to screen drawing code you have. >Or is it only available for a nominal fee? I know you mentioned something >about your sorce code was for sale for $25. The only program I've done so far that's available as shareware (and, therefore, that source could conceivably be available for) that does direct to screen drawing is Solarian II, and in fact the source to that is not available. However, this is dodging the question. In actuality, I don't post actual code because of a few reasons: o I would have to write the code, since Solarian II's code is not acceptable for general distribution, being poorly written and uncommented in large measure. o I would have to deal with all the questions and such that my post would generate (like I don't already... :-> ) o Most of all, I feel that direct to screen stuff is very touchy, and should not be attempted by people who don't know a lot about Color QuickDraw, GDevices, the cursor handling, etc. Anyone who can't write code based on the (fairly explicit) hints that I give shouldn't be anywhere *near* doing direct to screen stuff, IMHO. o A final reason: the point of writing direct to screen code is either to implement functionality that QuickDraw simply *cannot* do, which is very rare and very complex (since QD does everything easy...), or is to achieve significant speedups over using QuickDraw. To achieve a significant speedup, one needs to write fairly optimized assembly that is specifically geared towards the imaging being done. Any post I might do would be almost useless for anything beyond the (reasonably simple) details of how to set a pixel to a color without QuickDraw. This isn't a major point, since most people are stuck at the how-to-write-to-screen-memory-safely stage, but it is a minor point. -Ben Haller (deadman@garnet.berkeley.edu) "Jamaica...Afriki..." - Alpha Blondy It's fascinating the mundane things that pass for song lyrics... or .sigs...