home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / SDKs / ScreenLight™ 1.0.1 / CodeExamples / ModInterface-DRAFT next >
Encoding:
Text File  |  1996-01-05  |  14.9 KB  |  336 lines  |  [TEXT/CWIE]

  1. 14dec95
  2.  
  3. ScreenLight Module Interface
  4. Working Draft
  5.  
  6. OverView
  7.  
  8.     ScreenLight is a ScreenSaver. Although the application shows graphics modules of 
  9. all styles, a few points are worth mentioning:
  10.  
  11.   Support of Macintosh Environments
  12.   
  13.   The following is a breakdown of importance for various Macintosh environments:
  14.   
  15.   PowerPC
  16.   ************************************        (color)
  17.   *********************                        (b&w)
  18.   
  19.   68k/FPU
  20.   ***********************                    (color)
  21.   *********************                        (b&w)
  22.   
  23.   68k w/o FPU
  24.   ******                                    (color)
  25.   ****                                        (b&w)
  26.   
  27.   Notes:
  28.     PowerPC is the most important environment to support under ScreenLight. 
  29.     The PowerPC has lots of horsepower !!  Modules may choose to run
  30.     as PowerPC native only, which is fully supported by ScreenLight. It is 
  31.     encouraged, however, to compile a version for the 68k family as well.
  32.     
  33.     B&W Support means that if a monitor is set to 1 bit, that the graphics module
  34.     understands how to draw correctly to get a desired effect.
  35.    
  36.     Single bit video has a certain kind of appeal for many computer users. Cognitive
  37.     psychology studies have shown that information is clearly and rapidly represented
  38.     on a B&W display. B&W monitors emit less EMF radiation and may be less harmful
  39.     to the computer user over time. Although the market has largely embraced
  40.     color computers, there will always be support for B&W on the Macintosh computer.
  41.     Also, for those that have been around for a while, fond memories of a first 
  42.     experience with Macintosh include that old B&W display.
  43.     
  44.     The Macintosh Quadra series offers serious performance for many Macintosh
  45.     users. Also, due to the number of Macintoshes sold, there is a substantial 
  46.     base of Quadra and Macintosh II, particularly Mac IIci, users out there. Many 
  47.     graphics modules run very well under this environment. 
  48.     
  49.     Because of the strong emphasis on supporting B&W under ScreenLight, the B&W ratings
  50.     for PowerPC, Mac 68k/FPU and color 68k/FPU are roughly on par.
  51.     
  52.     The Performa line of computers has enjoyed a wide commercial success. With the 
  53.     68LC040, and some models like the IIsi and LC series, there are many Macs
  54.     without FPU co-processors.  ScreenLight will ship with several modules which run on
  55.     these machines, but authors are encouraged to support the PowerPC first.  
  56.     It's important to note that with small changes, many graphics algorithms will 
  57.     run very well on machines w/o Floating Point. So if your module is close to running 
  58.     w/o FPU support, consider making the effort to eliminate FPU instructions and produce
  59.     an 'FPU clean' module!
  60.     
  61.     Note that B&W support does _not_ mean the 68000 processor. The time for commercial
  62.     products that support the original Macintosh, for better or for worse, has 
  63.     largely passed. Note that in the PC World, the life expectancy of a CPU is about
  64.     18 _months_, while here we are talking about machines that are at least 7 years
  65.     old !
  66.  
  67.  
  68.   Aesthetics Notes - "Less is More" : 
  69.     
  70.     As a ScreenSaver, the idea is to light as few pixels as possible !  Many 
  71.     ScreenSaver modules, in an effort to broaden their scope, have elected to fill 
  72.     screen with bright colors and sharp, glaring content.  Consider for a moment the 
  73.     effect of your ScreenSaver module. Most modules need to give a good first 
  74.     impression - that is when the user clicks on a Module _something_ should happen.
  75.     But over time the user will be more likey to be concentrating on other tasks,
  76.     passing by in a hallway, or genuinely concerned with saving the screen!  So when 
  77.     designing a module, consider using fewer pixels, less bright colors. Attractive
  78.     motion and timing can substitute for bright, galring effects to make a great 
  79.     ScreenLight module.
  80.     
  81.     Having said this, a few of the ScreenLight Modules already break these rules.
  82.     So Be It. To make Great Graphics, freedom and creativity are encouraged. So 
  83.     do what you will, and make great ScreenLight Modules !
  84.  
  85.  
  86.     
  87. -----------------------------------------------------------------
  88. 0) Module Resources
  89.  
  90.     kFPU
  91.     
  92.     If a 68k Module requires an FPU, you must include a resource of type 'kFPU'. 
  93.     That way the App can filter out FPU modules on machines w/o
  94.     Floating Point support.  At the very least, check for an FPU in your
  95.     CheckRequiredFeatures() call.  Note that by turngin off '-881 code' in
  96.     your development system, you will get a compatible code module, but 
  97.     performace is likely to be very slow compared to FPU instructions.
  98.     Check your development system for more details.
  99.  
  100.  
  101.     icl8/ICN#
  102.     
  103.     If present, the Application uses a custom resource Icon (#-16455)
  104.     in the Module Picker. Try to supply both the icl8 (color) and 
  105.     ICN# (B&W + mask). The resources are made in a pair automatically
  106.     with a Resource Editor like Resorcerer.
  107.     
  108.     
  109.     SS-m
  110.     
  111.     The module code for a 68k module is stored in a resource of type 'SS-m',
  112.     created by your development system. Typically the resource is of ID 0,
  113.     although this is not required.
  114.  
  115.  
  116.     Control Templates
  117.     
  118.     The App supplies a number of templates (type TMPL) for defining your own 
  119.     custom controls.  See example code for usage in the Module. Basically,
  120.     a control is defined for each occurance of a resource from a given type.
  121.     For instance, if you have 2 resources of type 'cCHK', your module will
  122.     have 2 check boxes in the Application interface. Each control is given a 
  123.     UniqueID by you in the Module Control resource. When you recieve a Module
  124.     Control-related msg, your code checks the UniqueID to find out which control 
  125.     the msg is for. etc..
  126.  
  127.  
  128. -----------------------------------------------------------------
  129. 1) Module Calling Conventions
  130.  
  131.     A Module is called with a single, identical parameter at each 
  132.     entry point, the standard Module ParamBlk.  Currently, the ParamBlk 
  133.     looks like this:
  134.     
  135.         struct ModuleParamBlk {
  136.             GrafPtr            mGraf;
  137.             ModuleProcs        mProcs;
  138.             FSSpec            mSpec;
  139.             short            mResRefNum;
  140.             long            mStorage;
  141.             Boolean            mInPreview;
  142.             long            mInfo;
  143.         };
  144.  
  145.     Here are each of the fields, defined:
  146.     
  147.         GrafPtr mGraf;
  148.            the GrafPort in which you will draw. This is either a small window,
  149.            while the Module is in Preview mode, or it is a window covering all
  150.            GDevices on the machine, in ScreenSaving mode. The Port is color on 
  151.            any machine which supports CGrafPorts/CQD.
  152.         
  153.         ModuleProcs mProcs;
  154.             a struct containing UPPs to all of the Module's entry points, used by 
  155.             the App to call the Module. By convention, the Module fills out this
  156.             recordby calling the standard Module support routine
  157.             InitmProcs() on ModOpen. No other action is needed by the Module.
  158.         
  159.         FSSpec mSpec;
  160.             An FSSpec to the module itself. You may use the FSSpec for
  161.             additional operations on your Module or other files.
  162.     
  163.         short mResRefNum;
  164.             Your Module's resource refnum. Although you are the current resource 
  165.             in the resource chain when you are called, the App uses this refnum
  166.             to maintain the Module ControlRec structures in the Module's resource
  167.             fork.
  168.     
  169.         long mStorage;
  170.             A Module-defined pointer to storage. Almost any module will
  171.             want some kind of storage. This is typically used to point
  172.             to a struct defined privately by the Module. If the Module allocates
  173.             storage, the Module is responsible for de-allocating the storage,
  174.             and setting the mStorage field back to 0 on ModClose().
  175.         
  176.         Boolean mInPreview;
  177.             A Boolean flag which tells the Module if the Preview mode is in effect.
  178.             Some Module may wish to substantially alter their behavior for the 
  179.             Preview mode, as there is less time given for ModDraw calls, and the
  180.             display window is of limited, but fixed, size.
  181.     
  182.         long mInfo;
  183.             Used in the ModChangePrefs() call to hold a handle to the Module
  184.             ControlRec data. Your Module is passed a resource handle to your
  185.             defined Module controls, one at a time. As described below, these 
  186.             handles are not Toolbox handles, but rather handles to the Standard
  187.             Control Type structs as defined in ModuleAPI.h. 
  188.             
  189.             In the ModAbout() call, the mInfo field holds a pointer to an EventRecord
  190.             describing the click that called Module About. The Module can use the
  191.             'modifiers' field to look for special key combinations, etc.
  192.  
  193.  
  194. 2) Module Entry Points
  195.  
  196.     Currently, here are the Module Entry Points:
  197.     
  198.         OSErr    ModOpen                ( ModuleParamBlkPtr mpPtr);
  199.         OSErr    ModDraw                ( ModuleParamBlkPtr mpPtr);
  200.         OSErr    ModClose            ( ModuleParamBlkPtr mpPtr);
  201.         OSErr    ModAbout            ( ModuleParamBlkPtr mpPtr);
  202.         OSErr    ModChangePrefs        ( ModuleParamBlkPtr mpPtr);
  203.  
  204.     Here are each of the Entry Points, defined:
  205.     
  206.         ModOpen
  207.             Each time the Module is initialized, the Module gets the ModOpen
  208.             call. Consider this a complete start of your module. In practice, 
  209.             when ScreenLight changes the Module from Preview to ScreenSaving 
  210.             and back, a Close and Open pair is given. For simplicity, the Module 
  211.             completely closes and completely re-opens each time this happens.
  212.             
  213.             There are several standard actions which a Module typically takes. 
  214.             
  215.             * Call InitmProcs() to fill out the UPP record. 
  216.             * Check that the machine is satisfactory to run this Module. 
  217.             eg. Color, an FPU, 68020 instruction set, etc. Some checking for 
  218.             the machine type is done by ScreenLight, but it is the final 
  219.             responsibility of the Module to check for features.
  220.             * Check the Preview mode and make any adjustments necessary for 
  221.             the Module action.
  222.             * Allocate your storage. If your allocation fails, return an error,
  223.             or make appropriate adjustments. Store the pointer to the allocation 
  224.             in the mStorage field of the ModuleParamBlk.
  225.             
  226.             You can always return an error if initialization fails. If you do return 
  227.             an error, your ModClose() call will NOT be called.
  228.  
  229.  
  230.         ModDraw
  231.             The port is set for you on entry. If drawing or drawing calculations take 
  232.             a long time (subjectively defined), break the code into pieces to be
  233.             executed a part each call. When in ScreenSaver mode, the draw calls are 
  234.             as fast as performance permits - in Preview Mode the time between Draw
  235.             calls may be significantly longer (per WaitNextEvent)
  236.             
  237.             Some routines are supplied in ModuleRoutines.c to help with basic tasks
  238.             like color ramping and random number generation.
  239.             
  240.             In your global storage define any drawing variables, offscreen buffers,
  241.             settings, etc to control drawing. The contents of these variables will 
  242.             change only at ModChangePrefs() time, so your ModDraw() call can assume
  243.             that the values are constant and correct. NOTE: if you need to re-init
  244.             your graphics due to a change in a global, the right time to do this is
  245.             in response to the ModChangePrefs() call. It is up to your own code to
  246.             decide whether a re-init is needed. For example, if a check box boolean
  247.             is 'Use Color', and your GWorlds have been init'd as B&W, then a complete
  248.             re-init of your GWorlds is called for by a change to the value of the 
  249.             'Use Color' Boolean. It is up to the ModChangePrefs() code to call for 
  250.             this re-init.
  251.             
  252.             The Application sets certain GrafPort variables for you on entry to your
  253.             Module.  For instance, when copying from a GWorld to an onScreen GrafPort,
  254.             you must set ForeColor( blackColor)/BackColor( whiteColor) or you may
  255.             get unexpected results. Since this is such a common case, the Application 
  256.             sets the ForeColor and BackColor each time Draw() is called. In general,
  257.             set the Pen, Colors, Patterns and other Port variables each time your
  258.             Draw routine is called.
  259.  
  260.  
  261.         ModClose
  262.             Dispose of your own storage. No changes are needed to the machine, the 
  263.             GrafPort, or the state of your Settings.  Specifically your module's
  264.             resource fork and file will be closed properly by the Application.
  265.  
  266.  
  267.         ModAbout
  268.             Do your 'About Box'!  A default proc is supplied by the Application, 
  269.             which draws a PICT 128 or Styled Text 128 if present in your Module.
  270.             To Supply your own About proc, fill out your own About proc as shown 
  271.             in the example module code.
  272.             
  273.             On entry you will get the ModuleParamBlkRec, with the mInfo field 
  274.             pointing to an EventRecord describing the users click in the Pickers
  275.             'Info Module Title' field. Command and option keys, etc, can be detected
  276.             using the 'modifiers' field of the Event Record.  If your About box
  277.             waits for the user to given input before continuing, call WaitNextEvent()
  278.             with an event mask of mDownMask+keyDownMask as shown in the example code.
  279.  
  280.  
  281.         ModChangePrefs
  282.             You will be passed a handle in mInfo to one of the standard Module
  283.             ControlRec structures listed in Appendix A.  Controls are of one of
  284.             the following types: kSliderCntl, kButtonCntl, kCheckBoxCntl, kListCntl,
  285.             kStaticStrCntl.  (the List is a popupMenu)  Your Module defines
  286.             controls by creating resources with a resource editor and including these
  287.             resource in your Module. The Application then draws controls based on 
  288.             these resources, handles interaction with the user and notifies you 
  289.             when any control values have changed. 
  290.             
  291.             On entry, read the first long of the handle contents to determine the ID
  292.             of the control. This Unique ID is assigned by you when creating the  
  293.             Module's resources. Based on the ID and Control Type, you can then extract 
  294.             the current value of the control information being passed, modify your
  295.             globals in your private storage area, and take any further action required
  296.             to set up for the next ModDraw() call.
  297.             
  298.  
  299. 3) Known Gotcha's
  300.  
  301.         GWorlds
  302.             I have seen GWorlds with the 'tempMem' flag set allocate their space
  303.             in the Application heap. Since the App heap is of limited size, big
  304.             GWorlds may fail.
  305.     
  306.         TempMem
  307.             If you are using MFNewHandleTemp(), MFMaxMem(), etc to allcoate space
  308.             for your Module, be sure to deallocate these blocks on Close. For most
  309.             allocations, quitting the application restores the state of the machine.
  310.             Not so with MFTemp allocations! Your memory will be lost until the mac
  311.             restarts ! Don't forget to deallocate temporary memory allocations.
  312.     
  313.         FPUs
  314.             Be very careful about turning the -881 flag on in 68k projects. If you
  315.             accidently create FPU instructions in your module, and do not include
  316.             a 'kFPU' resource or check in 'CheckRequiredFeatures()' on ModOpen(),
  317.             you will crash the machine !  For instance, using a utility routine
  318.             which uses floating point may cause this to happen. If the -881 flag
  319.             is off, the generated code will call SANE, which is slow and very precise,
  320.             but the code is safe on all machines.
  321.     
  322.         Patterns
  323.             In Color QuickDraw, the meaning of the old patterns has changed in an 
  324.             important way. the 'white' pattern means "completely background color',
  325.             and black means 'completely Foreground color'. So if you set your 
  326.             background color to black, and use FillRect( r, white), guess what 
  327.             happens.
  328.             
  329.             As of this writing, I've seen bugs when attempting to use the qd globals.
  330.             (probably my fault)  As a work-around, just declare a variable of type
  331.             Pattern, and init it to the desired value (black, white, gray, etc).
  332.             See the 'Dots' example code for details.
  333.  
  334.  
  335. //************************************************************************************
  336.