topical media & game development
hush-src-multi-GamePlayer-GamePlayer.cpp / cpp
//------------------------------------------------------------------------------
// 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.h>
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<IMultiVMR9RenderEngine> 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<WORD>(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<LPVOID>(&bmpFHdr), 14, &dwWritten, NULL) )
{
if( TRUE == WriteFile(hFile, static_cast<LPVOID>(&bmpHdr), bmpHdr.biSize, &dwWritten, NULL))
{
if( TRUE == WriteFile(hFile, static_cast<LPVOID>(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
(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.