📄 server.cpp
字号:
//-----------------------------------------------------------------------------
// 名称: 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 + -