void QTTarg_SetTrackProperties (Media theMedia, UInt32 theIdleFrequency) { QTAtomContainer myTrackProperties; RGBColor myBackgroundColor; Boolean hasActions; UInt32 myFrequency; OSErr myErr = noErr; // add a background color to the sprite track myBackgroundColor.red = EndianU16_NtoB(0xffff); myBackgroundColor.green = EndianU16_NtoB(0xffff); myBackgroundColor.blue = EndianU16_NtoB(0xffff); myErr = QTNewAtomContainer(&myTrackProperties); if (myErr == noErr) { QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyBackgroundColor, 1, 1, sizeof(myBackgroundColor), &myBackgroundColor, NULL); // tell the movie controller that this sprite track has actions hasActions = true; QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyHasActions, 1, 1, sizeof(hasActions), &hasActions, NULL); // tell the sprite track to generate QTIdleEvents myFrequency = EndianU32_NtoB(theIdleFrequency); QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyQTIdleEventsFrequency, 1, 1, sizeof(myFrequency), &myFrequency, NULL); SetMediaPropertyAtom(theMedia, myTrackProperties); QTDisposeAtomContainer(myTrackProperties); } }
//------------------------------------------------ void visitprops(TPropertyGroup &pg, int &index, QTAtomContainer &atoms, QTAtom parent) { int count = pg.getPropertyCount(); while (index < count) { TStringProperty *p = (TStringProperty *)pg.getProperty(index++); string str0 = p->getName(); const char *buf = str0.c_str(); int atomType, id, sonCount; sscanf(buf, "%d %d %d", &atomType, &id, &sonCount); QTAtom newAtom; if (sonCount == 0) { wstring appow = p->getValue(); string appo = toString(appow); const char *str = appo.c_str(); vector<UCHAR> buf; while (strlen(str) > 0) { if (str[0] == 'z') { int count = atoi(str + 1); str += (count < 10) ? 4 : ((count < 100) ? 5 : 6); while (count--) buf.push_back(0); } else { int val = atoi(str); assert(val >= 0 && val < 256); str += (val < 10) ? 2 : ((val < 100) ? 3 : 4); buf.push_back(val); } } //const unsigned short*bufs = str1.c_str(); //UCHAR *bufc = new UCHAR[size]; //for (int i=0; i<size; i++) // { // assert(bufs[i]<257); // bufc[i] = (UCHAR)(bufs[i]-1); // } void *ptr = 0; if (buf.size() != 0) { ptr = &(buf[0]); } QTInsertChild(atoms, parent, (QTAtomType)atomType, (QTAtomID)id, 0, buf.size(), (void *)ptr, 0); } else { QTInsertChild(atoms, parent, (QTAtomType)atomType, (QTAtomID)id, 0, 0, 0, &newAtom); visitprops(pg, index, atoms, newAtom); } } }
void send_movie_changed_notification(Movie movie) { QTAtomContainer container; if(QTNewAtomContainer(&container) == noErr) { QTAtom anAction; OSType whichAction = EndianU32_NtoB(kActionMovieChanged); OSErr err = QTInsertChild(container, kParentAtomIsContainer, kAction, 1, 0, 0, NULL, &anAction); if(err == noErr) err = QTInsertChild(container, anAction, kWhichAction, 1, 0, sizeof(whichAction), &whichAction, NULL); if(err == noErr) MovieExecuteWiredActions(movie, 0, container); QTDisposeAtomContainer(container); } }
OSErr SpriteUtils_AddSpriteToSample (QTAtomContainer theSample, QTAtomContainer theSprite, QTAtomID theSpriteID) { QTAtom mySpriteAtom = 0; OSErr myErr = paramErr; // see if the sample already contains a sprite atom of the specified ID mySpriteAtom = QTFindChildByID(theSample, kParentAtomIsContainer, kSpriteAtomType, theSpriteID, NULL); if (mySpriteAtom != 0) goto bail; // here, the index 0 means to append the sprite to the sample myErr = QTInsertChild(theSample, kParentAtomIsContainer, kSpriteAtomType, theSpriteID, 0, 0, NULL, &mySpriteAtom); if (myErr != noErr) goto bail; myErr = QTInsertChildren(theSample, mySpriteAtom, theSprite); bail: return(myErr); }
static OSErr SpriteUtils_SetImageGroupID (QTAtomContainer theKeySample, QTAtom theImagesContainerAtom, short theImageIndex, long theGroupID) { QTAtom myImageAtom, myImageGroupAtom; OSErr myErr = noErr; myImageAtom = QTFindChildByIndex(theKeySample, theImagesContainerAtom, kSpriteImageAtomType, theImageIndex, NULL); if (myImageAtom == 0) { myErr = cannotFindAtomErr; goto bail; } myImageGroupAtom = QTFindChildByIndex(theKeySample, myImageAtom, kSpriteImageGroupIDAtomType, 1, NULL); if (myImageGroupAtom == 0) { myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageGroupIDAtomType, 1, 1, 0, NULL, &myImageGroupAtom); if (myErr != noErr) goto bail; } theGroupID = EndianU32_NtoB(theGroupID); myErr = QTSetAtomData(theKeySample, myImageGroupAtom, sizeof(theGroupID), &theGroupID); bail: return(myErr); }
OSErr QTWired_MakeSpriteDraggable (QTAtomContainer theContainer, QTAtomID theID) { QTAtom mySpriteAtom = 0; QTAtom myEventAtom = 0; QTAtom myActionAtom = 0; QTAtom myParamAtom = 0; QTAtom myConditionalAtom, myExpressionAtom, myOperatorAtom, myOperandAtom, myOperandTypeAtom, myActionListAtom, myParameterAtom; short myOperandIndex; long myAction; QTAtomID myVariableID; float myVariableValue; float myConstantValue; Boolean myIsAbsolute; OSErr myErr = noErr; // find the sprite atom with the specified ID in the specified container mySpriteAtom = QTFindChildByID(theContainer, kParentAtomIsContainer, kSpriteAtomType, theID, NULL); if (mySpriteAtom == 0) { // if there is none, insert a new sprite atom into the specified container myErr = QTInsertChild(theContainer, kParentAtomIsContainer, kSpriteAtomType, theID, 1, 0, NULL, &mySpriteAtom); if (myErr != noErr) goto bail; } ////////// // // add a mouse click event handler // ////////// // find the event atom of type kQTEventMouseClick in the sprite atom myEventAtom = QTFindChildByID(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClick, NULL); if (myEventAtom == 0) { // if there is none, insert a new event atom of type kQTEventMouseClick into the sprite atom myErr = QTInsertChild(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClick, 1, 0, NULL, &myEventAtom); if (myErr != noErr) goto bail; } // add an action atom to the mouse click event handler myErr = QTInsertChild(theContainer, myEventAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionSpriteTrackSetVariable); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; // add parameters to the set variable action: variable ID (QTAtomID) and value (float) myVariableID = EndianU32_NtoB(kMouseStateVariableID); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kFirstParam, sizeof(myVariableID), &myVariableID, NULL); if (myErr != noErr) goto bail; myVariableValue = (float)1; EndianUtils_Float_NtoB(&myVariableValue); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kSecondParam, sizeof(myVariableValue), &myVariableValue, NULL); if (myErr != noErr) goto bail; ////////// // // add a mouse click end event handler // ////////// // find the event atom of type kQTEventMouseClick in the sprite atom myEventAtom = QTFindChildByID(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClickEnd, NULL); if (myEventAtom == 0) { // if there is none, insert a new event atom of type kQTEventMouseClick into the sprite atom myErr = QTInsertChild(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClickEnd, 1, 0, NULL, &myEventAtom); if (myErr != noErr) goto bail; } // add an action atom to the mouse click event handler myErr = QTInsertChild(theContainer, myEventAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionSpriteTrackSetVariable); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; // add parameters to the set variable action: variable ID (QTAtomID) and value (float) myVariableID = EndianU32_NtoB(kMouseStateVariableID); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kFirstParam, sizeof(myVariableID), &myVariableID, NULL); if (myErr != noErr) goto bail; myVariableValue = (float)0; EndianUtils_Float_NtoB(&myVariableValue); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kSecondParam, sizeof(myVariableValue), &myVariableValue, NULL); if (myErr != noErr) goto bail; ////////// // // add an idle event handler // ////////// // find the event atom of type kQTEventIdle in the sprite atom myEventAtom = QTFindChildByID(theContainer, mySpriteAtom, kQTEventType, kQTEventIdle, NULL); if (myEventAtom == 0) { // if there is none, insert a new event atom of type kQTEventIdle into the sprite atom myErr = QTInsertChild(theContainer, mySpriteAtom, kQTEventType, kQTEventIdle, 1, 0, NULL, &myEventAtom); if (myErr != noErr) goto bail; } // add an action atom to the mouse click event handler myErr = QTInsertChild(theContainer, myEventAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionCase); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; // add a parameter atom to the kActionCase action atom; this will serve as a parent to hold the expression and action atoms myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 1, kFirstParam, 0, NULL, &myParamAtom); if (myErr != noErr) goto bail; // the condition atom myErr = QTInsertChild(theContainer, myParamAtom, kConditionalAtomType, 0, 1, 0, NULL, &myConditionalAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myConditionalAtom, kExpressionContainerAtomType, 1, 1, 0, NULL, &myExpressionAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myExpressionAtom, kOperatorAtomType, kOperatorEqualTo, 1, 0, NULL, &myOperatorAtom); if (myErr != noErr) goto bail; // add the operands to the operator atom myOperandIndex = 1; myConstantValue = 1; myErr = QTInsertChild(theContainer, myOperatorAtom, kOperandAtomType, 0, myOperandIndex, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandConstant, 1, 1, 0, NULL, &myOperandTypeAtom); if (myErr != noErr) goto bail; EndianUtils_Float_NtoB(&myConstantValue); myErr = QTSetAtomData(theContainer, myOperandTypeAtom, sizeof(myConstantValue), &myConstantValue); myOperandIndex = 2; myVariableID = kMouseStateVariableID; myErr = QTInsertChild(theContainer, myOperatorAtom, kOperandAtomType, 0, myOperandIndex, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myOperandTypeAtom); if (myErr != noErr) goto bail; myVariableID = EndianU32_NtoB(myVariableID); myErr = QTInsertChild(theContainer, myOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); if (myErr != noErr) goto bail; // add an action list atom myErr = QTInsertChild(theContainer, myConditionalAtom, kActionListAtomType, 1, 1, 0, NULL, &myActionListAtom); if (myErr != noErr) goto bail; // add sprite translate action myErr = QTInsertChild(theContainer, myActionListAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionSpriteTranslate); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; ////////// // // add parameters to the translate action: Fixed x, Fixed y, Boolean isAbsolute // ////////// // first parameter: get current mouse position x myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kFirstParam, 0, NULL, &myParameterAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myParameterAtom, kExpressionContainerAtomType, 1, 1, 0, NULL, &myExpressionAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandMouseLocalHLoc, 1, 1, 0, NULL, NULL); if (myErr != noErr) goto bail; // second parameter: get current mouse position y myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kSecondParam, 0, NULL, &myParameterAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myParameterAtom, kExpressionContainerAtomType, 1, 1, 0, NULL, &myExpressionAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandMouseLocalVLoc, 1, 1, 0, NULL, NULL); if (myErr != noErr) goto bail; myIsAbsolute = true; myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kThirdParam, sizeof(myIsAbsolute), &myIsAbsolute, NULL); bail: return(myErr); }
OSErr QTWired_AddCursorChangeOnMouseOver (QTAtomContainer theContainer, QTAtomID theID) { QTAtom mySpriteAtom = 0; QTAtom myBehaviorAtom = 0; QTSpriteButtonBehaviorStruct myBehaviorRec; OSErr myErr = noErr; // find the sprite atom with the specified ID in the specified container mySpriteAtom = QTFindChildByID(theContainer, kParentAtomIsContainer, kSpriteAtomType, theID, NULL); if (mySpriteAtom == 0) { // if there is none, insert a new sprite atom into the specified container myErr = QTInsertChild(theContainer, kParentAtomIsContainer, kSpriteAtomType, theID, 0, 0, NULL, &mySpriteAtom); if (myErr != noErr) goto bail; } // insert a new sprite behaviors atom into the sprite atom myErr = QTInsertChild(theContainer, mySpriteAtom, kSpriteBehaviorsAtomType, 1, 1, 0, NULL, &myBehaviorAtom); if (myErr != noErr) goto bail; ////////// // // insert three atoms into the sprite behaviors atom; these three atoms specify what to do on each // of the four defined state transitions for the (1) sprite image, (2) cursor, and (3) status string // ////////// // set the sprite image behavior; -1 means: no change associated with this state transition myBehaviorRec.notOverNotPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.overNotPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.overPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.notOverPressedStateID = EndianS32_NtoB(-1); myErr = QTInsertChild(theContainer, myBehaviorAtom, kSpriteImageBehaviorAtomType, 1, 1, sizeof(QTSpriteButtonBehaviorStruct), &myBehaviorRec, NULL); if (myErr != noErr) goto bail; // set the sprite cursor behavior; -1 means: no change associated with this state transition myBehaviorRec.notOverNotPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.overNotPressedStateID = EndianS32_NtoB(kQTCursorOpenHand); myBehaviorRec.overPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.notOverPressedStateID = EndianS32_NtoB(-1); myErr = QTInsertChild(theContainer, myBehaviorAtom, kSpriteCursorBehaviorAtomType, 1, 1, sizeof(QTSpriteButtonBehaviorStruct), &myBehaviorRec, NULL); if (myErr != noErr) goto bail; // set the status string behavior; -1 means: no change associated with this state transition myBehaviorRec.notOverNotPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.overNotPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.overPressedStateID = EndianS32_NtoB(-1); myBehaviorRec.notOverPressedStateID = EndianS32_NtoB(-1); myErr = QTInsertChild(theContainer, myBehaviorAtom, kSpriteStatusStringsBehaviorAtomType, 1, 1, sizeof(QTSpriteButtonBehaviorStruct), &myBehaviorRec, NULL); if (myErr != noErr) goto bail; bail: return(myErr); }
OSErr QTWired_CreateWiredSpritesMovie (void) { short myResRefNum = 0; short myResID = movieInDataForkResID; Movie myMovie = NULL; Track myTrack; Media myMedia; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kWiredSavePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kWiredSaveFileName); QTAtomContainer mySample = NULL; QTAtomContainer myActions = NULL; QTAtomContainer myBeginButton, myPrevButton, myNextButton, myEndButton; QTAtomContainer myPenguinOne, myPenguinTwo, myPenguinOneOverride; QTAtomContainer myBeginActionButton, myPrevActionButton, myNextActionButton, myEndActionButton; QTAtomContainer myPenguinOneAction, myPenguinTwoAction; RGBColor myKeyColor; Point myLocation; short isVisible, myLayer, myIndex, myID, i, myDelta; Boolean hasActions; long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; OSType myType = FOUR_CHAR_CODE('none'); UInt32 myFrequency; QTAtom myEventAtom; long myLoopingFlags; ModifierTrackGraphicsModeRecord myGraphicsMode; OSErr myErr = noErr; ////////// // // create a new movie file and set its controller type // ////////// // ask the user for the name of the new movie file QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); if (!myIsSelected) goto bail; // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie); if (myErr != noErr) goto bail; // select the "no controller" movie controller myType = EndianU32_NtoB(myType); SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); ////////// // // create the sprite track and media // ////////// myTrack = NewMovieTrack(myMovie, ((long)kSpriteTrackWidth << 16), ((long)kSpriteTrackHeight << 16), kNoVolume); myMedia = NewTrackMedia(myTrack, SpriteMediaType, kSpriteMediaTimeScale, NULL, 0); ////////// // // create a key frame sample containing six sprites and all of their shared images // ////////// // create a new, empty key frame sample myErr = QTNewAtomContainer(&mySample); if (myErr != noErr) goto bail; myKeyColor.red = 0xffff; // white myKeyColor.green = 0xffff; myKeyColor.blue = 0xffff; // add images to the key frame sample SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToBeginningButtonUp, &myKeyColor, kGoToBeginningButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToBeginningButtonDown, &myKeyColor, kGoToBeginningButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToEndButtonUp, &myKeyColor, kGoToEndButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToEndButtonDown, &myKeyColor, kGoToEndButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToPrevButtonUp, &myKeyColor, kGoToPrevButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToPrevButtonDown, &myKeyColor, kGoToPrevButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToNextButtonUp, &myKeyColor, kGoToNextButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToNextButtonDown, &myKeyColor, kGoToNextButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinForward, &myKeyColor, kPenguinForwardIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinLeft, &myKeyColor, kPenguinLeftIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinRight, &myKeyColor, kPenguinRightIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinClosed, &myKeyColor, kPenguinClosedIndex, NULL, NULL); for (myIndex = kPenguinDownRightCycleStartIndex, myID = kWalkDownRightCycleStart; myIndex <= kPenguinDownRightCycleEndIndex; myIndex++, myID++) SpriteUtils_AddPICTImageToKeyFrameSample(mySample, myID, &myKeyColor, myIndex, NULL, NULL); // assign group IDs to the images SpriteUtils_AssignImageGroupIDsToKeyFrame(mySample); ////////// // // add samples to the sprite track's media // ////////// BeginMediaEdits(myMedia); // go to beginning button with no actions myErr = QTNewAtomContainer(&myBeginButton); if (myErr != noErr) goto bail; myLocation.h = (1 * kSpriteTrackWidth / 8) - (kStartEndButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToBeginningButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myBeginButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // go to previous button with no actions myErr = QTNewAtomContainer(&myPrevButton); if (myErr != noErr) goto bail; myLocation.h = (3 * kSpriteTrackWidth / 8) - (kNextPrevButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToPrevButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myPrevButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // go to next button with no actions myErr = QTNewAtomContainer(&myNextButton); if (myErr != noErr) goto bail; myLocation.h = (5 * kSpriteTrackWidth / 8) - (kNextPrevButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToNextButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myNextButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // go to end button with no actions myErr = QTNewAtomContainer(&myEndButton); if (myErr != noErr) goto bail; myLocation.h = (7 * kSpriteTrackWidth / 8) - (kStartEndButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToEndButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myEndButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // first penguin sprite with no actions myErr = QTNewAtomContainer(&myPenguinOne); if (myErr != noErr) goto bail; myLocation.h = (3 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2); myLocation.v = (kSpriteTrackHeight / 4) - (kPenguinHeight / 2); isVisible = true; myLayer = 2; myIndex = kPenguinDownRightCycleStartIndex; myGraphicsMode.graphicsMode = blend; myGraphicsMode.opColor.red = myGraphicsMode.opColor.green = myGraphicsMode.opColor.blue = 0x8FFF; // grey myErr = SpriteUtils_SetSpriteData(myPenguinOne, &myLocation, &isVisible, &myLayer, &myIndex, &myGraphicsMode, NULL, myActions); if (myErr != noErr) goto bail; // second penguin sprite with no actions myErr = QTNewAtomContainer(&myPenguinTwo); if (myErr != noErr) goto bail; myLocation.h = (5 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2); myLocation.v = (kSpriteTrackHeight / 4) - (kPenguinHeight / 2); isVisible = true; myLayer = 3; myIndex = kPenguinForwardIndex; myErr = SpriteUtils_SetSpriteData(myPenguinTwo, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; ////////// // // add actions to the six sprites // ////////// // add go to beginning button myErr = QTCopyAtom(myBeginButton, kParentAtomIsContainer, &myBeginActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToBeginningButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToBeginningButtonUpIndex, NULL); WiredUtils_AddMovieGoToBeginningAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myBeginActionButton, kGoToBeginningSpriteID); QTDisposeAtomContainer(myBeginActionButton); // add go to prev button myErr = QTCopyAtom(myPrevButton, kParentAtomIsContainer, &myPrevActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToPrevButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToPrevButtonUpIndex, NULL); WiredUtils_AddMovieStepBackwardAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myPrevActionButton, kGoToPrevSpriteID); QTDisposeAtomContainer(myPrevActionButton); // add go to next button myErr = QTCopyAtom(myNextButton, kParentAtomIsContainer, &myNextActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToNextButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToNextButtonUpIndex, NULL); WiredUtils_AddMovieStepForwardAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myNextActionButton, kGoToNextSpriteID); QTDisposeAtomContainer(myNextActionButton); // add go to end button myErr = QTCopyAtom(myEndButton, kParentAtomIsContainer, &myEndActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToEndButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToEndButtonUpIndex, NULL); WiredUtils_AddMovieGoToEndAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myEndActionButton, kGoToEndSpriteID); QTDisposeAtomContainer(myEndActionButton); // add penguin one myErr = QTCopyAtom(myPenguinOne, kParentAtomIsContainer, &myPenguinOneAction); if (myErr != noErr) goto bail; // show the buttons on mouse enter and hide them on mouse exit WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToBeginningSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToBeginningSpriteID, false, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToPrevSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToPrevSpriteID, false, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToNextSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToNextSpriteID, false, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToEndSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToEndSpriteID, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myPenguinOneAction, kPenguinOneSpriteID); QTWired_AddCursorChangeOnMouseOver(mySample, kPenguinOneSpriteID); QTDisposeAtomContainer(myPenguinOneAction); // add penguin two myErr = QTCopyAtom(myPenguinTwo, kParentAtomIsContainer, &myPenguinTwoAction); if (myErr != noErr) goto bail; // blink when clicked on WiredUtils_AddSpriteSetImageIndexAction(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kPenguinClosedIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kPenguinForwardIndex, NULL); WiredUtils_AddQTEventAtom(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton, &myEventAtom); // toggle the movie rate and both of the birds' graphics modes QTWired_AddPenguinTwoConditionalActions(myPenguinTwoAction, myEventAtom); QTWired_AddWraparoundMatrixOnIdle(myPenguinTwoAction); SpriteUtils_AddSpriteToSample(mySample, myPenguinTwoAction, kPenguinTwoSpriteID); QTDisposeAtomContainer(myPenguinTwoAction); // add an action for when the key frame is loaded, to set the movie's looping mode to palindrome; // note that this will actually be triggered every time the key frame is reloaded, // so if the operation was expensive we could use a conditional to test if we've already done it myLoopingFlags = loopTimeBase | palindromeLoopTimeBase; WiredUtils_AddMovieSetLoopingFlagsAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, myLoopingFlags); // add the key frame sample to the sprite track media // // to add the sample data in a compressed form, you would use a QuickTime DataCodec to perform the // compression; replace the call to the utility AddSpriteSampleToMedia with a call to the utility // AddCompressedSpriteSampleToMedia to do this SpriteUtils_AddSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, true, NULL); //SpriteUtils_AddCompressedSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, true, zlibDataCompressorSubType, NULL); ////////// // // add a few override samples to move penguin one and change its image index // ////////// // original penguin one location myLocation.h = (3 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2); myLocation.v = (kSpriteTrackHeight / 4) - (kPenguinHeight / 2); myDelta = (kSpriteTrackHeight / 2) / kNumOverrideSamples; myIndex = kPenguinDownRightCycleStartIndex; for (i = 1; i <= kNumOverrideSamples; i++) { QTRemoveChildren(mySample, kParentAtomIsContainer); QTNewAtomContainer(&myPenguinOneOverride); myLocation.h += myDelta; myLocation.v += myDelta; myIndex++; if (myIndex > kPenguinDownRightCycleEndIndex) myIndex = kPenguinDownRightCycleStartIndex; SpriteUtils_SetSpriteData(myPenguinOneOverride, &myLocation, NULL, NULL, &myIndex, NULL, NULL, NULL); SpriteUtils_AddSpriteToSample(mySample, myPenguinOneOverride, kPenguinOneSpriteID); SpriteUtils_AddSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, false, NULL); QTDisposeAtomContainer(myPenguinOneOverride); } EndMediaEdits(myMedia); // add the media to the track InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); ////////// // // set the sprite track properties // ////////// { QTAtomContainer myTrackProperties; RGBColor myBackgroundColor; // add a background color to the sprite track myBackgroundColor.red = EndianU16_NtoB(0x8000); myBackgroundColor.green = EndianU16_NtoB(0); myBackgroundColor.blue = EndianU16_NtoB(0xffff); QTNewAtomContainer(&myTrackProperties); QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyBackgroundColor, 1, 1, sizeof(RGBColor), &myBackgroundColor, NULL); // tell the movie controller that this sprite track has actions, Jackson hasActions = true; QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyHasActions, 1, 1, sizeof(hasActions), &hasActions, NULL); // tell the sprite track to generate QTIdleEvents myFrequency = EndianU32_NtoB(2); QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyQTIdleEventsFrequency, 1, 1, sizeof(myFrequency), &myFrequency, NULL); myErr = SetMediaPropertyAtom(myMedia, myTrackProperties); if (myErr != noErr) goto bail; QTDisposeAtomContainer(myTrackProperties); } ////////// // // finish up // ////////// // add the movie resource to the movie file myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name); bail: free(myPrompt); free(myFileName); if (mySample != NULL) QTDisposeAtomContainer(mySample); if (myBeginButton != NULL) QTDisposeAtomContainer(myBeginButton); if (myPrevButton != NULL) QTDisposeAtomContainer(myPrevButton); if (myNextButton != NULL) QTDisposeAtomContainer(myNextButton); if (myEndButton != NULL) QTDisposeAtomContainer(myEndButton); if (myResRefNum != 0) CloseMovieFile(myResRefNum); if (myMovie != NULL) DisposeMovie(myMovie); return(myErr); }
OSErr SpriteUtils_AddCompressedImageToKeyFrameSample (QTAtomContainer theKeySample, ImageDescriptionHandle theImageDesc, long theDataSize, Ptr theCompressedDataPtr, QTAtomID theImageID, FixedPoint *theRegistrationPoint, StringPtr theImageName) { Handle myImageData = NULL; QTAtom myDefaultsAtom, myImagesContainerAtom, myImageAtom; ImageDescriptionHandle myImageDesc = NULL; OSErr myErr = noErr; #if TARGET_RT_LITTLE_ENDIAN myImageDesc = (ImageDescriptionHandle)NewHandle(GetHandleSize((Handle)theImageDesc)); BlockMoveData(*theImageDesc, *myImageDesc, GetHandleSize((Handle)theImageDesc)); EndianUtils_ImageDescription_NtoB(myImageDesc); #else myImageDesc = theImageDesc; // already is big endian #endif // append compressed picture data to myImageDesc to obtain sprite image data myImageData = NewHandle(0); myErr = MemError(); if (myErr != noErr) goto bail; myErr = HandAndHand((Handle)myImageDesc, myImageData); if (myErr != noErr) goto bail; myErr = PtrAndHand(theCompressedDataPtr, myImageData, theDataSize); if (myErr != noErr) goto bail; myDefaultsAtom = QTFindChildByIndex(theKeySample, 0, kSpriteSharedDataAtomType, 1, NULL); if (myDefaultsAtom == 0) { myErr = QTInsertChild(theKeySample, kParentAtomIsContainer, kSpriteSharedDataAtomType, 1, 0, 0, NULL, &myDefaultsAtom); if (myErr != noErr) goto bail; } myImagesContainerAtom = QTFindChildByIndex(theKeySample, myDefaultsAtom, kSpriteImagesContainerAtomType, 1, NULL); if (myImagesContainerAtom == 0) { myErr = QTInsertChild(theKeySample, myDefaultsAtom, kSpriteImagesContainerAtomType, 1, 0, 0, NULL, &myImagesContainerAtom); if (myErr != noErr) goto bail; } myErr = QTInsertChild(theKeySample, myImagesContainerAtom, kSpriteImageAtomType, theImageID, 0, 0, NULL, &myImageAtom); if (myErr != noErr) goto bail; HLock(myImageData); myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageDataAtomType, 1, 0, GetHandleSize(myImageData), *myImageData, NULL); if (myErr != noErr) goto bail; HUnlock(myImageData); if (theRegistrationPoint != NULL) { FixedPoint myRegistrationPoint; myRegistrationPoint.x = EndianS32_NtoB(theRegistrationPoint->x); myRegistrationPoint.y = EndianS32_NtoB(theRegistrationPoint->y); myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageRegistrationAtomType, 1, 0, sizeof(myRegistrationPoint), &myRegistrationPoint, NULL); if (myErr != noErr) goto bail; } else { FixedPoint myRegistrationPoint = { 0, 0 }; // flipping {0,0} doesn't change anything so we don't flip myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageRegistrationAtomType, 1, 0, sizeof(myRegistrationPoint), &myRegistrationPoint, NULL); if (myErr != noErr) goto bail; } if (theImageName != NULL) { myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageNameAtomType, 1, 0, theImageName[0], &theImageName[1], NULL); if (myErr != noErr) goto bail; } bail: #if TARGET_RT_LITTLE_ENDIAN if (myImageDesc != NULL) DisposeHandle((Handle)myImageDesc); #else // myImageDesc is still theImageDesc, so don't dispose of it #endif if (myImageData != NULL) DisposeHandle(myImageData); return(myErr); }
OSErr SpriteUtils_SetSpriteData (QTAtomContainer theSprite, Point *theLocation, short *theVisible, short *theLayer, short *theImageIndex, ModifierTrackGraphicsModeRecord *theGraphicsMode, StringPtr theSpriteName, QTAtomContainer theActionAtoms) { QTAtom myPropertyAtom; OSErr myErr = noErr; if (theSprite == NULL) return(paramErr); // set the sprite location data if (theLocation != NULL) { MatrixRecord myMatrix; SetIdentityMatrix(&myMatrix); myMatrix.matrix[2][0] = ((long)theLocation->h << 16); myMatrix.matrix[2][1] = ((long)theLocation->v << 16); EndianUtils_MatrixRecord_NtoB(&myMatrix); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyMatrix, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyMatrix, 1, 0, sizeof(MatrixRecord), &myMatrix, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(MatrixRecord), &myMatrix); if (myErr != noErr) goto bail; } // set the sprite visibility state if (theVisible != NULL) { short myVisible = *theVisible; myVisible = EndianS16_NtoB(myVisible); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyVisible, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyVisible, 1, 0, sizeof(short), &myVisible, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myVisible); if (myErr != noErr) goto bail; } // set the sprite layer if (theLayer != NULL) { short myLayer = *theLayer; myLayer = EndianS16_NtoB(myLayer); myPropertyAtom = QTFindChildByIndex(theSprite, 0, kSpritePropertyLayer, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, 0, kSpritePropertyLayer, 1, 0, sizeof(short), &myLayer, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myLayer); if (myErr != noErr) goto bail; } // set the sprite image index if (theImageIndex != NULL) { short myImageIndex = *theImageIndex; myImageIndex = EndianS16_NtoB(myImageIndex); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyImageIndex, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyImageIndex, 1, 0, sizeof(short), &myImageIndex, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myImageIndex); if (myErr != noErr) goto bail; } // set the sprite graphics mode if (theGraphicsMode != NULL) { ModifierTrackGraphicsModeRecord myGraphicsMode; myGraphicsMode.graphicsMode = EndianU32_NtoB(theGraphicsMode->graphicsMode); myGraphicsMode.opColor.red = EndianU16_NtoB(theGraphicsMode->opColor.red); myGraphicsMode.opColor.green = EndianU16_NtoB(theGraphicsMode->opColor.green); myGraphicsMode.opColor.blue = EndianU16_NtoB(theGraphicsMode->opColor.blue); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyGraphicsMode, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyGraphicsMode, 1, 0, sizeof(myGraphicsMode), &myGraphicsMode, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(myGraphicsMode), &myGraphicsMode); if (myErr != noErr) goto bail; } // set the sprite name if (theSpriteName != NULL) { QTAtom mySpriteNameAtom; mySpriteNameAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpriteNameAtomType, 1, NULL); if (mySpriteNameAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpriteNameAtomType, 1, 0, theSpriteName[0] + 1, theSpriteName, NULL); else myErr = QTSetAtomData(theSprite, mySpriteNameAtom, theSpriteName[0] + 1, theSpriteName); if (myErr != noErr) goto bail; } // set the action atoms if (theActionAtoms != NULL) myErr = QTInsertChildren(theSprite, kParentAtomIsContainer, theActionAtoms); bail: if ((myErr != noErr) && (theSprite != NULL)) QTRemoveChildren(theSprite, 0); return(myErr); }
void QTEffects_RespondToDialogSelection (OSErr theErr) { Boolean myDialogWasCancelled = false; short myResID = movieInDataForkResID; UInt16 myMovieIter; short mySrcMovieRefNum = 0; Movie myPrevSrcMovie = NULL; Track myPrevSrcTrack = NULL; Movie myNextSrcMovie = NULL; Track myNextSrcTrack = NULL; short myDestMovieRefNum = 0; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kEffectsSaveMoviePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kEffectsSaveMovieFileName); Movie myDestMovie = NULL; Fixed myDestMovieWidth, myDestMovieHeight; ImageDescriptionHandle myDesc = NULL; Track videoTrackFX, videoTrackA, videoTrackB; Media videoMediaFX, videoMediaA, videoMediaB; TimeValue myCurrentDuration = 0; TimeValue myReturnedDuration; Boolean isFirstTransition = true; TimeValue myMediaTransitionDuration; TimeValue myMediaFXStartTime, myMediaFXDuration; OSType myEffectCode; long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; long myLong; OSErr myErr = noErr; // standard parameter box has been dismissed, so remember that fact gEffectsDialog = 0L; myDialogWasCancelled = (theErr == userCanceledErr); // we're finished with the effect list and movie posters QTDisposeAtomContainer(gEffectList); if (gPosterA != NULL) KillPicture(gPosterA); if (gPosterB != NULL) KillPicture(gPosterB); // when the sign says stop, then stop if (myDialogWasCancelled) goto bail; // add atoms naming the sources to gEffectSample myLong = EndianU32_NtoB(kSourceOneName); QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 1, 0, sizeof(myLong), &myLong, NULL); myLong = EndianU32_NtoB(kSourceTwoName); QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 2, 0, sizeof(myLong), &myLong, NULL); // extract the 'what' atom to find out what kind of effect it is { QTAtom myEffectAtom; QTAtomID myEffectAtomID; long myEffectCodeSize; Ptr myEffectCodePtr; myEffectAtom = QTFindChildByIndex(gEffectSample, kParentAtomIsContainer, kParameterWhatName, kParameterWhatID, &myEffectAtomID); myErr = QTLockContainer(gEffectSample); BailError(myErr); myErr = QTGetAtomDataPtr(gEffectSample, myEffectAtom, &myEffectCodeSize, &myEffectCodePtr); BailError(myErr); if (myEffectCodeSize != sizeof(OSType)) { myErr = paramErr; goto bail; } myEffectCode = *(OSType *)myEffectCodePtr; // "tsk" myEffectCode = EndianU32_BtoN(myEffectCode); // because the data is read from an atom container myErr = QTUnlockContainer(gEffectSample); BailError(myErr); } // ask the user for the name of the new movie file QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); if (!myIsSelected) goto bail; // deal with user cancelling // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), 0, myFlags, &myDestMovieRefNum, &myDestMovie); BailError(myErr); // open the first file as a movie; call the first movie myPrevSrcMovie myErr = OpenMovieFile(&gSpecList[0], &mySrcMovieRefNum, fsRdPerm); BailError(myErr); myErr = NewMovieFromFile(&myPrevSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL); BailError(myErr); myErr = CloseMovieFile(mySrcMovieRefNum); BailError(myErr); // if the movie is shorter than kMinimumDuration, scale it to that length SetMovieTimeScale(myPrevSrcMovie, kTimeScale); myErr = QTEffects_GetFirstVideoTrackInMovie(myPrevSrcMovie, &myPrevSrcTrack); BailNil(myPrevSrcTrack); if (GetTrackDuration(myPrevSrcTrack) < kMinimumDuration) { myErr = ScaleTrackSegment(myPrevSrcTrack, 0, GetTrackDuration(myPrevSrcTrack), kMinimumDuration); BailError(myErr); } // find out how big the first movie is; we'll use it as the size of all our tracks GetTrackDimensions(myPrevSrcTrack, &myDestMovieWidth, &myDestMovieHeight); #if USES_MAKE_IMAGE_DESC_FOR_EFFECT // create a new sample description for the effect, // which is just an image description specifying the effect and its dimensions myErr = MakeImageDescriptionForEffect(myEffectCode, &myDesc); if (myErr != noErr) BailError(myErr); #else // create a new sample description for the effect, // which is just an image description specifying the effect and its dimensions myDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); BailNil(myDesc); (**myDesc).idSize = sizeof(ImageDescription); (**myDesc).cType = myEffectCode; (**myDesc).hRes = 72L << 16; (**myDesc).vRes = 72L << 16; (**myDesc).dataSize = 0L; (**myDesc).frameCount = 1; (**myDesc).depth = 0; (**myDesc).clutID = -1; #endif // fill in the fields of the sample description (**myDesc).vendor = kAppleManufacturer; (**myDesc).temporalQuality = codecNormalQuality; (**myDesc).spatialQuality = codecNormalQuality; (**myDesc).width = FixRound(myDestMovieWidth); (**myDesc).height = FixRound(myDestMovieHeight); // add three video tracks to the destination movie: // - videoTrackFX is where the effects and stills live; it's user-visible. // - videoTrackA is where the "source A"s for effects live; it's hidden by the input map // - videoTrackB is where the "source B"s for effects live; it's hidden by the input map videoTrackFX = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0); BailNil(videoTrackFX); videoMediaFX = NewTrackMedia(videoTrackFX, VideoMediaType, kTimeScale, NULL, 0); BailNil(videoMediaFX); myErr = BeginMediaEdits(videoMediaFX); BailError(myErr); videoTrackA = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0); BailNil(videoTrackA); videoMediaA = NewTrackMedia(videoTrackA, VideoMediaType, kTimeScale, NULL, 0); BailNil(videoMediaA); videoTrackB = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0); BailNil(videoTrackB); videoMediaB = NewTrackMedia(videoTrackB, VideoMediaType, kTimeScale, NULL, 0); BailNil(videoMediaB); // create the input map { long myRefIndex1, myRefIndex2; QTAtomContainer myInputMap; QTAtom myInputAtom; OSType myInputType; QTNewAtomContainer(&myInputMap); // first input if (videoTrackA) { AddTrackReference(videoTrackFX, videoTrackA, kTrackModifierReference, &myRefIndex1); QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex1, 0, 0, NULL, &myInputAtom); myInputType = EndianU32_NtoB(kTrackModifierTypeImage); QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL); myLong = EndianU32_NtoB(kSourceOneName); QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL); } // second input if (videoTrackB) { AddTrackReference(videoTrackFX, videoTrackB, kTrackModifierReference, &myRefIndex2); QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex2, 0, 0, NULL, &myInputAtom); myInputType = EndianU32_NtoB(kTrackModifierTypeImage); QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL); myLong = EndianU32_NtoB(kSourceTwoName); QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL); } // set that map SetMediaInputMap(GetTrackMedia(videoTrackFX), myInputMap); QTDisposeAtomContainer(myInputMap); } myCurrentDuration = 0; #if MAKE_STILL_SECTIONS // copy the first sample of the first video track of the first movie to videoTrackFX, with duration kStillDuration. myErr = CopyPortionOfTrackToTrack(myPrevSrcTrack, eStartPortion + eMiddlePortion, videoTrackFX, myCurrentDuration, &myReturnedDuration); BailError(myErr); myCurrentDuration += myReturnedDuration; #endif // now process any remaining files myMovieIter = 1; while (myMovieIter < gSpecCount) { // open the next file as a movie; call it nextSourceMovie myErr = OpenMovieFile(&gSpecList[myMovieIter], &mySrcMovieRefNum, fsRdPerm); BailError(myErr); myErr = NewMovieFromFile(&myNextSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL); BailError(myErr); // we're done with the movie file, so close it myErr = CloseMovieFile(mySrcMovieRefNum); BailError(myErr); // if the movie is shorter than kMinimumDuration, scale it to that length SetMovieTimeScale(myNextSrcMovie, kTimeScale); myErr = QTEffects_GetFirstVideoTrackInMovie(myNextSrcMovie, &myNextSrcTrack); BailNil(myNextSrcTrack); if (GetTrackDuration(myNextSrcTrack) < kMinimumDuration) { myErr = ScaleTrackSegment(myNextSrcTrack, 0, GetTrackDuration(myNextSrcTrack), kMinimumDuration); BailError(myErr); } // create a transition effect from the previous source movie's first video sample to the next source movie's first video sample // (the effect should have duration kEffectDuration); // this involves adding one sample to each of the three video tracks: // sample from previous source movie -> videoTrackA myErr = QTEffects_CopyPortionOfTrackToTrack(myPrevSrcTrack, eFinishPortion, videoTrackA, myCurrentDuration, &myReturnedDuration); BailError(myErr); // sample from next source movie -> videoTrackB myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eStartPortion, videoTrackB, myCurrentDuration, &myReturnedDuration); BailError(myErr); // effect sample -> videoTrackFX if (isFirstTransition) { myMediaTransitionDuration = myReturnedDuration; myMediaFXStartTime = GetMediaDuration(videoMediaFX); myErr = AddMediaSample(videoMediaFX, gEffectSample, 0, GetHandleSize(gEffectSample), myMediaTransitionDuration, (SampleDescriptionHandle)myDesc, 1, 0, NULL); BailError(myErr); myMediaFXDuration = GetMediaDuration(videoMediaFX) - myMediaFXStartTime; isFirstTransition = false; } myErr = InsertMediaIntoTrack(videoTrackFX, myCurrentDuration, myMediaFXStartTime, myMediaFXDuration, FixRatio(myReturnedDuration, myMediaTransitionDuration)); BailError(myErr); myCurrentDuration += myReturnedDuration; #if MAKE_STILL_SECTIONS // copy the first video sample of myNextSrcMovie to videoTrackFX, with duration kStillDuration. myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eMiddlePortion + (myMovieIter + 1 == theSpecCount) ? eFinishPortion : 0, videoTrackFX, myCurrentDuration, &myReturnedDuration); BailError(myErr); myCurrentDuration += myReturnedDuration; #endif // MAKE_STILL_SECTIONS // dispose of previous source movie. DisposeMovie(myPrevSrcMovie); myPrevSrcMovie = myNextSrcMovie; myPrevSrcTrack = myNextSrcTrack; myNextSrcMovie = NULL; myNextSrcTrack = NULL; myMovieIter++; } // while myErr = EndMediaEdits(videoMediaFX); BailError(myErr); myErr = AddMovieResource(myDestMovie, myDestMovieRefNum, &myResID, "\pMovie 1"); BailError(myErr); CloseMovieFile(myDestMovieRefNum); if (myPrevSrcMovie != NULL) DisposeMovie(myPrevSrcMovie); DisposeMovie(myDestMovie); bail: free(myPrompt); free(myFileName); QTDisposeAtomContainer(gEffectSample); DisposeHandle((Handle)myDesc); return; }