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

📄 input.cpp

📁 一个自己写的游戏引擎,用DirectX 写成
💻 CPP
字号:
//--------------------------------------------------
//  Desc: The Implementation of Input
//  Author: artsylee/2006.8.8
//--------------------------------------------------
#include "../stdafx.h"
#include "Input.h"
#include "Log.h"

LPDIRECTINPUT8 g_lpDI = NULL;

//----------------------------------------
//----------------------------------------
// The Implementation of CInput
//----------------------------------------
//----------------------------------------
CInput::CInput()
{	
	m_hWnd = 0;
}

CInput::~CInput()
{
	ReleaseInput();
}

BOOL CInput::CreateInput(HWND hWnd)
{
	HRESULT hr;
	HMODULE hInst = GetModuleHandle(NULL);
	hr = DirectInput8Create((HINSTANCE)hInst, DIRECTINPUT_VERSION,
		                    IID_IDirectInput8, (void**)&g_lpDI, NULL);
	if(FAILED(hr))
	{
		WriteLog(INFO_ERROR, "Create DirectInput8 Failed");
		return FALSE;
	}
	m_hWnd = hWnd;
	m_Key.CreateDevice(hWnd);
	m_Mouse.CreateDevice(hWnd);
	return TRUE;
}

void CInput::ReleaseInput(void)
{
	m_Key.ReleaseDevice();
	m_Mouse.ReleaseDevice();
}

//-------------------------------------------------
// Get input information in a loop
//-------------------------------------------------
BOOL CInput::UpdateBufferInput(stInputInfo *input)
{
//	if(m_Key==NULL || m_Mouse==NULL)
//		return FALSE;

	GetCursorPos(&(input->point));
	ScreenToClient(m_hWnd, &(input->point));

	m_Key.GetData();
	m_Mouse.GetData();
	m_Key.GetState();
	m_Mouse.GetState();

	input->KeyValue = m_Key.GetBufferKey();
	input->MouseValue = m_Mouse.GetBufferKey();
	if((input->point.x != m_OldPt.x) || (input->point.y != m_OldPt.y))
	{
		input->MouseMove = true;
	}
	else
	{
		input->MouseMove = false;
	}
	return TRUE;
}

//----------------------------------------
//----------------------------------------
// The Implementation of CInputDevice
//----------------------------------------
//----------------------------------------
CInputDevice::CInputDevice()
{
	m_lpDevice = NULL;

	memset(m_BufferData, 0, sizeof(m_BufferData));
	m_BufferStart = 0;
	m_BufferEnd = 0;
}

CInputDevice::~CInputDevice()
{

}

//-------------------------------------------------
// Get buffer value in buffered mode
//-------------------------------------------------
// return 0 if no buffer key
unsigned int CInputDevice::GetBufferKey(void)
{
	if(m_BufferStart == m_BufferEnd)
		return 0;

	int ret = m_BufferStart;
	m_BufferStart++;
	if(m_BufferStart >= BUFFERSIZE)
		m_BufferStart = 0;

	return m_BufferData[ret];
}

//-------------------------------------------------
// Clear all buffer value in buffered
//-------------------------------------------------
void CInputDevice::ClearBufferKey(void)
{
	GetData();
	while(TRUE)
	{
		if(GetBufferKey()== 0) 
			break;
	}
}


//----------------------------------------
//----------------------------------------
// The Implementation of CKey
//----------------------------------------
//----------------------------------------
CKey::CKey()
{
	memset(m_KeyState, 0, sizeof(m_KeyState));
}

CKey::~CKey()
{
	ReleaseDevice();
}

BOOL CKey::CreateDevice(HWND hWnd)
{
	//需要dxguid.lib才能找到_IID_IDirectInput8A
	HRESULT hr;
	HMODULE hInst = GetModuleHandle(NULL);
	if(g_lpDI == NULL)
	{
		hr = DirectInput8Create((HINSTANCE)hInst, DIRECTINPUT_VERSION,
		                    IID_IDirectInput8, (void**)&g_lpDI, NULL);
		if(FAILED(hr))
		{
			WriteLog(INFO_ERROR, "Create DirectInput8 Failed");
			return FALSE;
		}
	}

	hr = g_lpDI->CreateDevice(GUID_SysKeyboard, &m_lpDevice, NULL);
	if(FAILED(hr))
	{
		ReleaseDevice();
		WriteLog(INFO_ERROR, "Create Keyboard Device Failed");
		return FALSE;
	}
	// Set the data format
	hr = m_lpDevice->SetDataFormat(&c_dfDIKeyboard); 
 
    if(FAILED(hr))
    { 
        ReleaseDevice();
		WriteLog(INFO_ERROR, "Set Keyboard Data Format Failed");
        return FALSE; 
    } 
 
    // Set the cooperative level 
    hr = m_lpDevice->SetCooperativeLevel(hWnd, 
                             DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); 
    if(FAILED(hr))
    { 
        ReleaseDevice();
		WriteLog(INFO_ERROR, "Set Keyboard Cooperative Level Failed");
        return FALSE; 
    } 

	// Set property
	DIPROPDWORD property;
	property.diph.dwSize = sizeof(DIPROPDWORD);
	property.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	property.diph.dwObj = 0;
	property.diph.dwHow = DIPH_DEVICE;
	property.dwData = BUFFERSIZE;

	hr = m_lpDevice->SetProperty(DIPROP_BUFFERSIZE, &property.diph);
	if(FAILED(hr))
	{
		ReleaseDevice();
		WriteLog(INFO_ERROR, "Set Key Buffer Size Failed");
		return FALSE; 
    }
 
    // Get access to the input device. 
/*    hr = m_lpDevice->Acquire(); 
    if(FAILED(hr))
    { 
        ReleaseDevice();
		WriteLog(INFO_ERROR, "Acquire Keyboard Failed"); 
        return FALSE; 
    }*/
	return TRUE;
}

void CKey::ReleaseDevice(void)
{
	if(m_lpDevice)
	{
		m_lpDevice->Unacquire();
		m_lpDevice->Release();
		m_lpDevice = NULL;
	}
}

//-------------------------------------------------
// Read the device's state when in immediate mode
//-------------------------------------------------
HRESULT CKey::GetState(void)
{
	HRESULT hr;
	if(!m_lpDevice)
	{
		WriteLog(INFO_WARNING, "CKey::m_lpDevice==NULL");
		return -1;
	}

	ZeroMemory(m_KeyState, sizeof(m_KeyState));
	hr = m_lpDevice->GetDeviceState(sizeof(m_KeyState), (LPVOID)&m_KeyState);
	if(FAILED(hr))
	{
		hr = m_lpDevice->Acquire();
		while(hr == DIERR_INPUTLOST)
			hr = m_lpDevice->Acquire();
		if(hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED)
		{
		//	WriteLog(INFO_ERROR, "CKey::GetState Unacquired");
			return -1;
		}
		ZeroMemory(m_KeyState, sizeof(m_KeyState));
		hr = m_lpDevice->GetDeviceState(sizeof(m_KeyState), (LPVOID)&m_KeyState);
	}
	if(FAILED(hr))
	{
		WriteLog(INFO_WARNING, "CKey::GetState Failed");
	}
	return hr;
}

//-------------------------------------------------
// Read the device's state when in buffered mode
//-------------------------------------------------
HRESULT CKey::GetData(void)
{
	if(!m_lpDevice)
	{
		WriteLog(INFO_WARNING, "CKey::m_lpDevice==NULL");
		return -1;
	}
	
	DIDEVICEOBJECTDATA diod[BUFFERSIZE];
	DWORD dwItems = BUFFERSIZE;

	HRESULT hr = m_lpDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diod, &dwItems, 0);
	if(hr!=DI_OK)		
	{
		hr = m_lpDevice->Acquire();
		while(hr == DIERR_INPUTLOST)
			hr = m_lpDevice->Acquire();

		if(hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED)
		{
		//	WriteLog(INFO_WARNING, "[CKey::GetData] Acquire Device Failed");
			return -1;
		}
		hr = m_lpDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diod, &dwItems, 0);
		if(FAILED(hr))
		{
			WriteLog(INFO_WARNING, "[CKey::GetData] GetDeviceData Failed");
			return hr;
		}
	}
	
	if(SUCCEEDED(hr) && dwItems>0)
	{
		for(DWORD i=0; i<dwItems; i++)
		{
			if((diod[i].dwData & 0x80))
			{
				// Key Down
				m_BufferData[m_BufferEnd] = (UINT)(diod[i].dwOfs);
				m_BufferEnd++;
				if(m_BufferEnd >= BUFFERSIZE)
					m_BufferEnd = 0;
			}
			else
			{
				// Key Up
				m_BufferData[m_BufferEnd] = (UINT)(diod[i].dwOfs + MAXKEY);
				m_BufferEnd++;
				if(m_BufferEnd >= BUFFERSIZE) 
					m_BufferEnd = 0;
			}
		}
	}
	return hr;
}

bool CKey::IsKeyDown(unsigned char key)
{
	if(KEYDOWN(m_KeyState, key))
	{
		return true;
	}
	return false;
}

//-------------------------------------------------
// Set a key value
//-------------------------------------------------
void CKey::SetBufferKey(unsigned int key, bool bKeyDown)
{
	if(key<DIK_ESCAPE || key>0xED)
		return;

	if(bKeyDown)
	{
		m_BufferData[m_BufferEnd] = (UINT)key;
	}
	else
	{
		m_BufferData[m_BufferEnd] = (UINT)(key + MAXKEY);
	}
	
	m_BufferEnd++;
	if(m_BufferEnd >= BUFFERSIZE)
	m_BufferEnd = 0;
}

//----------------------------------------
//----------------------------------------
// The Implementation of CMouse
//----------------------------------------
//----------------------------------------
CMouse::CMouse()
{
	m_XPos = 0;
	m_YPos = 0;
	m_ZPos = 0;
	memset(MouseButton, 0, sizeof(MouseButton));
}

CMouse::~CMouse()
{
	ReleaseDevice();
}

BOOL CMouse::CreateDevice(HWND hWnd)
{
	HRESULT hr;
	HMODULE hInst = GetModuleHandle(NULL);
	if(g_lpDI==NULL)
	{
		hr = DirectInput8Create((HINSTANCE)hInst, DIRECTINPUT_VERSION,
		                    IID_IDirectInput8, (void**)&g_lpDI, NULL);
		if(FAILED(hr))
		{
			WriteLog(INFO_ERROR, "Create DirectInput8 Failed");
			return FALSE;
		}
	}
	
	hr = g_lpDI->CreateDevice(GUID_SysMouse, &m_lpDevice, NULL);
	if(FAILED(hr))
	{
		ReleaseDevice();
		WriteLog(INFO_ERROR, "Create Mouse Device Failed");
		return FALSE;
	}
	// Set the data format
	hr = m_lpDevice->SetDataFormat(&c_dfDIMouse); 
 
    if(FAILED(hr))
    { 
        ReleaseDevice();
		WriteLog(INFO_ERROR, "Set Mouse Data Format Failed");
        return FALSE; 
    } 
 
    // Set the cooperative level 
    hr = m_lpDevice->SetCooperativeLevel(hWnd, 
                             DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); 
    if(FAILED(hr))
    { 
        ReleaseDevice();
		WriteLog(INFO_ERROR, "Set Mouse Cooperative Level Failed");
        return FALSE; 
    } 

	// Set property
	DIPROPDWORD property;
	property.diph.dwSize = sizeof(DIPROPDWORD);
	property.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	property.diph.dwObj = 0;
	property.diph.dwHow = DIPH_DEVICE;
	property.dwData = BUFFERSIZE;

	hr = m_lpDevice->SetProperty(DIPROP_BUFFERSIZE, &property.diph);
	if(FAILED(hr))
	{
		ReleaseDevice();
		WriteLog(INFO_ERROR, "Set Mouse Buffer Size Failed");
		return FALSE; 
    }
	/*
	RECT rectWindow;
	if(GetWindowRect(hWnd, &rectWindow))
	{
		m_XPos = (rectWindow.left + rectWindow.right) / 2;
		m_YPos = (rectWindow.top + rectWindow.bottom) / 2;
	}
	else
	{
		m_XPos = 0;
		m_YPos = 0;
	}
	*/
 
    // Get access to the input device. 
/*    hr = m_lpDevice->Acquire(); 
    if(FAILED(hr))
    { 
        ReleaseDevice();
		WriteLog(INFO_ERROR, "Acquire Mouse Failed"); 
        return FALSE; 
    }*/

	return TRUE;
}

void CMouse::ReleaseDevice(void)
{
	if(m_lpDevice)
	{
		m_lpDevice->Unacquire();
		m_lpDevice->Release();
		m_lpDevice = NULL;
	}
}

//-------------------------------------------------
// Read the device's state when in immediate mode
//-------------------------------------------------
HRESULT CMouse::GetState(void)
{
	if(!m_lpDevice)
	{
		WriteLog(INFO_WARNING, "CMouse::m_lpDevice==NULL");
		return -1;
	}
	
	HRESULT hr;
	DIMOUSESTATE dims;
	ZeroMemory(&dims, sizeof(dims));
	hr = m_lpDevice->GetDeviceState(sizeof(dims), (LPVOID)&dims);
	if(FAILED(hr))
	{
		hr = m_lpDevice->Acquire();
		while(hr == DIERR_INPUTLOST)
			hr = m_lpDevice->Acquire();
		if(hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED)
		{
		//	WriteLog(INFO_ERROR, "CMouse::GetState Unacquired");
			return -1;
		}
		ZeroMemory(&dims, sizeof(dims));
		hr = m_lpDevice->GetDeviceState(sizeof(dims), (LPVOID)&dims);
	}
	if(SUCCEEDED(hr))
	{
		m_XPos = dims.lX;
		m_YPos = dims.lY;
		m_ZPos = dims.lZ;

		if(dims.rgbButtons[0] & 0x80)
			MouseButton[LBUTTON]=1;
		else 
			MouseButton[LBUTTON]=0;

		if(dims.rgbButtons[1] & 0x80)
			MouseButton[RBUTTON]=1;
		else 
			MouseButton[RBUTTON]=0;

		if(dims.rgbButtons[2] & 0x80)
			MouseButton[MBUTTON]=1;
		else 
			MouseButton[MBUTTON]=0;

		if(dims.rgbButtons[3] & 0x80)
			MouseButton[LRBUTTON]=1;
		else 
			MouseButton[LRBUTTON]=0;

		return hr;
	}
	else
	{
		WriteLog(INFO_WARNING, "CMouse::GetState Failed");
		return hr;
	}
}

//-------------------------------------------------
// Read the device's state when in buffered mode
//-------------------------------------------------
HRESULT CMouse::GetData(void)
{
	if(!m_lpDevice)
	{
		WriteLog(INFO_WARNING, "CMouse::m_lpDevice==NULL");
		return -1;
	}
	
	DIDEVICEOBJECTDATA diod[BUFFERSIZE];
	DWORD dwItems = BUFFERSIZE;

	HRESULT hr = m_lpDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diod, &dwItems, 0);
	if(hr!=DI_OK)		
	{
		hr = m_lpDevice->Acquire();
		while(hr == DIERR_INPUTLOST)
			hr = m_lpDevice->Acquire();

		if(hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED)
		{
		//	WriteLog(INFO_WARNING, "[CMouse::GetData] Acquire Device Failed");
			return -1;
		}
		hr = m_lpDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diod, &dwItems, 0);
		if(FAILED(hr))
		{
			WriteLog(INFO_WARNING, "[CMouse::GetData] GetDeviceData Failed");
			return hr;
		}
	}
	
	if(SUCCEEDED(hr) && dwItems>0)
	{
		for(DWORD i=0; i<dwItems; i++)
		{
			switch(diod[i].dwOfs)
			{
            case DIMOFS_BUTTON0:
				{
					if(diod[i].dwData & 0x80)
						m_BufferData[m_BufferEnd] = (UINT)LB_DOWN;
					else
						m_BufferData[m_BufferEnd] = (UINT)LB_UP;
				}
				break;
            case DIMOFS_BUTTON1:
				{
					if(diod[i].dwData & 0x80)
						m_BufferData[m_BufferEnd] = (UINT)RB_DOWN;
					else
						m_BufferData[m_BufferEnd] = (UINT)RB_UP;
				}
				break;
            case DIMOFS_BUTTON2:
				{
					if(diod[i].dwData & 0x80)
						m_BufferData[m_BufferEnd] = (UINT)MB_DOWN;
					else
						m_BufferData[m_BufferEnd] = (UINT)MB_UP;
				}
				break;
            case DIMOFS_BUTTON3:
            case DIMOFS_X:
            case DIMOFS_Y:
            case DIMOFS_Z:
				{
					continue;
				}
			}
			m_BufferEnd ++;
			if(m_BufferEnd >= BUFFERSIZE)
			{
				m_BufferEnd = 0;
			}
		}
	}
	return hr;
}

bool CMouse::IsKeyDown(unsigned char mouse)
{
	if(mouse>=MOUSEBUTTON)
	{
		WriteLog(INFO_WARNING, "[CMouse::IsKeyDown] wrong input");
		return false;
	}
	if(MouseButton[mouse])
	{
		return true;
	}
	return false;
}

//-------------------------------------------------
// Set a mouse button value
// bKeyDown not use
// 判断key的范围不合适
//-------------------------------------------------
void CMouse::SetBufferKey(unsigned int key, bool bKeyDown)
{
	if(key<1 || key>32)
		return;

	m_BufferData[m_BufferEnd] = (UINT)(key);
	
	m_BufferEnd++;
	if(m_BufferEnd >= BUFFERSIZE)
	m_BufferEnd = 0;
}

void CMouse::GetPointerOffset(long *x, long *y, long *z)
{
	*x = m_XPos;
	*y = m_YPos;
	*z = m_ZPos;
}

//-------------------------------------------------
// end of this file
//-------------------------------------------------

⌨️ 快捷键说明

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