Start Code/QTSprites.c

//////////
//
//  File:       QTSprites.c
//
//  Contains:   QuickTime sprites support for QuickTime movies.
//
//  Written by: ???
//  Revised by: Deeje Cooley and Tim Monroe
//              Based (heavily!) on the existing MakeSpriteMovie.c code written by ???.
//
//  Copyright:  © 1997-1998 by Apple Computer, Inc., all rights reserved.
//
//  Change History (most recent first):
//
//     <5>      03/17/00    rtm     made changes to get things running under CarbonLib
//     <4>      09/30/98    rtm     tweaked call to AddMovieResource to create single-fork movies
//     <3>      06/19/98    rtm     moved to new routine names (e.g. SpriteMediaSetSpriteProperty)
//     <2>      04/09/98    rtm     added sprite hit-testing
//     <1>      04/02/98    rtm     first file; integrated existing code with shell framework
//     
//  This sample code creates a sprite movie containing one sprite track. The sprite track contains
//  a static background picture sprite (or just a colored background, depending on the value of the
//  global variable gUseBackgroundPicture) and three other sprites that change their properties over time.
//  The track's media contains only one key frame sample followed by many override samples. The key
//  frame contains all of the images used by the sprites; the override frames only contain the overrides
//  of the locations, image indices, and layers needed for the other sprites.
//
//  This sample code also shows how to hit test sprites. It uses the function SpriteMediaHitTestAllSprites
//  to find mouse clicks on the sprites in the first sprite track in a movie. If the user clicks on a
//  sprite, we toggle the visibility state of the sprite. You would probably want to do something a bit
//  more interesting when the user clicks on a sprite.
//
//////////
 
 
//////////
//
// header files
//
//////////
 
#include "QTSprites.h"
 
 
//////////
//
// global variables
//
//////////
 
Boolean                         gUseBackgroundPicture = true;       // do we display a background picture?
 
 
//////////
//
// QTSprites_InitWindowData
// Do any sprite-specific initialization for the specified window.
//
//////////
 
ApplicationDataHdl QTSprites_InitWindowData (WindowObject theWindowObject)
{
    ApplicationDataHdl      myAppData = NULL;
    Track                   myTrack = NULL;
    MediaHandler            myHandler = NULL;
 
    myAppData = (ApplicationDataHdl)NewHandleClear(sizeof(ApplicationDataRecord));
    if (myAppData != NULL) {
    
        myTrack = GetMovieIndTrackType((**theWindowObject).fMovie, 1, SpriteMediaType, movieTrackMediaType | movieTrackEnabledOnly);
        if (myTrack != NULL)
            myHandler = GetMediaHandler(GetTrackMedia(myTrack));
    
        // remember the sprite media handler
        (**myAppData).fMovieHasSprites = (myTrack != NULL);
        (**myAppData).fSpriteHandler = myHandler;
    }
    
    return(myAppData);
}
 
 
//////////
//
// QTSprites_DumpWindowData
// Get rid of any window-specific data for the sprite media handler.
//
//////////
 
void QTSprites_DumpWindowData (WindowObject theWindowObject)
{
    ApplicationDataHdl      myAppData = NULL;
        
    myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject);
    if (myAppData != NULL)
        DisposeHandle((Handle)myAppData);
}
 
 
//////////
//
// QTSprites_CreateSpritesMovie
// Create a QuickTime movie containing a sprite track.
//
//////////
 
OSErr QTSprites_CreateSpritesMovie (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(kSpriteSavePrompt);
    StringPtr               myFileName = QTUtils_ConvertCToPascalString(kSpriteSaveMovieFileName);
    QTAtomContainer         mySample = NULL;
    QTAtomContainer         mySpriteData = NULL;
    RGBColor                myKeyColor;
    Point                   myLocation, myIconLocation;
    short                   isVisible, myLayer, myIndex, i, myDelta, myIconMinH, myIconMaxH;
    long                    myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
    OSErr                   myErr = noErr;
 
    //////////
    //
    // create a new movie file
    //
    //////////
 
    // prompt user for the destination file name
    QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing);
    if (!myIsSelected)
        goto bail;
 
// Step 1.
// Insert "CreateSpriteMovie.clp" here
 
 
// Step 2.
// Insert "CreateSpriteTrackAndMedia.clp" here
    
 
// Step 3.
// Insert "CreateKeyFrameSample.clp" here
 
 
// Step 4.
// Insert "AddSpritesToKeyFrameSample.clp" here
 
    
// Step 5.
// Insert "AddKeyFrameSampleMedia.clp" here
 
 
// Step 6.
// Insert "AddOverrideSamples.clp" here
 
    
 
 
    //////////
    //
    // set the sprite track properties
    //
    //////////
    
    if (!gUseBackgroundPicture) {
        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);
 
        myErr = SetMediaPropertyAtom(myMedia, myTrackProperties);
        if (myErr != noErr)
            goto bail;
 
        QTDisposeAtomContainer(myTrackProperties);
    }
    
// Step 7.
// Insert "AddMovieResource.clp" here
 
    
bail:
    free(myPrompt);
    free(myFileName);
 
    if (mySample != NULL)
        QTDisposeAtomContainer(mySample);
 
    if (mySpriteData != NULL)
        QTDisposeAtomContainer(mySpriteData);   
            
    if (myResRefNum != 0)
        CloseMovieFile(myResRefNum);
 
    if (myMovie != NULL)
        DisposeMovie(myMovie);
        
    return(myErr);
}
 
 
//////////
//
// QTSprites_HitTestSprites
// Determine whether a mouse click is on a sprite; return true if it is, false otherwise.
//
// This routine is intended to be called from your movie controller action filter function,
// in response to mcActionMouseDown actions.
//
//////////
 
Boolean QTSprites_HitTestSprites (WindowObject theWindowObject, EventRecord *theEvent)
{
    ApplicationDataHdl      myAppData = NULL;
    MediaHandler            myHandler = NULL;
    Boolean                 isHandled = false;
    long                    myFlags = 0L;
    QTAtomID                myAtomID = 0;
    Point                   myPoint;
    ComponentResult         myErr = noErr;
 
    myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject);
    if (myAppData == NULL)
        goto bail;
        
    if (theEvent == NULL)
        goto bail;
        
    myHandler = (**myAppData).fSpriteHandler;
    myFlags = spriteHitTestImage | spriteHitTestLocInDisplayCoordinates | spriteHitTestInvisibleSprites;
    myPoint = theEvent->where;
    
    myErr = SpriteMediaHitTestAllSprites(myHandler, myFlags, myPoint, &myAtomID);
    if ((myErr == noErr) && (myAtomID != 0)) {
        Boolean             isVisible;
        
        // the user has clicked on a sprite;
        // for now, we'll just toggle the visibility state of the sprite
        SpriteMediaGetSpriteProperty(myHandler, myAtomID, kSpritePropertyVisible, (void *)&isVisible);
        SpriteMediaSetSpriteProperty(myHandler, myAtomID, kSpritePropertyVisible, (void *)!isVisible);
 
        isHandled = true;
    }
 
bail:
    return(isHandled);
}