#include "directplay.h"
#include "glText.h"
#include "chatmsglist.h"
extern CglText glText;
extern CChatMsgList ChatMsgList;
//-----------------------------------------------------------------------------
// Name: DirectPlayMessageHandler
// Desc: Handler for DirectPlay messages.
//-----------------------------------------------------------------------------
HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD dwMessageId,
PVOID pMsgBuffer)
{
switch( dwMessageId )
{
// case DPN_MSGID_RECEIVE:
// {
// *****************************
// *** Create New Player ***
// *****************************
case DPN_MSGID_CREATE_PLAYER:
{
// static float diff = 40.0;
// Remote player to be inserted
// Player* rPlayer;
// rPlayer = new Player;
// rPlayer->LoadTrisAndTextures("models\\bong\\tris.md2", "models\\bong\\zigzag.pcx");
// rPlayer->SetPosition(0.0, diff, 0.0);
// insertPlayer( &g_startPtr, rPlayer);
// diff = diff + 40.0;
break;
}
// **************************************
// *** Reeive Message From Player ***
// **************************************
case DPN_MSGID_RECEIVE:
{
PDPNMSG_RECEIVE pMsg;
TCHAR strBuffer[256];
pMsg = (PDPNMSG_RECEIVE) pMsgBuffer;
Position *pRemotePlayerPosition;
pRemotePlayerPosition = (Position*)pMsg->pReceiveData;
// if chat msg is not empty, then print msg
if ( strcmp(pRemotePlayerPosition->strChatMsg, "") != 0)
{
ChatMsgList.insertChatMsg( pRemotePlayerPosition->strPlayerName,
pRemotePlayerPosition->strChatMsg );
}
remotePlayerList.updatePosition( pRemotePlayerPosition );
break;
}
// }
}
return(DPN_OK);
// return S_OK;
}
// Default Constructor
CDirectPlay::CDirectPlay()
{
g_pDP = NULL;
g_pDeviceAddress = NULL;
g_pHostAddress = NULL;
g_bHosting = FALSE;
g_bConnected = FALSE;
g_dwLocalPort = CONNECT_PORT;
g_dwRemotePort = CONNECT_PORT;
}
//-----------------------------------------------------------------------------
// Name: InitDirectPlay()
// Desc: Initialize DirectPlay
//-----------------------------------------------------------------------------
HRESULT CDirectPlay::InitDirectPlay()
{
HRESULT hr = S_OK;
InitCommonControls();
// Init COM so we can use CoCreateInstance
CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Create the IDirectPlay8Peer Object
if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Peer, NULL,
CLSCTX_INPROC_SERVER,
IID_IDirectPlay8Peer,
(LPVOID*) &g_pDP ) ) )
{
// OutputError( TEXT("Failed Creating the IDirectPlay8Peer Object"), hr );
return hr;
}
// Init DirectPlay
if( FAILED( hr = g_pDP->Initialize(NULL, DirectPlayMessageHandler, 0 ) ) )
{
// OutputError( TEXT("Failed Initializing DirectPlay"), hr );
return hr;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CreateDeviceAddress()
// Desc: Creates a device address
//-----------------------------------------------------------------------------
HRESULT CDirectPlay::CreateDeviceAddress( bool bIsHost )
{
HRESULT hr = S_OK;
// Start clean
// SAFE_RELEASE( g_pDeviceAddress );
// Create our IDirectPlay8Address Device Address
if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,
CLSCTX_INPROC_SERVER,
IID_IDirectPlay8Address,
(LPVOID*) &g_pDeviceAddress ) ) )
{
OutputError( TEXT("Failed Creating the IDirectPlay8Address Object"), hr );
return hr;
}
// Set the SP for our Device Address
if( FAILED( hr = g_pDeviceAddress->SetSP(&CLSID_DP8SP_TCPIP ) ) )
{
OutputError( TEXT("Failed Setting the Service Provider"), hr );
return hr;
}
// Set the port number on which to host
if( bIsHost && g_dwLocalPort > 0 )
{
if( FAILED( hr = g_pDeviceAddress->AddComponent( DPNA_KEY_PORT,
&g_dwLocalPort,
sizeof(DWORD),
DPNA_DATATYPE_DWORD ) ) )
{
OutputError( TEXT("Failed setting the local port"), hr );
return hr;
}
}
return hr;
}
//-----------------------------------------------------------------------------
// Name: CleanupDirectPlay()
// Desc: Cleanup DirectPlay
//-----------------------------------------------------------------------------
void CDirectPlay::CleanupDirectPlay()
{
// Cleanup DirectPlay
// if( g_pDP)
// g_pDP->Close(0);
// SAFE_RELEASE(g_pDeviceAddress);
// SAFE_RELEASE(g_pHostAddress);
// SAFE_RELEASE(g_pDP);
g_pDP->Close(0);
g_pDP->Release();
g_pDP = NULL;
// Cleanup COM
CoUninitialize();
}
void CDirectPlay::SendPosition(Position localPlayerPosition)
{
// *****************************************************
// *** Send Local Player Position to all Players ***
// *****************************************************
// becomes their remote player position
DPN_BUFFER_DESC dpnBuffer;
WCHAR wszData[256];
TCHAR strBuffer[256] = "testing";
// convert string to WCHAR
// DXUtil_ConvertGenericStringToWideCch( wszData, strBuffer, 256 );
// dpnBuffer.pBufferData = (BYTE*) wszData;
// dpnBuffer.dwBufferSize = 2 * (wcslen(wszData) + 1);
dpnBuffer.pBufferData = (BYTE*) &localPlayerPosition;
dpnBuffer.dwBufferSize = sizeof(localPlayerPosition);
HRESULT hr;
hr = g_pDP->SendTo( DPNID_ALL_PLAYERS_GROUP, // dpnid
&dpnBuffer, // pBufferDesc
1, // cBufferDesc
0, // dwTimeOut
NULL, // pvAsyncContext
NULL, // pvAsyncHandle
DPNSEND_SYNC |
DPNSEND_NOLOOPBACK );
}
//-----------------------------------------------------------------------------
// Name: HostSession()
// Desc: Host a DirectPlay session
//-----------------------------------------------------------------------------
HRESULT CDirectPlay::HostSession()
{
HRESULT hr = S_OK;
DPN_APPLICATION_DESC dpAppDesc;
// Now set up the Application Description
ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
dpAppDesc.guidApplication = guidApp;
dpAppDesc.dwFlags = DPNSESSION_NODPNSVR | DPNSESSION_MIGRATE_HOST;
// We are now ready to host the app
if( FAILED( hr = g_pDP->Host( &dpAppDesc, // AppDesc
&g_pDeviceAddress, 1, // Device Address
NULL, NULL, // Reserved
NULL, // Player Context
0 ) ) ) // dwFlags
{
OutputError( TEXT("Failed to host a new session"), hr );
return hr;
}
else
{
// SendMessage( GetDlgItem( g_hDlg, IDC_STATUS ), WM_SETTEXT, 0,
// (LPARAM) TEXT("Hosting a session.") );
// SendMessage( GetDlgItem( g_hDlg, IDC_HOST ), WM_SETTEXT, 0,
// (LPARAM) TEXT("St&op Hosting") );
g_bHosting = true;
}
return S_OK;
}
HRESULT CDirectPlay::Host()
{
HRESULT hr = S_OK;
// Init the DirectPlay system
if( FAILED( hr = InitDirectPlay() ) )
{
// OutputError( TEXT("Failed to initialize DirectPlay.")
// TEXT("\n\nThe sample will now exit.") );
// goto LCleanup;
// Cleanup DirectPlay
// CleanupDirectPlay();
return 0;
}
// *****************************************
// *** Create Device Address (local) ***
// *****************************************
CreateDeviceAddress(true); // pass true if hosting
// Everything OK so far, go ahead and start hosting
hr = HostSession();
g_bHosting = true;
return hr;
}
HRESULT CDirectPlay::ConnectToHost( char* szHostAddress )
{
HRESULT hr = S_OK;
// Init the DirectPlay system
if( FAILED( hr = InitDirectPlay() ) )
{
// OutputError( TEXT("Failed to initialize DirectPlay.")
// TEXT("\n\nThe sample will now exit.") );
// goto LCleanup;
// Cleanup DirectPlay
// CleanupDirectPlay();
return 0;
}
// *****************************************
// *** Create Device Address (local) ***
// *****************************************
CreateDeviceAddress(false);
// ****************************************
// *** Create Host Address (remote) ***
// ****************************************
// TCHAR strHost[128] = "127.0.0.1";
WCHAR strBuffer[128] = {0};
hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,
CLSCTX_INPROC_SERVER,
IID_IDirectPlay8Address,
(LPVOID*) &g_pHostAddress );
hr = g_pHostAddress->SetSP( &CLSID_DP8SP_TCPIP );
// Convert the generic host string to UNICODE.
DXUtil_ConvertGenericStringToWideCch( strBuffer, szHostAddress, 20 );
// g_pHostIPAddress->BuildAddress( (const WCHAR* const)"127.0.0.1", 4200);
hr = g_pHostAddress->AddComponent( DPNA_KEY_HOSTNAME, strBuffer,
2*((UINT)wcslen(strBuffer) + 1), /*bytes*/
DPNA_DATATYPE_STRING );
// hr = g_pHostAddress->AddComponent( DPNA_KEY_HOSTNAME, strBuffer,
// sizeof(strBuffer), /*bytes*/
// DPNA_DATATYPE_STRING );
hr = g_pHostAddress->AddComponent( DPNA_KEY_PORT,
&g_dwRemotePort,
sizeof(DWORD),
DPNA_DATATYPE_DWORD );
// *************************************
// *** Connect to remote session ***
// *************************************
DPN_APPLICATION_DESC dpAppDesc;
// Now set up the Application Description
ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
dpAppDesc.guidApplication = guidApp;
hr = g_pDP->Connect(&dpAppDesc, // pdnAppDesc
g_pHostAddress, // pHostAddr
g_pDeviceAddress, // pDeviceInfo
NULL, // pdnSecurity
NULL, // pdnCredentials
NULL, 0, // pvUserConnectData/Size
NULL, // pvPlayerContext
NULL, // pvAsyncContext
NULL, // pvAsyncHandle
DPNCONNECT_SYNC); // dwFlags
if( SUCCEEDED(hr) )
{
g_bConnected = true;
OutputError( TEXT("Connected.")
TEXT("\n\nWoohoo.") );
}
}
//-----------------------------------------------------------------------------
// Name: OutputError
// Desc: Output the error and error code using a message box
//-----------------------------------------------------------------------------
void CDirectPlay::OutputError( TCHAR* str, HRESULT hr )
{
TCHAR strBuf[256] = {0};
if( hr )
_stprintf( strBuf, TEXT("%s: 0x%X"), str, hr );
else
_stprintf( strBuf, TEXT("%s"), str );
MessageBox( NULL, strBuf, TEXT("DirectPlay Sample"), MB_OK );
}
bool CDirectPlay::isHosting()
{
return g_bHosting;
}
bool CDirectPlay::isConnected()
{
return g_bConnected;
}
void CDirectPlay::SetRemotePlayerPosition( Position rPosition )
{
*m_pRemotePlayerPosition = rPosition;
}