MCPlayMovie.c

/*
  File:         MCPlayMovie.c
  Contains:     Movie Playing Application Using Movie Controllers.
  Written by:   John Wang / DTS
  Copyright:    © 1991-1994 by Apple Computer, Inc., all rights reserved.
  Change History (most recent first):
  <3>       12/4/94     khs     changed the format of the file to the new look and feel
  <2>       xx/xx/91    JW      Added palette support so that app restores color table
                                when changed by another app.
  <1>       11/17/91    JW      1.0 Completed
  To Do:
*/
 
 
// INCLUDEs
#include    <GestaltEqu.h>
#include    <Palettes.h>
#include    <SegLoad.h>
#include    <Devices.h>
#include    <ToolUtils.h>
#include    <Errors.h>
 
#include    <Movies.h>
 
 
// DEFINES
#define Gestalttest     0xA1AD
#define NoTrap          0xA89F
 
#define appleID         128         
#define appleMenu       0
#define aboutMeCommand  1
 
#define fileID          129
#define openCommand     1
#define flattenCommand  2
#define closeCommand    3
#define quitCommand     5
 
#define aboutMeDLOG     128
#define okButton        1
 
#define MAXWINDOWS      5
 
 
// FUNCTION PROTOTYPES
Movie GetMovieFromFile(void);
OSErr PlayMovie(int index);
short Flatten(int index);
void ShowAboutMeDialog(void);
void Init(void);
void Finish(void);
void DoCloseCommand(void);
void DoCommand(long mResult);
int PlayMovies(EventRecord* myEvent);
void DoOpenCommand(void);
void DoFlattenCommand(void);
 
// GLOBALS
Boolean DoneFlag = false;
MenuHandle mymenu0, mymenu1;
Boolean playingMovie[MAXWINDOWS];
Movie myMovie[MAXWINDOWS];
WindowPtr myWindow[MAXWINDOWS];
MovieController mcPlay[MAXWINDOWS];
int startlocation;
CTabHandle mycolors;
PaletteHandle srcPalette;
 
 
// FUNCTIONS
/*------------------------------------------------------*/
/*  GetMovieFromFile().                                 */
/*------------------------------------------------------*/
 
Movie GetMovieFromFile(void)
{
    OSErr err;
    StandardFileReply reply;
    Point where =
    {
        200,  50
    }
    ;
    SFTypeList types;
    short movieResRefNum;
    short actualResId;
    Movie theMovie;
 
    types[0] = 'MooV';
    StandardGetFilePreview(nil, 1, types, &reply);
    if (!reply.sfGood)
        return ((Movie)0);
 
    err = OpenMovieFile(&reply.sfFile, &movieResRefNum, fsRdPerm);
    if (GetMoviesError())
        return ((Movie)0);
    if (err)
        return ((Movie)0);
    actualResId = DoTheRightThing;
 
    err = NewMovieFromFile(&theMovie, movieResRefNum, &actualResId, NULL, newMovieActive, (Boolean *)0);
    if (GetMoviesError())
        return ((Movie)0);
    if (err)
        return ((Movie)0);
 
    err = CloseMovieFile(movieResRefNum);
    if (GetMoviesError())
        return ((Movie)0);
    if (err)
        return ((Movie)0);
 
    return (theMovie);
}
 
/*------------------------------------------------------*/
/*  PlayMovie().                                            */
/*------------------------------------------------------*/
 
OSErr PlayMovie(int index)
{
    Rect movieBounds;
 
    GetMovieBox(myMovie[index], &movieBounds);
    OffsetRect(&movieBounds, -movieBounds.left, -movieBounds.top);
    SetMovieBox(myMovie[index], &movieBounds);
    OffsetRect(&movieBounds, startlocation, startlocation);
 
 
 
    myWindow[index] = NewCWindow(0L, &movieBounds, "\pMovie!", 1, 0, (WindowPtr) - 1, false, 0L);
    SetPalette((WindowPtr)myWindow[index], srcPalette, true);
 
    OffsetRect(&movieBounds, -startlocation, -startlocation);
    startlocation += 50;
    if (startlocation > 300)
        startlocation = 50;
 
    SetMovieGWorld(myMovie[index], (CGrafPtr)myWindow[index], 0);
 
    if (GetMoviesError())
        DebugStr("\pSetMovieGWorld error.");
 
    mcPlay[index] = NewMovieController(myMovie[index], &movieBounds, mcTopLeftMovie);
    MCGetControllerBoundsRect(mcPlay[index], &movieBounds);
    SizeWindow(myWindow[index], movieBounds.right - movieBounds.left, movieBounds.bottom - movieBounds.top, true);
    /*  Uncomment these lines if you want to pre load the movie into ram.
      Don't forget to increase the partition size when recompiling.
      GotoBeginningOfMovie(myMovie[index]);
      if (LoadMovieIntoRam(myMovie[index], GetMovieTime(myMovie[index], 0L),
      GetMovieDuration(myMovie[index]),
      0) != noErr)
      DebugStr("\PNot enough memory to load movie into ram.");
    */
 
    return noErr;
}
 
/*------------------------------------------------------*/
/*  Flatten().                                          */
/*------------------------------------------------------*/
 
short Flatten(int index)
{
    StandardFileReply reply;
    OSErr theErr = noErr;
 
    StandardPutFile("\pName of flattened movie.", "\pUntitled", &reply);
    if (!reply.sfGood)
        return fnOpnErr;
 
    theErr = GetMoviesError();
    if (theErr != noErr)
        DebugStr("\pCall Before FlattenMovies failed.");
 
    FlattenMovie(myMovie[index], flattenAddMovieToDataFork, &reply.sfFile, 'JWJW', 0, createMovieFileDeleteCurFile, nil, nil);
 
    theErr = GetMoviesError();
    if (theErr != noErr)
        DebugStr("\pFlattenMovies failed.");
 
    return (theErr);
}
 
/*------------------------------------------------------*/
/*  ShowAboutMeDialog()                                 */
/*------------------------------------------------------*/
 
void ShowAboutMeDialog(void)
{
    GrafPtr savePort;
    DialogPtr theDialog;
    short itemHit;
 
    GetPort(&savePort);
    theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) - 1);
    SetPort(theDialog);
 
    do
    {
        ModalDialog(nil, &itemHit);
    } while (itemHit != okButton);
 
    CloseDialog(theDialog);
 
    SetPort(savePort);
    return;
}
 
/*------------------------------------------------------*/
/*  Init().                                             */
/*------------------------------------------------------*/
 
void Init(void)
{
    OSErr err;
    int i;
    long QDfeature, OSfeature;
 
    /*  Initialize Managaer.    */
    InitGraf(&qd.thePort);
    FlushEvents(everyEvent, 0);
    InitWindows();
    InitDialogs(nil);
    InitCursor();
 
    /*  Set up menus.   */
    mymenu0 = GetMenu(appleID);
    AddResMenu(mymenu0, 'DRVR');
    InsertMenu(mymenu0, 0);
    mymenu1 = GetMenu(fileID);
    InsertMenu(mymenu1, 0);
    DrawMenuBar();
 
    /*  Set up variables.   */
    startlocation = 50;
    for (i = 0; i < MAXWINDOWS; i++)
    {
        playingMovie[i] = false;
        myWindow[i] = nil;
    }
    mycolors = GetCTable(72);
    if (mycolors == nil)
        Debugger();
    srcPalette = NewPalette(((**mycolors).ctSize) + 1, mycolors, pmTolerant, 0);
 
    /*  Use Gestalt to find if QuickDraw and QuickTime is available.    */
    if ((GetTrapAddress(Gestalttest) != GetTrapAddress(NoTrap)))
    {
        err = Gestalt(gestaltQuickdrawVersion, &QDfeature);
        if (err)
            ExitToShell();
        err = Gestalt(gestaltSystemVersion, &OSfeature);
        if (err)
            ExitToShell();
        if (!DoneFlag && (QDfeature & 0x0f00) != 0x0200 && OSfeature < 0x0607)
            ExitToShell();
        err = Gestalt(gestaltQuickTime, &QDfeature);
        if (err)
            ExitToShell();
    }
    else
        ExitToShell();
 
    /*  Open QuickTime last.    */
    err = EnterMovies();
    if (err)
        ExitToShell();
}
 
/*------------------------------------------------------*/
/*  Finish().                                           */
/*------------------------------------------------------*/
 
void Finish(void)
{
    int i;
 
    for (i = 0; i < MAXWINDOWS; i++)
        if (playingMovie[i] == true)
        {
            CloseComponent(mcPlay[i]);
            DisposeMovie(myMovie[i]);
            DisposeWindow(myWindow[i]);
            playingMovie[i] = false;
        }
 
    ExitMovies();
    ExitToShell();
}
 
/*------------------------------------------------------*/
/*  DoOpenCommand().                                        */
/*------------------------------------------------------*/
 
void DoOpenCommand(void)
{
    int i,
     useThisIndex;
 
    useThisIndex = -1;
 
    /*  Search for the first window that is nil.    */
    for (i = MAXWINDOWS - 1; i >= 0; i--)
        if (myWindow[i] == nil)
            useThisIndex = i;
 
        /*  If index = -1, then it means that there are no windows avaiable.    */
    if (useThisIndex != -1)
    {
        myMovie[useThisIndex] = GetMovieFromFile();
        if (myMovie[useThisIndex] != 0)
        {
            PlayMovie(useThisIndex);
            playingMovie[useThisIndex] = true;
        }
    }
}
 
/*------------------------------------------------------*/
/*  DoFlattenCommand().                                     */
/*------------------------------------------------------*/
 
void DoFlattenCommand(void)
{
    int i;
    WindowPtr myTempWindow;
 
    /*  Flatten movie that is currently selected.   */
    myTempWindow = FrontWindow();
    if (myTempWindow == nil)
        return;
    for (i = 0; i < MAXWINDOWS; i++)
        if (myWindow[i] == myTempWindow)
            Flatten(i);
}
 
/*------------------------------------------------------*/
/*  DoCloseCommand().                                       */
/*------------------------------------------------------*/
 
void DoCloseCommand(void)
{
    int i;
    WindowPtr myTempWindow;
 
    /*  Close selected window.  */
    myTempWindow = FrontWindow();
    if (myTempWindow == nil)
        return;
    for (i = 0; i < MAXWINDOWS; i++)
        if (myWindow[i] == myTempWindow)
        {
            CloseComponent(mcPlay[i]);
            DisposeMovie(myMovie[i]);
            DisposeWindow(myTempWindow);
            playingMovie[i] = false;
            myWindow[i] = nil;
        }
}
 
/*------------------------------------------------------*/
/*  DoCommand().                                        */
/*------------------------------------------------------*/
 
void DoCommand(long mResult)
{
    int theMenu, theItem;
    Str255 daName;
    GrafPtr savePort;
 
    theItem = LoWord(mResult);
    theMenu = HiWord(mResult);
 
    switch (theMenu)
    {
        case appleID:
            if (theItem == aboutMeCommand)
                ShowAboutMeDialog();
            else
            {
                GetItem(mymenu0, theItem, daName);
                GetPort(&savePort);
                (void)OpenDeskAcc(daName);
                SetPort(savePort);
            }
            break;
 
        case fileID:
            switch (theItem)
            {
                case openCommand:
                    DoOpenCommand();
                    break;
                case flattenCommand:
                    DoFlattenCommand();
                    break;
                case closeCommand:
                    DoCloseCommand();
                    break;
                case quitCommand:
                    DoneFlag = true;
                    break;
                default:
                    break;
            }
            break;
    }
    HiliteMenu(0);
    return;
}
 
/*------------------------------------------------------*/
/*  PlayMovies().                                           */
/*------------------------------------------------------*/
 
int PlayMovies(EventRecord* myEvent)
{
    int i;
 
    for (i = 0; i < MAXWINDOWS; i++)
        if (playingMovie[i] == true)
        {
            if (MCIsPlayerEvent(mcPlay[i], myEvent))
                return (true);
        }
    return (false);
}
 
/*------------------------------------------------------*/
/*  main().                                             */
/*------------------------------------------------------*/
 
main()
{
    int i;
    char key;
    Boolean track;
    EventRecord myEvent;
    WindowPtr whichWindow;
    int yieldTime;
    int ret;
 
    Init();
    yieldTime = 0;
    for (;;)
    {
 
        /*  We can't just do ExitToShell because we must cann ExitMovies.   */
        if (DoneFlag)
            Finish();
 
        ret = WaitNextEvent(everyEvent, &myEvent, yieldTime, nil);
 
        if (PlayMovies(&myEvent))
            continue;
 
        if (ret)
        {
 
            switch (myEvent.what)
            {
                case mouseDown:
                    switch (FindWindow(myEvent.where, &whichWindow))
                    {
                        case inSysWindow:
                            SystemClick(&myEvent, whichWindow);
                            break;
                        case inMenuBar:
                            DoCommand(MenuSelect(myEvent.where));
                            break;
                        case inContent:
                            SelectWindow(whichWindow);
                            break;
                        case inDrag:
                            DragWindow(whichWindow, myEvent.where, &qd.screenBits.bounds);
                            break;
                        case inGrow:
                            break;
                        case inGoAway:
                            track = TrackGoAway(whichWindow, myEvent.where);
                            if (track)
                                DoCloseCommand();
                            break;
                        case inZoomIn:
                            break;
                        case inZoomOut:
                            break;
                        default:
                            break;
                    }
                    break;
                case keyDown:
                case autoKey:
                    key = myEvent.message & charCodeMask;
                    if (myEvent.modifiers & cmdKey)
                        if (myEvent.what == keyDown)
                            DoCommand(MenuKey(key));
                    break;
                case updateEvt:
                    for (i = 0; i < MAXWINDOWS; i++)
                        if ((WindowPtr)myEvent.message == myWindow[i])
                        {
                            BeginUpdate((WindowPtr)myWindow[i]);
                            EndUpdate((WindowPtr)myWindow[i]);
                        }
                    break;
                case diskEvt:
                    break;
                case activateEvt:
                    break;
                case app4Evt:
                    break;
                default:
                    break;
            }
        }
    }
}