topical media & game development

talk show tell print

hush-src-multi-GamePlayer-CustomMixer.cpp / cpp



  //------------------------------------------------------------------------------
  // File: CustomMixer.cpp
  //
  // Desc: DirectShow sample code - MultiVMR9 GamePlayer
  //
  // Copyright (c) Microsoft Corporation.  All rights reserved.
  //------------------------------------------------------------------------------
  
  include <stdafx.h>
  include <hall.h>
  include <CustomMixer.h>
  include "MultiVMR9_i.c"
  include <VMR9Subgraph.h>
  include <GamePlayer.h>
  
  include <vip.h>
  
  IDirect3DTexture9* gCaptureTexture;
  extern vip* VP;
  static int g_index = 0;
  
  D3DXMATRIX* g_world = 0;
  D3DXMATRIX* g_view = 0;
  D3DXMATRIX* g_proj = 0;
  
  extern CGamePlayerSession* g_pSession;
  
  // world matrix (combined projection and view)
  D3DXMATRIX g_matWorld(
              -0.681917f,   -0.094384f,  -0.725303f, 0.f,
              -0.727560f,    0.189257f,   0.659417f, 0.f,
               0.075027f,    0.977377f,  -0.197721f, 0.f,
            -318.524170f, -210.488570f,  81.793221f, 1.f
                        );
  
  const D3DCOLOR g_colorPale   = D3DCOLOR_RGBA( 0xFD, 0xBB, 0x40, 0x30 );
  const D3DCOLOR g_colorGold   = D3DCOLOR_RGBA( 0xFD, 0xBB, 0x40, 0xC0 );
  
  // start position of the left top corner of the first movie screen
  const float g_fXStart = -370.f;
  const float g_fYStart = -1900.f;
  const float g_fZStart = 610.f;
  
  const float g_fMovieSlotWidth = 600.f;  // width of the movie screen
  const float g_fMovieSlotHeight = 450.f; // height of the movie screen
  
  const float g_fFrameWidth = 5.f; // width of the frame for the movie screen
  
  const float g_fDelta = 100.f; // distance between movies
  const float g_fDarknessRange[] = {-2000.f, -1500.f, 1500.f, 2000.f}; 
  const float g_fSpeed = 0.19f; // gait speed
  
  
****************************Public*Routine******************************\ CGameMixer constructor \*************************************************************************

  
  
  static int _total = 9;
  
  STDMETHODIMP
  CGameMixer::GetBackgroundColor(COLORREF* pColor) {
  HRESULT hr = S_OK;
  char* pc = scene::cm("bgcolor");
  float args[4];
  scene::getfv(pc,3,args);
  //*pColor = RGB(255,0,0);
  *pColor = RGB(int(255*args[0]/100.0),int(255*args[1]/100.0),int(255*args[2]/100.0));
  
  return hr;
  }
  
  CGameMixer::CGameMixer(LPUNKNOWN pUnk, HRESULT *phr)
      : CUnknown(NAME("GameMixer Control for MultiVMR9"), pUnk)
      , m_bInitialized( FALSE )
      , m_pOwner( NULL )
      , m_fSpeed( g_fSpeed )
      , m_dwPrevTick( NULL )
      , m_pFont( NULL )
      , m_Left( 0)
      , m_bAnimate( TRUE )
      , m_pActiveMovie( NULL)
          , m_last(NULL)
          , m_pHall( NULL )
          , m_pCharacter( NULL )
  {
      float fAspect;
      int i;
  
      m_matWorld = g_matWorld;
  
      D3DXVECTOR3 vEye( 0, 0, -700.f );
      D3DXVECTOR3 vAt( 0, 0, 0 );
      D3DXVECTOR3 vUp( 0, 1, 0 );
  
      m_pFont = new CD3DFont( _T("Trebuchet MS"), 12, D3DFONT_BOLD );
  
      D3DXMatrixLookAtLH( &m_matView, &vEye, &vAt, &vUp);
  
      fAspect = 4.f / 3.f;
  
      D3DXMatrixPerspectiveFovLH( &m_matProj, 
                                  D3DX_PI/4.f, // FOV
                                  4.f/3.f,     // aspect ratio: always 4:3
                                  10.f,        // nearest plane
                                  100000.f);   // far plane
  
      D3DVECTOR vecStart;
      vecStart.x = g_fXStart;
      vecStart.y = g_fYStart;
      vecStart.z = g_fZStart;
  
      for( i=0; i<64; i++)
      {
          m_Frames[i].Calculate(i, vecStart, NULL);
      }
  
          g_world = &m_matWorld;
          g_view = &m_matView;
          g_proj = &m_matProj;
  
          //VP->debug("walk init");
      m_scene = VP->_main(); //scene::_main;
          VP->_main()->popt("main",VP->_main());
          scene::fx("dummy",0);
          scene::ds("character",1);
          scene::ds("hall",1);
          scene::ds("paintings",1);
          scene::ds("floor",1);
          scene::ds("wall",1);
          scene::ds("frame",1);
          scene::ds("movie",1);
          scene::ds("activemovie",1);
          scene::ds("movie:0",1);
          scene::ds("movie:1",1);
          scene::ds("movie:2",1);
          scene::ds("movie:3",1);
          scene::ds("movie:4",1);
          scene::ds("movie:5",1);
          scene::ds("movie:6",1);
          scene::ds("movie:7",1);
          scene::ds("movie:8",1);
          scene::ds("movie:9",1);
          scene::ds("slide:1",0);
          scene::ds("slide:2",0);
          scene::ds("slide:3",0);
          scene::ds("slide:4",0);
          scene::ds("slide:5",0);
          scene::ds("slide:6",0);
          scene::ds("slide:7",0);
          scene::ds("slide:8",0);
          scene::ds("slide:9",0);
          for (int i = 0; i < 64; i++) scene::ds(i,1);
          scene::cm("hall","1");
          scene::cm("floor","1");
          scene::cm("character","active");
          scene::ds("walk:speed",100);
          //scene::cm("bgcolor","(0,0,0)");
          scene::cm("bgcolor","(100,100,100)");
  
          
  
          m_pHall = new CHall();
          if( !m_pHall )
          {
  		*phr = E_OUTOFMEMORY;
          }
          m_pCharacter = new CCharacter();
          if( !m_pCharacter )
          {
  		*phr = E_OUTOFMEMORY;
          }
  }
  
  
****************************Public*Routine******************************\ ~CMultiVMR9MixerControl destructor \*************************************************************************

  
  CGameMixer::~CGameMixer()
  {
      CAutoLock Lock(&m_ObjectLock);
      Clean_();
  }
  
  
/////////////////// IUnknown
///////////////////////////////////


****************************Public*Routine******************************\ CreateInstance \*************************************************************************

  
  CUnknown* CGameMixer::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
  {
      return new CGameMixer(pUnk, phr);
  }
  
  
****************************Public*Routine******************************\ NonDelegatingQueryInterface \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::NonDelegatingQueryInterface(
      REFIID riid,
      void ** ppv)
  {
      HRESULT hr = E_NOINTERFACE;
      *ppv = NULL;
  
      if (riid == IID_IMultiVMR9MixerControl) 
      {
          hr = GetInterface((IMultiVMR9MixerControl *)this, ppv);
      }
      else 
      {
          hr = CUnknown::NonDelegatingQueryInterface(riid,ppv);
      }
      return hr;
  }
  
  
/////////////////// IMultiVMR9MixerControl
/////////////////////////


****************************Public*Routine******************************\ Compose \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::Compose(
          void* lpParam)
  {
      HRESULT hr = S_OK;
  
      DWORD t = reinterpret_cast<DWORD>(lpParam);
      LONG dt;
      float dy;
  
      if( 0L == m_dwPrevTick )
      {
          m_dwPrevTick = t;
          return S_OK;
      }
  
          float speed = 2 * scene::ds("walk:speed") / 100.0;
      dt = (t - m_dwPrevTick) * speed;
      m_dwPrevTick = t;
  
      CAutoLock Lock(&m_ObjectLock);
  
      try
      {
          CHECK_HR(
              ( !m_bInitialized ) ? VFW_E_WRONG_STATE : S_OK,
              DbgMsg("CGameMixer::Compose: mixer was not initialized!"));
          scene::ds("walk:animate",0);
          if(1 || m_bAnimate )
          {
                          if (m_bAnimate) scene::ds("walk:animate",1);
                          if( m_pHall )
                          {
                                  // compose the hall
                                  CHECK_HR(
                                          hr = m_pHall->Compose( t ),
                                          DbgMsg("CGameMixer::Compose: failed to compose the hall, hr = 0x%08x",hr));
                          }
              
                          if( m_pCharacter )
                          {
                                  // compose the figure
                                  CHECK_HR(
                                          hr = m_pCharacter->Compose( t ),
                                          DbgMsg("CGameMixer::Compose: failed to compose the character, hr = 0x%08x",hr));
                          }
              
              // compose frames
              dy = m_fSpeed * dt;
  
              // check if we have to flip "left"
              if( m_Frames[m_Left].m_S[1].Pos.y +dy > g_fDarknessRange[3])
              {
                                  m_Frames[m_Left].FlipToEnd( _total ); //8 );
                  m_Left++;
                                  if( /*8*/ _total == m_Left )
                  {
                      m_Left = 0;
                  }
              }
  
              // update coordinates for "left"
              m_Frames[m_Left].MoveY( dy );
          }// if animate
  
      }// try
      catch( HRESULT hr1 )
      {
          hr = hr1;
      }
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ BeginDeviceLoss \*************************************************************************

  
  STDMETHODIMP CGameMixer::BeginDeviceLoss( void )
  {
          HRESULT hr = S_OK;
          HWND hwndVideo = NULL;
  
          if( m_pHall )
          {
                  delete m_pHall;
                  m_pHall = NULL;
          }
          if( m_pCharacter )
          {
                  delete m_pCharacter;
                  m_pCharacter = NULL;
          }
          m_bInitialized = FALSE;
  
          return S_OK;
  }
  
  
****************************Public*Routine******************************\ EndDeviceLoss \*************************************************************************

  
  STDMETHODIMP CGameMixer::EndDeviceLoss( IDirect3DDevice9* pDevice )
  {
          HRESULT hr = S_OK;
          if( !pDevice )
                  return E_POINTER;
          if( m_pHall )
          {
                  delete m_pHall;
                  m_pHall = NULL;
          }
          m_pHall = new CHall();
          if( !m_pHall )
                  return E_OUTOFMEMORY;
  
          if( m_pCharacter )
          {
                  delete m_pCharacter;
                  m_pCharacter = NULL;
          }
          m_pCharacter = new CCharacter();
          if( !m_pCharacter )
                  return E_OUTOFMEMORY;
          m_bInitialized =  FALSE;
          hr = Initialize( pDevice );
          return hr;
  }
  
  
****************************Public*Routine******************************\ Compose \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::Render(
                     IDirect3DDevice9* pDevice, 
                     void *lpParam )
  {
      HRESULT hr = S_OK;
      list<CMovie*>::iterator start, end, it;
      CMovie* pMovie = NULL;
      int FrameRate100 = 0;
      int FrameRateAvg100 = 0;
      TCHAR achFrameRate[MAX_PATH];
      
      CComPtr<IMultiVMR9Wizard> pWizard;
      CComPtr<IDirect3DTexture9> pTexture;
  
          
  
      if( !pDevice )
      {
          return E_POINTER;
      }
  
          hr = pDevice->SetTransform( D3DTS_VIEW, &m_matView );
          hr = pDevice->SetTransform( D3DTS_PROJECTION, &m_matProj );
  
      CAutoLock Lock(&m_ObjectLock);
  
          //if (GM->_main()) GM->_main()->render(pDevice,gCaptureTexture);
      try
      {
          // error if not initialized
          CHECK_HR(
              m_bInitialized ? S_OK : VFW_E_WRONG_STATE,
              DbgMsg("CGameMixer::Render: mixer was not initialized!"));
  
          CHECK_HR(
              m_pOwner ? S_OK : E_UNEXPECTED,
              DbgMsg("CGameMixer::Render: mixer is initialized, but has no Render engine owner!"));
  
          CHECK_HR(
              hr = m_pOwner->GetWizardOwner( &(pWizard.p) ),
              DbgMsg("CGameMixer::Render: mixer has owner, but has no parent wizard!"));
  
          if(m_bAnimate )
          {
              // make sure we are in the right world
              CHECK_HR(
                  hr = pDevice->SetTransform( D3DTS_WORLD, &m_matWorld ),
                  DbgMsg("CGameMixer::Render: failed to set the world transform, hr = 0x%08x", hr));
  
                          if( m_pCharacter && scene::ds("character") && !scene::ds("noenv"))
                          {
                                  // render the figure
                                  CHECK_HR(
                                          hr = m_pCharacter->Render( pDevice ),
                                          DbgMsg("CGameMixer::Render: failed to render the character, hr = 0x%08x", hr));
                          }
  
              // make sure we are in the right world
              CHECK_HR(
                  hr = pDevice->SetTransform( D3DTS_WORLD, &m_matWorld ),
                  DbgMsg("CGameMixer::Render: failed to set the world transform, hr = 0x%08x", hr));
              
  
                          if(1 && m_pHall && m_pHall && scene::ds("hall") && !scene::ds("noenv"))
                          {
                                  // render the hall
                                  CHECK_HR(
                                          hr = m_pHall->Render( pDevice ),
                                          DbgMsg("CGameMixer::Render: failed to render the hall, hr = 0x%08x", hr));
                          }
  
              // restore device objects for movies
              CHECK_HR(
                  hr = RestoreDeviceObjects( pDevice ),
                  DbgMsg("CGameMixer::Render: failed in RestoreDeviceObjects, hr = 0x%08x", hr));
  
              
                          static int _startit = 0;
                          // render all the movies
              start = m_listMovies.begin();
              end = m_listMovies.end();
  
                          
  
              if( false == m_listMovies.empty() )
              {
                  int Index;
                  D3DVECTOR vecStart;
  
                  vecStart.x = g_fXStart; 
                  vecStart.z = g_fZStart;
  
                                  _startit++;
                  it = start;
                                  //if (1 || !_startit) { it = start; _startit = 1; }
                                  int mi = 0;
                                  int _ktotal = _total = scene::_total(); // do check morph active
                                  if (scene::ds("total")) _total = scene::ds("total");
                                  if (_ktotal < 8) _ktotal = 8;
                                  if (_total < 8) _total = 8;
                                  
                                  int ki = 0; //int _ktotal = _total;
                  for( int i=0; i<_ktotal; i++)
                  {
                                          if( 0 &&  it == end )
                      {
                          it = start;
                                                  mi = 0;
                      }
                                          
                      pMovie = (CMovie*)(*it);
  
                                          //if (_startit > 1000) VP->debug(vip::fm("frame: \%d (\%d)",mi,i));
  
                                          mi++;
                                          if (1 && pMovie && !pMovie->_capture) { //0 && ((i == 0) || pMovie && pMovie->_capture)) {
                                                  //pMovie->m_dwID //AE
                                                  CVMR9Subgraph* pSource = NULL;
                              pSource = g_pSession->GetSubgraph( pMovie->m_dwID);
                                                  if (pSource) {
                                                          if (scene::ds(vip::fm("run:\%d",mi))) 
                                                           pSource->Run();
                                                          else pSource->Pause();
                                                  }
                                          }
  
                      CHECK_HR(
                          pMovie ? S_OK : E_UNEXPECTED,
                          DbgMsg("CGameMixer::Render: FATAL, list contains NULL movies"));
  
                      CHECK_HR(
                          hr = pWizard->GetTexture( pMovie->m_dwID, &pTexture ),
                          DbgMsg("CGameMixer::Render: failed to get the texture for movie \%ld, hr = 0x%08x", pMovie->m_dwID, hr));
  
                      VP->set_capture(i,pTexture);
                                          //scene::tx(vip::fm("\%d",mi),pTexture);
  
                      Index = ki - m_Left;
                      if( Index < 0 )
                      {
                          Index += _total; //_total; //8; // _total;
                      }
  
                      vecStart.y = m_Frames[m_Left].m_S[0].Pos.y;
                                          //g_index = i;
                                          g_index = mi-1;
                                          
  
                      CHECK_HR(
                          hr = m_Frames[i].Calculate( Index, vecStart, pMovie),
                          DbgMsg("CGameMixer::Render: failed to recalculate coordinates for frame \%d, movie \%ld, hr = 0x%08x", i, pMovie->m_dwID, hr));
  
                                          char buf[64]; sprintf(buf,"\%d",mi);
                                          //scene::tx("z",scene::tx(mi-scene::ds("z")));
                                          //if (mi != scene::ds("slide:movie")) 
                                          //if (!scene::ds(scene::fm("slide:\%d"),mi)) // != scene::ds("slide:movie"))
                                          //if (!scene::ds(mi))        
                                          scene::cp(mi,pTexture);
                                          //if (!scene::ds(scene::fm("slide:\%d"),mi)) //(mi != scene::ds("slide:movie")) 
                                          //if (!scene::ds(mi))
                                          scene::tx(mi,pTexture); // AE
                                          if (!scene::ds("noslides") && !scene::ds(scene::fm("nomovie:\%d",mi)) && scene::ds(scene::fm("movie:\%d"),mi)) {
                                                  scene::tx(mi,scene::tx(scene::fm("movie:\%d",mi)));
                                                  //scene::cp(mi,scene::tx(scene::fm("movie:\%d",mi)));
                                                  //scene::tx(mi,scene::tx("slide:movie"));
                                          }
  
                                          if (mi == scene::ds("video:map") && scene::tx("camera")) {
                                                  //scene::tx(mi,scene::tx("camera"));
  
                                          scene::tx(scene::ds("video:map"),scene::tx("camera"));
                                          }
  
                                          char sbuf[64]; sprintf(sbuf,"shift:\%d",mi);
                                          if (scene::ds(buf)) { //&& (mi < 9)) {
                      //CHECK_HR(
                                                  if (mi == scene::ds("slide:movie")) {
                                                    //hr = m_Frames[i].Render( pDevice, scene::tx("slide:movie"));
                                                     if (!scene::ds("noenv")) hr = m_Frames[ki].Render( pDevice, scene::tx(mi));
                                                  //hr = m_Frames[i].Render( pDevice, pTexture),
                          //DbgMsg("CGameMixer::Render: failed to render movie \%ld, hr = 0x%08x", pMovie->m_dwID, hr));
                                                  } else 
                                                     if (!scene::ds("noenv")) hr = m_Frames[ki].Render( pDevice, scene::tx(mi));
                                          } else if (scene::ds(sbuf)) { // || (mi > 8)) {
                                                  //i = i - 1;
                                                  ki = ki - 1;
                                                  g_index -= 1;
                                                  //_total -= 1;
                                          }
                      it++; ki++;
                      if( it == end )
                      {
                          it = start;
                                                  mi = 0;
                      }
                      pTexture = NULL;
                  }
                                  gCaptureTexture = VP->get_capture(0); //GM->get_select());
              }// if list is not empty
          
                          //scene::tx(1,scene::tx("camera"));
                          
                          if (m_bAnimate) {
  
              
                                  if( 0 && m_pHall && scene::ds("hall") && !scene::ds("noenv"))
                          {
                                  // render the hall
                                  CHECK_HR(
                                          hr = m_pHall->Render( pDevice ),
                                          DbgMsg("CGameMixer::Render: failed to render the hall, hr = 0x%08x", hr));
                          }
                          }
                  }// if animate
  
                  
          else // draw selected movie
          {
                          if( m_pActiveMovie && scene::ds("activemovie"))
              {
                  D3DXMATRIX matPlainWorld;
                  D3DXMatrixIdentity( &matPlainWorld );
  
                                   CMovie* pMovie = m_pActiveMovie;
                                          //mi++;
                                          if (1 && pMovie && !pMovie->_capture) { //0 && ((i == 0) || pMovie && pMovie->_capture)) {
                                                  //pMovie->m_dwID //AE
                                                  CVMR9Subgraph* pSource = NULL;
                              pSource = g_pSession->GetSubgraph( pMovie->m_dwID);
                                                  if (pSource) { // && !scene::ds("focus:stop")) {
                                                          if (!scene::ds("focus:stop") || scene::ds(vip::fm("run:\%d",VP->get_active()))) 
                                                           pSource->Run();
                                                          else if (scene::ds("mfocus:stop") && !scene::ds(vip::fm("run:\%d",VP->get_active()))) pSource->Pause();
                                                  }
                                          }
  
                  pDevice->SetTransform( D3DTS_WORLD, &matPlainWorld);
                  
                  // restore device objects for movies
                                  if (1) { // XX
                  CHECK_HR(
                      hr = RestoreDeviceObjects( pDevice ),
                      DbgMsg("CGameMixer::Render: failed in RestoreDeviceObjects, hr = 0x%08x", hr));
                                  }
                  //CHECK_HR(
                      hr = pWizard->GetTexture( m_pActiveMovie->m_dwID, &pTexture );
                      //DbgMsg("CGameMixer::Render: failed to get the texture for active movie \%ld, hr = 0x%08x", m_pActiveMovie->m_dwID, hr));
               
                  CHECK_HR(
                      hr = m_ActiveMovieFrame.CalculateInFocus( m_pActiveMovie ),
                      DbgMsg("CGameMixer::Render: hr = 0x%08x", hr));
  
                                  if (0) {
                                  hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
                  hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
                  hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
                  hr = pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
                                  hr = pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
                                  }
                  //CHECK_HR(
                                  //if (scene::ds("slide:movie") == pMovie->_number)
                                  if (scene::ds(scene::fm("slide:\%d"),pMovie->_number))
                                          hr = m_ActiveMovieFrame.Render( pDevice, scene::tx(pMovie->_number));
                                  else
                      hr = m_ActiveMovieFrame.Render( pDevice, pTexture);
                      //DbgMsg("CGameMixer::Render: failed to render 'active' movie \%ld, hr = 0x%08x", m_pActiveMovie->m_dwID, hr));
  
                  pDevice->SetTransform( D3DTS_WORLD, &m_matWorld );
  
              }// if active movie
          }
  
          hr = m_pOwner->GetFrameRate( &FrameRate100 );
          hr = m_pOwner->GetFrameRateAvg( &FrameRateAvg100 );
          _stprintf( achFrameRate, TEXT("FPS: %6.2f\t (average %6.2f fps)"), (float)FrameRate100/100.f, (float)FrameRateAvg100/100.f);
  
          //if (GM->_main()) GM->_main()->render(pDevice,gCaptureTexture);
  
          if( 0 && m_pFont )
          {
              m_pFont->DrawText( 20,  570, D3DCOLOR_ARGB(180,133,197,235), achFrameRate );
          }
  
      }
      catch( HRESULT hr1 )
      {
                  if( hr1 == D3DERR_DEVICELOST && m_pOwner )
                  {
                          hr = m_pOwner->ProcessLostDevice();
                  }
                  else
                  {
                          hr = hr1;
                  }
      }
      return hr;
  }
  
  
****************************Public*Routine******************************\ AddVideoSource \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::AddVideoSource(
                              DWORD_PTR dwID,
                              LONG lImageWidth,
                              LONG lImageHeight,
                              LONG lTextureWidth,
                              LONG lTextureHeight)
  {
      HRESULT hr = S_OK;
      CMovie *pMovie = NULL;
      float dy = 0.f;
  
          static int num = 0;
  
      CAutoLock Lock(&m_ObjectLock);
  
      try
      {
          pMovie = new CMovie( dwID, 
                               lImageWidth, 
                               lImageHeight, 
                               lTextureWidth, 
                               lTextureHeight);
          CHECK_HR(
              pMovie ? S_OK: E_OUTOFMEMORY,
              DbgMsg("CGameMixer::AddVideoSource: failed to create new CMovieFrame object"));
  
                  CVMR9Subgraph* pSource = NULL;
             pSource = g_pSession->GetSubgraph( dwID);
             if (pSource && pSource->capture) pMovie->_capture = 1;
                  
  
          m_listMovies.push_back( pMovie );
                  num++;
                  pMovie->_number = num;
      }
      catch( HRESULT hr1 )
      {
          hr = hr1;
      }
      return hr;
  }
  
  
****************************Public*Routine******************************\ DeleteVideoSource \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::DeleteVideoSource(
                          DWORD_PTR dwID)
  {
      HRESULT hr = S_OK;
  
      list<CMovie*>::iterator start, end, it;
      CMovie* pMovie = NULL;
      CMovie* pMovieRequested = NULL;
  
      start = m_listMovies.begin();
      end = m_listMovies.end();
  
      CAutoLock Lock(&m_ObjectLock);
  
      try
      {
          for( it=start; it!=end; it++)
          {
              pMovie = (CMovie*)(*it);
              
              CHECK_HR(
                  pMovie? S_OK : E_UNEXPECTED,
                  DbgMsg("CGameMixer::DeleteVideoSource: FATAL, list contains NULL movies!"));
              
              if( dwID == pMovie->m_dwID )
              {
                  pMovieRequested = pMovie;
                  break;
              }
          }
  
          CHECK_HR(
              pMovieRequested ? S_OK : VFW_E_NOT_FOUND,
              DbgMsg("CGameMixer::DeleteVideoSource: requested movie ID = 0x%08x was not found in the list", dwID));
  
          // if movie found, delete it from the list
          m_listMovies.remove( pMovieRequested );
          delete pMovieRequested;
          pMovieRequested = NULL;
  
      }
      catch(HRESULT hr1)
      {
          hr = hr1;
      }
      return hr;
  }
  
  
****************************Public*Routine******************************\ SetRenderEngineOwner \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::SetRenderEngineOwner(
          IMultiVMR9RenderEngine* pRenderEngine)
  {
      HRESULT hr = S_OK;
      CAutoLock Lock(&m_ObjectLock);
  
      try
      {
          RELEASE( m_pOwner );
          if( pRenderEngine )
          {
              m_pOwner = pRenderEngine;
              m_pOwner->AddRef();
          }
      }
      catch( HRESULT hr1)
      {
          hr = hr1;
      }
      return hr;
  }
  
  
****************************Public*Routine******************************\ GetRenderEngineOwner \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::GetRenderEngineOwner(
          IMultiVMR9RenderEngine** ppRenderEngine)
  {
      if( !ppRenderEngine )
      {
          return E_POINTER;
      }
      if( !m_pOwner )
      {
          return VFW_E_NOT_FOUND;
      }
  
      *ppRenderEngine = m_pOwner;
      (*ppRenderEngine)->AddRef();
  
      return S_OK;
  }
  
  
****************************Public*Routine*****************************\ Initialize \*************************************************************************

  
  STDMETHODIMP
  CGameMixer::Initialize(
                         IDirect3DDevice9 *pDevice)
  {
      HRESULT hr = S_OK;
      TCHAR achMessage[MAX_PATH];
  
      CAutoLock Lock(&m_ObjectLock);
  
      achMessage[0] = TEXT('\0');
  
      if( m_bInitialized )
      {
          return VFW_E_WRONG_STATE;
      }
  
      if( !pDevice )
      {
          return E_POINTER;
      }
  
      try
      {
          CHECK_HR(
              hr = m_pFont->InitDeviceObjects( pDevice ),
              DbgMsg("CGameMixer::Initialize: failed to initialize font, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = m_pFont->RestoreDeviceObjects(),
              DbgMsg("CGameMixer::Initialize: failed to RestoreDeviceObjects for the font, hr = 0x%08x", hr));
  
                  if( m_pHall )
                  {
                          CHECK_HR(
                                  hr = m_pHall->Initialize( pDevice ),
                                  DbgMsg("CGameMixer::Initialize: failed to initialize the hall, hr = 0x%08x", hr));
                          m_pHall->SetSpeed( g_fSpeed );
                  }
  
                  if( m_pCharacter )
                  {
                          CHECK_HR(
                                  hr = m_pCharacter->Initialize( pDevice ),
                                  DbgMsg("CGameMixer::Initialize: failed to initialize the character, hr = 0x%08x", hr));
                  }
  
          CHECK_HR(
              hr = pDevice->SetTransform( D3DTS_VIEW, &m_matView ),
              DbgMsg("CGameMixer::Initialize: failed to set the view matrix, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetTransform( D3DTS_PROJECTION, &m_matProj ),
              DbgMsg("CGameMixer::Initialize: failed to set the projection matrix, hr = 0x%08x", hr));
  
          m_bInitialized = TRUE;
      }
      catch( HRESULT hr1 )
      {
          hr = hr1;
      }
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ RestoreDeviceObjects \*************************************************************************

  
  HRESULT CGameMixer::RestoreDeviceObjects( IDirect3DDevice9 *pDevice )
  {
      HRESULT hr = S_OK;
  
      if( !pDevice )
      {
          return E_POINTER;
      }
  
      try
      {
                  if (0) { //XX
          CHECK_HR(
              hr = pDevice->SetRenderState( D3DRS_AMBIENT,      0x00FFFFFF ),
              DbgMsg("CGameMixer::RestoreDeviceObjects: failed to set render state D3DRS_AMBIENT/0xFFFFFFFF, hr = 0x%08x",hr));
          CHECK_HR(
              hr = pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE),
              DbgMsg("CGameMixer::RestoreDeviceObjects: failed to set render state D3DRS_CULLMODE/D3DCULL_NONE, hr = 0x%08x",hr));
          CHECK_HR(
              hr = pDevice->SetRenderState(D3DRS_ZENABLE, TRUE),
              DbgMsg("CGameMixer::RestoreDeviceObjects: failed to set render state D3DRS_ZENABLE/FALSE, hr = 0x%08x",hr));
                  }
                  if (0) { //XX
          CHECK_HR(
              hr = pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU ,D3DTADDRESS_CLAMP),
              DbgMsg("CGameMixer::RestoreDeviceObjects: failed to set sampler state D3DSAMP_ADDRESSU/D3DTADDRESS_CLAMP, hr = 0x%08x",hr));
          CHECK_HR(
              hr = pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV ,D3DTADDRESS_CLAMP),
              DbgMsg("CGameMixer::RestoreDeviceObjects: failed to set sampler state D3DSAMP_ADDRESSV/D3DTADDRESS_CLAMP, hr = 0x%08x",hr));
  
                  }
          }
      catch(HRESULT hr1)
      {
          hr = hr1;
      }
      return hr;
  }
  
  
****************************Public*Routine******************************\ SetWorldMatrix \*************************************************************************

  
  HRESULT CGameMixer::SetWorldMatrix( D3DXMATRIX& M )
  {
      m_matWorld = M;
      return S_OK;
  }
  
  
****************************Public*Routine******************************\ Animate \*************************************************************************

  
  HRESULT CGameMixer::Animate( BOOL bAnimate)
  {
      DWORD_PTR dwID = NULL;
      int nIndex = 0;
      float dY_min;
      float dY_cur;
  
          CVMR9Subgraph* pSource = NULL;
          char buf[64];
          
          if (m_last) {
                  pSource = g_pSession->GetSubgraph( m_last->m_dwID);
              sprintf(buf,"run:\%d",pSource->_id);
              }
          if (pSource && !pSource->capture && !scene::ds(buf) ) pSource->Pause();
  
      m_bAnimate = bAnimate;
      if( m_bAnimate == FALSE )
      {
          // do not stop if movie list is empty
          if( m_listMovies.empty())
          {
              m_bAnimate = TRUE;
              return S_FALSE;
          }
          // select movie that is closest to the center
          nIndex = 0;
          dY_min = (m_Frames[0].m_S[0].Pos.y + m_Frames[0].m_S[1].Pos.y) / 2.f;
          if( dY_min < 0.f )
          {
              dY_min  = - dY_min;
          }
          for( int i=1; i < _total; i++ ) //i<_total; i++)
          {
              dY_cur = (m_Frames[i].m_S[0].Pos.y + m_Frames[i].m_S[1].Pos.y) / 2.f;
              if( dY_cur < 0.f )
              {
                  dY_cur  = - dY_cur;
              }
              if( dY_cur < dY_min )
              {
                  dY_min = dY_cur;
                  nIndex = i;
              }
          }// for
  
          dwID = m_Frames[nIndex].m_dwID;
          // try to find this movie in the list
          list<CMovie*>::iterator start, end, it;
  
          m_pActiveMovie = NULL;
          start = m_listMovies.begin();
          end = m_listMovies.end();
          for( it=start; it!=end; it++)
          {
                          CVMR9Subgraph* pSource = NULL;
                          int focus = scene::ds("focus");
              int found = 0;
                          if( !focus && (*it)->m_dwID == dwID ) {
              
                  m_pActiveMovie = (*it);
                                  m_last = m_pActiveMovie;
                                  found = 1;
                          } else if (focus) {
                                  pSource = g_pSession->GetSubgraph( (*it)->m_dwID);
                  //if (pSource) pSource->Pause();
                                  if (pSource->_id == focus) {
                                          m_pActiveMovie = (*it);
                                          m_last = m_pActiveMovie = (*it);
                                          found = 1;
                                          if (scene::ds("nofocus")) scene::ds("focus",0);
                                  }
                          }
                          if (found) {
                                  char buf[64];
                                  sprintf(buf,"restart:\%d",focus);
                                  pSource = g_pSession->GetSubgraph( (*it)->m_dwID);
                                  if ((focus && scene::ds(buf)) || VP->get_shift()) {
                                  if (scene::ds(buf)) scene::ds(buf,0);
                                  pSource->Stop();
                  pSource->SetTime(0);
                              pSource->Run();
                                  } else pSource->Run();
                  break;
                          }
  
                          if (found)        break;
                  }
                  
          if( !m_pActiveMovie )
          {
              m_bAnimate = TRUE;
              return S_FALSE;
          }
          return S_OK;
      }
  
      m_pActiveMovie = NULL;
      return S_OK;
  }
  
  
//////////////////////// CMovie
///////////////////////////////


****************************Public*Routine******************************\ CMovie \*************************************************************************

  
  CGameMixer::CMovie::CMovie( 
                  DWORD_PTR dwID, 
                  LONG lImageWidth, 
                  LONG lImageHeight, 
                  LONG lTextureWidth, 
                  LONG lTextureHeight)
      : m_dwID( dwID), _capture(0)
  {
      float w;
      float h;
      float ar; // aspect ratio
  
      m_fU = 1.f;//( lTextureWidth  ) ? (float)lImageWidth/(float)lTextureWidth : 1.f;
      m_fV = 1.f;//( lTextureHeight ) ? (float)lImageHeight/(float)lTextureHeight : 1.f;
  
      ar = (float)lImageWidth / (float)lImageHeight;
  
      // try to fit movie withing the width
      w = g_fMovieSlotWidth;
      h = (float)w / ar;
  
      if( h > g_fMovieSlotHeight )
      {
          h = g_fMovieSlotHeight;
          w = h * ar;
      }
  
      m_fY = (g_fMovieSlotWidth - w)/2.f;
      m_fZ = (g_fMovieSlotHeight -h)/2.f;
  }
  
  
//////////////////////// CFrame
///////////////////////////////


****************************Public*Routine******************************\ CFrame constructor \*************************************************************************

  
  CGameMixer::CFrame::CFrame( )
  {
      int i;
  
      for( i=0; i<4; i++)
      {
          m_V[i].color = D3DCOLOR_ARGB( 0xCC, 0xFF, 0xFF, 0xFF );
      }
      for( i=0; i<10; i++)
      {
          m_F[i].color = g_colorPale;
      }
  }
  
  
****************************Public*Routine******************************\ Calculate calculates position of the movie screen in the "walking girl" scene \*************************************************************************

  
  HRESULT CGameMixer::CFrame::Calculate(  int n, 
                                          D3DVECTOR& v0, 
                                          CGameMixer::CMovie* pMovie )
  {
      HRESULT hr = S_OK;
      int j;
  
      if( n<0 || n>_total )
          return E_FAIL;
  
      float fYShift = -(g_fMovieSlotWidth + g_fDelta) * n;
  
      float fCenter;
      float c, l, t, r, b, a;
      D3DCOLOR colorFrame;
  
      float x0 = v0.x;
      float y0 = v0.y;
      float z0 = v0.z;
  
      float fy = 0.f;
      float fz = 0.f;
      float fU = 0.f;
      float fV = 0.f;
  
      if( pMovie )
      {
          fy = pMovie->m_fY;
          fz = pMovie->m_fZ;
          fU = pMovie->m_fU;
          fV = pMovie->m_fV;
      }
  
      m_S[0].Pos.x = x0;
      m_S[0].Pos.y = y0 + fYShift;
      m_S[0].Pos.z = z0;
  
      m_V[0].Pos.x = m_S[0].Pos.x;  
      m_V[0].Pos.y = m_S[0].Pos.y - fy;   
      m_V[0].Pos.z = m_S[0].Pos.z - fz;
  
      m_S[1].Pos.x = x0;
      m_S[1].Pos.y = y0 + fYShift - g_fMovieSlotWidth;
      m_S[1].Pos.z = z0;
  
      m_V[1].Pos.x = m_S[1].Pos.x;  
      m_V[1].Pos.y = m_S[1].Pos.y + fy;   
      m_V[1].Pos.z = m_S[1].Pos.z - fz;
  
      m_S[2].Pos.x = x0;
      m_S[2].Pos.y = y0 + fYShift;
      m_S[2].Pos.z = z0 - g_fMovieSlotHeight;
  
      m_V[2].Pos.x = m_S[2].Pos.x;  
      m_V[2].Pos.y = m_S[2].Pos.y - fy;   
      m_V[2].Pos.z = m_S[2].Pos.z + fz;
  
      m_S[3].Pos.x = x0;
      m_S[3].Pos.y = y0 + fYShift - g_fMovieSlotWidth;
      m_S[3].Pos.z = z0 - g_fMovieSlotHeight;
  
      m_V[3].Pos.x = m_S[3].Pos.x;  
      m_V[3].Pos.y = m_S[3].Pos.y + fy;   
      m_V[3].Pos.z = m_S[3].Pos.z + fz;
  
      m_V[0].tu = 0.f;    m_V[0].tv = 0.f;
      m_V[1].tu =  fU;    m_V[1].tv = 0.f;
      m_V[2].tu = 0.f;    m_V[2].tv = fV;
      m_V[3].tu =  fU;    m_V[3].tv = fV;
  
      // calculate frame
  
      c = m_V[0].Pos.x;
      a = g_fFrameWidth;
      l = m_V[0].Pos.y;
      r = m_V[1].Pos.y;
      t = m_V[0].Pos.z;
      b = m_V[2].Pos.z;
  
      m_F[0].Pos.x = c;   m_F[0].Pos.y = l+a;     m_F[0].Pos.z = t+a;
      m_F[1].Pos.x = c;   m_F[1].Pos.y = l;       m_F[1].Pos.z = t;
      m_F[2].Pos.x = c;   m_F[2].Pos.y = r-a;     m_F[2].Pos.z = t+a;
      m_F[3].Pos.x = c;   m_F[3].Pos.y = r;       m_F[3].Pos.z = t;
      m_F[4].Pos.x = c;   m_F[4].Pos.y = r-a;     m_F[4].Pos.z = b-a;
      m_F[5].Pos.x = c;   m_F[5].Pos.y = r;       m_F[5].Pos.z = b;
      m_F[6].Pos.x = c;   m_F[6].Pos.y = l+a;     m_F[6].Pos.z = b-a;
      m_F[7].Pos.x = c;   m_F[7].Pos.y = l;       m_F[7].Pos.z = b;
      m_F[8].Pos.x = c;   m_F[8].Pos.y = l+a;     m_F[8].Pos.z = t+a;
      m_F[9].Pos.x = c;   m_F[9].Pos.y = l;       m_F[9].Pos.z = t;
  
      fCenter = (m_V[0].Pos.y + m_V[1].Pos.y)/2.f;
  
      if( fCenter > -350.f && fCenter < 350.f)
      {
          colorFrame = g_colorGold;
                  VP->set_active(g_index);
      }
      else
      {
          colorFrame = g_colorPale;
      }
      for( j=0; j<10; j++)
      {
          m_F[j].color = colorFrame;
      }
  
      m_dwID = pMovie? pMovie->m_dwID : NULL;
  
      return S_OK;
  }
  
  
****************************Public*Routine******************************\ CalculateInFocus calculates position of the movie screen in the "in-focus" scene \*************************************************************************

  
  HRESULT CGameMixer::CFrame::CalculateInFocus(CGameMixer::CMovie* pMovie)
  {
      HRESULT hr = S_OK;
  
      int i;
  
      if( !pMovie )
          return E_POINTER;
  
      float left = -380.f + pMovie->m_fY/600.f*760.f;
      float right = 380.f - pMovie->m_fY/600.f*760.f;
      float top = 285.f - pMovie->m_fZ/450.f*570.f;
      float bottom = -285.f + pMovie->m_fZ/450.f*570.f;
  
      m_V[0].Pos.x = left;    m_V[0].Pos.y = top;     m_V[0].Pos.z = 0.f;
      m_V[1].Pos.x = right;   m_V[1].Pos.y = top;     m_V[1].Pos.z = 0.f;
      m_V[2].Pos.x = left;    m_V[2].Pos.y = bottom;  m_V[2].Pos.z = 0.f;
      m_V[3].Pos.x = right;   m_V[3].Pos.y = bottom;  m_V[3].Pos.z = 0.f;
  
      m_V[0].tu = 0.f;            m_V[0].tv = 0.f;
      m_V[1].tu = pMovie->m_fU;   m_V[1].tv = 0.f;
      m_V[2].tu = 0.f;            m_V[2].tv = pMovie->m_fV;
      m_V[3].tu = pMovie->m_fU;   m_V[3].tv = pMovie->m_fV;
  
      for( i=0; i<4; i++)
      {
          m_V[i].color = D3DCOLOR_RGBA( 0xFF, 0xFF, 0xFF, 0xFF);
      }
  
      float c = 0.f;
      float a = g_fFrameWidth;
      float l = m_V[0].Pos.x;
      float r = m_V[1].Pos.x;
      float t = m_V[0].Pos.y;
      float b = m_V[2].Pos.y;
  
      m_F[0].Pos.x = l-a;     m_F[0].Pos.y = t+a;     m_F[0].Pos.z = c;
      m_F[1].Pos.x = l;       m_F[1].Pos.y = t;       m_F[1].Pos.z = c;
      m_F[2].Pos.x = r+a;     m_F[2].Pos.y = t+a;     m_F[2].Pos.z = c;
      m_F[3].Pos.x = r;       m_F[3].Pos.y = t;       m_F[3].Pos.z = c;
      m_F[4].Pos.x = r+a;     m_F[4].Pos.y = b-a;     m_F[4].Pos.z = c;
      m_F[5].Pos.x = r;       m_F[5].Pos.y = b;       m_F[5].Pos.z = c;
      m_F[6].Pos.x = l-a;     m_F[6].Pos.y = b-a;     m_F[6].Pos.z = c;
      m_F[7].Pos.x = l;       m_F[7].Pos.y = b;       m_F[7].Pos.z = c;
      m_F[8].Pos.x = l-a;     m_F[8].Pos.y = t+a;     m_F[8].Pos.z = c;
      m_F[9].Pos.x = l;       m_F[9].Pos.y = t;       m_F[9].Pos.z = c;
  
      for( i=0; i<10; i++)
      {
          m_F[i].color = g_colorGold;
      }
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ Render \*************************************************************************

  
  HRESULT CGameMixer::CFrame::Render(
                                          IDirect3DDevice9* pDevice,
                                          IDirect3DTexture9* pTexture)
  {
      HRESULT hr = S_OK;
  
      if( !pDevice || !pTexture)
      {
          return E_POINTER;
      }
  
      try
      {
          CHECK_HR(
              hr = pDevice->SetTexture(0, pTexture),
              DbgMsg("CFrame::Render: failed in SetTexture, hr = 0x%08x",hr));
  
          CHECK_HR(
              hr = pDevice->SetFVF( g_FVFMixer ),
              DbgMsg("CFrame::Render: failed to set FVF, hr = 0x%08x",hr));
                  if (0) { //XX
          CHECK_HR(
              hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1),
              DbgMsg("CFrame::Render: failed to set texture stage state D3DTSS_ALPHAOP/D3DTOP_MODULATE, hr = 0x%08x",hr));
  
          CHECK_HR(
              hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE),
              DbgMsg("CFrame::Render: failed to set texture stage state D3DTSS_ALPHAARG1/D3DTA_TEXTURE, hr = 0x%08x",hr));
              
      pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
          pDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
                  }
                  if (1) { //XX
                  
      hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
      hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
      hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
      hr = pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
          } 
            //CHECK_HR(
                  if (0) { //XX        
                  // hr = pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
                          if (!scene::ds("movie:blend")) hr = pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
              //DbgMsg("CHall::RestoreDeviceObjects failed to set D3DRS_ALPHABLENDENABLE/TRUE, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DRS_SRCBLEND/D3DBLEND_SRCALPHA, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DRS_DESTBLEND/D3DBLEND_INVSRCALPHA, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE ),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DRS_DITHERENABLE/TRUE, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetRenderState( D3DRS_AMBIENT, 0xFFFFFFFF ),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DRS_AMBIENT/0xFFFFFFFF, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetRenderState(D3DRS_LIGHTING, FALSE),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DRS_LIGHTING/FALSE, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DRS_CULLMODE/D3DCULL_NONE, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU ,D3DTADDRESS_WRAP),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DSAMP_ADDRESSU/D3DTADDRESS_WRAP, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV ,D3DTADDRESS_WRAP),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DSAMP_ADDRESSV/D3DTADDRESS_WRAP, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DTSS_ALPHAOP/D3DTOP_SELECTARG1, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE),
              DbgMsg("CHall::RestoreDeviceObjects failed to set D3DTSS_ALPHAARG1/D3DTA_DIFFUSE, hr = 0x%08x", hr));
                      // AE
                  }
                      static float roty = 0;
                          roty += 0.008;
                          //D3DXMatrixRotationY(g_world,roty);
                          //pDevice->SetTransform( D3DTS_WORLD, g_world );
              
                          D3DXMATRIXA16 matWorld;
                          D3DXMatrixIdentity( &matWorld );
              D3DXMatrixRotationY( &matWorld, roty);
          
          
              // change 1
                          if (!scene::ds("walk:animate") && scene::ds("activemovie:ry")) 
                                              pDevice->MultiplyTransform( D3DTS_WORLD, &matWorld );  
  
                          //rotate left / flat to ground
                          if (scene::ds("movie:transform")) 
                                              pDevice->MultiplyTransform( D3DTS_WORLD, g_world );
           
                      ieffect* _effect = 0; //scene::fx(g_index);
                          //_effect = scene::fx(g_index);
                          char* s = scene::cm("walk:fx");
                          if (s) _effect = scene::fx(s);
  
                  if (scene::ds("movie")) { 
                     if ( _effect) { // AE
  
                      D3DXMATRIX wvp =  (*g_world) * (*g_view) * (*g_proj); 
                          D3DXMATRIX vp = (*g_view) * (*g_proj); 
  
                          double tFactor = 0.001f;
              double dxtime = ((double)timeGetTime()) * tFactor;
              itexture* _texture = pTexture;
              float _factor = 1.0;
  
                     _effect->SetMatrix( "wvp", &wvp); //  &mWorldViewProjection );
             _effect->SetMatrix( "world", g_world); //&mWorld );
                     _effect->SetMatrix( "view", g_view); //&mWorld );
  
                    
  
                     //_effect->SetMatrix( "vp", &vp );
             _effect->SetFloat( "time",dxtime );
                     _effect->SetTexture("tex",_texture);
                     if (scene::cm("overlay")) _texture = scene::tx(scene::cm("overlay"));
                     _effect->SetTexture("overlay",_texture);
                     _effect->SetTexture("tex0",_texture);
                     _effect->SetTexture("tex1",_texture);
                     _effect->SetFloat( "factor",_factor );
                     _effect->SetTexture("bump",_texture);
                     
                     UINT iPass,cPasses;
                     _effect->Begin(&cPasses, 0);
                     for (iPass = 0; iPass < cPasses; iPass++) {
              hr = _effect->BeginPass(iPass);
             
                      hr = pDevice->DrawPrimitiveUP(  D3DPT_TRIANGLESTRIP,
                                              2,
                                              (LPVOID)(m_V),
                                              sizeof(m_V[0]));
                          hr = _effect->EndPass();
  
                     }
             _effect->End();
                     } else { 
              hr = pDevice->DrawPrimitiveUP(  D3DPT_TRIANGLESTRIP,
                                              2,
                                              (LPVOID)(m_V),
                                              sizeof(m_V[0]));
                     }
                                                                                          // DbgMsg("CFrame::Render: failed in DrawPrimitiveUP, hr = 0x%08x", hr));
  
          CHECK_HR(
              hr = pDevice->SetTexture(0, NULL),
              DbgMsg("CFrame::Render: failed in SetTexture(NULL), hr = 0x%08x",hr));
  
          // draw frame around the movie
                  if (0) { //XX
          CHECK_HR(
              hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1),
              DbgMsg("CFrame::Render: failed to set texture stage state D3DTSS_ALPHAOP/D3DTOP_MODULATE, hr = 0x%08x",hr));
          CHECK_HR(
              hr = pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE),
              DbgMsg("CFrame::Render: failed to set texture stage state D3DTSS_ALPHAARG1/D3DTA_TEXTURE, hr = 0x%08x",hr));
  
                  }
          CHECK_HR(
              hr = pDevice->SetFVF( g_FVFframe ),
              DbgMsg("CFrame::Render: failed to set FVFhr = 0x%08x",hr));
  
                  if (scene::ds("frame")) {
          CHECK_HR(
              hr = pDevice->DrawPrimitiveUP(  D3DPT_TRIANGLESTRIP,
                                              8,
                                              (LPVOID)(m_F),
                                              sizeof(m_F[0])),
              DbgMsg("CFrame::Render: failed in DrawPrimitiveUP for the frame, hr = 0x%08x", hr));
                  }
                  }
          
                  pDevice->SetTransform( D3DTS_WORLD, g_world );
      }
      catch( HRESULT hr1 )
      {
          hr = hr1;
      }
  
          
      return hr;
  }
  
  
****************************Public*Routine******************************\ FlipToEnd \*************************************************************************

  
  void CGameMixer::CFrame::FlipToEnd( int N)
  {
      float Shift = -( g_fMovieSlotWidth + g_fDelta ) * N;
  
      MoveY( Shift);
  }
  
  
****************************Public*Routine******************************\ MoveY \*************************************************************************

  
  void CGameMixer::CFrame::MoveY( float Shift )
  {
      int i;
      for( i=0; i<4; i++)
      {
          //m_V[i].Pos.y += Shift;
          m_S[i].Pos.y += Shift;
      }
      /*
      for( i=0; i<10; i++)
      {
          m_F[i].Pos.y += Shift;
      }
      */
  }
  
/////////////////////// PRIVATE DOMAIN
/////////////////////////////


****************************Private*Routine*****************************\ Clean_ \*************************************************************************

  
  void CGameMixer::Clean_()
  {
      RELEASE(m_pOwner);
  
      // clean the list
      list<CMovie*>::iterator start, end, it;
      CMovie *pMovie = NULL;
      
      start = m_listMovies.begin();
      end = m_listMovies.end();
  
      for( it=start; it!=end; it++)
      {
          pMovie = (CMovie*)(*it);
          if( pMovie )
          {
              delete pMovie;
              pMovie = NULL;
          }
      }
      m_listMovies.clear();
  
      if( m_pFont )
      {
          m_pFont->InvalidateDeviceObjects();
          m_pFont->DeleteDeviceObjects();
          delete m_pFont;
          m_pFont = NULL;
      }
          if( m_pHall )
          {
                  delete m_pHall;
                  m_pHall = NULL;
          }
          if( m_pCharacter )
          {
                  delete m_pCharacter;
                  m_pCharacter = NULL;
          }
  }
  
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.