381 lines
7.3 KiB
C++
381 lines
7.3 KiB
C++
#include "..\ebase.h"
|
|
|
|
#pragma comment(lib, "dinput8.lib")
|
|
#pragma comment(lib, "dxguid.lib")
|
|
|
|
using namespace e2d;
|
|
|
|
static IDirectInput8* s_pDirectInput = nullptr; // DirectInput 接口对象
|
|
static IDirectInputDevice8* s_KeyboardDevice = nullptr; // 键盘设备接口
|
|
static char s_KeyBuffer[256] = { 0 }; // 用于保存键盘按键信息缓冲区
|
|
static char s_KeyRecordBuffer[256] = { 0 }; // 键盘消息二级缓冲区
|
|
|
|
static IDirectInputDevice8* s_MouseDevice = nullptr; // 鼠标设备接口
|
|
static DIMOUSESTATE s_MouseState; // 鼠标信息存储结构体
|
|
static DIMOUSESTATE s_MouseRecordState; // 鼠标信息二级缓冲
|
|
static POINT s_MousePosition; // 鼠标位置存储结构体
|
|
|
|
// 监听器容器
|
|
static std::vector<Listener*> s_vListeners;
|
|
|
|
|
|
bool Input::__init()
|
|
{
|
|
ZeroMemory(s_KeyBuffer, sizeof(s_KeyBuffer));
|
|
ZeroMemory(s_KeyRecordBuffer, sizeof(s_KeyRecordBuffer));
|
|
ZeroMemory(&s_MouseState, sizeof(s_MouseState));
|
|
ZeroMemory(&s_MouseRecordState, sizeof(s_MouseRecordState));
|
|
|
|
// 初始化接口对象
|
|
HRESULT hr = DirectInput8Create(
|
|
HINST_THISCOMPONENT,
|
|
DIRECTINPUT_VERSION,
|
|
IID_IDirectInput8,
|
|
(void**)&s_pDirectInput,
|
|
nullptr
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// 初始化键盘设备
|
|
hr = s_pDirectInput->CreateDevice(
|
|
GUID_SysKeyboard,
|
|
&s_KeyboardDevice,
|
|
nullptr
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
s_KeyboardDevice->SetCooperativeLevel(
|
|
Window::getHWnd(),
|
|
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE
|
|
);
|
|
s_KeyboardDevice->SetDataFormat(
|
|
&c_dfDIKeyboard);
|
|
s_KeyboardDevice->Acquire();
|
|
s_KeyboardDevice->Poll();
|
|
}
|
|
else
|
|
{
|
|
MessageBox(nullptr, L"Keyboard not found!", L"Error", MB_ICONERROR | MB_OK);
|
|
Game::quit();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// 初始化鼠标设备
|
|
hr = s_pDirectInput->CreateDevice(GUID_SysMouse, &s_MouseDevice, nullptr);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
s_MouseDevice->SetCooperativeLevel(Window::getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
|
s_MouseDevice->SetDataFormat(&c_dfDIMouse);
|
|
s_MouseDevice->Acquire();
|
|
s_MouseDevice->Poll();
|
|
}
|
|
else
|
|
{
|
|
MessageBox(nullptr, L"Mouse not found!", L"Error", MB_ICONERROR | MB_OK);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
void Input::__uninit()
|
|
{
|
|
if (s_KeyboardDevice)
|
|
s_KeyboardDevice->Unacquire();
|
|
if (s_MouseDevice)
|
|
s_MouseDevice->Unacquire();
|
|
|
|
SafeReleaseInterface(&s_MouseDevice);
|
|
SafeReleaseInterface(&s_KeyboardDevice);
|
|
SafeReleaseInterface(&s_pDirectInput);
|
|
}
|
|
|
|
void e2d::Input::__update()
|
|
{
|
|
Input::__updateDeviceState();
|
|
|
|
for (size_t i = 0; i < s_vListeners.size(); i++)
|
|
{
|
|
auto pListener = s_vListeners[i];
|
|
// 更新监听器
|
|
if (pListener->m_bClear)
|
|
{
|
|
pListener->release();
|
|
s_vListeners.erase(s_vListeners.begin() + i);
|
|
}
|
|
else if (pListener->isRunning())
|
|
{
|
|
pListener->update();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Input::__updateDeviceState()
|
|
{
|
|
if (s_KeyboardDevice)
|
|
{
|
|
HRESULT hr = s_KeyboardDevice->Poll();
|
|
if (FAILED(hr))
|
|
{
|
|
hr = s_KeyboardDevice->Acquire();
|
|
while (hr == DIERR_INPUTLOST)
|
|
hr = s_KeyboardDevice->Acquire();
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < 256; i++)
|
|
s_KeyRecordBuffer[i] = s_KeyBuffer[i];
|
|
|
|
s_KeyboardDevice->GetDeviceState(sizeof(s_KeyBuffer), (void**)&s_KeyBuffer);
|
|
}
|
|
}
|
|
|
|
if (s_MouseDevice)
|
|
{
|
|
HRESULT hr = s_MouseDevice->Poll();
|
|
if (FAILED(hr))
|
|
{
|
|
hr = s_MouseDevice->Acquire();
|
|
while (hr == DIERR_INPUTLOST)
|
|
hr = s_MouseDevice->Acquire();
|
|
}
|
|
else
|
|
{
|
|
s_MouseRecordState = s_MouseState;
|
|
s_MouseDevice->GetDeviceState(sizeof(s_MouseState), (void**)&s_MouseState);
|
|
}
|
|
}
|
|
|
|
GetCursorPos(&s_MousePosition);
|
|
ScreenToClient(Window::getHWnd(), &s_MousePosition);
|
|
}
|
|
|
|
void e2d::Input::__add(Listener * pListener)
|
|
{
|
|
WARN_IF(pListener == nullptr, "Listener NULL pointer exception!");
|
|
|
|
if (pListener)
|
|
{
|
|
auto findListener = [](Listener * pListener) -> bool
|
|
{
|
|
for (const auto &l : s_vListeners)
|
|
{
|
|
if (pListener == l)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
bool bHasListener = findListener(pListener);
|
|
WARN_IF(bHasListener, "The listener is already added, cannot be added again!");
|
|
|
|
if (!bHasListener)
|
|
{
|
|
pListener->retain();
|
|
s_vListeners.push_back(pListener);
|
|
}
|
|
}
|
|
}
|
|
|
|
void e2d::Input::add(Function func, String name)
|
|
{
|
|
(new Listener(func, name))->start();
|
|
}
|
|
|
|
void e2d::Input::start(String name)
|
|
{
|
|
for (const auto & pListener : s_vListeners)
|
|
{
|
|
if (pListener->getName() == name)
|
|
{
|
|
pListener->start();
|
|
}
|
|
}
|
|
}
|
|
|
|
void e2d::Input::stop(String name)
|
|
{
|
|
for (const auto & pListener : s_vListeners)
|
|
{
|
|
if (pListener->getName() == name)
|
|
{
|
|
pListener->stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
void e2d::Input::clear(String name)
|
|
{
|
|
for (const auto & pListener : s_vListeners)
|
|
{
|
|
if (pListener->getName() == name)
|
|
{
|
|
pListener->stopAndClear();
|
|
}
|
|
}
|
|
}
|
|
|
|
void e2d::Input::startAll()
|
|
{
|
|
for (const auto & pListener : s_vListeners)
|
|
{
|
|
pListener->start();
|
|
}
|
|
}
|
|
|
|
void e2d::Input::stopAll()
|
|
{
|
|
for (const auto & pListener : s_vListeners)
|
|
{
|
|
pListener->stop();
|
|
}
|
|
}
|
|
|
|
void e2d::Input::clearAll()
|
|
{
|
|
for (const auto & pListener : s_vListeners)
|
|
{
|
|
pListener->stopAndClear();
|
|
}
|
|
}
|
|
|
|
std::vector<Listener*> e2d::Input::get(String name)
|
|
{
|
|
std::vector<Listener*> vListeners;
|
|
for (auto pListener : s_vListeners)
|
|
{
|
|
if (pListener->getName() == name)
|
|
{
|
|
vListeners.push_back(pListener);
|
|
}
|
|
}
|
|
return std::move(vListeners);
|
|
}
|
|
|
|
std::vector<Listener*> e2d::Input::getAll()
|
|
{
|
|
return s_vListeners;
|
|
}
|
|
|
|
bool Input::isKeyDown(int nKeyCode)
|
|
{
|
|
if (s_KeyBuffer[nKeyCode] & 0x80)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isKeyPress(int nKeyCode)
|
|
{
|
|
if ((s_KeyBuffer[nKeyCode] & 0x80) && !(s_KeyRecordBuffer[nKeyCode] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isKeyRelease(int nKeyCode)
|
|
{
|
|
if (!(s_KeyBuffer[nKeyCode] & 0x80) && (s_KeyRecordBuffer[nKeyCode] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseLButtonDown()
|
|
{
|
|
if (s_MouseState.rgbButtons[0] & 0x80)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseRButtonDown()
|
|
{
|
|
if (s_MouseState.rgbButtons[1] & 0x80)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseMButtonDown()
|
|
{
|
|
if (s_MouseState.rgbButtons[2] & 0x80)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseLButtonPress()
|
|
{
|
|
if ((s_MouseState.rgbButtons[0] & 0x80) && !(s_MouseRecordState.rgbButtons[0] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseRButtonPress()
|
|
{
|
|
if ((s_MouseState.rgbButtons[1] & 0x80) && !(s_MouseRecordState.rgbButtons[1] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseMButtonPress()
|
|
{
|
|
if ((s_MouseState.rgbButtons[2] & 0x80) && !(s_MouseRecordState.rgbButtons[2] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseLButtonRelease()
|
|
{
|
|
if (!(s_MouseState.rgbButtons[0] & 0x80) && (s_MouseRecordState.rgbButtons[0] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseRButtonRelease()
|
|
{
|
|
if (!(s_MouseState.rgbButtons[1] & 0x80) && (s_MouseRecordState.rgbButtons[1] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Input::isMouseMButtonRelease()
|
|
{
|
|
if (!(s_MouseState.rgbButtons[2] & 0x80) && (s_MouseRecordState.rgbButtons[2] & 0x80))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
double Input::getMouseX()
|
|
{
|
|
return (double)s_MousePosition.x;
|
|
}
|
|
|
|
double Input::getMouseY()
|
|
{
|
|
return (double)s_MousePosition.y;
|
|
}
|
|
|
|
Point Input::getMousePos()
|
|
{
|
|
return Point((double)s_MousePosition.x, (double)s_MousePosition.y);
|
|
}
|
|
|
|
double Input::getMouseDeltaX()
|
|
{
|
|
return (double)s_MouseState.lX;
|
|
}
|
|
|
|
double Input::getMouseDeltaY()
|
|
{
|
|
return (double)s_MouseState.lY;
|
|
}
|
|
|
|
double Input::getMouseDeltaZ()
|
|
{
|
|
return (double)s_MouseState.lZ;
|
|
} |