//------------------------------------------------------------------------------ // File: GamePlayer.cpp // // Desc: DirectShow sample code - MultiVMR9 GamePlayer // Defines the class behaviors for the application // // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ #include "stdafx.h" #include "GamePlayer.h" #include "StartDialog.h" #include "dxutil.h" #include vip* VP; #ifdef _DEBUG #define new DEBUG_NEW #endif HINSTANCE g_hInstance = NULL; // CGamePlayerApp BEGIN_MESSAGE_MAP(CGamePlayerApp, CWinApp) ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() // CGamePlayerApp construction CGamePlayerApp::CGamePlayerApp() { } // The one and only CGamePlayerApp object CGamePlayerApp theApp; //---------------------------------------------------------------------------- // VerifyVMR9 // // Verifies that VMR9 COM objects exist on the system and that the VMR9 // can be instantiated. // // Returns: FALSE if the VMR9 can't be created //---------------------------------------------------------------------------- BOOL CGamePlayerApp::VerifyVMR9(void) { HRESULT hr; // Verify that the VMR exists on this system IBaseFilter* pBF = NULL; hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC, IID_IBaseFilter, (LPVOID *)&pBF); if(SUCCEEDED(hr)) { pBF->Release(); return TRUE; } else { MessageBox(NULL, TEXT("This application requires the Video Mixing Renderer, which is present\r\n") TEXT("only on DirectX 9 systems with hardware video acceleration enabled.\r\n\r\n") TEXT("The Video Mixing Renderer (VMR9) is not enabled when viewing a \r\n") TEXT("remote Windows XP machine through a Remote Desktop session.\r\n") TEXT("You can run VMR-enabled applications only on your local machine.\r\n\r\n") TEXT("To verify that hardware acceleration is enabled on a Windows XP\r\n") TEXT("system, follow these steps:\r\n") TEXT("-----------------------------------------------------------------------\r\n") TEXT(" - Open 'Display Properties' in the Control Panel\r\n") TEXT(" - Click the 'Settings' tab\r\n") TEXT(" - Click on the 'Advanced' button at the bottom of the page\r\n") TEXT(" - Click on the 'Troubleshooting' tab in the window that appears\r\n") TEXT(" - Verify that the 'Hardware Acceleration' slider is at the rightmost position\r\n") TEXT("\r\nThis sample will now exit."), TEXT("Video Mixing Renderer (VMR9) capabilities are required"), MB_OK); return FALSE; } } // CGamePlayerApp initialization BOOL CGamePlayerApp::InitInstance() { // InitCommonControls() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. InitCommonControls(); CWinApp::InitInstance(); g_hInstance = m_hInstance; HRESULT hr = CoInitialize(NULL); // Verify that the VMR9 is present on this system if(!VerifyVMR9()) { CoUninitialize(); return FALSE; } CStartDialog dlg; m_pMainWnd = &dlg; VP = new vip("walk",1,0); //VP->debug("walk (vip)"); dlg.DoModal(); // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } ///////////////////////////////////// CGamePlayerSession ////////////////////////// /*********************************************************************************\ * CGamePlayerSession * constructor \*********************************************************************************/ CGamePlayerSession::CGamePlayerSession() : CMultigraphSession() , m_pMixer( NULL ) , m_pUI( NULL ) { } /*********************************************************************************\ * ~CGamePlayerSession * destructor \*********************************************************************************/ CGamePlayerSession::~CGamePlayerSession() { Terminate(); RELEASE( m_pMixer ); RELEASE( m_pUI ); } /*********************************************************************************\ * Initialize * loads and initializes custom mixer control and UI Layer \*********************************************************************************/ HRESULT CGamePlayerSession::Initialize() { HRESULT hr = S_OK; CComPtr pRenderEngine; try { if( m_pWizard ) throw VFW_E_WRONG_STATE; // create wizard hr = CoCreateInstance( CLSID_MultiVMR9Wizard, NULL, CLSCTX_INPROC_SERVER, IID_IMultiVMR9Wizard, (void**)&m_pWizard); CHECK_HR( hr, DbgMsg("CGamePlayerSession::Initialize: Failed to create instance of MultiVMR9Wizard, hr = 0x%08x", hr)); // create render engine hr = CoCreateInstance( CLSID_MultiVMR9RenderEngine, NULL, CLSCTX_INPROC_SERVER, IID_IMultiVMR9RenderEngine, (void**)&(pRenderEngine.p)); CHECK_HR( hr, DbgMsg("CGamePlayerSession::Initialize: Failed to create instance of MultiVMR9RenderEngine, hr = 0x%08x", hr)); // create video window CHECK_HR( //hr = CreateVideoWindow_(800,600,WS_OVERLAPPED|WS_BORDER), hr = CreateVideoWindow_(VP->width(),VP->height()+25,WS_OVERLAPPED|WS_BORDER), DbgMsg("CGamePlayerSession::Initialize: failed to create video window")); // create mixer control m_pMixer = new CGameMixer(NULL, &hr); CHECK_HR( FAILED(hr) ? hr : (!m_pMixer ? E_OUTOFMEMORY : S_OK), DbgMsg("CGamePlayerSession::Initialize: failed to create custom mixer control")); m_pMixer->AddRef(); // create UI layer m_pUI = new CGameUILayer( NULL, &hr); CHECK_HR( FAILED(hr) ? hr : (!m_pUI ? E_OUTOFMEMORY : S_OK), DbgMsg("CGamePlayerSession::Initialize: failed to create custom UI layer")); m_pUI->AddRef(); CHECK_HR( hr = m_pUI->SetMixer( m_pMixer), DbgMsg("CGamePlayerSession::Initialize: failed to sync mixer and UI layer")); // initialize render engine with custom mixer control and UI layer CHECK_HR( hr = pRenderEngine->Initialize( m_hwndVideo, NULL, m_pMixer, m_pUI), DbgMsg("CGamePlayerSession::Initialize: failed to initialize customized render engine, hr = 0x%08x", hr)); // initialize wizard with customized render engine CHECK_HR( hr = m_pWizard->Initialize(NULL, m_hwndVideo, pRenderEngine), DbgMsg("CMultiPlayerSession::Initialize: failed to initialize the wizard, hr = 0x%08x", hr)); // get interfaces CHECK_HR( hr = m_pWizard->GetRenderEngine( &m_pRenderEngine), DbgMsg("CMultiPlayerSession::Initialize: failed to get Render Engine, hr = 0x%08x", hr)); CHECK_HR( hr = m_pRenderEngine->GetMixerControl( &m_pMixerControl), DbgMsg("CMultiPlayerSession::Initialize: failed to get Mixer Control, hr = 0x%08x", hr)); CHECK_HR( hr = m_pRenderEngine->GetUILayer( &m_pUILayer), DbgMsg("CMultiPlayerSession::Initialize: failed to get UILayer, hr = 0x%08x", hr)); CHECK_HR( hr = m_pRenderEngine->SetFrameRate( 5000 ), DbgMsg("CMultiPlayerSession::Initialize: failed to set frame rate, hr = 0x%08x", hr)); ::ShowWindow( m_hwndVideo, SW_SHOW); } catch( HRESULT hr1 ) { if( pRenderEngine ) { pRenderEngine->Terminate(); } hr = hr1; } return hr; } /*********************************************************************************\ * Terminate * \*********************************************************************************/ HRESULT CGamePlayerSession::Terminate() { HRESULT hr = S_OK; hr = CMultigraphSession::Terminate(); return hr; } /*********************************************************************************\ * FindMediaFile * Searches for a media file in (a) current directory, (b) DirectX SDK media folder, * (c) resources \*********************************************************************************/ HRESULT FindMediaFile( TCHAR* achPath, DWORD size, TCHAR* achShortName, LPCTSTR lpResourceName, LPCTSTR lpResourceType ) { HRESULT hr = S_OK; TCHAR achTempPath[MAX_PATH]; bool bSuccess = false; HANDLE hFile = NULL; HRSRC hRsrc = NULL; HGLOBAL hResMem = NULL; HBITMAP hBitmap = NULL; DWORD dwSize = 0L; LPVOID pData = NULL; CBitmap* pBitmap = NULL; BITMAP bitmap; BITMAPINFOHEADER bmpHdr; BITMAPFILEHEADER bmpFHdr; DWORD dwWritten = 0L; if( !achPath || !achShortName || !lpResourceName ) { return E_POINTER; } // first, try current directory GetCurrentDirectory( MAX_PATH, achTempPath ); _tcsncat( achTempPath, TEXT("\\"), MAX_PATH); _tcsncat( achTempPath, achShortName, MAX_PATH); if( INVALID_FILE_ATTRIBUTES != ::GetFileAttributes( achTempPath )) { // file is in the current folder if( size < _tcslen( achTempPath )) return E_OUTOFMEMORY; _tcsncpy( achPath, achTempPath, size ); return S_OK; } // second, try DXSDK media folder hr = DXUtil_FindMediaFileCb( achTempPath, sizeof(TCHAR) * MAX_PATH, (TCHAR*)achShortName ); if( S_OK == hr ) { if( INVALID_FILE_ATTRIBUTES != ::GetFileAttributes( achTempPath )) { // file is in the DXSDK media folder if( size < _tcslen( achTempPath )) return E_OUTOFMEMORY; _tcsncpy( achPath, achTempPath, size ); return S_OK; } } // create specified file in the current directory GetCurrentDirectory( MAX_PATH, achTempPath ); _tcsncat( achTempPath, TEXT("\\"), MAX_PATH); _tcsncat( achTempPath, achShortName, MAX_PATH); hFile = ::CreateFile( achTempPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if( INVALID_HANDLE_VALUE == hFile ) { return E_FAIL; } // third, try to load it from the resource hRsrc = FindResource( AfxGetInstanceHandle(), lpResourceName, lpResourceType); if( NULL != hRsrc ) { // if the resource is a bitmap if( lpResourceType == RT_BITMAP ) { hBitmap = LoadBitmap( AfxGetInstanceHandle(), lpResourceName); if( hBitmap ) { pBitmap = CBitmap::FromHandle( hBitmap ); pBitmap->GetBitmap( &bitmap ); ZeroMemory( &bmpHdr, sizeof(BITMAPINFOHEADER)); bmpHdr.biSize = sizeof(BITMAPINFOHEADER); bmpHdr.biWidth = bitmap.bmWidth; bmpHdr.biHeight = -bitmap.bmHeight; bmpHdr.biPlanes = bitmap.bmPlanes; bmpHdr.biBitCount = bitmap.bmBitsPixel; bmpHdr.biCompression = bitmap.bmType; bmpHdr.biSizeImage = bitmap.bmHeight * bitmap.bmWidthBytes; pData = malloc(bmpHdr.biSizeImage); pBitmap->GetBitmapBits( bmpHdr.biSizeImage, pData ); bmpFHdr.bfType = static_cast(L'B'|(L'M'<<8)); bmpFHdr.bfSize = 14 + sizeof(BITMAPINFOHEADER) + bmpHdr.biSizeImage; bmpFHdr.bfOffBits = 14 + bmpHdr.biSize; bmpFHdr.bfReserved1 = 0; bmpFHdr.bfReserved2 = 0; if( TRUE == WriteFile(hFile, static_cast(&bmpFHdr), 14, &dwWritten, NULL) ) { if( TRUE == WriteFile(hFile, static_cast(&bmpHdr), bmpHdr.biSize, &dwWritten, NULL)) { if( TRUE == WriteFile(hFile, static_cast(pData), bmpHdr.biSizeImage, &dwWritten, NULL)) { bSuccess = true; } } } free( pData ); pData = NULL; } } else // consider it a raw data { // ::MessageBox(NULL, TEXT("Cannot find mesh file for the character. Make sure you have DirectX SDK installed"), TEXT("GamePlayer"), MB_OK); /* hResMem = ::LoadResource( AfxGetInstanceHandle(), hRsrc ); if( NULL != hResMem ) { dwSize = ::SizeofResource( AfxGetInstanceHandle(), hRsrc); pData = ::LockResource( hResMem ); if( pData ) { if( TRUE == ::WriteFile( hFile, pData, dwSize, &dwWritten, NULL)) { bSuccess = true; } } }*/ } } CloseHandle( hFile ); if( false == bSuccess ) { return E_FAIL; } if( size < _tcslen( achTempPath )) return E_OUTOFMEMORY; _tcsncpy( achPath, achTempPath, size ); return S_OK; } /*********************************************************************************\ * DbgMsg * debug tracing function \*********************************************************************************/ #ifdef _DEBUG void DbgMsg( char* szMessage, ... ) { char szFullMessage[MAX_PATH]; char szFormatMessage[MAX_PATH]; DWORD dwWritten = 0L; // format message va_list ap; va_start(ap, szMessage); _vsnprintf( szFormatMessage, MAX_PATH, szMessage, ap); va_end(ap); strncat( szFormatMessage, "\n", MAX_PATH); strcpy( szFullMessage, "~*~*~*~*~*~ "); strcat( szFullMessage, szFormatMessage ); OutputDebugStringA( szFullMessage ); /* if( INVALID_HANDLE_VALUE != g_hLog ) { WriteFile( g_hLog, (LPVOID)szFullMessage, (DWORD)strlen(szFullMessage), &dwWritten, NULL); FlushFileBuffers( g_hLog); } */ } #else void DbgMsg( char* szMessage, ... ){;} #endif