Advancing the Frames

Although the mmpStartAnimating function notifies the Movie Player to start playback, your application must advance the animation using mmpAnimate. Your application calls mmpAnimate at regular intervals, generally in the message loop, and prompts the Movie Player to advance the animation.

It's useful to think of the movie frame as an expanse of time rather than a collection of animation data elements. Your application can call mmpAnimate many times during a given movie frame; with each call, the Movie Player performs whatever task is appropriate given the current state of the animation. These tasks can include the following:

Drawing a subframe or frame. On frames that use complex transitions, each mmpAnimate call completes one subframe, and the transition occurs over a series of mmpAnimate calls. For simpler transitions such as a straight copy, only one mmpAnimate call is required to complete the frame drawing.

Processing script-channel commands.

Waiting for a tempo period to expire.

Waiting for an MCI device to finish processing a script-channel command.

Noting the end of the frame.

Because mmpAnimate might be called while the animation is stopped, or while a device or tempo wait is in effect, the Movie Player might not perform any animation task in response to the mmpAnimate call.

The mmpAnimate function has the following syntax:

int mmpAnimate(idMovie)

The return value of mmpAnimate indicates the current state of the animation. The mmpAnimate return values are described in the Programmer's Reference. A positive return value indicates the animation is progressing, and a negative return value indicates the Movie Player is waiting for a Windows message to proceed to the next frame.

The following diagram shows a typical movie frame (including subframes, script-channel text, and a tempo wait period) and the values returned by mmpAnimate as the Movie Player advances through the frame.

The rest of this section describes how to structure your message loop to keep the movie frames advancing while allowing other applications to run.

Summary: Calling mmpAnimate in the Message Loop

You must call mmpAnimate for each Movie Player instance you loaded. The following code fragment shows the minimum message loop required to animate a single movie:

while(TRUE)
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if(msg.message == WM_QUIT)
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
                if(mmpAnimate(idMovie) < 0)
                        WaitMessage();
}

·To process Windows messages, and yield control to other applications:

1.Call PeekMessage to check the message queue for messages and yield control to other applications. PeekMessage does not wait for a message to enter the queue before returning, allowing your application to continue calling mmpAnimate at regular intervals.

2.Call mmpAnimate if no other program has a message to process.

3.Check the mmpAnimate return value.

4.If mmpAnimate returned a positive value, let the loop continue.

5.If mmpAnimate returned a negative value, call WaitMessage.

Note:

If mmpAnimate returns a negative value, don't loop around and call the function again (the frames won't advance until a message is received, and such a loop just uses CPU resources).

If your application loads multiple Movie Player instances, you might use a message loop like the following:

#define MAX_MOVIES 4
BOOL bRunning;
int i;
MMPID idMovies[MAX_MOVIES];
    .
    .
    .
while(TRUE)
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if(msg.message == WM_QUIT)
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        bRunning = FALSE;
        for(i = 0; i < MAX_MOVIES; i++)
            if(idMovies[i] && mmpAnimate(idMovies[i]) > 0)
                bRunning = TRUE;
        if(!bRunning)
            WaitMessage();
    }
}