//------------------------------------------------------------------------------ // 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 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(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::iterator start, end, it; CMovie* pMovie = NULL; int FrameRate100 = 0; int FrameRateAvg100 = 0; TCHAR achFrameRate[MAX_PATH]; CComPtr pWizard; CComPtr 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::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::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::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; } }