Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
QTWiredActions.c
////////// |
// |
// File: QTWiredActions.c |
// |
// Contains: QuickTime wired sprites target support for QuickTime movies. |
// |
// Written by: Tim Monroe |
// |
// Copyright: © 2001 by Apple Computer, Inc., all rights reserved. |
// |
// Change History (most recent first): |
// |
// <2> 03/28/01 rtm begun adding advanced sprite code |
// <1> 03/10/01 rtm first file; based on existing AddHTActions sample code |
// |
// |
////////// |
////////// |
// |
// header files |
// |
////////// |
#include "QTWiredActions.h" |
////////// |
// |
// QTWired_CreateTextMovie |
// Create a movie with a text track. |
// |
////////// |
OSErr QTWired_CreateTextMovie (FSSpec *theFSSpec) |
{ |
short myResRefNum = -1; |
short myResID = movieInDataForkResID; |
Movie myMovie = NULL; |
Track myTrack = NULL; |
Media myMedia = NULL; |
MediaHandler myHandler = NULL; |
Rect myTextBox; |
RGBColor myTextColor = {0x0000, 0x0000, 0x0000}; |
RGBColor myBackColor = {0x8888, 0x8888, 0x8888}; |
RGBColor myHiliteColor = {0x0000, 0x0000, 0x0000}; |
long myDisplayFlags = 0; |
short myHiliteStart = 0; |
short myHiliteEnd = 0; |
TimeValue myNewMediaTime; |
TimeValue myScrollDelay = 0; |
#if TARGET_OS_MAC |
char myText[] = "\rPlease take me to Apple or CNN"; |
#else |
char myText[] = "\nPlease take me to Apple or CNN"; |
#endif |
long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile | newMovieActive; |
OSType myType = FOUR_CHAR_CODE('none'); |
OSErr myErr = noErr; |
////////// |
// |
// create a new text movie |
// |
////////// |
myErr = CreateMovieFile(theFSSpec, FOUR_CHAR_CODE('TVOD'), 0, myFlags, &myResRefNum, &myMovie); |
if (myErr != noErr) |
goto bail; |
// select the "no-interface" movie controller |
myType = EndianU32_NtoB(myType); |
SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); |
myTrack = NewMovieTrack(myMovie, FixRatio(kWidth320, 1), FixRatio(kHeight240, 1), kTrackVolumeZero); |
myMedia = NewTrackMedia(myTrack, TextMediaType, kTimeScale600, NULL, 0); |
if ((myTrack == NULL) || (myMedia == NULL)) |
goto bail; |
myErr = BeginMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
myHandler = GetMediaHandler(myMedia); |
if (myHandler == NULL) |
goto bail; |
////////// |
// |
// add a text sample to the movie |
// |
////////// |
MacSetRect(&myTextBox, 0, 0, kWidth320, kHeight240); |
MacInsetRect(&myTextBox, kTextBoxInset, kTextBoxInset); |
myErr = (OSErr)TextMediaAddTextSample( myHandler, |
myText, |
strlen(myText), |
kFontIDTimes, |
kSize48, |
kFacePlain, |
&myTextColor, |
&myBackColor, |
teCenter, |
&myTextBox, |
myDisplayFlags, |
myScrollDelay, |
myHiliteStart, |
myHiliteEnd, |
&myHiliteColor, |
kTimeScale600, |
&myNewMediaTime); |
if (myErr != noErr) |
goto bail; |
myErr = EndMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
// add the media to the track, at time 0 |
myErr = InsertMediaIntoTrack(myTrack, kTrackStartTimeZero, myNewMediaTime, kTimeScale600, fixed1); |
if (myErr != noErr) |
goto bail; |
// add the movie resource |
myErr = AddMovieResource(myMovie, myResRefNum, &myResID, NULL); |
bail: |
if (myResRefNum != -1) |
CloseMovieFile(myResRefNum); |
if (myMovie != NULL) |
DisposeMovie(myMovie); |
return(myErr); |
} |
////////// |
// |
// QTWired_CreateHyperTextActionContainer |
// Return, through the theActions parameter, an atom container that contains some hypertext actions. |
// |
////////// |
static OSErr QTWired_CreateHyperTextActionContainer (QTAtomContainer *theActions) |
{ |
QTAtom myEventAtom = 0; |
QTAtom myActionAtom = 0; |
QTAtom myHyperTextAtom = 0; |
QTAtom myWiredObjectsAtom = 0; |
long mySelStart1 = 19; |
long mySelEnd1 = 24; |
long mySelStart2 = 28; |
long mySelEnd2 = 31; |
long myValue; |
short myIndex; |
char myAppleURL[] = "www.apple.com"; |
char myCNNURL[] = "www.cnn.com"; |
ModifierTrackGraphicsModeRecord myGraphicsModeRecord; |
OSErr myErr = noErr; |
myErr = QTNewAtomContainer(theActions); |
if (myErr != noErr) |
goto bail; |
// create a wired objects atom |
myErr = QTInsertChild(*theActions, kParentAtomIsContainer, kTextWiredObjectsAtomType, kIndexOne, kIndexZero, kZeroDataLength, NULL, &myWiredObjectsAtom); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add a hypertext link to the wired objects atom: ID 1 |
// |
////////// |
myErr = QTInsertChild(*theActions, myWiredObjectsAtom, kHyperTextItemAtomType, kIDOne, kIndexZero, kZeroDataLength, NULL, &myHyperTextAtom); |
if (myErr != noErr) |
goto bail; |
myValue = EndianS32_NtoB(mySelStart1); |
myErr = QTInsertChild(*theActions, myHyperTextAtom, kRangeStart, kIDOne, kIndexZero, sizeof(long), &myValue, NULL); |
if (myErr != noErr) |
goto bail; |
myValue = EndianS32_NtoB(mySelEnd1); |
myErr = QTInsertChild(*theActions, myHyperTextAtom, kRangeEnd, kIDOne, kIndexZero, sizeof(long), &myValue, NULL); |
if (myErr != noErr) |
goto bail; |
// add an event atom to the hypertext atom |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, myHyperTextAtom, kQTEventMouseClick, kActionGoToURL, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexOne, strlen(myAppleURL) + 1, &myAppleURL, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, myHyperTextAtom, kQTEventMouseEnter, kActionTextTrackSetHyperTextColor, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myIndex = EndianS16_NtoB(1); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexOne, sizeof(myIndex), &myIndex, NULL); |
if (myErr != noErr) |
goto bail; |
myGraphicsModeRecord.graphicsMode = EndianS32_NtoB(ditherCopy); |
myGraphicsModeRecord.opColor.red = EndianS16_NtoB(0x9999); |
myGraphicsModeRecord.opColor.green = EndianS16_NtoB(0x0000); |
myGraphicsModeRecord.opColor.blue = EndianS16_NtoB(0xcccc); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexTwo, sizeof(myGraphicsModeRecord), &myGraphicsModeRecord, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, myHyperTextAtom, kQTEventMouseExit, kActionTextTrackSetHyperTextColor, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myIndex = EndianS16_NtoB(1); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexOne, sizeof(myIndex), &myIndex, NULL); |
if (myErr != noErr) |
goto bail; |
myGraphicsModeRecord.graphicsMode = EndianS32_NtoB(ditherCopy); |
myGraphicsModeRecord.opColor.red = EndianS16_NtoB(0x0000); |
myGraphicsModeRecord.opColor.green = EndianS16_NtoB(0x0000); |
myGraphicsModeRecord.opColor.blue = EndianS16_NtoB(0xffff); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexTwo, sizeof(myGraphicsModeRecord), &myGraphicsModeRecord, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add a hypertext link to the wired objects atom: ID 2 |
// |
////////// |
myErr = QTInsertChild(*theActions, myWiredObjectsAtom, kHyperTextItemAtomType, kIDTwo, kIndexZero, kZeroDataLength, NULL, &myHyperTextAtom); |
if (myErr != noErr) |
goto bail; |
myValue = EndianS32_NtoB(mySelStart2); |
myErr = QTInsertChild(*theActions, myHyperTextAtom, kRangeStart, kIDOne, kIndexZero, sizeof(long), &myValue, NULL); |
if (myErr != noErr) |
goto bail; |
myValue = EndianS32_NtoB(mySelEnd2); |
myErr = QTInsertChild(*theActions, myHyperTextAtom, kRangeEnd, kIDOne, kIndexZero, sizeof(long), &myValue, NULL); |
if (myErr != noErr) |
goto bail; |
// add an event atom to the hypertext atom |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, myHyperTextAtom, kQTEventMouseClick, kActionGoToURL, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexOne, strlen(myCNNURL) + 1, &myCNNURL, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, myHyperTextAtom, kQTEventMouseEnter, kActionTextTrackSetHyperTextColor, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myIndex = EndianS16_NtoB(2); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexOne, sizeof(myIndex), &myIndex, NULL); |
if (myErr != noErr) |
goto bail; |
myGraphicsModeRecord.graphicsMode = EndianS32_NtoB(ditherCopy); |
myGraphicsModeRecord.opColor.red = EndianS16_NtoB(0x9999); |
myGraphicsModeRecord.opColor.green = EndianS16_NtoB(0x0000); |
myGraphicsModeRecord.opColor.blue = EndianS16_NtoB(0xcccc); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexTwo, sizeof(myGraphicsModeRecord), &myGraphicsModeRecord, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, myHyperTextAtom, kQTEventMouseExit, kActionTextTrackSetHyperTextColor, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myIndex = EndianS16_NtoB(2); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexOne, sizeof(myIndex), &myIndex, NULL); |
if (myErr != noErr) |
goto bail; |
myGraphicsModeRecord.graphicsMode = EndianS32_NtoB(ditherCopy); |
myGraphicsModeRecord.opColor.red = EndianS16_NtoB(0x0000); |
myGraphicsModeRecord.opColor.green = EndianS16_NtoB(0x0000); |
myGraphicsModeRecord.opColor.blue = EndianS16_NtoB(0xffff); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, kIndexTwo, sizeof(myGraphicsModeRecord), &myGraphicsModeRecord, NULL); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTWired_AddActionsToSample |
// Add the specified atom container to the end of the specified media sample. |
// |
// Text actions are stored at the end of the sample as a normal text atom extension. |
// |
////////// |
static OSErr QTWired_AddActionsToSample (Handle theSample, QTAtomContainer theActions, SInt32 theAtomExtType) |
{ |
Ptr myPtr = NULL; |
long myHandleLength; |
long myContainerLength; |
long myNewLength; |
OSErr myErr = noErr; |
if ((theSample == NULL) || (theActions == NULL)) |
return(paramErr); |
myHandleLength = GetHandleSize(theSample); |
myContainerLength = GetHandleSize((Handle)theActions); |
myNewLength = (long)(sizeof(long) + sizeof(OSType) + myContainerLength); |
SetHandleSize(theSample, (myHandleLength + myNewLength)); |
myErr = MemError(); |
if (myErr != noErr) |
goto bail; |
HLock(theSample); |
// get a pointer to the beginning of the new block of space added to the sample |
// by the previous call to SetHandleSize; we need to format that space as a text |
// atom extension |
myPtr = *theSample + myHandleLength; |
// set the length of the text atom extension |
*(long *)myPtr = EndianS32_NtoB((long)(sizeof(long) + sizeof(OSType) + myContainerLength)); |
myPtr += (sizeof(long)); |
// set the type of the text atom extension |
*(OSType *)myPtr = EndianS32_NtoB(theAtomExtType); |
myPtr += (sizeof(OSType)); |
// set the data of the text atom extension; |
// we assume that this data is already in big-endian format |
HLock((Handle)theActions); |
BlockMove(*theActions, myPtr, myContainerLength); |
HUnlock((Handle)theActions); |
HUnlock(theSample); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTWired_AddActionsToTextMovie |
// Add some actions to the specified text movie; theMenuItem specifies which actions to add. |
// |
////////// |
OSErr QTWired_AddActionsToTextMovie (FSSpec *theFSSpec, UInt16 theMenuItem) |
{ |
short myResID = 0; |
short myResRefNum = -1; |
Movie myMovie = NULL; |
Track myTrack = NULL; |
Media myMedia = NULL; |
TimeValue myTrackOffset; |
TimeValue myMediaTime; |
TimeValue mySampleDuration; |
TimeValue mySelectionDuration; |
TimeValue myNewMediaTime; |
TextDescriptionHandle myTextDesc = NULL; |
Handle mySample = NULL; |
short mySampleFlags; |
Fixed myTrackEditRate; |
QTAtomContainer myActions = NULL; |
OSErr myErr = noErr; |
////////// |
// |
// open the movie file and get the first text track from the movie |
// |
////////// |
// open the movie file for reading and writing |
myErr = OpenMovieFile(theFSSpec, &myResRefNum, fsRdWrPerm); |
if (myErr != noErr) |
goto bail; |
myErr = NewMovieFromFile(&myMovie, myResRefNum, &myResID, NULL, newMovieActive, NULL); |
if (myErr != noErr) |
goto bail; |
// find first text track in the movie |
myTrack = GetMovieIndTrackType(myMovie, kIndexOne, TextMediaType, movieTrackMediaType); |
if (myTrack == NULL) |
goto bail; |
////////// |
// |
// get first media sample in the text track |
// |
////////// |
myMedia = GetTrackMedia(myTrack); |
if (myMedia == NULL) |
goto bail; |
myTrackOffset = GetTrackOffset(myTrack); |
myMediaTime = TrackTimeToMediaTime(myTrackOffset, myTrack); |
// allocate some storage to hold the sample description for the text track |
myTextDesc = (TextDescriptionHandle)NewHandle(4); |
if (myTextDesc == NULL) |
goto bail; |
mySample = NewHandle(0); |
if (mySample == NULL) |
goto bail; |
myErr = GetMediaSample(myMedia, mySample, 0, NULL, myMediaTime, NULL, &mySampleDuration, (SampleDescriptionHandle)myTextDesc, NULL, 1, NULL, &mySampleFlags); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add actions to the first media sample |
// |
////////// |
switch (theMenuItem) { |
case IDM_MAKE_HYPERTEXT_MOVIE: |
// create an action container for hypertext actions |
myErr = QTWired_CreateHyperTextActionContainer(&myActions); |
if (myErr != noErr) |
goto bail; |
// add hypertext actions to sample |
myErr = QTWired_AddActionsToSample(mySample, myActions, kHyperTextTextAtomType); |
if (myErr != noErr) |
goto bail; |
break; |
case IDM_MAKE_MEM_DISPLAY_MOVIE: |
// create an action container for wired actions |
myErr = QTWired_CreateMemoryDisplayActionContainer(&myActions); |
if (myErr != noErr) |
goto bail; |
// add actions to sample |
myErr = QTWired_AddActionsToSample(mySample, myActions, kQTEventType); |
if (myErr != noErr) |
goto bail; |
break; |
default: |
myErr = paramErr; |
goto bail; |
} |
////////// |
// |
// replace sample in media |
// |
////////// |
myTrackEditRate = GetTrackEditRate(myTrack, myTrackOffset); |
if (GetMoviesError() != noErr) |
goto bail; |
GetTrackNextInterestingTime(myTrack, nextTimeMediaSample | nextTimeEdgeOK, myTrackOffset, fixed1, NULL, &mySelectionDuration); |
if (GetMoviesError() != noErr) |
goto bail; |
myErr = DeleteTrackSegment(myTrack, myTrackOffset, mySelectionDuration); |
if (myErr != noErr) |
goto bail; |
myErr = BeginMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
myErr = AddMediaSample( myMedia, |
mySample, |
0, |
GetHandleSize(mySample), |
mySampleDuration, |
(SampleDescriptionHandle)myTextDesc, |
1, |
mySampleFlags, |
&myNewMediaTime); |
if (myErr != noErr) |
goto bail; |
myErr = EndMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
// add the media to the track |
myErr = InsertMediaIntoTrack(myTrack, myTrackOffset, myNewMediaTime, mySelectionDuration, myTrackEditRate); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// update the movie resource |
// |
////////// |
myErr = UpdateMovieResource(myMovie, myResRefNum, myResID, NULL); |
if (myErr != noErr) |
goto bail; |
// close the movie file |
myErr = CloseMovieFile(myResRefNum); |
bail: |
if (myActions != NULL) |
(void)QTDisposeAtomContainer(myActions); |
if (mySample != NULL) |
DisposeHandle(mySample); |
if (myTextDesc != NULL) |
DisposeHandle((Handle)myTextDesc); |
if (myMovie != NULL) |
DisposeMovie(myMovie); |
return(myErr); |
} |
////////// |
// |
// QTWired_CreateMemoryDisplayMovie |
// Create a movie that displays the available application memory in a text track. |
// |
////////// |
OSErr QTWired_CreateMemoryDisplayMovie (FSSpec *theFSSpec) |
{ |
short myResRefNum = -1; |
short myResID = movieInDataForkResID; |
Movie myMovie = NULL; |
Track myTrack = NULL; |
Media myMedia = NULL; |
MediaHandler myHandler = NULL; |
Rect myTextBox; |
RGBColor myTextColor = {0x0000, 0x0000, 0x0000}; |
RGBColor myBackColor = {0x8888, 0x8888, 0x8888}; |
RGBColor myHiliteColor = {0x0000, 0x0000, 0x0000}; |
long myDisplayFlags = 0; |
short myHiliteStart = 0; |
short myHiliteEnd = 0; |
TimeValue myNewMediaTime; |
TimeValue myScrollDelay = 0; |
char myText[] = "0"; |
long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile | newMovieActive; |
OSType myType = FOUR_CHAR_CODE('none'); |
OSErr myErr = noErr; |
////////// |
// |
// create a new text movie |
// |
////////// |
myErr = CreateMovieFile(theFSSpec, FOUR_CHAR_CODE('TVOD'), 0, myFlags, &myResRefNum, &myMovie); |
if (myErr != noErr) |
goto bail; |
// select the "no-interface" movie controller |
myType = EndianU32_NtoB(myType); |
SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); |
myTrack = NewMovieTrack(myMovie, FixRatio(kWidth200, 1), FixRatio(kHeight50, 1), kTrackVolumeZero); |
myMedia = NewTrackMedia(myTrack, TextMediaType, kTimeScale600, NULL, 0); |
if ((myTrack == NULL) || (myMedia == NULL)) |
goto bail; |
myErr = BeginMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
myHandler = GetMediaHandler(myMedia); |
if (myHandler == NULL) |
goto bail; |
////////// |
// |
// add a text sample to the movie |
// |
////////// |
MacSetRect(&myTextBox, 0, 0, kWidth200, kHeight50); |
MacInsetRect(&myTextBox, kTextBoxInset, kTextBoxInset); |
myErr = (OSErr)TextMediaAddTextSample( myHandler, |
myText, |
strlen(myText), |
kFontIDTimes, |
kSize48, |
kFacePlain, |
&myTextColor, |
&myBackColor, |
teCenter, |
&myTextBox, |
myDisplayFlags, |
myScrollDelay, |
myHiliteStart, |
myHiliteEnd, |
&myHiliteColor, |
kTimeScale600, |
&myNewMediaTime); |
if (myErr != noErr) |
goto bail; |
myErr = EndMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
// add the media to the track, at time 0 |
myErr = InsertMediaIntoTrack(myTrack, kTrackStartTimeZero, myNewMediaTime, kTimeScale600, fixed1); |
if (myErr != noErr) |
goto bail; |
// set the text track properties |
QTWired_SetTextTrackProperties(myMedia, 120, false); |
// add the movie resource |
myErr = AddMovieResource(myMovie, myResRefNum, &myResID, NULL); |
bail: |
if (myResRefNum != -1) |
CloseMovieFile(myResRefNum); |
if (myMovie != NULL) |
DisposeMovie(myMovie); |
return(myErr); |
} |
////////// |
// |
// QTWired_CreateMemoryDisplayActionContainer |
// Return, through the theActions parameter, an atom container that contains some edit-text actions. |
// |
////////// |
static OSErr QTWired_CreateMemoryDisplayActionContainer (QTAtomContainer *theActions) |
{ |
QTAtom myEventAtom = 0; |
QTAtom myActionAtom = 0; |
QTAtom myParamAtom = 0; |
short myEditState; |
UInt32 myPos; |
QTAtom myParameterAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myOperandAtom = 0; |
OSErr myErr = noErr; |
myErr = QTNewAtomContainer(theActions); |
if (myErr != noErr) |
goto bail; |
// add an event atom that enables text editing; |
// in theory we could do this just once in a frame-loaded event, but it doesn't seem to impact performance here |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, kParentAtomIsContainer, kQTEventIdle, kActionTextTrackSetEditable, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myEditState = EndianS16_NtoB(kKeyEntryScript); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, 1, sizeof(myEditState), &myEditState, NULL); |
if (myErr != noErr) |
goto bail; |
// add an event atom that displays the amount of application memory currently free |
myErr = WiredUtils_AddQTEventAndActionAtoms(*theActions, kParentAtomIsContainer, kQTEventIdle, kActionTextTrackPasteText, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
// first parameter: the text to be pasted |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, 1, 0, NULL, &myParameterAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(*theActions, myParameterAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(*theActions, myExpressionAtom, kOperandAtomType, 1, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(*theActions, myOperandAtom, kOperandFreeMemory, 1, 1, 0, NULL, NULL); |
if (myErr != noErr) |
goto bail; |
// second parameter: selection range begin: 0 |
myPos = EndianU32_NtoB(0); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, 2, sizeof(myPos), &myPos, NULL); |
if (myErr != noErr) |
goto bail; |
// third parameter: selection range end: 0xffff |
myPos = EndianU32_NtoB(0xffff); |
myErr = WiredUtils_AddActionParameterAtom(*theActions, myActionAtom, 3, sizeof(myPos), &myPos, NULL); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTWired_SetTextTrackProperties |
// Set the track properties for the specified text media. |
// |
////////// |
void QTWired_SetTextTrackProperties (Media theMedia, UInt32 theIdleFrequency, Boolean isEditable) |
{ |
QTAtomContainer myTrackProperties; |
Boolean myBoolean; |
UInt32 myFrequency; |
OSErr myErr = noErr; |
myErr = QTNewAtomContainer(&myTrackProperties); |
if (myErr == noErr) { |
// tell the movie controller that this text track has actions |
myBoolean = true; |
QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyHasActions, 1, 1, sizeof(myBoolean), &myBoolean, NULL); |
// tell the text track to generate QTIdleEvents |
myFrequency = EndianU32_NtoB(theIdleFrequency); |
QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyQTIdleEventsFrequency, 1, 1, sizeof(myFrequency), &myFrequency, NULL); |
// set the text track to be editable or not, as determined by the isEditable parameter |
QTInsertChild(myTrackProperties, 0, kTrackFocusCanEditFlag, 1, 1, sizeof(isEditable), &isEditable, NULL); |
SetMediaPropertyAtom(theMedia, myTrackProperties); |
QTDisposeAtomContainer(myTrackProperties); |
} |
} |
////////// |
// |
// QTWired_CreateWiredIconMovie |
// Create a wired sprite movie containing one or more icons with the specified behavior. |
// |
////////// |
OSErr QTWired_CreateWiredIconMovie (UInt16 theMenuItem) |
{ |
Movie myMovie = NULL; |
Track myTrack = NULL; |
Media myMedia = NULL; |
FSSpec myFile; |
Boolean myIsSelected = false; |
Boolean myIsReplacing = false; |
Fixed myHeight = 0; |
Fixed myWidth = 0; |
StringPtr myPrompt = QTUtils_ConvertCToPascalString(kSpriteSavePrompt); |
StringPtr myFileName = QTUtils_ConvertCToPascalString(kSpriteSaveMovieFileName); |
long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; |
OSType myType = FOUR_CHAR_CODE('none'); |
short myResRefNum = 0; |
short myResID = movieInDataForkResID; |
OSErr myErr = noErr; |
////////// |
// |
// create a new movie file |
// |
////////// |
// prompt the user for the destination file name |
QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); |
myErr = myIsSelected ? noErr : userCanceledErr; |
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-interface" movie controller |
myType = EndianU32_NtoB(myType); |
SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); |
////////// |
// |
// create the sprite track and media |
// |
////////// |
myWidth = Long2Fix(kIconSpriteTrackWidth); |
myHeight = Long2Fix(kIconSpriteTrackHeight); |
myTrack = NewMovieTrack(myMovie, myWidth, myHeight, kNoVolume); |
myMedia = NewTrackMedia(myTrack, SpriteMediaType, kSpriteMediaTimeScale, NULL, 0); |
myErr = BeginMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add the appropriate samples to the sprite media |
// |
////////// |
switch (theMenuItem) { |
case IDM_MAKE_BOUNCE_ICON_MOVIE: |
myErr = QTWired_AddBouncingIconSpriteToMedia(myMedia); |
break; |
case IDM_MAKE_COLLIDE_ICONS_MOVIE: |
myErr = QTWired_AddCollidingIconsSpritesToMedia(myMedia); |
break; |
// case IDM_MAKE_CUSTOM_EVENT_MOVIE: |
// myErr = QTWired_AddCustomEventSpritesToMedia(myMedia); |
// break; |
default: |
myErr = paramErr; |
break; |
} |
if (myErr != noErr) |
goto bail; |
myErr = EndMediaEdits(myMedia); |
if (myErr != noErr) |
goto bail; |
// add the media to the track |
InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); |
////////// |
// |
// set the sprite track properties |
// |
////////// |
QTWired_SetTrackProperties(myMedia, 1); |
////////// |
// |
// add the movie resource to the movie file |
// |
////////// |
myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name); |
bail: |
if (myResRefNum != 0) |
CloseMovieFile(myResRefNum); |
if (myMovie != NULL) |
DisposeMovie(myMovie); |
free(myPrompt); |
free(myFileName); |
return(myErr); |
} |
////////// |
// |
// QTWired_AddBouncingIconSpriteToMedia |
// Build the key frame for the bouncing icon sprite movie. |
// |
////////// |
OSErr QTWired_AddBouncingIconSpriteToMedia (Media theMedia) |
{ |
QTAtomContainer mySample = NULL; |
QTAtomContainer mySpriteData = NULL; |
QTAtom myEventAtom = 0; |
QTAtom myActionAtom = 0; |
QTAtom myNewParamAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myOperandAtom = 0; |
QTAtom myOperandTypeAtom = 0; |
RGBColor myKeyColor; |
short isVisible, myIndex; |
FixedPoint myPoint; |
OSErr myErr = noErr; |
////////// |
// |
// create a key frame sample containing the sprite images |
// |
////////// |
// create a new, empty key frame sample |
myErr = QTNewAtomContainer(&mySample); |
if (myErr != noErr) |
goto bail; |
myKeyColor.red = myKeyColor.green = myKeyColor.blue = 0xffff; // white |
myPoint.x = 0; |
myPoint.y = 0; |
// add images to the key frame sample |
myErr = SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kNewQTIconID, &myKeyColor, 1, &myPoint, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add frame-loaded events that initialize the two sprite track variables to 1 |
// |
////////// |
myErr = WiredUtils_AddSpriteTrackSetVariableAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, kXMoveVarID, kIdleOffset, 0, NULL, 0); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddSpriteTrackSetVariableAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, kYMoveVarID, kIdleOffset, 0, NULL, 0); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add the initial sprite properties to the key frame sample |
// |
////////// |
myErr = QTNewAtomContainer(&mySpriteData); |
if (myErr != noErr) |
goto bail; |
// the QT icon sprite |
isVisible = true; |
myIndex = kQTIconImageIndex; |
myErr = SpriteUtils_SetSpriteData(mySpriteData, NULL, &isVisible, NULL, &myIndex, NULL, NULL, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add idle event actions to the sprite: |
// (1) translate by the current x and y offsets |
// (2) if the left side of the sprite is less than 1 or the right side is greater than the track width, |
// negate the x offset and move the sprite back to the edge |
// (3) if the top side of the sprite is less than 1 or the bottom side is greater than the track height, |
// negate the y offset and move the sprite back to the edge |
// |
////////// |
////////// |
// |
// (1) translate by the current x and y offsets |
// |
////////// |
myErr = WiredUtils_AddQTEventAtom(mySpriteData, kParentAtomIsContainer, kQTEventIdle, &myEventAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddTranslateByVariablesAction(mySpriteData, myEventAtom, kXMoveVarID, kYMoveVarID, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// (2) and (3): if we hit a side, bounce back |
// |
////////// |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsLeft, 1, kOperatorLessThan, kXMoveVarID); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsRight, kIconSpriteTrackWidth, kOperatorGreaterThan, kXMoveVarID); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsTop, 1, kOperatorLessThan, kYMoveVarID); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsBottom, kIconSpriteTrackHeight, kOperatorGreaterThan, kYMoveVarID); |
if (myErr != noErr) |
goto bail; |
// add the sprite to the key frame sample |
myErr = SpriteUtils_AddSpriteToSample(mySample, mySpriteData, kQTIconSpriteAtomID); |
if (myErr != noErr) |
goto bail; |
myErr = SpriteUtils_AddSpriteSampleToMedia(theMedia, mySample, kSpriteMediaFrameDurationIcon, true, NULL); |
bail: |
if (mySample != NULL) |
QTDisposeAtomContainer(mySample); |
if (mySpriteData != NULL) |
QTDisposeAtomContainer(mySpriteData); |
return(myErr); |
} |
////////// |
// |
// QTWired_AddSideBounceToSprite |
// If the specified sprite side is beyond the limit, bounce back. |
// |
////////// |
OSErr QTWired_AddSideBounceToSprite (QTAtomContainer theSprite, QTAtomType theSide, float theLimit, QTAtomType theTest, QTAtomID theVariableID) |
{ |
QTAtom myActionAtom = 0; |
QTAtom myNewActionAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myParamAtom = 0; |
QTAtom myNewParamAtom = 0; |
QTAtom myOperatorAtom = 0; |
QTAtom myOperandAtom = 0; |
QTAtom myOperandTypeAtom = 0; |
QTAtom myConditionalAtom = 0; |
QTAtom myActionListAtom = 0; |
Boolean myBoolean; |
OSErr myErr = noErr; |
// add an idle event "if" action |
myErr = WiredUtils_AddQTEventAndActionAtoms(theSprite, kParentAtomIsContainer, kQTEventIdle, kActionCase, &myActionAtom); |
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 = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kFirstParam, 0, NULL, &myNewParamAtom); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// if the side of the sprite is less/greater than the specified limit... |
// |
////////// |
myErr = WiredUtils_AddConditionalAtom(theSprite, myNewParamAtom, 1, &myConditionalAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myConditionalAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddOperatorAtom(theSprite, myExpressionAtom, theTest, &myOperatorAtom); |
if (myErr != noErr) |
goto bail; |
// first operand: the specified side of the sprite |
myErr = QTInsertChild(theSprite, myOperatorAtom, kOperandAtomType, 1, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, theSide, 1, 1, 0, NULL, NULL); |
if (myErr != noErr) |
goto bail; |
// second operand: the specified limit |
myErr = WiredUtils_AddOperandAtom(theSprite, myOperatorAtom, kOperandConstant, 2, NULL, theLimit); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// ...translate back to the edge... |
// |
////////// |
myErr = WiredUtils_AddActionListAtom(theSprite, myConditionalAtom, &myActionListAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddActionAtom(theSprite, myActionListAtom, kActionSpriteTranslate, &myNewActionAtom); |
if (myErr != noErr) |
goto bail; |
// add parameters to the translate action: Fixed x, Fixed y, Boolean isAbsolute |
// first parameter: theLimit - the side of sprite |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myNewActionAtom, kFirstParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myParamAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myExpressionAtom, kOperatorAtomType, kOperatorSubtract, 1, 0, NULL, &myOperatorAtom); |
if (myErr != noErr) |
goto bail; |
// first operand: theLimit |
myErr = WiredUtils_AddOperandAtom(theSprite, myOperatorAtom, kOperandConstant, 1, NULL, theLimit); |
if (myErr != noErr) |
goto bail; |
// second operand: the side of sprite |
myErr = QTInsertChild(theSprite, myOperatorAtom, kOperandAtomType, 2, 2, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, theSide, 1, 1, 0, NULL, NULL); |
if (myErr != noErr) |
goto bail; |
// second parameter: 0 |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myNewActionAtom, kSecondParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myParamAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddOperandAtom(theSprite, myExpressionAtom, kOperandConstant, 1, NULL, 0); |
if (myErr != noErr) |
goto bail; |
// third parameter: false |
myBoolean = false; |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myNewActionAtom, kThirdParam, sizeof(myBoolean), &myBoolean, NULL); |
////////// |
// |
// ...and negate the x or y offset |
// |
////////// |
myErr = QTWired_AddNegateVariableAction(theSprite, myActionListAtom, theVariableID); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTWired_AddCollidingIconsSpritesToMedia |
// Build the key frame for the colliding icons sprite movie. |
// |
////////// |
OSErr QTWired_AddCollidingIconsSpritesToMedia (Media theMedia) |
{ |
QTAtomContainer mySample = NULL; |
QTAtomContainer mySpriteData = NULL; |
QTAtom myEventAtom = 0; |
QTAtom myActionAtom = 0; |
QTAtom myNewParamAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myOperandAtom = 0; |
QTAtom myOperandTypeAtom = 0; |
RGBColor myKeyColor; |
short isVisible, myIndex, myLayer; |
FixedPoint myPoint; |
short myCount; |
Point myLocation; |
OSErr myErr = noErr; |
////////// |
// |
// create a key frame sample containing the sprite images |
// |
////////// |
// create a new, empty key frame sample |
myErr = QTNewAtomContainer(&mySample); |
if (myErr != noErr) |
goto bail; |
myKeyColor.red = myKeyColor.green = myKeyColor.blue = 0xffff; // white |
myPoint.x = 0; |
myPoint.y = 0; |
// add images to the key frame sample |
myErr = SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kOldQTIconID, &myKeyColor, kOldQTIconSpriteAtomID, &myPoint, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kNewQTIconID, &myKeyColor, kNewQTIconSpriteAtomID, &myPoint, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add frame-loaded events that initialize the sprite track variables |
// |
////////// |
myErr = WiredUtils_AddSpriteTrackSetVariableAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, kXMoveVarIDNew, kIdleOffset, 0, NULL, 0); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddSpriteTrackSetVariableAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, kYMoveVarIDNew, kIdleOffset, 0, NULL, 0); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddSpriteTrackSetVariableAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, kXMoveVarIDOld, -kIdleOffset, 0, NULL, 0); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddSpriteTrackSetVariableAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, kYMoveVarIDOld, kIdleOffset, 0, NULL, 0); |
if (myErr != noErr) |
goto bail; |
for (myCount = 0; myCount <= 1; myCount++) { |
myErr = QTNewAtomContainer(&mySpriteData); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add the initial sprite properties to the key frame sample |
// |
////////// |
isVisible = true; |
myIndex = kOldQTIconImageIndex + myCount; |
myLayer = myCount; |
myLocation.h = 100 * myCount; |
myLocation.v = 50 * myCount; |
myErr = SpriteUtils_SetSpriteData(mySpriteData, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// add idle event actions to the sprite: |
// (1) translate by the current x and y offsets |
// (2) if the left side of the sprite is less than 1 or the right side is greater than the track width, |
// negate the x offset and move the sprite back to the edge |
// (3) if the top side of the sprite is less than 1 or the bottom side is greater than the track height, |
// negate the y offset and move the sprite back to the edge |
// (4) if we hit another sprite, recoil |
// |
////////// |
////////// |
// |
// (1) translate by the current x and y offsets |
// |
////////// |
myErr = WiredUtils_AddQTEventAtom(mySpriteData, kParentAtomIsContainer, kQTEventIdle, &myEventAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddTranslateByVariablesAction(mySpriteData, myEventAtom, kXMoveVarID + myCount, kYMoveVarID + myCount, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// (2) and (3): if we hit a side, bounce back |
// |
////////// |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsLeft, 1, kOperatorLessThan, kXMoveVarID + myCount); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsRight, kIconSpriteTrackWidth, kOperatorGreaterThan, kXMoveVarID + myCount); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsTop, 1, kOperatorLessThan, kYMoveVarID + myCount); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddSideBounceToSprite(mySpriteData, kOperandSpriteBoundsBottom, kIconSpriteTrackHeight, kOperatorGreaterThan, kYMoveVarID + myCount); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// (4) if we hit another sprite, recoil |
// |
////////// |
if (myCount == 1) |
QTWired_AddCollisionLogicToSprite(mySpriteData); |
// add the sprite to the key frame sample |
myErr = SpriteUtils_AddSpriteToSample(mySample, mySpriteData, kOldQTIconSpriteAtomID + myCount); |
if (myErr != noErr) |
goto bail; |
} |
// myErr = SpriteUtils_AddSpriteSampleToMedia(theMedia, mySample, kSpriteMediaFrameDurationIcon, true, NULL); |
myErr = SpriteUtils_AddCompressedSpriteSampleToMedia(theMedia, mySample, kSpriteMediaFrameDurationIcon, true, zlibDataCompressorSubType, NULL); |
bail: |
if (mySample != NULL) |
QTDisposeAtomContainer(mySample); |
if (mySpriteData != NULL) |
QTDisposeAtomContainer(mySpriteData); |
return(myErr); |
} |
////////// |
// |
// QTWired_AddCollisionLogicToSprite |
// If the specified sprite hits another sprite, have both recoil in the appropriate directions. |
// |
////////// |
OSErr QTWired_AddCollisionLogicToSprite (QTAtomContainer theSprite) |
{ |
OSErr myErr = noErr; |
myErr = QTWired_AddCornerCollisionLogicToSprite(theSprite, kOperandSpriteBoundsLeft, kOperandSpriteBoundsTop); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddCornerCollisionLogicToSprite(theSprite, kOperandSpriteBoundsRight, kOperandSpriteBoundsTop); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddCornerCollisionLogicToSprite(theSprite, kOperandSpriteBoundsLeft, kOperandSpriteBoundsBottom); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddCornerCollisionLogicToSprite(theSprite, kOperandSpriteBoundsRight, kOperandSpriteBoundsBottom); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTWired_AddCornerCollisionLogicToSprite |
// If the corner of the specified sprite hits another sprite, have both recoil in the appropriate directions. |
// |
// set variable kSpriteHitID to the value of kOperandSpriteTrackSpriteIDAtPoint[theHorizCorner,theVertCorner]; |
// if value of kSpriteHitID is equal to ID of other sprite, |
// if xdir[1] != xdir[2] then |
// xdir[1] = -xdir[1] |
// xdir[2] = -xdir[2] |
// if ydir[1] != ydir[2] then |
// ydir[1] = -ydir[1] |
// ydir[2] = -ydir[2] |
// |
// Keep in mind that calling kOperandSpriteTrackSpriteIDAtPoint with the parameters set to the corner of a sprite |
// will always return the ID of that sprite, UNLESS some other sprite at that location has a lower layer. |
// |
////////// |
OSErr QTWired_AddCornerCollisionLogicToSprite (QTAtomContainer theSprite, UInt32 theHorizCorner, UInt32 theVertCorner) |
{ |
QTAtom myActionAtom = 0; |
QTAtom myNewActionAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myNewExpressionAtom = 0; |
QTAtom myParamAtom = 0; |
QTAtom myNewParamAtom = 0; |
QTAtom myOperatorAtom = 0; |
QTAtom myNewOperatorAtom = 0; |
QTAtom myOperandAtom = 0; |
QTAtom myNewOperandAtom = 0; |
QTAtom myOperandTypeAtom = 0; |
QTAtom myNewOperandTypeAtom = 0; |
QTAtom myConditionalAtom = 0; |
QTAtom myNewConditionalAtom = 0; |
QTAtom myActionListAtom = 0; |
QTAtom myNewActionListAtom = 0; |
QTAtomID myVariableID; |
OSErr myErr = noErr; |
////////// |
// |
// set variable kSpriteHitID to the value of kOperandSpriteTrackSpriteIDAtPoint[theHorizCorner, theVertCorner] |
// |
////////// |
myErr = WiredUtils_AddQTEventAndActionAtoms(theSprite, kParentAtomIsContainer, kQTEventIdle, kActionSpriteTrackSetVariable, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
// add parameters to the set variable action: variable ID (QTAtomID) and value (float) |
myVariableID = EndianU32_NtoB(kSpriteHitID); |
myErr = QTInsertChild(theSprite, myActionAtom, kActionParameter, 0, (short)kFirstParam, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myActionAtom, kActionParameter, 0, (short)kSecondParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myParamAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, kOperandSpriteTrackSpriteIDAtPoint, 1, 1, 0, NULL, &myOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
// add parameters to kOperandSpriteTrackSpriteIDAtPoint operand; |
// first param: theHorizCorner |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myOperandTypeAtom, kFirstParam, 0, NULL, &myNewParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myNewParamAtom, &myNewExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myNewOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewOperandAtom, theHorizCorner, 1, 1, 0, NULL, NULL); |
if (myErr != noErr) |
goto bail; |
// second param: theVertCorner |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myOperandTypeAtom, kSecondParam, 0, NULL, &myNewParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myNewParamAtom, &myNewExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myNewOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewOperandAtom, theVertCorner, 1, 1, 0, NULL, NULL); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// if value of variable kSpriteHitID is ID of other sprite (kOldQTIconSpriteAtomID)... |
// |
////////// |
// add an idle event "if" action |
myErr = WiredUtils_AddQTEventAndActionAtoms(theSprite, kParentAtomIsContainer, kQTEventIdle, kActionCase, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
// add a parameter atom to the kActionCase action atom |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kFirstParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddConditionalAtom(theSprite, myParamAtom, 1, &myConditionalAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myConditionalAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddOperatorAtom(theSprite, myExpressionAtom, kOperatorEqualTo, &myOperatorAtom); |
if (myErr != noErr) |
goto bail; |
// first operand: the value of kSpriteHitID variable |
myErr = QTInsertChild(theSprite, myOperatorAtom, kOperandAtomType, 1, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(kSpriteHitID); |
myErr = QTInsertChild(theSprite, myOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
// second operand: the sprite ID |
myErr = WiredUtils_AddOperandAtom(theSprite, myOperatorAtom, kOperandConstant, 2, NULL, (float)kOldQTIconSpriteAtomID); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// ...and if the two sprites are moving in different horizontal directions... |
// |
////////// |
myErr = WiredUtils_AddActionListAtom(theSprite, myConditionalAtom, &myActionListAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddActionAtom(theSprite, myActionListAtom, kActionCase, &myNewActionAtom); |
if (myErr != noErr) |
goto bail; |
// add a parameter atom to the kActionCase action atom |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myNewActionAtom, kFirstParam, 0, NULL, &myNewParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddConditionalAtom(theSprite, myNewParamAtom, 1, &myNewConditionalAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myNewConditionalAtom, &myNewExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddOperatorAtom(theSprite, myNewExpressionAtom, kOperatorNotEqualTo, &myNewOperatorAtom); |
if (myErr != noErr) |
goto bail; |
// first operand: the value of kXMoveVarIDNew |
myErr = QTInsertChild(theSprite, myNewOperatorAtom, kOperandAtomType, 1, 1, 0, NULL, &myNewOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myNewOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(kXMoveVarIDNew); |
myErr = QTInsertChild(theSprite, myNewOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
// second operand: the value of kXMoveVarIDOld |
myErr = QTInsertChild(theSprite, myNewOperatorAtom, kOperandAtomType, 2, 2, 0, NULL, &myNewOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myNewOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(kXMoveVarIDOld); |
myErr = QTInsertChild(theSprite, myNewOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
// ...adjust the direction of travel... |
myErr = WiredUtils_AddActionListAtom(theSprite, myNewConditionalAtom, &myNewActionListAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddNegateVariableAction(theSprite, myNewActionListAtom, kXMoveVarIDNew); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddNegateVariableAction(theSprite, myNewActionListAtom, kXMoveVarIDOld); |
if (myErr != noErr) |
goto bail; |
////////// |
// |
// ...and if the two sprites are moving in different vertical directions... |
// |
////////// |
myErr = WiredUtils_AddActionAtom(theSprite, myActionListAtom, kActionCase, &myNewActionAtom); |
if (myErr != noErr) |
goto bail; |
// add a parameter atom to the kActionCase action atom |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myNewActionAtom, kFirstParam, 0, NULL, &myNewParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddConditionalAtom(theSprite, myNewParamAtom, 1, &myNewConditionalAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myNewConditionalAtom, &myNewExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddOperatorAtom(theSprite, myNewExpressionAtom, kOperatorNotEqualTo, &myNewOperatorAtom); |
if (myErr != noErr) |
goto bail; |
// first operand: the value of kYMoveVarIDNew |
myErr = QTInsertChild(theSprite, myNewOperatorAtom, kOperandAtomType, 1, 1, 0, NULL, &myNewOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myNewOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(kYMoveVarIDNew); |
myErr = QTInsertChild(theSprite, myNewOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
// second operand: the value of kYMoveVarIDOld |
myErr = QTInsertChild(theSprite, myNewOperatorAtom, kOperandAtomType, 2, 2, 0, NULL, &myNewOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myNewOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(kYMoveVarIDOld); |
myErr = QTInsertChild(theSprite, myNewOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
// ...adjust the direction of travel... |
myErr = WiredUtils_AddActionListAtom(theSprite, myNewConditionalAtom, &myNewActionListAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddNegateVariableAction(theSprite, myNewActionListAtom, kYMoveVarIDNew); |
if (myErr != noErr) |
goto bail; |
myErr = QTWired_AddNegateVariableAction(theSprite, myNewActionListAtom, kYMoveVarIDOld); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTWired_SetTrackProperties |
// Set the track properties for the specified sample sprite media. |
// |
////////// |
void QTWired_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); |
} |
} |
////////// |
// |
// QTWired_AddNegateVariableAction |
// Add an action atom that negates the specified sprite track variable. |
// |
////////// |
static OSErr QTWired_AddNegateVariableAction (QTAtomContainer theSprite, QTAtom theParentAtom, QTAtomID theVariableID) |
{ |
QTAtom myActionAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myParamAtom = 0; |
QTAtom myOperatorAtom = 0; |
QTAtom myOperandAtom = 0; |
QTAtom myOperandTypeAtom = 0; |
QTAtomID myVariableID; |
OSErr myErr = paramErr; |
if ((theSprite == NULL) || (theParentAtom == 0)) |
goto bail; |
myErr = WiredUtils_AddActionAtom(theSprite, theParentAtom, kActionSpriteTrackSetVariable, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
// add parameters to the set variable action: variable ID (QTAtomID) and value (float) |
myVariableID = EndianU32_NtoB(theVariableID); |
myErr = QTInsertChild(theSprite, myActionAtom, kActionParameter, 0, (short)kFirstParam, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myActionAtom, kActionParameter, 0, (short)kSecondParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myParamAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myExpressionAtom, kOperatorAtomType, kOperatorNegate, 1, 0, NULL, &myOperatorAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperatorAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(theVariableID); |
myErr = QTInsertChild(theSprite, myOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTWired_AddTranslateByVariablesAction |
// Add an action atom that translates the specified sprite relatively by an amount specified by two variables. |
// |
////////// |
static OSErr QTWired_AddTranslateByVariablesAction (QTAtomContainer theSprite, QTAtom theParentAtom, QTAtomID theXVariableID, QTAtomID theYVariableID, QTAtom *theActionAtom) |
{ |
QTAtom myActionAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myParamAtom = 0; |
QTAtom myOperatorAtom = 0; |
QTAtom myOperandAtom = 0; |
QTAtom myOperandTypeAtom = 0; |
QTAtomID myVariableID; |
Boolean myBoolean; |
OSErr myErr = paramErr; |
if (theSprite == NULL) |
goto bail; |
// add a translate action atom to the specified parent atom |
myErr = WiredUtils_AddActionAtom(theSprite, theParentAtom, kActionSpriteTranslate, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
// add parameters to the translate action: Fixed x, Fixed y, Boolean isAbsolute |
// first parameter: get value of variable theXVariableID |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kFirstParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myParamAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(theXVariableID); |
myErr = QTInsertChild(theSprite, myOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
// second parameter: get value of variable theYVariableID |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kSecondParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myParamAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(theYVariableID); |
myErr = QTInsertChild(theSprite, myOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
// third parameter: false (for relative translation) |
myBoolean = false; |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kThirdParam, sizeof(myBoolean), &myBoolean, NULL); |
bail: |
if (theActionAtom != NULL) |
*theActionAtom = myActionAtom; |
return(myErr); |
} |
////////// |
// |
// QTWired_AddGetValueOfVarIDAction |
// Add an action atom that sets theTempVariableID to the value in the variable whose ID is the value of theVarID. |
// |
////////// |
static OSErr QTWired_AddGetValueOfVarIDAction (QTAtomContainer theSprite, QTAtom theParentAtom, QTAtomID theTempVariableID, QTAtomID theVarID) |
{ |
QTAtom myActionAtom = 0; |
QTAtom myExpressionAtom = 0; |
QTAtom myNewExpressionAtom = 0; |
QTAtom myParamAtom = 0; |
QTAtom myNewParamAtom = 0; |
QTAtom myOperandAtom = 0; |
QTAtom myNewOperandAtom = 0; |
QTAtom myOperandTypeAtom = 0; |
QTAtom myNewOperandTypeAtom = 0; |
QTAtomID myVariableID; |
OSErr myErr = paramErr; |
if (theSprite == NULL) |
goto bail; |
#if 0 |
{ |
Str255 myString; |
NumToString(theTempVariableID, myString); |
myErr = WiredUtils_AddActionAtom(theSprite, theParentAtom, kActionDebugStr, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
// add a target atom as the first parameter |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kFirstParam, myString[0], &myString, NULL); |
if (myErr != noErr) |
goto bail; |
} |
#endif |
myErr = WiredUtils_AddActionAtom(theSprite, theParentAtom, kActionSpriteTrackSetVariable, &myActionAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(theTempVariableID); |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kFirstParam, sizeof(myVariableID), &myVariableID, NULL); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myActionAtom, kSecondParam, 0, NULL, &myParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myParamAtom, &myExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddActionParameterAtom(theSprite, myOperandTypeAtom, kFirstParam, 0, NULL, &myNewParamAtom); |
if (myErr != noErr) |
goto bail; |
myErr = WiredUtils_AddExpressionContainerAtomType(theSprite, myNewParamAtom, &myNewExpressionAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myNewOperandAtom); |
if (myErr != noErr) |
goto bail; |
myErr = QTInsertChild(theSprite, myNewOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myNewOperandTypeAtom); |
if (myErr != noErr) |
goto bail; |
myVariableID = EndianU32_NtoB(theVarID); |
myErr = QTInsertChild(theSprite, myNewOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); |
bail: |
return(myErr); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-02-25