home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Essentials / Developer Essentials Nov 90 / DTS Sample Code / Macintosh Sample Code / SC.023.FracApp 2.0 / Read Me < prev    next >
Encoding:
Text File  |  1990-05-01  |  21.1 KB  |  385 lines  |  [TEXT/MPS ]

  1. ---------------------------------------------------------------------------------------------------
  2.  
  3.                                     FracApp 2.0
  4.                                   for MacApp® 2.0
  5.                                     -----------
  6.                             By Keith Rollin & Bo3b Johnson
  7.                         of Macintosh Developer Technical Support
  8.  
  9.         This is a not too small application which can calculate a fractal in full color
  10.         on the Mac II, using direct 881 code for speed. It saves files on disk as PICT.
  11.         This version specifically is set up to be fully compatible, and does not
  12.         support color table animation when not using 32-Bit Color QuickDraw.
  13.  
  14.  
  15.         Files:                FracApp.MAMake
  16.                             FracApp.r
  17.                             GoFigger.a
  18.                             MFracApp.p
  19.                             Read Me
  20.                             UAreaSelector.inc1.p
  21.                             UAreaSelector.p
  22.                             UFracApp.inc1.p
  23.                             UFracApp.p
  24.                             UOffScreen.inc1.p
  25.                             UOffScreen.p
  26.                             URectStack.inc1.p
  27.                             URectStack.p
  28.  
  29. ---------------------------------------------------------------------------------------------------
  30. The first time, build with:
  31.  
  32.     MABuild -NeedsColorQD -NeedsFPU [-NeedsMC68020] FracApp -AutoBuild
  33.  
  34. After the first time, MacApp will be properly built, so you can take out the “-AutoBuild”
  35.  
  36.     MABuild -NeedsColorQD -NeedsFPU [-NeedsMC68020] FracApp
  37.  
  38. ---------------------------------------------------------------------------------------------------
  39.  
  40. Features that FracApp demonstrates (or, “Why is it so damn big?”):
  41.  
  42.     Features of FracApp 1.0
  43.         - Complete MacApp 1.1.1 application
  44.         - Demostrated speed gains using direct 881 code
  45.         - Calculated the fractal in the background
  46.         - Printing at 300 dpi (FracApp 300)
  47.         - Use of the Color Manager
  48.         - Use of the Palette Manager
  49.         - Drawing to offscreen PixMap and GDevice
  50.         - Saving file as PICT
  51.         - Replacing QuickDraw bottlenecks to reduce memory hit when read or writing files
  52.         - MultiFinder friendly
  53.         - Color Table animation
  54.         - Custom mouse tracking when etching a selection rectangle
  55.         - Create a new document from the current selection
  56.         - Batch mode - creating multiple documents in succession, saving each one
  57.  
  58.     New with FracApp 2.0
  59.         - Uses MacApp 2.0.
  60.         - Broken out into multiple files.
  61.         - Uses new 32 bit Color QuickDraw offscreen routines.
  62.         - Palette animation courtesy of 32 bit Color QuickDraw.
  63.         - Implements faster algorithm for figuring Mandelbrot fractals
  64.             (Mariani/Silver method).
  65.         - Shows use of new TDynamicArray class.
  66.         - Uses new document structure (TFracAppDocument <- TPICTDocument <- TDocument).
  67.         - Fractal calculations broken into their own engine classes.
  68.         - Faster core routine to figure pixel colors. Should be fairly optimized for 68882.
  69.         - Created new TOffscreen class for handling different offscreen techniques.
  70.         - Cleaned up “Unsafe use of an object field as a var or > 4 byte parameter” errors.
  71.         - Added Time manager routines for arbitrating calculation time.
  72.         - Document preference for idle time calculations now works in a front-to-back
  73.             order, rather than all documents being given time simultaneously.
  74.         - Added info bar to show elapsed time and algorithm name.
  75.         - Added scrollbar info tile to show percentage of fractal complete.
  76.         - Uses new header data format, so we use a different version number in header.
  77.  
  78.  
  79. Where does it fit:
  80.     This is a series of sample programs for those doing development
  81.     using Color QuickDraw.  Since the whole color problem depends
  82.     upon the exact effect desired, there are a number of answers
  83.     to how to use colors, from the simple to the radically complex.
  84.     These programs try to cover the gamut, so you should use
  85.     which ever seems appropriate.  In most cases, use the simplest
  86.     one that will give the desired results.  The compatibility
  87.     rating is from 0..9 where low is better.  The more known risks
  88.     there are the higher the rating.
  89.  
  90.  
  91.     The programs (in order of compatibility):
  92.  
  93.         SillyBalls: (SC.003)
  94.             This is the simplest use of Color QuickDraw, and does
  95.             not use the Palette Manager.  It draws randomly colored
  96.             balls in a color window.  This is intended to give you
  97.             the absolute minimum required to get color on the screen.
  98.             Written in straight Pascal code.
  99.             Compatibility rating = 0, no known risks.
  100.  
  101.         FracAppPalette:    (SC.008)
  102.             This is a version of FracApp that uses only the Palette
  103.             Manager.  It does not support color table animation
  104.             since that part of the Palette Manager is not sufficient.
  105.             The program demonstrates a full color palette that is
  106.             used to display the Mandelbrot set.  It uses an offscreen
  107.             gDevice w/ Port to handle the data, using CopyBits to
  108.             draw to the window.  The Palette is automatically
  109.             associated with each window.  The PICT files are read
  110.             and written using the bottlenecks, to save on memory
  111.             usage.
  112.             Written in MacApp Object Pascal code.
  113.             Compatibility rating = 0, no known risks.
  114.  
  115.         TubeTest: (SC.004)
  116.             This is a small demo program that demonstrates using the
  117.             Palette Manager for color table animation.  It uses a
  118.             color palette with animating entries, and draws using the
  119.             Palette Manager.  There are two circles of animating colors
  120.             which gives a flowing tube effect.  This is a valid case
  121.             for using the animating colors aspect of the Palette Manager,
  122.             since the image is being drawn directly.
  123.             Written in straight Pascal code.
  124.             Compatibility rating = 0, no known risks.
  125.  
  126.         FracApp: (SC.007)
  127.             This is the ‘commercial quality’ version of FracApp.  This
  128.             version supports color table animation, using an offscreen
  129.             gDevice w/ Port, and handles multiple documents.  The
  130.             CopyBits updates to the screen are as fast as possible.  The
  131.             program does not use the Palette Manager, except to
  132.             provide for the system palette, or color modes with less than
  133.             255 colors.  For color table animation using an offscreen
  134.             gDevice w/ Port, it uses the Color Manager and handles the
  135.             colors itself.  Strict compatibility was relaxed to allow for
  136.             a higher performance program.  This is the most ‘real’ of the
  137.             sample programs.
  138.             Written in MacApp Object Pascal code.
  139.             Compatibility rating = 2.  (nothing will break, but it may not
  140.                 always look correct.)
  141.  
  142.         FracApp300: (SC.009)
  143.             This doesn’t support colors, but demonstrates how to create and
  144.             use a 300 dpi bitmap w/ Port.  The bitmap is printed at full
  145.             resolution on LaserWriters, and clipped on other printers (but
  146.             they still print).  It demonstrates how to use a high resolution
  147.             image as a PICT file, and how to print them out.
  148.             Written in MacApp Object Pascal code.
  149.             Compatibility rating = 1.  (The use of PrGeneral is slightly
  150.                 out of the ordinary, although supported.)
  151.  
  152.         FracApp 2.0: (SC.02x)
  153.             Re-organized to use MacApp 2.0. Is pretty much based on FracApp
  154.             Palette for compatibility, but takes advantage of 32-Bit Color
  155.             QuickDraw features where possible to perform the same effects
  156.             that are available in FracApp 1.0.
  157.             Written in MacApp Object Pascal code.
  158.             Compatibility rating = 1.  (Direct slamming of ctFlags and hand
  159.                 rolled GetCPixel are questionable.)
  160.  
  161.  
  162. Reasons for this version of reality (the strategy):
  163.  
  164.     The main idea behind this program is to allow you to create and fool around
  165.     with the Mandelbrot set, using this number cruncher wizzo computer we got here.
  166.     While we are making these documents, we also throw in a couple of special
  167.     effects to make it more fun, like the special color mapping. This program is
  168.     specifically intended to be a sample program, and as such takes no
  169.     compatibility risks.  This means that while it is not the highest performance,
  170.     it is the safest.  Like all real programs, some people will like it and some
  171.     people will hate it.  I hope you like it, but if you don’t, send me some mail
  172.     telling me why.
  173.  
  174.     The original version of this program did not support color table animation, even
  175.     though this was one of the most interesting effects.  The Palette Manager was
  176.     not sufficient to perform the color table animation for multiple documents, so
  177.     for that version it was removed.  With 32-Bit Color QuickDraw, intelligent
  178.     Palette Manager animation is possible, and so I put it in.
  179.  
  180.     The overall structure of the program starts with the TFracAppApplication
  181.     object. This guy descends from TApplication, and is responsible for creating
  182.     new documents and giving them idle time for them to do their stuff. When giving
  183.     documents time to idle and calculate themselves, TFracAppApplication keeps
  184.     track of which ones are finished that might also be part of a multi-doccing
  185.     sequence. This is where you can launch a series of documents in series, each
  186.     one calculating itself and then being saved to disk. This is great for putting
  187.     your Macintosh to useful purpose at night. When one of these  documents is
  188.     done, TFracAppApplication takes care of saving and closing it, and then
  189.     creating and starting the next one.
  190.  
  191.     TFracAppApplication also takes care of the Windows menu. Because each window
  192.     tends to take up most of the screen real estate, it was handy to add a Windows
  193.     menu so that we can easily get to the ones that are hidden. When a new window
  194.     is created it tells the TFracAppApplication that it is about to show itself.
  195.     Similarly, when the window is about to be closed, it also informs the
  196.     TFracAppApplication. The TFracAppApplication object keeps a list of the windows
  197.     in the order in which they appeared. This way, it can make a Windows menu that
  198.     contains the name of the oldest windows at top, and the newest windows at the
  199.     bottom. It does all this by overriding DoSetupMenus. If necessary, it tears
  200.     down the old menu and builds up a new one. It then enables all the menu items,
  201.     and puts a check mark by the one that belongs to the topmost window. When one
  202.     of those menu items is selected, it is brought to the front.
  203.  
  204.     The major unit of information in FracApp is the TFracAppDocument. Each of these
  205.     is responsible for maintaining all information relating to a specific fractal. It
  206.     keeps track of the data that appears on the screen, the amount of the fractal that
  207.     has been calculated so far, and has methods for saving to and writing from disk. To
  208.     do all this, TFracAppDocument gets helps from some friends. It has a TOffscreen
  209.     object for managing the offscreen stuff, and TFracAppEngine that does the
  210.     actual fractal calculations, and a TFracAppView for displaying.
  211.  
  212.     For the actual handling of data we use a TOffScreen object. This object is
  213.     responsible for managing the offscreen environment, swapping it in and out as
  214.     necessary. TOffscreen objects come in two flavors: TOldGrossOffscreen, and
  215.     TNewCoolOffscreen. The former is based on all the offscreen handling routines
  216.     that FracApp 1.0 used; it builds everything up by hand. This means bulding up
  217.     an offscreen GDevice, initializing all the right fields, adding color tables,
  218.     attaching a color offscreen GrafPort, making sure it’s got all the right
  219.     memory, etc. A real drag. The new way of doing this is with the offscreen
  220.     handling routines provided by 32-Bit Color QuickDraw. These routines will be
  221.     used if a) we’ve got them, and b) the user has specified that we want them by
  222.     selecting the right menu option. By default, if we’ve got ‘em, we use ‘em.
  223.  
  224.     For viewing the data, we have a TFracAppView. This just CopyBits the data as
  225.     needed, and maintains the current selection (if any).
  226.  
  227.     Finally, we have a TFracAppEngine which is used to do the actual fractal
  228.     calculations. TFracAppEngines also come in two sizes: TNormalFracAppEngine and
  229.     TFastFracAppEngine. Again, the former is based on FracApp 1.0, where we
  230.     calculate each and every pixel one by one. This is OK for complex documents
  231.     (i.e., ones with lots of different colors all over the place), but we can make
  232.     an enhancement for documents that have large blocks of the same color. The
  233.     TFastFracAppEngine uses a recursive technique of dividing the document into
  234.     four parts, and then examining each part. If the colors of the pixels on the
  235.     border of the area we are looking at are all the same, then we assume that all
  236.     of the interior colors are the same as well. If so, we then just blast all the
  237.     pixels with a large PaintRect call. If not, then we divide THAT area into 4
  238.     parts, and perform the process again. If the rectangles start to get really
  239.     small (less than 4 pixels on a side), then I just fill it all in by hand, a
  240.     pixel at a time. This takes care of not losing fine detail. This stategy was
  241.     pointed out by Arthur Britto, and is called the Mariani/Silver algorithm.
  242.  
  243.     The fractal calculation is done by the CalcCity routine of the FracAppEngine.
  244.     The TApplication object gets the DoIdle call, and it finds a document that
  245.     needs some time for its calculations. Once it finds one, it calls the engine
  246.     for that document. That engine is given a small amount of time to do its stuff,
  247.     and then returns to the DoIdle method of TFracAppApplication. In this program,
  248.     a lot of pain was taken to make sure that we didn’t hog all the foreground
  249.     time, and made the application as responsible as possible. When in the
  250.     foreground the fractal engine takes about 50 milliseconds before relinquishing
  251.     control. While  in the background, the engine only gets a millisecond, tops.
  252.     When running in Non-Debug mode, we use the Time Manager to make sure that
  253.     everyone is given their fair share of time. If we are running in Debug mode, we
  254.     base our calcuations on TickCount, as the Time Manager may not be available to
  255.     us (the VIAs might be in use by the Performance Tools).
  256.  
  257.     When we set up the offscreen gDevice, we set it up using a 3 bit iTable to save
  258.     on memory that isn’t used. We would use a larger iTable if we were going to be
  259.     doing a lot of color mapping and wanted to stay away from the more extensive
  260.     color searching Color QuickDraw needs to do with smaller color tables. However,
  261.     most of the time is spent in the TFracAppEngine core loop that figures out the
  262.     color  a certain pixel should be. By comparison, we spend very little time
  263.     having the  color manager do color matching, so 3 bits is OK.
  264.  
  265.     When a document is saved the color table from the offscreen gDevice is saved
  266.     along with it. This is the clut resource that is used uniformly throughout the
  267.     program. When we save the document, we have to make sure that we clear bit 14
  268.     of the ctFlags. This bit is the one that allows us to do the fancy QuickDraw
  269.     color matching that lets us do palette animation. However, we DON’T want to do
  270.     this matching when we read the document back in so we have to make sure that
  271.     bit is cleared on the disk.
  272.  
  273.     If you hate my choice of colors, you can change the clut to something else and
  274.     all should work the same (except old documents will map into something else).
  275.  
  276.     Another goal of course was to get this thing done.  A goal that tends to slide
  277.     away as more things are added to the program, so in true Macintosh style, even
  278.     the 2.0 version of the program is somewhat limited, and may not be fully
  279.     debugged. Some things specifically left out: printing the documents to a
  280.     LaserWriter with grey scales instead, using temporary documents to make the
  281.     program crashless (so you can start up where you left off, saving the
  282.     computation it took to get there), an option to make the ‘pen’ size bigger so
  283.     you can do a low-res fractal to begin with, the ability to read in old document
  284.     formats and convert them to newer ones. These things are all admirable features
  285.     to add, but you have to finish sometime, so this was it. These other things
  286.     will be added if possible.
  287.  
  288.     I am aware of the fact that this program does not really calculate Fractals.
  289.     Actually it calculates and displays the Mandelbrot set which is not
  290.     self-similar so it cannot really be called a fractal.  It is distressing to add
  291.     to the confusion as to what fractals are, but it is too late.  For more
  292.     information on Fractals and the Mandelbrot set (no umlaut on the o), you could
  293.     see Mandelbrot’s book ‘The Fractal Geometry of Nature’, but it is pretty
  294.     mathematical and not all that helpful.  A better source is the Peitgen-Richter
  295.     book ‘The Beauty of Fractals’, which has a do it yourself section in the back.
  296.  
  297.     The program is structured primarily around the document, even though the
  298.     document hardly does any work itself. It relies on the reading and writing of
  299.     its base class, TPICTDocument, and the objects that it creates for support
  300.     (TFracAppEngine and TOffscreen).
  301.  
  302.     Originally, the TFracAppDocument itself was the superclass of two other
  303.     classes: TNormalFracAppDocument and TFastFracAppDocument. All of the routines
  304.     that performed the calculations were stored in these classes. However, I had a
  305.     hard time figuring which one to instantiate when reading in a saved document.
  306.     All of my documents are stored as PICT files, so that any application can read
  307.     them in. However, there are really two different flavors of document, depending
  308.     on what algorithm I am using. The specific data needed for each algorithm is
  309.     stored in the user data area of the PICT file (the first 512 bytes). This means
  310.     that I don’t know what algorithm to use, and hence what kind of document to
  311.     create, until I open up the file and look at some bytes in the header. On the
  312.     other hand, I can’t read from the file until I have created a document! Bummer.
  313.     The solution was to break out all of the differences between the two documents
  314.     and encapsulate them into their own objects. These objects can then be
  315.     instantiated by the document after it’s had a chance to open the file and take
  316.     a peek inside.
  317.  
  318.     For the zoom operation, there was no really great way to handle the new
  319.     document case based on another document.  This is a little strange to be doing,
  320.     and the structure of MacApp was such that we couldn’t get to the data desired
  321.     at the right time.  The logical place to put it in at DoMakeDocument was too
  322.     early to have the gDevice allocated and ready to start more stuff.  The problem
  323.     was resolved by using global variables to transmit the information to the other
  324.     piece of the program that might need it.  Essentially DoInitialState decides if
  325.     this is a brand new base level document or a zoom in based on the state of the
  326.     global variables.
  327.  
  328.     The MacApp memory management approach is used as well.  The big pieces used by
  329.     the Documents come out of permanent memory, helping to avoid a crash from no
  330.     memory.  When we allocate something that will be thrown away immediately, it of
  331.     course comes out of normal (temporary) memory.  We did not do a full blown
  332.     memory analysis of the program since it is such a memory hog anyway.  The mem!
  333.     resource is set up in a form that is roughly close (a bit high) without trying
  334.     to be extra accurate.  When a document takes 500K of RAM to open it hardly
  335.     seems relevant to make sure the mem! is accurate to 2K.  Because of this
  336.     somewhat cavalier approach you may not be able to open a document in a few
  337.     cases where you really should be able to.  The mem! in use of 60K is close with
  338.     a +2K/-10K error on how big it should really be.
  339.  
  340.     The QuickDraw BottleNecks are used to both read and write the actual fractal
  341.     data from/to the disk.  This is done since the data in the document may be very
  342.     large (100K) and if we just spool the data from the file we don’t actually have
  343.     to use that extra hunk of memory.  We have to read the data anyway, so we go
  344.     ahead and just read it in as we play it back. As it is played back it goes into
  345.     the offscreen gDevice’s pixMap, so we have the data to display.  Having no
  346.     memory hit for the document is a big win. When writing the data, the same thing
  347.     is true so we don’t have to have a huge handle to hold the picture data itself.
  348.     We also avoid the problem of not having enough memory to create the picture in
  349.     the first place, making a document unsaveable.  That is particularly annoying,
  350.     and is easy to avoid using the spooling approach.   The drawback here is that
  351.     the spooling process slows down opening and closing documents rather severely,
  352.     since it breaks up a long read/write operation into hundreds of small ones.
  353.  
  354.     With thanks to Guillermo Ortiz and Jon Zap for their Color QuickDraw advice; to
  355.     Rich Collyer for helping me with the 68882 routines; to Arthur Britto at OMI
  356.     for suggesting the Mariani/Silver algorithm; to Steve Friedrich for his
  357.     suggestions on mapping one file type to two document classes; and to Bo3b
  358.     Johnson for writing FracApp 1.0, and who had the following thanks in FracApp
  359.     1.0:
  360.  
  361.         With thanks to Rick (nee Skippy) Blair for the discussions of color QuickDraw
  362.         and the Palette Manager.  Thanks to Darin Adler for further discussion of the
  363.         Palette Manager and for good suggestions on making it more MacApp friendly.
  364.  
  365.     Special thanks to Darin Adler, Mary Boetcher, Chris Knepper, Andy Shebanow,
  366.     Bo3b Johnson, and Dave Wilson for reviewing version 2.0 of this program for me.
  367.  
  368.  
  369.  
  370. The following is a list of features or bug fixes that could be added to the program:
  371.  
  372.     *** Make it run crashless using temp documents to store partial fractals.
  373.     *** Override TWindow.Draw so we can avoid the EraseRect on updates.
  374.     *** Draw selection rect in offscreen, copy up to screen for flicker free selection.
  375.     *** Crash on 3 monitor system during window drag (don’t know if this is still true).
  376.     *** Could set the bytes directly in offscreen PixMap, skip using PaintRect.
  377.     *** Copy up from small picture up to big screen gets garbage, src rect too big?
  378.     *** Allow a way to Zoom in using coordinates.
  379.     *** Allow the user to set the colors used in display.
  380.     *** Bigger penSize for fast, lo-res fractals.  Allow user to set size of pen.
  381.     *** Add in full support for different dpi settings.
  382.     *** Set Calc Rect to size of printer page.
  383.     *** Read in and convert old (FracApp 1.0) documents.
  384.     *** Some things for the reader to do to modify the program.
  385.