home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-05-01 | 21.1 KB | 385 lines | [TEXT/MPS ] |
- ---------------------------------------------------------------------------------------------------
-
- FracApp 2.0
- for MacApp® 2.0
- -----------
- By Keith Rollin & Bo3b Johnson
- of Macintosh Developer Technical Support
-
- This is a not too small application which can calculate a fractal in full color
- on the Mac II, using direct 881 code for speed. It saves files on disk as PICT.
- This version specifically is set up to be fully compatible, and does not
- support color table animation when not using 32-Bit Color QuickDraw.
-
-
- Files: FracApp.MAMake
- FracApp.r
- GoFigger.a
- MFracApp.p
- Read Me
- UAreaSelector.inc1.p
- UAreaSelector.p
- UFracApp.inc1.p
- UFracApp.p
- UOffScreen.inc1.p
- UOffScreen.p
- URectStack.inc1.p
- URectStack.p
-
- ---------------------------------------------------------------------------------------------------
- The first time, build with:
-
- MABuild -NeedsColorQD -NeedsFPU [-NeedsMC68020] FracApp -AutoBuild
-
- After the first time, MacApp will be properly built, so you can take out the “-AutoBuild”
-
- MABuild -NeedsColorQD -NeedsFPU [-NeedsMC68020] FracApp
-
- ---------------------------------------------------------------------------------------------------
-
- Features that FracApp demonstrates (or, “Why is it so damn big?”):
-
- Features of FracApp 1.0
- - Complete MacApp 1.1.1 application
- - Demostrated speed gains using direct 881 code
- - Calculated the fractal in the background
- - Printing at 300 dpi (FracApp 300)
- - Use of the Color Manager
- - Use of the Palette Manager
- - Drawing to offscreen PixMap and GDevice
- - Saving file as PICT
- - Replacing QuickDraw bottlenecks to reduce memory hit when read or writing files
- - MultiFinder friendly
- - Color Table animation
- - Custom mouse tracking when etching a selection rectangle
- - Create a new document from the current selection
- - Batch mode - creating multiple documents in succession, saving each one
-
- New with FracApp 2.0
- - Uses MacApp 2.0.
- - Broken out into multiple files.
- - Uses new 32 bit Color QuickDraw offscreen routines.
- - Palette animation courtesy of 32 bit Color QuickDraw.
- - Implements faster algorithm for figuring Mandelbrot fractals
- (Mariani/Silver method).
- - Shows use of new TDynamicArray class.
- - Uses new document structure (TFracAppDocument <- TPICTDocument <- TDocument).
- - Fractal calculations broken into their own engine classes.
- - Faster core routine to figure pixel colors. Should be fairly optimized for 68882.
- - Created new TOffscreen class for handling different offscreen techniques.
- - Cleaned up “Unsafe use of an object field as a var or > 4 byte parameter” errors.
- - Added Time manager routines for arbitrating calculation time.
- - Document preference for idle time calculations now works in a front-to-back
- order, rather than all documents being given time simultaneously.
- - Added info bar to show elapsed time and algorithm name.
- - Added scrollbar info tile to show percentage of fractal complete.
- - Uses new header data format, so we use a different version number in header.
-
-
- Where does it fit:
- This is a series of sample programs for those doing development
- using Color QuickDraw. Since the whole color problem depends
- upon the exact effect desired, there are a number of answers
- to how to use colors, from the simple to the radically complex.
- These programs try to cover the gamut, so you should use
- which ever seems appropriate. In most cases, use the simplest
- one that will give the desired results. The compatibility
- rating is from 0..9 where low is better. The more known risks
- there are the higher the rating.
-
-
- The programs (in order of compatibility):
-
- SillyBalls: (SC.003)
- This is the simplest use of Color QuickDraw, and does
- not use the Palette Manager. It draws randomly colored
- balls in a color window. This is intended to give you
- the absolute minimum required to get color on the screen.
- Written in straight Pascal code.
- Compatibility rating = 0, no known risks.
-
- FracAppPalette: (SC.008)
- This is a version of FracApp that uses only the Palette
- Manager. It does not support color table animation
- since that part of the Palette Manager is not sufficient.
- The program demonstrates a full color palette that is
- used to display the Mandelbrot set. It uses an offscreen
- gDevice w/ Port to handle the data, using CopyBits to
- draw to the window. The Palette is automatically
- associated with each window. The PICT files are read
- and written using the bottlenecks, to save on memory
- usage.
- Written in MacApp Object Pascal code.
- Compatibility rating = 0, no known risks.
-
- TubeTest: (SC.004)
- This is a small demo program that demonstrates using the
- Palette Manager for color table animation. It uses a
- color palette with animating entries, and draws using the
- Palette Manager. There are two circles of animating colors
- which gives a flowing tube effect. This is a valid case
- for using the animating colors aspect of the Palette Manager,
- since the image is being drawn directly.
- Written in straight Pascal code.
- Compatibility rating = 0, no known risks.
-
- FracApp: (SC.007)
- This is the ‘commercial quality’ version of FracApp. This
- version supports color table animation, using an offscreen
- gDevice w/ Port, and handles multiple documents. The
- CopyBits updates to the screen are as fast as possible. The
- program does not use the Palette Manager, except to
- provide for the system palette, or color modes with less than
- 255 colors. For color table animation using an offscreen
- gDevice w/ Port, it uses the Color Manager and handles the
- colors itself. Strict compatibility was relaxed to allow for
- a higher performance program. This is the most ‘real’ of the
- sample programs.
- Written in MacApp Object Pascal code.
- Compatibility rating = 2. (nothing will break, but it may not
- always look correct.)
-
- FracApp300: (SC.009)
- This doesn’t support colors, but demonstrates how to create and
- use a 300 dpi bitmap w/ Port. The bitmap is printed at full
- resolution on LaserWriters, and clipped on other printers (but
- they still print). It demonstrates how to use a high resolution
- image as a PICT file, and how to print them out.
- Written in MacApp Object Pascal code.
- Compatibility rating = 1. (The use of PrGeneral is slightly
- out of the ordinary, although supported.)
-
- FracApp 2.0: (SC.02x)
- Re-organized to use MacApp 2.0. Is pretty much based on FracApp
- Palette for compatibility, but takes advantage of 32-Bit Color
- QuickDraw features where possible to perform the same effects
- that are available in FracApp 1.0.
- Written in MacApp Object Pascal code.
- Compatibility rating = 1. (Direct slamming of ctFlags and hand
- rolled GetCPixel are questionable.)
-
-
- Reasons for this version of reality (the strategy):
-
- The main idea behind this program is to allow you to create and fool around
- with the Mandelbrot set, using this number cruncher wizzo computer we got here.
- While we are making these documents, we also throw in a couple of special
- effects to make it more fun, like the special color mapping. This program is
- specifically intended to be a sample program, and as such takes no
- compatibility risks. This means that while it is not the highest performance,
- it is the safest. Like all real programs, some people will like it and some
- people will hate it. I hope you like it, but if you don’t, send me some mail
- telling me why.
-
- The original version of this program did not support color table animation, even
- though this was one of the most interesting effects. The Palette Manager was
- not sufficient to perform the color table animation for multiple documents, so
- for that version it was removed. With 32-Bit Color QuickDraw, intelligent
- Palette Manager animation is possible, and so I put it in.
-
- The overall structure of the program starts with the TFracAppApplication
- object. This guy descends from TApplication, and is responsible for creating
- new documents and giving them idle time for them to do their stuff. When giving
- documents time to idle and calculate themselves, TFracAppApplication keeps
- track of which ones are finished that might also be part of a multi-doccing
- sequence. This is where you can launch a series of documents in series, each
- one calculating itself and then being saved to disk. This is great for putting
- your Macintosh to useful purpose at night. When one of these documents is
- done, TFracAppApplication takes care of saving and closing it, and then
- creating and starting the next one.
-
- TFracAppApplication also takes care of the Windows menu. Because each window
- tends to take up most of the screen real estate, it was handy to add a Windows
- menu so that we can easily get to the ones that are hidden. When a new window
- is created it tells the TFracAppApplication that it is about to show itself.
- Similarly, when the window is about to be closed, it also informs the
- TFracAppApplication. The TFracAppApplication object keeps a list of the windows
- in the order in which they appeared. This way, it can make a Windows menu that
- contains the name of the oldest windows at top, and the newest windows at the
- bottom. It does all this by overriding DoSetupMenus. If necessary, it tears
- down the old menu and builds up a new one. It then enables all the menu items,
- and puts a check mark by the one that belongs to the topmost window. When one
- of those menu items is selected, it is brought to the front.
-
- The major unit of information in FracApp is the TFracAppDocument. Each of these
- is responsible for maintaining all information relating to a specific fractal. It
- keeps track of the data that appears on the screen, the amount of the fractal that
- has been calculated so far, and has methods for saving to and writing from disk. To
- do all this, TFracAppDocument gets helps from some friends. It has a TOffscreen
- object for managing the offscreen stuff, and TFracAppEngine that does the
- actual fractal calculations, and a TFracAppView for displaying.
-
- For the actual handling of data we use a TOffScreen object. This object is
- responsible for managing the offscreen environment, swapping it in and out as
- necessary. TOffscreen objects come in two flavors: TOldGrossOffscreen, and
- TNewCoolOffscreen. The former is based on all the offscreen handling routines
- that FracApp 1.0 used; it builds everything up by hand. This means bulding up
- an offscreen GDevice, initializing all the right fields, adding color tables,
- attaching a color offscreen GrafPort, making sure it’s got all the right
- memory, etc. A real drag. The new way of doing this is with the offscreen
- handling routines provided by 32-Bit Color QuickDraw. These routines will be
- used if a) we’ve got them, and b) the user has specified that we want them by
- selecting the right menu option. By default, if we’ve got ‘em, we use ‘em.
-
- For viewing the data, we have a TFracAppView. This just CopyBits the data as
- needed, and maintains the current selection (if any).
-
- Finally, we have a TFracAppEngine which is used to do the actual fractal
- calculations. TFracAppEngines also come in two sizes: TNormalFracAppEngine and
- TFastFracAppEngine. Again, the former is based on FracApp 1.0, where we
- calculate each and every pixel one by one. This is OK for complex documents
- (i.e., ones with lots of different colors all over the place), but we can make
- an enhancement for documents that have large blocks of the same color. The
- TFastFracAppEngine uses a recursive technique of dividing the document into
- four parts, and then examining each part. If the colors of the pixels on the
- border of the area we are looking at are all the same, then we assume that all
- of the interior colors are the same as well. If so, we then just blast all the
- pixels with a large PaintRect call. If not, then we divide THAT area into 4
- parts, and perform the process again. If the rectangles start to get really
- small (less than 4 pixels on a side), then I just fill it all in by hand, a
- pixel at a time. This takes care of not losing fine detail. This stategy was
- pointed out by Arthur Britto, and is called the Mariani/Silver algorithm.
-
- The fractal calculation is done by the CalcCity routine of the FracAppEngine.
- The TApplication object gets the DoIdle call, and it finds a document that
- needs some time for its calculations. Once it finds one, it calls the engine
- for that document. That engine is given a small amount of time to do its stuff,
- and then returns to the DoIdle method of TFracAppApplication. In this program,
- a lot of pain was taken to make sure that we didn’t hog all the foreground
- time, and made the application as responsible as possible. When in the
- foreground the fractal engine takes about 50 milliseconds before relinquishing
- control. While in the background, the engine only gets a millisecond, tops.
- When running in Non-Debug mode, we use the Time Manager to make sure that
- everyone is given their fair share of time. If we are running in Debug mode, we
- base our calcuations on TickCount, as the Time Manager may not be available to
- us (the VIAs might be in use by the Performance Tools).
-
- When we set up the offscreen gDevice, we set it up using a 3 bit iTable to save
- on memory that isn’t used. We would use a larger iTable if we were going to be
- doing a lot of color mapping and wanted to stay away from the more extensive
- color searching Color QuickDraw needs to do with smaller color tables. However,
- most of the time is spent in the TFracAppEngine core loop that figures out the
- color a certain pixel should be. By comparison, we spend very little time
- having the color manager do color matching, so 3 bits is OK.
-
- When a document is saved the color table from the offscreen gDevice is saved
- along with it. This is the clut resource that is used uniformly throughout the
- program. When we save the document, we have to make sure that we clear bit 14
- of the ctFlags. This bit is the one that allows us to do the fancy QuickDraw
- color matching that lets us do palette animation. However, we DON’T want to do
- this matching when we read the document back in so we have to make sure that
- bit is cleared on the disk.
-
- If you hate my choice of colors, you can change the clut to something else and
- all should work the same (except old documents will map into something else).
-
- Another goal of course was to get this thing done. A goal that tends to slide
- away as more things are added to the program, so in true Macintosh style, even
- the 2.0 version of the program is somewhat limited, and may not be fully
- debugged. Some things specifically left out: printing the documents to a
- LaserWriter with grey scales instead, using temporary documents to make the
- program crashless (so you can start up where you left off, saving the
- computation it took to get there), an option to make the ‘pen’ size bigger so
- you can do a low-res fractal to begin with, the ability to read in old document
- formats and convert them to newer ones. These things are all admirable features
- to add, but you have to finish sometime, so this was it. These other things
- will be added if possible.
-
- I am aware of the fact that this program does not really calculate Fractals.
- Actually it calculates and displays the Mandelbrot set which is not
- self-similar so it cannot really be called a fractal. It is distressing to add
- to the confusion as to what fractals are, but it is too late. For more
- information on Fractals and the Mandelbrot set (no umlaut on the o), you could
- see Mandelbrot’s book ‘The Fractal Geometry of Nature’, but it is pretty
- mathematical and not all that helpful. A better source is the Peitgen-Richter
- book ‘The Beauty of Fractals’, which has a do it yourself section in the back.
-
- The program is structured primarily around the document, even though the
- document hardly does any work itself. It relies on the reading and writing of
- its base class, TPICTDocument, and the objects that it creates for support
- (TFracAppEngine and TOffscreen).
-
- Originally, the TFracAppDocument itself was the superclass of two other
- classes: TNormalFracAppDocument and TFastFracAppDocument. All of the routines
- that performed the calculations were stored in these classes. However, I had a
- hard time figuring which one to instantiate when reading in a saved document.
- All of my documents are stored as PICT files, so that any application can read
- them in. However, there are really two different flavors of document, depending
- on what algorithm I am using. The specific data needed for each algorithm is
- stored in the user data area of the PICT file (the first 512 bytes). This means
- that I don’t know what algorithm to use, and hence what kind of document to
- create, until I open up the file and look at some bytes in the header. On the
- other hand, I can’t read from the file until I have created a document! Bummer.
- The solution was to break out all of the differences between the two documents
- and encapsulate them into their own objects. These objects can then be
- instantiated by the document after it’s had a chance to open the file and take
- a peek inside.
-
- For the zoom operation, there was no really great way to handle the new
- document case based on another document. This is a little strange to be doing,
- and the structure of MacApp was such that we couldn’t get to the data desired
- at the right time. The logical place to put it in at DoMakeDocument was too
- early to have the gDevice allocated and ready to start more stuff. The problem
- was resolved by using global variables to transmit the information to the other
- piece of the program that might need it. Essentially DoInitialState decides if
- this is a brand new base level document or a zoom in based on the state of the
- global variables.
-
- The MacApp memory management approach is used as well. The big pieces used by
- the Documents come out of permanent memory, helping to avoid a crash from no
- memory. When we allocate something that will be thrown away immediately, it of
- course comes out of normal (temporary) memory. We did not do a full blown
- memory analysis of the program since it is such a memory hog anyway. The mem!
- resource is set up in a form that is roughly close (a bit high) without trying
- to be extra accurate. When a document takes 500K of RAM to open it hardly
- seems relevant to make sure the mem! is accurate to 2K. Because of this
- somewhat cavalier approach you may not be able to open a document in a few
- cases where you really should be able to. The mem! in use of 60K is close with
- a +2K/-10K error on how big it should really be.
-
- The QuickDraw BottleNecks are used to both read and write the actual fractal
- data from/to the disk. This is done since the data in the document may be very
- large (100K) and if we just spool the data from the file we don’t actually have
- to use that extra hunk of memory. We have to read the data anyway, so we go
- ahead and just read it in as we play it back. As it is played back it goes into
- the offscreen gDevice’s pixMap, so we have the data to display. Having no
- memory hit for the document is a big win. When writing the data, the same thing
- is true so we don’t have to have a huge handle to hold the picture data itself.
- We also avoid the problem of not having enough memory to create the picture in
- the first place, making a document unsaveable. That is particularly annoying,
- and is easy to avoid using the spooling approach. The drawback here is that
- the spooling process slows down opening and closing documents rather severely,
- since it breaks up a long read/write operation into hundreds of small ones.
-
- With thanks to Guillermo Ortiz and Jon Zap for their Color QuickDraw advice; to
- Rich Collyer for helping me with the 68882 routines; to Arthur Britto at OMI
- for suggesting the Mariani/Silver algorithm; to Steve Friedrich for his
- suggestions on mapping one file type to two document classes; and to Bo3b
- Johnson for writing FracApp 1.0, and who had the following thanks in FracApp
- 1.0:
-
- With thanks to Rick (nee Skippy) Blair for the discussions of color QuickDraw
- and the Palette Manager. Thanks to Darin Adler for further discussion of the
- Palette Manager and for good suggestions on making it more MacApp friendly.
-
- Special thanks to Darin Adler, Mary Boetcher, Chris Knepper, Andy Shebanow,
- Bo3b Johnson, and Dave Wilson for reviewing version 2.0 of this program for me.
-
-
-
- The following is a list of features or bug fixes that could be added to the program:
-
- *** Make it run crashless using temp documents to store partial fractals.
- *** Override TWindow.Draw so we can avoid the EraseRect on updates.
- *** Draw selection rect in offscreen, copy up to screen for flicker free selection.
- *** Crash on 3 monitor system during window drag (don’t know if this is still true).
- *** Could set the bytes directly in offscreen PixMap, skip using PaintRect.
- *** Copy up from small picture up to big screen gets garbage, src rect too big?
- *** Allow a way to Zoom in using coordinates.
- *** Allow the user to set the colors used in display.
- *** Bigger penSize for fast, lo-res fractals. Allow user to set size of pen.
- *** Add in full support for different dpi settings.
- *** Set Calc Rect to size of printer page.
- *** Read in and convert old (FracApp 1.0) documents.
- *** Some things for the reader to do to modify the program.
-