예제 #1
0
//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CDPlay8Client::UpdateConnectionInfo()
{
    if( NULL == m_pDPlay )
        return E_FAIL;

    // Update the DPN_CONNECTION_INFO every 1/2 second...
    float fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    if( fCurTime - m_fLastUpdateConnectInfoTime > 0.5f )
    {
        // Call GetConnectionInfo to get DirectPlay stats about connection 
        ZeroMemory( &m_dpnConnectionInfo, sizeof(DPN_CONNECTION_INFO) );
        m_dpnConnectionInfo.dwSize = sizeof(DPN_CONNECTION_INFO);
        m_pDPlay->GetConnectionInfo( &m_dpnConnectionInfo, 0 );

        // Call GetSendQueueInfo to get DirectPlay stats about messages
        m_pDPlay->GetSendQueueInfo( &m_dwHighPriMessages, &m_dwHighPriBytes, 
                                    DPNGETSENDQUEUEINFO_PRIORITY_HIGH );
        m_pDPlay->GetSendQueueInfo( &m_dwNormalPriMessages, &m_dwNormalPriBytes, 
                                    DPNGETSENDQUEUEINFO_PRIORITY_NORMAL );
        m_pDPlay->GetSendQueueInfo( &m_dwLowPriMessages, &m_dwLowPriBytes, 
                                    DPNGETSENDQUEUEINFO_PRIORITY_LOW );

        m_fLastUpdateConnectInfoTime = fCurTime;
    }

    return S_OK;
}
예제 #2
0
//-----------------------------------------------------------------------------
// Name: Run()
// Desc: Handles the message loop and calls FrameMove() and Render() when
//       idle.
//-----------------------------------------------------------------------------
INT CMyApplication::Run()
{
    MSG msg;

    // Message loop to run the app
    while( TRUE )
    {
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            // Skip WM_KEYDOWN so they aren't handled by the dialog
            if( msg.message == WM_KEYDOWN )
                continue;

            if( !IsDialogMessage( m_hWnd, &msg ) )  
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }

            if( msg.message == WM_QUIT )
            {
                DestroyWindow( m_hWnd );
                break;
            }
        }
        else
        {
            // Update the time variables
            m_fTime        = DXUtil_Timer( TIMER_GETAPPTIME );
            m_fElapsedTime = DXUtil_Timer( TIMER_GETELAPSEDTIME );

            // This app uses idle time processing for the game loop
            if( FAILED( FrameMove() ) )
                SendMessage( m_hWnd, WM_DESTROY, 0, 0 );
            if( FAILED( Render() ) ) 
                SendMessage( m_hWnd, WM_DESTROY, 0, 0 );

            Sleep( 20 );
        }
    }

    FinalCleanup();

    return (INT)msg.wParam;
}
예제 #3
0
//-----------------------------------------------------------------------------
// Name: Create()
// Desc: Creates the window
//-----------------------------------------------------------------------------
HRESULT CMyApplication::Create( HINSTANCE hInstance )
{
    // Display the main dialog box.
    CreateDialog( hInstance, MAKEINTRESOURCE(IDD_MAIN), 
                  NULL, StaticMsgProc );
    if( NULL == m_hWnd )
        return E_FAIL;

    // Initialize the application timer
    DXUtil_Timer( TIMER_START );

    return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Create()
// Desc: Here's what this function does:
//       - Checks to make sure app is still active (if fullscreen, etc)
//       - Checks to see if it is time to draw with DXUtil_Timer, if not, it just returns S_OK
//       - Calls FrameMove() to recalculate new positions
//       - Calls Render() to draw the new frame
//       - Updates some frame count statistics
//       - Calls m_pd3dDevice->Present() to display the rendered frame.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Create( HINSTANCE hInstance)
{
    HRESULT hr;

    // Create the Direct3D object
    m_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
    if( m_pD3D == NULL )
        return DisplayErrorMsg( D3DAPPERR_NODIRECT3D, MSGERR_APPMUSTEXIT );

    // Build a list of Direct3D adapters, modes and devices. The
    // ConfirmDevice() callback is used to confirm that only devices that
    // meet the app's requirements are considered.
    m_d3dEnumeration.SetD3D( m_pD3D );
    m_d3dEnumeration.ConfirmDeviceCallback = ConfirmDeviceHelper;
    if( FAILED( hr = m_d3dEnumeration.Enumerate() ) )
    {
        SAFE_RELEASE( m_pD3D );
        return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
    }

    // Unless a substitute hWnd has been specified, create a window to
    // render into
    if( m_hWnd == NULL)
    {
        // Register the windows class
        WNDCLASS wndClass = { 0, WndProc, 0, 0, hInstance,
                              LoadIcon( hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON) ),
                              LoadCursor( NULL, IDC_ARROW ),
                              (HBRUSH)GetStockObject(WHITE_BRUSH),
                              NULL, _T("D3D Window") };
        RegisterClass( &wndClass );

        // Set the window's initial style
        m_dwWindowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | 
                          WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
        
        HMENU hMenu = LoadMenu( hInstance, MAKEINTRESOURCE(IDR_MENU) );

        // Set the window's initial width
        RECT rc;
        SetRect( &rc, 0, 0, m_dwCreationWidth, m_dwCreationHeight );        
        AdjustWindowRect( &rc, m_dwWindowStyle, ( hMenu != NULL ) ? true : false );

        // Create the render window
        m_hWnd = CreateWindow( _T("D3D Window"), m_strWindowTitle, m_dwWindowStyle,
                               CW_USEDEFAULT, CW_USEDEFAULT,
                               (rc.right-rc.left), (rc.bottom-rc.top), 0,
                               hMenu, hInstance, 0 );
    }

    // The focus window can be a specified to be a different window than the
    // device window.  If not, use the device window as the focus window.
    if( m_hWndFocus == NULL )
        m_hWndFocus = m_hWnd;

    // Save window properties
    m_dwWindowStyle = GetWindowLong( m_hWnd, GWL_STYLE );
    GetWindowRect( m_hWnd, &m_rcWindowBounds );
    GetClientRect( m_hWnd, &m_rcWindowClient );

    if( FAILED( hr = ChooseInitialD3DSettings() ) )
    {
        SAFE_RELEASE( m_pD3D );
        return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
    }

    // Initialize the application timer
    DXUtil_Timer( TIMER_START );

    // Initialize the app's custom scene stuff
    if( FAILED( hr = OneTimeSceneInit() ) )
    {
        SAFE_RELEASE( m_pD3D );
        return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
    }

    // Initialize the 3D environment for the app
    if( FAILED( hr = Initialize3DEnvironment() ) )
    {
        SAFE_RELEASE( m_pD3D );
        return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
    }

    // The app is ready to go
    Pause( false );

    return S_OK;
}
예제 #5
0
//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CDPlay8Client::ReceiveHandler( void *pvContext, DWORD dwMessageType, 
                                       void *pvMessage )
{
     // Increment our Active Thread Counter.
    EnterCriticalSection( &m_csThreadCountLock );

    //Get the time when we entered the Message Handler
    FLOAT fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );

    m_wActiveThreadCount++;

    if(m_wActiveThreadCount > m_wMaxThreadCount)
        m_wMaxThreadCount = m_wActiveThreadCount;

    
    // Calculate an average.
    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    m_fAvgThreadCount += fdiff/8;
    
    LeaveCriticalSection( &m_csThreadCountLock );

    
    switch( dwMessageType )
    {
        case DPN_MSGID_RECEIVE:
        {
            PDPNMSG_RECEIVE pRecvData = (PDPNMSG_RECEIVE) pvMessage;

            // Update the throughput counter
            m_dwThroughputBytes += pRecvData->dwReceiveDataSize;

            if( m_pClient != NULL )
            {
                m_pClient->OnPacket( pRecvData->dpnidSender, 
                                     pRecvData->pReceiveData, 
                                     pRecvData->dwReceiveDataSize );
            }
            break;
        }
        
        case DPN_MSGID_TERMINATE_SESSION:
        {
            m_dwSessionLostReason = DISCONNNECT_REASON_UNKNOWN;
            PDPNMSG_TERMINATE_SESSION pTermMsg = (PDPNMSG_TERMINATE_SESSION) pvMessage;

            // The MazeServer passes a DWORD in pvTerminateData if 
            // it disconnected us, otherwise it will be null.
            if( pTermMsg->pvTerminateData != NULL )
            {
                DWORD* pdw = (DWORD*) pTermMsg->pvTerminateData;
                m_dwSessionLostReason = *pdw;
            }

            if( m_pClient != NULL )
                m_pClient->OnSessionLost( m_dwSessionLostReason );

            // Now that the session is lost we need to restart DirectPlay by calling
            // Close() and Init() on m_pDPlay, however this can not be 
            // done in the DirectPlay message callback, so the main thread will
            // do this when IsSessionLost() returns TRUE
            m_bSessionLost = TRUE;
            break;
        }

        case DPN_MSGID_ENUM_HOSTS_RESPONSE:
        {
            PDPNMSG_ENUM_HOSTS_RESPONSE pEnumResponse = (PDPNMSG_ENUM_HOSTS_RESPONSE) pvMessage;

            EnumSessionCallback( pEnumResponse->pApplicationDescription, 
                                 pEnumResponse->pAddressSender,
                                 pEnumResponse->pAddressDevice );
            break;
        }
    }

 
    EnterCriticalSection( &m_csThreadCountLock );
    
    m_wActiveThreadCount-- ;
    
    // Calculate an average.

    FLOAT fDiffTime = ( DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime ) - m_fAvgThreadTime;
    m_fAvgThreadTime += fDiffTime/8;

    //Get the Max time in the thread.
    if ( fDiffTime > m_fMaxThreadTime )
    {
        m_fMaxThreadTime = fDiffTime;
    }
    
    LeaveCriticalSection( &m_csThreadCountLock );

    return S_OK;
}
예제 #6
0
//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CDPlay8Client::JoinSession( DWORD num )
{
    HRESULT hr;
    IDirectPlay8Address* pHostAddress = NULL;
    IDirectPlay8Address* pDeviceAddress = NULL;

    if( m_pDPlay == NULL )
        return E_FAIL;

    DXTRACE( TEXT("MazeClient: Trying to connect to server\n") );

    DPN_APPLICATION_DESC dpnAppDesc;
    ZeroMemory( &dpnAppDesc, sizeof( DPN_APPLICATION_DESC ) );
    dpnAppDesc.dwSize          = sizeof( DPN_APPLICATION_DESC );
    dpnAppDesc.guidApplication = StressMazeAppGUID;
    dpnAppDesc.guidInstance    = m_Sessions[num].guidInstance;

    EnterCriticalSection( &m_csLock );
    
    // Copy the host and device address pointers, and addref them.
    // If this is not done, then there is a rare chance that 
    // EnumSessionCallback() may be called during the Connect() call 
    // and destory the address before DirectPlay gets a chance to copy them.
    pHostAddress = m_pHostAddresses[num];
    pHostAddress->AddRef();

    pDeviceAddress = m_pDeviceAddresses[num];
    pDeviceAddress->AddRef();

    LeaveCriticalSection( &m_csLock );

    // Connect to the remote host
    // The enumeration is automatically canceled after Connect is called 
    if( FAILED( hr = m_pDPlay->Connect( &dpnAppDesc,        // Application description
                                        pHostAddress,       // Session host address
                                        pDeviceAddress,     // Address of device used to connect to the host
                                        NULL, NULL,         // Security descriptions & credientials (MBZ in DPlay8)
                                        NULL, 0,            // User data & its size
                                        NULL,               // Asynchronous connection context (returned with DPNMSG_CONNECT_COMPLETE in async handshaking)
                                        NULL,               // Asynchronous connection handle (used to cancel connection process)
                                        DPNOP_SYNC ) ) )    // Connect synchronously
    {
        if( hr == DPNERR_NORESPONSE || hr == DPNERR_ABORTED )
            goto LCleanup; // These are possible if the server exits while joining 

        if( hr == DPNERR_INVALIDINSTANCE )
            goto LCleanup; // This is possible if the original server exits and another server comes online while we are connecting

        DXTRACE_ERR_NOMSGBOX( TEXT("Connect"), hr );
        goto LCleanup;
    }

    m_bSessionLost = FALSE;
    
    DXTRACE( TEXT("MazeClient: Connected to server.  Enum automatically canceled\n") );

    UpdateConnectionInfo();
    m_fLastUpdateConnectInfoTime = DXUtil_Timer( TIMER_GETAPPTIME );


LCleanup:
    SAFE_RELEASE( pHostAddress );
    SAFE_RELEASE( pDeviceAddress );

    return hr;
}