home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************************
- ModuleRoutines.c
-
-
- DOCUMENTATION
-
- Module support routines for Meddle, the Fat Binary
-
-
- ROUTINE DESCRIPTIONS
-
- InitmProcs()
- CheckRequiredFeatures()
- hasPowerPCArch()
- ProfileMonitors()
- GetLargestRect()
- IsColorPort()
- GetPortPixDepth()
- CalcHSBtoRGB()
- IRandom()
-
-
- HISTORY
-
- 27nov95 bh New Today
-
-
- Copyright )WORK-IN_PROGRESS Noesis Software Construction
- **********************************************************************************/
-
- #include "ModuleRoutines.h"
-
-
- //--------------------------------------------------
- OSErr InitmProcs( ModuleParamBlkPtr mpPtr)
- {
- extern OSErr ModDraw( ModuleParamBlkPtr mpPtr);
- extern OSErr ModClose( ModuleParamBlkPtr mpPtr);
- extern OSErr ModChangePrefs( ModuleParamBlkPtr mpPtr);
-
- // allocate proc pointers
- mpPtr->mProcs.drawProc = NewModDrawProc(ModDraw);
- mpPtr->mProcs.closeProc = NewModCloseProc(ModClose);
- mpPtr->mProcs.chngPrefsProc = NewModChangePrefsProc(ModChangePrefs);
- mpPtr->mProcs.aboutProc = 0;
-
- return noErr;
- }
-
-
- //-----------------------------------------------------------------------
- // CheckRequiredFeatures
- //
- // You may want to copy this routine into your own Module code
- // and modify the requirements to check for features
- // needed by your module.
- //
- // When requiring an FPU for your module (generating '881->ON)
- // please remember to add a resource of type 'kFPU' in your module.
- // Your module will then be filtered out on machines without an
- // FPU, so the check for an FPU is optional here...
- //
- // PowerPC's have FPU instructions built in.
- //
-
- OSErr CheckRequiredFeatures()
- {
- SysEnvRec tEnv;
- OSErr err;
-
- if ((err=SysEnvirons( 2, &tEnv)) != noErr)
- return (-1);
-
- // Note that there is a bug in Gestalt selector 'qdrw' which
- // tells us incorrectly that CQD is present on non-color
- // machines. HOWEVER, we use SysEnvirons() to tell us if
- // CQD is present, and the always correct Gestalt selector
- // 'qd ' for _version_ information, if we have Gestalt...
-
- if ( !tEnv.hasColorQD)
- return kNoCQDerr;
-
- return noErr;
- }
-
- //*********************************************************************************
- // hasPowerPCArch
- //
- // Gestalt will return an error if the gestaltSysArchitecture selector is
- // not recognized by the System, so we can assume this is a 68K machine.
- // Otherwise, this function returns true for a Power Mac and false for
- // a 68K Mac.
- //
- //*********************************************************************************
-
- Boolean hasPowerPCArch()
- {
- long gestaltResult;
-
- if (Gestalt(gestaltSysArchitecture, &gestaltResult))
- return(false);
- else
- return(gestaltResult == gestaltPowerPC);
- }
-
- //*********************************************************************************
- // IsColorPort
- // Simple test for a CGrafPort
- //*********************************************************************************
- Boolean IsColorPort( GrafPtr tPort)
- {
- return (tPort->portBits.rowBytes & 0xC000) != 0;
- }
-
- //*********************************************************************************
- // GetPortPixDepth
- // Return bit-depth of a GrafPort
- //*********************************************************************************
- short GetPortPixDepth( GrafPtr tPort)
- {
- if ( (tPort->portBits.rowBytes & 0xC000) == 0)
- return 1;
- else
- return (*((CGrafPtr)tPort)->portPixMap)->pixelSize;
- }
-
-
- //*********************************************************************************
- // Example Profile Routine
- //
- // Modules may wish to profile monitors. Currently, the Drawing Window
- // is opened across all active Screens using GrayRgn. In a multiple monitor
- // environment, drawing across all screens may or may not be what the Module
- // wants to do! SO here is an example routine making a convenient structure
- // containing a few imortant pieces of info on available monitors....
- //
-
- //include <Quickdraw.h>
-
- //------------------------------------------
- struct SMonProfile {
- Rect sMonRect; // in GLOBAL co-ords
- short sMonCurDepth; // always a power of two
- short sMonType; // 0=clut,1=fixed,2=direct
- };
- typedef struct SMonProfile SMonProfile;
-
- struct SDeviceList {
- short sDevCnt;
- SMonProfile sDevs[1];
- };
- typedef struct SDeviceList SDeviceList;
- //------------------------------------------
- OSErr ProfileMonitors(void);
-
- //------------------------------------------
- OSErr ProfileMonitors(void)
- {
- SDeviceList **xDeviceListH; // <- make this into a global
- short cnt;
- GDHandle device;
- Size siz;
- OSErr err = noErr;
-
- cnt = 0;
- xDeviceListH = (SDeviceList **)NewHandle(0); // stub
- for (device = GetDeviceList(); device != 0; device = GetNextDevice(device)) {
- if (TestDeviceAttribute(device, screenDevice)
- && TestDeviceAttribute(device, screenActive)) {
- siz = sizeof(SDeviceList) + cnt*sizeof(SMonProfile);
- SetHandleSize( (Handle)xDeviceListH, siz);
- if ( (err=MemError()) != noErr) // bail if unlikely error occurs
- return err;
- (**xDeviceListH).sDevs[cnt].sMonRect = (**device).gdRect;
- (**xDeviceListH).sDevs[cnt].sMonCurDepth = (**(**device).gdPMap).pixelSize;
- (**xDeviceListH).sDevs[cnt].sMonType = (**device).gdType;
- cnt++;
- }
- }
- (**xDeviceListH).sDevCnt = cnt;
- return err;
- }
-
-
- //*********************************************************************************
- // GetLargestRect -
- //
- // Here is a sample routine for finding the monitor rect of the largest Monitor
- // for use by a Mosule while drawing in ScreenSaving mode (not inPreview!)
- // Note that the Rect is adjusted by an additional offset at the end of the
- // routine. This is because no matter which monitor your Rect lands on, when
- // the global drawing window is created, it will be offset by the negative
- // coords of the left and upper-most monitor from the MenuBar. Since the coords
- // of the Drawing window are always 0,0 in the UpperLeft corner, this routine
- // adds an additional offset to compensate.
- //
-
- void GetLargestRect( Rect *r)
- {
- short cnt;
- long curWid, curHt, bestWid, bestHt;
- short mostNegH, mostNegV;
- Rect bestR, curR;
- GDHandle device;
-
- *r = qd.screenBits.bounds;
- bestR.left = bestR.right = bestR.top = bestR.bottom = 0;
- bestWid = bestHt = 0;
- mostNegH = mostNegV = 0;
-
- for (device = GetDeviceList(); device != 0; device = GetNextDevice(device)) {
- if (TestDeviceAttribute(device, screenDevice)
- && TestDeviceAttribute(device, screenActive)) {
-
- curR = (**device).gdRect;
- curWid = (curR.right-curR.left);
- curHt = (curR.bottom-curR.top);
-
- if ( curWid*curHt > bestWid*bestHt) {
- bestR = curR;
- bestWid = (bestR.right-bestR.left);
- bestHt = (bestR.bottom-bestR.top);
- }
- // Adjust for monitors to the left of the Main Device
- if ( curR.left < mostNegH) mostNegH = curR.left;
- if ( curR.top < mostNegV) mostNegV = curR.top;
- }
- }
-
- *r = bestR;
- r->left -= mostNegH; r->right -= mostNegH;
- r->top -= mostNegV; r->bottom -= mostNegV;
-
- return;
- }
-
-
- //*********************************************************************
- // CalcHSBtoRGB
- //
- // Use a simple conversion system to get a Mac RGB triplet out
- // of an HSB request. Hue is measured in 0-360° units, while
- // Saturation and Brightness are in 0-100%.
- //
- // Only integer math is used. There is a rounding error of
- // 1/4 unit per RGB component when calculating the Hue in each
- // sextant - meaning that 59° will result in an RGB triplet that
- // is 14 units less than it should be in each of RGB. In an 8 bit
- // system this is ignored, but in a 'true color' system this will
- // cause a slight darkening of the resultant colors. (16/65535 or
- // 0.0244 percent error per component)
- //
- //
- // 15aug94 - bh New Today
- //--------------------------------------------------------------------
-
- OSErr CalcHSBtoRGB( long hue, long sat, long bright, RGBColor *dstRGB)
- {
- unsigned short tComp;
- unsigned short tProp;
-
- #ifdef RANGE_CHK
- if ( hue > 360 || hue < 0) return -1;
- if ( sat > 100 || sat < 0) return -1;
- if ( bright > 100 || bright < 0) return -1;
- #endif
-
- #if(0)
- if ( hue > 360) hue = hue % 360;
- if ( sat > 100) sat = 100;
- if ( bright > 100) bright = 100;
- #endif
- // catch a special case of black
- if ( bright == 0) {
- dstRGB->red = 0;
- dstRGB->green = 0;
- dstRGB->blue = 0;
- return noErr;
- }
-
- // catch a special case of white
- if ( sat == 0 ) {
- dstRGB->red = 0xFFFF;
- dstRGB->green = 0xFFFF;
- dstRGB->blue = 0xFFFF;
- return noErr;
- }
-
- //--------------------------------------
- // Set RGB based on hue
-
- tProp = 0xFFFF/60;
-
- if ( hue <= 60) { // 0-60 green+
- tComp = hue;
- dstRGB->red = 0xFFFF;
- dstRGB->green = 0 + (tComp * tProp);
- dstRGB->blue = 0;
- } else if ( hue <= 120) { // 61-120 red-
- tComp = hue-60;
- dstRGB->red = 0xFFFF - (tComp * tProp);
- dstRGB->green = 0xFFFF;
- dstRGB->blue = 0;
- } else if ( hue <= 180) { // 121-180 blue+
- tComp = hue-120;
- dstRGB->red = 0;
- dstRGB->green = 0xFFFF;
- dstRGB->blue = 0 + (tComp * tProp);
- } else if ( hue <= 240) { // 181-240 green-
- tComp = hue-180;
- dstRGB->red = 0;
- dstRGB->green = 0xFFFF - (tComp * tProp);
- dstRGB->blue = 0xFFFF;
- } else if ( hue <= 300) { // 241-300 red+
- tComp = hue-240;
- dstRGB->red = 0 + (tComp * tProp);
- dstRGB->green = 0;
- dstRGB->blue = 0xFFFF;
- } else { // 301-360 blue-
- tComp = hue-300;
- dstRGB->red = 0xFFFF;
- dstRGB->green = 0;
- dstRGB->blue = 0xFFFF - (tComp * tProp);
- }
-
- //--------------------------------------
- // This color is now 100% saturated. Take
- // the difference betwee this color and white,
- // divide into 100 parts, add 1 for every
- // 1 part less than 100% saturation.
- //
-
- if ( sat != 100) {
- unsigned short dR, dG, dB, invSat;
-
- dR = (0xFFFF - dstRGB->red)/100;
- dG = (0xFFFF - dstRGB->green)/100;
- dB = (0xFFFF - dstRGB->blue)/100;
- invSat = 100 - sat;
- dstRGB->red = dstRGB->red + (invSat*dR);
- dstRGB->green = dstRGB->green + (invSat*dG);
- dstRGB->blue = dstRGB->blue + (invSat*dB);
- } /* else { already set} */
-
- //--------------------------------------
- // now divide by brightness
- if ( bright != 100 ) {
- char b = bright; // get rid of 68k 'long multiply'
-
- dstRGB->red = (dstRGB->red/100) * b;
- dstRGB->green = (dstRGB->green/100) * b;
- dstRGB->blue = (dstRGB->blue/100) * b;
- } /* else { already set} */
-
- return noErr;
- }
-
-
- //----------------------
- short IRandom( short min, short max)
- {
- short r;
-
- // TO DO: Handle Negative Range
- r = Random();
- if ( r < 0) r *= -1;
- return ((r % (max - min)) + min);
- }
-
-
- //**********************************************************************************
- // E N D O F L I S T I N G E N D O F L I S T I N G
-