/******************************Module*Header*******************************\ * Module Name: mtkanim.cxx * * Copyright (c) 1997 Microsoft Corporation * \**************************************************************************/ #include "mtk.hxx" #include "mtkanim.hxx" /**************************************************************************\ * MTKANIMATOR constructors * * The object needs to be attached to an hwnd, since it's required for timer * creation, and msg posting. \**************************************************************************/ MTKANIMATOR::MTKANIMATOR() { hwnd = NULL; Init(); } MTKANIMATOR::MTKANIMATOR( HWND hwndAttach ) : hwnd( hwndAttach ) { Init(); } /**************************************************************************\ * \**************************************************************************/ void MTKANIMATOR::Init() { idTimer = 0; nFrames = 0; mode = MTK_ANIMATE_CONTINUOUS; msUpdateInterval = 0; AnimateFunc = NULL; } /**************************************************************************\ * MTKANIMATOR destructor * \**************************************************************************/ MTKANIMATOR::~MTKANIMATOR() { Stop(); } /**************************************************************************\ * SetFunc * * Set the animation function callback. This immediately replaces the previous * callback, and if a timer is currently running, then the new function gets * called. If the new callback is NULL, then the timer is stopped. * \**************************************************************************/ void MTKANIMATOR::SetFunc( MTK_ANIMATEPROC Func ) { AnimateFunc = Func; if( ! AnimateFunc ) { Stop(); } } /**************************************************************************\ * SetMode * \**************************************************************************/ void MTKANIMATOR::SetMode( UINT newMode, float *fParam ) { switch( newMode ) { case MTK_ANIMATE_CONTINUOUS : // First param is animation period ( 1/fps ) { float fUpdateInterval = fParam[0]; if( fUpdateInterval < 0.0f ) SS_WARNING( "MTKANIMATOR::SetMode: bad update interval parameter\n" ); fUpdateInterval = 0.0f; msUpdateInterval = (UINT) (fUpdateInterval * 1000.0f); } break; case MTK_ANIMATE_INTERVAL : // First param is number of frames, // Second param is total desired duration of the animation { int iFrameCount = (int) fParam[0]; float fDuration = fParam[1]; // Check parameters // fDuration = 0.0f is valid - it means go as fast as possible... if( (fDuration < 0.0f) || (iFrameCount <= 0) ) SS_ERROR( "MTKANIMATOR::SetMode: bad parameter\n" ); return; nFrames = iFrameCount; msUpdateInterval = (UINT) ( (fDuration / (float) nFrames) * 1000.0f); } break; default : return; } mode = newMode; } /**************************************************************************\ * Start * * Start the animation by creating a new timer, if there is a valid animation * callback function. * \**************************************************************************/ void MTKANIMATOR::Start( ) { // Create new timer if( idTimer || !AnimateFunc ) return; // Timer already running, or no animate func idTimer = SetTimer( hwnd, MTK_ANIMATE_TIMER_ID, msUpdateInterval, NULL ); if( ! idTimer ) SS_WARNING( "MTKANIMATOR::Start: SetTimer failure\n" ); } /**************************************************************************\ * Stop * * Stop the animation by killing the timer. Remove any WM_TIMER msgs * \**************************************************************************/ void MTKANIMATOR::Stop( ) { if( !idTimer ) return; if( ! KillTimer( hwnd, MTK_ANIMATE_TIMER_ID ) ) SS_WARNING( "MTKANIMATOR::Stop: KillTimer failure\n" ); // remove any timer messages from queue MSG Msg; PeekMessage( &Msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE ); idTimer = 0; } //mf: need better name for this /**************************************************************************\ * * Call the animate function * * A return value of FALSE indicates that an interval based animation has * finished - TRUE otherwise. * \**************************************************************************/ BOOL MTKANIMATOR::Draw( ) { if( !AnimateFunc ) return TRUE; (*AnimateFunc)(); if( mode == MTK_ANIMATE_INTERVAL ) { if( --nFrames <= 0 ) return FALSE; } return TRUE; }