home *** CD-ROM | disk | FTP | other *** search
- /*
-
- SampleXsn.c
-
- Sample transition effect for VideoShop
-
- */
-
- /* Includes */
-
- #include <Types.h>
- #include <Memory.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <QDOffscreen.h>
- #include <Dialogs.h>
- #include <OSUtils.h>
- #include <Packages.h>
- #include <Errors.h>
- #include <ToolUtils.h>
- #include <SysEqu.h>
- #include <Math.h>
- #include <GestaltEqu.h>
- #include "DiVATransition.h"
-
- /* Type definitions */
-
- typedef struct WipeParams {
- unsigned short angle;
- } WipeParams, *WipeParamPtr, **WipeParamHandle;
-
- /* Konstants */
-
- #define dialogID 16001
- #define defaultItem 3
- #define leftToRightItem 5
- #define topToBottomItem 6
- #define rightToLeftItem 7
- #define bottomToTopItem 8
- #define dividerItem 10
-
- /* Prototypes */
-
- XsnErr DoParameters (XsitionParamPtr params);
-
- XsnErr DoProcessFrame (XsitionParamPtr params, short transitionIntensity,
- short maxTransitionIntensity);
-
- pascal XsnErr XsnEntryPoint (short selector, XsitionParamPtr params, long *data,
- short transitionIntensity, short maxTransitionIntensity)
- /*
- The transition entry point and dispatcher routine. Calls the appropriate
- subroutine based on the selector passed.
- */
- {
- #pragma unused(data)
- switch (selector) {
- case XSParameters:
- return (DoParameters (params));
- break;
- case XSPrepare:
- case XSStart:
- case XSFinish:
- return (noErr);
- break;
- case XSProcessFrame:
- return (DoProcessFrame (params, transitionIntensity, maxTransitionIntensity));
- break;
- default:
- return (-1);
- }
- }
-
- pascal Boolean DoTestAbort (ProcPtr codeAddress)
- /* Inline code to call the TestAbort function */
- = {0x205F, // move.l (a7)+,a0 pop procPtr from stack
- 0x4E90}; // jsr (a0) and call it
-
- Boolean TestAbort (XsitionParamPtr params)
- {
- ProcPtr address;
-
- address = params->abortProc;
- return (DoTestAbort (address));
- }
-
- pascal void DoUpdateProgress (long done, long total, ProcPtr codeAddress)
- /* Inline code to call the UpdateProgress function */
- = {0x205F, // move.l (a7)+,a0 pop procPtr from stack
- 0x4E90}; // jsr (a0) and call it
-
- void UpdateProgress (XsitionParamPtr params, long done, long total)
- {
- ProcPtr address;
-
- address = params->progressProc;
- DoUpdateProgress (done, total, address);
- }
-
- void CenterDialog (DialogTHndl dt)
- /*
- Given a dialog template in dt, modify it so as to center the dialog on the
- main device.
- */
- {
- Rect r;
- short width;
- short height;
- GDHandle mainDevice;
-
- mainDevice = GetMainDevice();
- width = (**mainDevice).gdRect.right;
- height = (**mainDevice).gdRect.bottom;
-
- r = (**dt).boundsRect;
- OffsetRect (&r, -r.left, -r.top);
- OffsetRect (&r, (width - r.right) / 2,
- (height - r.bottom - GetMBarHeight()) / 3 + GetMBarHeight());
- (**dt).boundsRect = r;
- }
-
- pascal void OutlineOK (DialogPtr dp, short item)
- /*
- userItem drawing routine for outlining the default button in the dialog box
- */
- {
- Rect r;
- Handle h;
- short itemType;
-
- item = ok;
- GetDItem (dp, item, &itemType, &h, &r);
- PenNormal ();
- PenSize (3, 3);
- InsetRect (&r, -4, -4);
- FrameRoundRect (&r, 16, 16);
- PenNormal ();
- }
-
- GDHandle GetWindowGDevice(WindowPtr w)
- /*
- Find the deepest gdevice the window intersects. Used for determining the depth
- of the screen we're drawing on (to look good on B/W displays).
- */
- {
- Rect r=w->portRect;
- GrafPtr oldPort;
- GDHandle theGD;
-
- GetPort (&oldPort);
- SetPort (w);
- LocalToGlobal((Point *)&r);
- LocalToGlobal((Point *)(&(r.bottom)));
- theGD = GetMaxDevice(&r);
- SetPort (oldPort);
- return (theGD);
- }
-
- pascal void DrawLines (DialogPtr theDialog, short itemNo)
- /*
- userItem drawing routine for dividing lines (with shadow)
- */
- {
- RGBColor oldColor,greyColor;
- short itemType;
- Handle me;
- Rect box;
-
- GetDItem(theDialog,itemNo,&itemType,&me,&box);
- GetForeColor(&oldColor);
- RGBForeColor((RGBColor*)RGBBlack);
- MoveTo(box.left,box.top);
- LineTo(box.right-2,box.top);
- MoveTo(box.left,box.top+3);
- LineTo(box.right-2,box.top+3);
- if (((**((*GetWindowGDevice(theDialog))->gdPMap)).pixelSize >= 8)) {
- greyColor.red = greyColor.green = greyColor.blue = 0x7777;
- RGBForeColor (&greyColor);
- MoveTo(box.left+1,box.top+1);
- LineTo(box.right-1,box.top+1);
- MoveTo(box.left+1,box.top+4);
- LineTo(box.right-1,box.top+4);
- }
- RGBForeColor(&oldColor);
- }
-
- void SetupDItems (DialogPtr dp)
- /*
- Set up the dialog items
- */
- {
- Rect r;
- short itemType;
- Handle item;
-
- // default outline
- GetDItem (dp, defaultItem, &itemType, &item , &r);
- SetDItem (dp, defaultItem, itemType, (Handle) &OutlineOK, &r);
-
- // dividing lines
- GetDItem (dp, dividerItem, &itemType, &item , &r);
- SetDItem (dp, dividerItem, itemType, (Handle) DrawLines, &r);
- }
-
- /*
- Macro to disable all but one dialog items in a given range. Used for managing
- sets of radio buttons.
- */
- #define DisableAllButMe(i) for (j=leftToRightItem; j<=bottomToTopItem; j++) { \
- if (j==i) continue; GetDItem (dp,j,&itemType,&h,&r); \
- SetCtlValue((ControlHandle)h,0); }
-
- void RecalcDItems (WipeParamHandle p, DialogPtr dp)
- {
- short itemType,j;
- Handle h;
- Rect r;
-
- switch ((**p).angle) {
- case 0:
- DisableAllButMe(bottomToTopItem);
- GetDItem (dp,bottomToTopItem,&itemType,&h,&r);
- SetCtlValue ((ControlHandle)h,1);
- break;
- case 90:
- DisableAllButMe(leftToRightItem);
- GetDItem (dp,leftToRightItem,&itemType,&h,&r);
- SetCtlValue ((ControlHandle)h,1);
- break;
- case 180:
- DisableAllButMe(topToBottomItem);
- GetDItem (dp,topToBottomItem,&itemType,&h,&r);
- SetCtlValue ((ControlHandle)h,1);
- break;
- case 270:
- DisableAllButMe(rightToLeftItem);
- GetDItem (dp,rightToLeftItem,&itemType,&h,&r);
- SetCtlValue ((ControlHandle)h,1);
- break;
- }
- }
-
- XsnErr DoParameters (XsitionParamPtr params)
- /*
- Prompt the user for parameters if necessary.
- */
- {
- short item;
- DialogPtr dp;
- DialogTHndl dt;
- WipeParamHandle theParams;
-
- /* If we didn't get passed a params handle, allocate and initialize it */
- if (!params->parameters) {
- params->parameters = NewHandle (sizeof (WipeParams));
- if (!params->parameters) return (XSErrOutOfMemory|MemError());
- theParams = (WipeParamHandle) params->parameters;
- (**theParams).angle = 90;
- } else
- /*
- Otherwise, we just return. If we required specific hardware or mounds of
- memory we would check here.
- */
- return(noErr);
-
- /* Load in the dialog and center it */
- dt = (DialogTHndl) GetResource ('DLOG', dialogID);
- HNoPurge ((Handle) dt);
- CenterDialog (dt);
-
- /* Show it */
- dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
-
- /* Setup the user items and initialize all controls to initial state */
- SetupDItems (dp);
- RecalcDItems (theParams, dp);
-
- do {
- ModalDialog (nil, &item);
- switch (item) {
- case topToBottomItem:
- (**theParams).angle=180;
- RecalcDItems (theParams, dp);
- break;
- case leftToRightItem:
- (**theParams).angle=90;
- RecalcDItems (theParams, dp);
- break;
- case bottomToTopItem:
- (**theParams).angle=0;
- RecalcDItems (theParams, dp);
- break;
- case rightToLeftItem:
- (**theParams).angle=270;
- RecalcDItems (theParams, dp);
- break;
- }
- } while (item != ok && item != cancel);
-
- DisposDialog (dp);
- HPurge ((Handle) dt);
-
- if (item == cancel) {
- DisposHandle ((Handle)theParams);
- params->parameters = nil;
- return (XSErrReported);
- }
- return (noErr);
- }
-
- XsnErr DoProcessFrame (XsitionParamPtr params, short transitionIntensity, short maxTransitionIntensity)
- /* Perform the effect */
- {
- PixMapHandle srcA,srcB,dest;
- GWorldFlags pmStateA,pmStateB,pmStateDest;
- unsigned char stateA,stateB,stateDest;
- Rect r,bounds;
- GWorldPtr oldGW, destGW;
- GDHandle oldGD;
- short ySize,xSize;
- short angle;
- RGBColor oldFore,oldBack;
-
- if (TestAbort (params)) return (XSErrReported);
-
- srcA = params->srcA;
- srcB = params->srcB;
- destGW = params->destImage;
-
- /* Get the image pixmaps, dealing with pre-System 7 GetGWorldPixMap bug */
- if (*((short*)SysVersion)<0x700) {
- dest = destGW->portPixMap;
- } else {
- dest = GetGWorldPixMap (destGW);
- }
-
- r = (**srcA).bounds;
- ySize = r.bottom - r.top;
- xSize = r.right - r.left;
- UpdateProgress (params,0,3);
-
- /* Calculate the rectangle to copy based on the wipe direction */
- angle = (**((WipeParamHandle)(params->parameters))).angle;
- switch (angle) {
- case 0:
- SetRect (&r,0,0,xSize,ySize);
- r.top = r.bottom - (transitionIntensity * xSize / maxTransitionIntensity);
- break;
- case 90:
- SetRect (&r,0,0,xSize,ySize);
- r.right = r.left + (transitionIntensity * xSize / maxTransitionIntensity);
- break;
- case 180:
- SetRect (&r,0,0,xSize,ySize);
- r.bottom = r.top + (transitionIntensity * ySize / maxTransitionIntensity);
- break;
- case 270:
- SetRect (&r,0,0,xSize,ySize);
- r.left = r.right - (transitionIntensity * xSize / maxTransitionIntensity);
- break;
- }
-
- /* spin the beachball */
- UpdateProgress (params,1,3);
-
- /* save offscreen pixels state and lock them down for drawing */
- pmStateA = GetPixelsState(srcA);
- LockPixels (srcA);
- stateA = HGetState ((Handle)srcA);
- MoveHHi ((Handle)srcA);
- HLock ((Handle)srcA);
- pmStateB = GetPixelsState(srcB);
- LockPixels (srcB);
- stateB = HGetState ((Handle)srcB);
- MoveHHi ((Handle)srcB);
- HLock ((Handle)srcB);
- pmStateDest = GetPixelsState(dest);
- LockPixels (dest);
- stateDest = HGetState ((Handle)dest);
- MoveHHi ((Handle)dest);
- HLock ((Handle)dest);
-
- /* save drawing state */
- GetGWorld(&oldGW,&oldGD);
- SetGWorld (destGW,GetGWorldDevice(destGW));
- GetForeColor (&oldFore);
- GetBackColor (&oldBack);
- RGBForeColor ((RGBColor*)RGBBlack);
- RGBBackColor ((RGBColor*)RGBWhite);
-
- bounds = (**srcA).bounds;
-
- /* copy entire first source image */
- CopyBits((BitMap*)*srcA,(BitMap*)*dest,&bounds,&bounds,srcCopy,nil);
-
- /* spin beachball, restoring original graphic state */
- SetGWorld (oldGW,oldGD);
- UpdateProgress (params,2,3);
- SetGWorld (destGW,GetGWorldDevice(destGW));
-
- /* wait for accelerators */
- while (!QDDone((GrafPtr)destGW)); // Wait for accelerator.
-
- /* copy the piece of the second source that we calculated earlier */
- CopyBits((BitMap*)*srcB,(BitMap*)*dest,&r,&r,srcCopy,nil);
-
- /* wait for accelerators */
- while (!QDDone((GrafPtr)destGW)); // Wait for accelerator.
-
- /* restore graphic state */
- RGBForeColor (&oldFore);
- RGBBackColor (&oldBack);
-
- SetGWorld (oldGW,oldGD);
- UpdateProgress (params,3,3);
-
- /* restore offscreen pixmaps' state */
- HSetState ((Handle)srcA,stateA);
- SetPixelsState(srcA,pmStateA);
- HSetState ((Handle)srcB,stateB);
- SetPixelsState(srcB,pmStateB);
- HSetState ((Handle)dest,stateDest);
- SetPixelsState(dest,pmStateDest);
-
- return (noErr);
- }
-