⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.cpp

📁 是《3D游戏编程》的代码 买了这本书
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// 名称: RenderSene.cpp
// 
// 功能: 进行3D场景的渲染——使用显示内存的顶点缓冲区。
//       
//-----------------------------------------------------------------------------

#include <tchar.h>
#include <windows.h>
#include <basetsd.h>
#include <objbase.h>

// 包含Direct3D头文件
#include <d3d8.h>
#include <d3dx8.h>
#include <dinput.h>
#include <dplay8.h>
#include <dpaddr.h>
#include <dxerr8.h>
#include <dpaddr.h>
// Windows类的名称宏定义
#define  MY_WINCLASS_NAME      "Direct3D"

struct PLAYER
{
    D3DXVECTOR3    LookAt[3];
};

// 定义个表示顶点的结构
struct CUSTOMVERTEX
{
    FLOAT x, y, z; // x,y,z表示点的三维坐标值,
    DWORD color;        // 顶点颜色
};

// 自定义的顶点格式
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

// 定义全局变量
LPDIRECT3D8             g_pMyD3D          = NULL; // 定义Direct3D对象的指针
LPDIRECT3DDEVICE8       g_pMyd3dDevice    = NULL; // 定义Direct3D设备指针
LPDIRECT3DVERTEXBUFFER8 g_pMyVxBufferRec     = NULL; // 定义顶点缓冲区对象指针
LPDIRECT3DVERTEXBUFFER8 g_pMyVxBufferLine     = NULL;

PLAYER  g_Player;
float   g_Angle = 0;

#define LINE_VECTOR_NUM 20

// 定义包含4个顶点的顶点数组
CUSTOMVERTEX g_Vertices[] =
{
        { -1.5f, 0.0f, 0.0f, 0xffff0000, },  
        { -1.5f, 2.0f, 0.0f, 0xffff0000, },
		{  1.5f, 0.0f, 0.0f, 0xffff0000, },
		{  1.5f, 2.0f, 0.0f, 0xffff0000, },  

};
#define GRID_WIDTH       20.0f
#define NUM_GRID         20


#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define SAMPLE_BUFFER_SIZE 8
#define TIME2FRAME 15

#define KEYDOWN(name, key) (name[key] & 0x80)

LPDIRECTINPUT8       g_pDI       = NULL;         
LPDIRECTINPUTDEVICE8 g_pKeyboard = NULL;     

IDirectPlay8Server* g_pDPServer  = NULL;
DWORD              g_dwPort;
GUID g_guidApp = { 0xede9493e, 0x6ac8, 0x4f15, { 0x8d, 0x1, 0x8b, 0x16, 0x32, 0x0, 0xb9, 0x66 } };

struct APP_PLAYER_INFO
{
    LONG  lRefCount;                        // Ref count so we can cleanup when all threads 
                                            // are done w/ this object
    DPNID dpnidPlayer;                      // DPNID of player
    TCHAR strPlayerName[20];   // Player name
};

#define GAME_MSGID_MESSAGE          1
#define GAME_MSGID_CREATE_PLAYER    2
#define GAME_MSGID_DESTROY_PLAYER   3
#define GAME_MSGID_SET_ID           4

struct GAMEMSG_GENERIC
{
	DWORD dwtype;
    char  buffer[256];
};

char  g_chKeybuffer[256];

//-----------------------------------------------------------------------------
// 名称: NetServerMessageHandler()
// 功能: 处理消息接收。
//       
//-----------------------------------------------------------------------------
HRESULT WINAPI NetServerMessageHandler( PVOID pvUserContext, 
                                         DWORD dwMessageId, 
                                         PVOID pMsgBuffer )
{
   switch( dwMessageId )
    {
        case DPN_MSGID_CREATE_PLAYER:
        {
            HRESULT hr;
            PDPNMSG_CREATE_PLAYER pCreatePlayerMsg;
            pCreatePlayerMsg = (PDPNMSG_CREATE_PLAYER)pMsgBuffer;

            // 得到对端信息
            DWORD dwSize = 0;
            DPN_PLAYER_INFO* pdpPlayerInfo = NULL;
            hr = g_pDPServer->GetClientInfo( pCreatePlayerMsg->dpnidPlayer, 
                                             pdpPlayerInfo, &dwSize, 0 );
            if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL )
            {
                if( hr == DPNERR_INVALIDPLAYER )
                {
                    break;
                }

                return DXTRACE_ERR( TEXT("GetClientInfo"), hr );
            }
            pdpPlayerInfo = (DPN_PLAYER_INFO*) new BYTE[ dwSize ];
            ZeroMemory( pdpPlayerInfo, dwSize );
            pdpPlayerInfo->dwSize = sizeof(DPN_PLAYER_INFO);
            hr = g_pDPServer->GetClientInfo( pCreatePlayerMsg->dpnidPlayer, 
                                       pdpPlayerInfo, &dwSize, 0 );
            if( FAILED(hr) )
                return DXTRACE_ERR( TEXT("GetClientInfo"), hr );

            break;
        }

        case DPN_MSGID_DESTROY_PLAYER:
        {
            break;
        }

        case DPN_MSGID_TERMINATE_SESSION:
        {
            break;
        }

        case DPN_MSGID_RECEIVE:
        {
			// 接收数据
            PDPNMSG_RECEIVE pReceiveMsg;
            pReceiveMsg = (PDPNMSG_RECEIVE)pMsgBuffer;
            APP_PLAYER_INFO* pPlayerInfo = (APP_PLAYER_INFO*) pReceiveMsg->pvPlayerContext;

            GAMEMSG_GENERIC* pMsg = (GAMEMSG_GENERIC*) pReceiveMsg->pReceiveData;
			if(pMsg->dwtype == 0x55)
			{
				memcpy(g_chKeybuffer, pMsg->buffer, 256);
			} 
            
            break;
        }
    }

    return S_OK;
}


//-----------------------------------------------------------------------------
// 名称: StartServer()
// 功能: 启动服务器。
//       
//-----------------------------------------------------------------------------
HRESULT NetServerStart( HWND hWnd )
{
    HRESULT hr;
    PDIRECTPLAY8ADDRESS pDP8AddrLocal = NULL;

    CHAR wstrSessionName[MAX_PATH] = TEXT("GameTest");


    g_dwPort = 25857;

    // 创建 IDirectPlay8Server 对象接口
    if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Server, NULL, 
                                       CLSCTX_INPROC_SERVER,
                                       IID_IDirectPlay8Server, 
                                       (LPVOID*) &g_pDPServer ) ) )
        return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );

    // 初始化 IDirectPlay8Server
    if( FAILED( hr = g_pDPServer->Initialize( NULL, NetServerMessageHandler, 0 ) ) )
        return DXTRACE_ERR( TEXT("Initialize"), hr );

    hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL, 
                           CLSCTX_ALL, IID_IDirectPlay8Address, 
                           (LPVOID*) &pDP8AddrLocal );
    if( FAILED(hr) )
    {
        DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
        goto LCleanup;
    }

    hr = pDP8AddrLocal->SetSP( &CLSID_DP8SP_TCPIP );
    if( FAILED(hr) )
    {
        DXTRACE_ERR( TEXT("SetSP"), hr );
        goto LCleanup;
    }

    // 添加使用的端口信息
    if( g_dwPort != 0 )
    {
        if( FAILED( hr = pDP8AddrLocal->AddComponent( DPNA_KEY_PORT, 
                                                      &g_dwPort, sizeof(g_dwPort),
                                                      DPNA_DATATYPE_DWORD ) ) )
            return DXTRACE_ERR( TEXT("AddComponent"), hr );
    }

    DPN_APPLICATION_DESC dpnAppDesc;
    ZeroMemory( &dpnAppDesc, sizeof(DPN_APPLICATION_DESC) );
    dpnAppDesc.dwSize           = sizeof( DPN_APPLICATION_DESC );
    dpnAppDesc.dwFlags          = DPNSESSION_CLIENT_SERVER;
    dpnAppDesc.guidApplication  = g_guidApp;
    dpnAppDesc.pwszSessionName  = (unsigned short *)wstrSessionName;

    hr = g_pDPServer->Host( &dpnAppDesc, &pDP8AddrLocal, 1, NULL, NULL, NULL, 0  );
    if( FAILED(hr) )
    {
        DXTRACE_ERR( TEXT("Host"), hr );
        goto LCleanup;
    }

LCleanup:
    SAFE_RELEASE( pDP8AddrLocal );

    return hr;
}

//-----------------------------------------------------------------------------
// 名称: NetServerStop()
// 功能: 启动服务器。
//       
//-----------------------------------------------------------------------------
VOID NetServerStop( )
{
    if( g_pDPServer )
    {
        g_pDPServer->Close(0);
        SAFE_RELEASE( g_pDPServer );
    }

}



//-----------------------------------------------------------------------------
// 名称: FreeDirectInput()
// 功能: 释放键盘设备。
//       
//-----------------------------------------------------------------------------
VOID KeyboardFree()
{
    // 释放设备
    if( g_pKeyboard ) 
        g_pKeyboard->Unacquire();
    
    // 释放所有的DirectInput资源
    SAFE_RELEASE( g_pKeyboard );
    SAFE_RELEASE( g_pDI );
}


//-----------------------------------------------------------------------------
// 名称: KeyboardCreate()
// 功能: 创建键盘设备。
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT KeyboardCreate( HWND hWnd )
{
    HRESULT hr;      
	DIPROPDWORD dipdw;

    // 创建DirectInput对象
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                                         IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
        return hr;
    
    // 创建DirectInput设备对象
    if( FAILED( hr = g_pDI->CreateDevice( GUID_SysKeyboard, &g_pKeyboard, NULL ) ) )
        return hr;
    
    // 设置键盘数据为通用键盘数据格式,使用256字节的数组保存按键状态
    if( FAILED( hr = g_pKeyboard->SetDataFormat( &c_dfDIKeyboard ) ) )
        return hr;
   
	// 设置键盘的协作水平为非独占方式和前台操作方式
	hr = g_pKeyboard->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );

    if( hr == DIERR_UNSUPPORTED )
    {
        KeyboardFree();
        MessageBox( hWnd, _T("SetCooperativeLevel() 不支持的协作模式\n"), 
						  _T("Keyboard"), MB_OK );
        return S_OK;
    }

    if( FAILED(hr) )
        return hr;


    // 对于立即数据,需要把输入数据的缓冲区大小设置为0,任何输入数据直接读取,
	// 不需要存放在缓冲区中
	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = SAMPLE_BUFFER_SIZE; 

    if( FAILED( hr = g_pKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
		return hr;

	// 获取创建的键盘设备,在读取设备输入数据之前,这是必须的操作步骤
    g_pKeyboard->Acquire();

    return S_OK;
}


//-----------------------------------------------------------------------------
// 名称: KeyboardRead()
// 功能: 读取键盘设备的输入数据。
//       
//-----------------------------------------------------------------------------
HRESULT KeyboardRead()
{
	char     buffer[256]; 
	HRESULT  hr; 
/*		
	hr = g_pKeyboard->GetDeviceState(sizeof(buffer),(LPVOID)&buffer); 
	if FAILED(hr) 
	{ 
        hr = g_pKeyboard->Acquire();
        while( hr == DIERR_INPUTLOST ) 
            hr = g_pKeyboard->Acquire();

        return S_OK; 
	} 
*/
	// 修改为直接从全局消息缓冲区中取数据
    memcpy(buffer, g_chKeybuffer, 256);

	// 从buffer 数组中取按键值进行处理
	// 判断输入的方向键

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -