2018-04-21 21:24:46 +08:00
|
|
|
|
#include "..\e2dbase.h"
|
|
|
|
|
|
#include "..\e2dtool.h"
|
|
|
|
|
|
#include "..\e2dmanager.h"
|
2018-01-30 16:45:38 +08:00
|
|
|
|
|
|
|
|
|
|
#pragma comment(lib, "dinput8.lib")
|
|
|
|
|
|
|
|
|
|
|
|
using namespace e2d;
|
|
|
|
|
|
|
2018-05-14 22:51:40 +08:00
|
|
|
|
#define BUFFER_SIZE 256
|
|
|
|
|
|
|
2018-01-30 16:45:38 +08:00
|
|
|
|
static IDirectInput8* s_pDirectInput = nullptr; // DirectInput <20>ӿڶ<D3BF><DAB6><EFBFBD>
|
|
|
|
|
|
static IDirectInputDevice8* s_KeyboardDevice = nullptr; // <20><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD>ӿ<EFBFBD>
|
2018-05-17 23:53:27 +08:00
|
|
|
|
static char s_KeyBuffer[BUFFER_SIZE] = { 0 }; // <20><><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
static char s_KeyRecordBuffer[BUFFER_SIZE] = { 0 }; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2018-01-30 16:45:38 +08:00
|
|
|
|
|
|
|
|
|
|
static IDirectInputDevice8* s_MouseDevice = nullptr; // <20><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD>ӿ<EFBFBD>
|
|
|
|
|
|
static DIMOUSESTATE s_MouseState; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>洢<EFBFBD>ṹ<EFBFBD><E1B9B9>
|
2018-02-02 10:06:29 +08:00
|
|
|
|
static DIMOUSESTATE s_MouseRecordState; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2018-01-30 16:45:38 +08:00
|
|
|
|
static POINT s_MousePosition; // <20><><EFBFBD><EFBFBD>λ<EFBFBD>ô洢<C3B4>ṹ<EFBFBD><E1B9B9>
|
|
|
|
|
|
|
2018-05-22 00:36:03 +08:00
|
|
|
|
static std::vector<e2d::Listener*> s_vListeners; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
2018-01-30 16:45:38 +08:00
|
|
|
|
|
2018-02-07 16:37:12 +08:00
|
|
|
|
bool Input::__init()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
ZeroMemory(s_KeyBuffer, sizeof(s_KeyBuffer));
|
2018-02-02 10:06:29 +08:00
|
|
|
|
ZeroMemory(s_KeyRecordBuffer, sizeof(s_KeyRecordBuffer));
|
2018-01-30 16:45:38 +08:00
|
|
|
|
ZeroMemory(&s_MouseState, sizeof(s_MouseState));
|
2018-02-02 10:06:29 +08:00
|
|
|
|
ZeroMemory(&s_MouseRecordState, sizeof(s_MouseRecordState));
|
2018-01-30 16:45:38 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD>ӿڶ<D3BF><DAB6><EFBFBD>
|
|
|
|
|
|
HRESULT hr = DirectInput8Create(
|
|
|
|
|
|
HINST_THISCOMPONENT,
|
|
|
|
|
|
DIRECTINPUT_VERSION,
|
|
|
|
|
|
IID_IDirectInput8,
|
|
|
|
|
|
(void**)&s_pDirectInput,
|
2018-02-01 22:07:44 +08:00
|
|
|
|
nullptr
|
2018-01-30 16:45:38 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸
|
|
|
|
|
|
hr = s_pDirectInput->CreateDevice(
|
|
|
|
|
|
GUID_SysKeyboard,
|
|
|
|
|
|
&s_KeyboardDevice,
|
2018-02-01 22:07:44 +08:00
|
|
|
|
nullptr
|
2018-01-30 16:45:38 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
|
{
|
|
|
|
|
|
s_KeyboardDevice->SetCooperativeLevel(
|
2018-02-07 16:37:12 +08:00
|
|
|
|
Window::getHWnd(),
|
2018-01-30 16:45:38 +08:00
|
|
|
|
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE
|
|
|
|
|
|
);
|
|
|
|
|
|
s_KeyboardDevice->SetDataFormat(
|
|
|
|
|
|
&c_dfDIKeyboard);
|
|
|
|
|
|
s_KeyboardDevice->Acquire();
|
|
|
|
|
|
s_KeyboardDevice->Poll();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-05-10 18:18:02 +08:00
|
|
|
|
Window::error(L"Keyboard not found!");
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸
|
2018-02-01 22:07:44 +08:00
|
|
|
|
hr = s_pDirectInput->CreateDevice(GUID_SysMouse, &s_MouseDevice, nullptr);
|
2018-01-30 16:45:38 +08:00
|
|
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
|
{
|
2018-02-07 16:37:12 +08:00
|
|
|
|
s_MouseDevice->SetCooperativeLevel(Window::getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
2018-01-30 16:45:38 +08:00
|
|
|
|
s_MouseDevice->SetDataFormat(&c_dfDIMouse);
|
|
|
|
|
|
s_MouseDevice->Acquire();
|
|
|
|
|
|
s_MouseDevice->Poll();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-05-10 18:18:02 +08:00
|
|
|
|
Window::error(L"Mouse not found!");
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return SUCCEEDED(hr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-11 23:56:40 +08:00
|
|
|
|
void Input::__uninit()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_KeyboardDevice)
|
|
|
|
|
|
s_KeyboardDevice->Unacquire();
|
|
|
|
|
|
if (s_MouseDevice)
|
|
|
|
|
|
s_MouseDevice->Unacquire();
|
|
|
|
|
|
|
2018-05-22 12:24:43 +08:00
|
|
|
|
SafeRelease(s_MouseDevice);
|
|
|
|
|
|
SafeRelease(s_KeyboardDevice);
|
|
|
|
|
|
SafeRelease(s_pDirectInput);
|
2018-03-11 23:56:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::__update()
|
|
|
|
|
|
{
|
|
|
|
|
|
Input::__updateDeviceState();
|
2018-05-22 00:36:03 +08:00
|
|
|
|
Input::__updateListeners();
|
2018-03-11 23:56:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-07 16:37:12 +08:00
|
|
|
|
void Input::__updateDeviceState()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (s_KeyboardDevice)
|
|
|
|
|
|
{
|
|
|
|
|
|
HRESULT hr = s_KeyboardDevice->Poll();
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
|
|
{
|
|
|
|
|
|
hr = s_KeyboardDevice->Acquire();
|
|
|
|
|
|
while (hr == DIERR_INPUTLOST)
|
|
|
|
|
|
hr = s_KeyboardDevice->Acquire();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-05-14 22:51:40 +08:00
|
|
|
|
for (int i = 0; i < BUFFER_SIZE; ++i)
|
2018-02-02 10:06:29 +08:00
|
|
|
|
s_KeyRecordBuffer[i] = s_KeyBuffer[i];
|
2018-01-30 16:45:38 +08:00
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
{
|
2018-02-02 10:06:29 +08:00
|
|
|
|
s_MouseRecordState = s_MouseState;
|
2018-01-30 16:45:38 +08:00
|
|
|
|
s_MouseDevice->GetDeviceState(sizeof(s_MouseState), (void**)&s_MouseState);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GetCursorPos(&s_MousePosition);
|
2018-02-07 16:37:12 +08:00
|
|
|
|
ScreenToClient(Window::getHWnd(), &s_MousePosition);
|
2018-01-30 16:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-18 23:56:36 +08:00
|
|
|
|
bool Input::isDown(Key key)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-04-24 21:22:34 +08:00
|
|
|
|
if (s_KeyBuffer[static_cast<int>(key)] & 0x80)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-18 23:56:36 +08:00
|
|
|
|
bool Input::isPress(Key key)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-04-24 21:22:34 +08:00
|
|
|
|
if ((s_KeyBuffer[static_cast<int>(key)] & 0x80) &&
|
|
|
|
|
|
!(s_KeyRecordBuffer[static_cast<int>(key)] & 0x80))
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-18 23:56:36 +08:00
|
|
|
|
bool Input::isRelease(Key key)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-04-24 21:22:34 +08:00
|
|
|
|
if (!(s_KeyBuffer[static_cast<int>(key)] & 0x80) &&
|
|
|
|
|
|
(s_KeyRecordBuffer[static_cast<int>(key)] & 0x80))
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-18 23:56:36 +08:00
|
|
|
|
bool e2d::Input::isDown(Mouse code)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-05-17 15:22:14 +08:00
|
|
|
|
if (s_MouseState.rgbButtons[static_cast<int>(code)] & 0x80)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-18 23:56:36 +08:00
|
|
|
|
bool e2d::Input::isPress(Mouse code)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-05-17 15:22:14 +08:00
|
|
|
|
if ((s_MouseState.rgbButtons[static_cast<int>(code)] & 0x80) &&
|
|
|
|
|
|
!(s_MouseRecordState.rgbButtons[static_cast<int>(code)] & 0x80))
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-18 23:56:36 +08:00
|
|
|
|
bool e2d::Input::isRelease(Mouse code)
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-05-17 15:22:14 +08:00
|
|
|
|
if (!(s_MouseState.rgbButtons[static_cast<int>(code)] & 0x80) &&
|
|
|
|
|
|
(s_MouseRecordState.rgbButtons[static_cast<int>(code)] & 0x80))
|
2018-01-30 16:45:38 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-27 21:07:43 +08:00
|
|
|
|
double Input::getMouseX()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-02-27 21:07:43 +08:00
|
|
|
|
return (double)s_MousePosition.x;
|
2018-01-30 16:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-27 21:07:43 +08:00
|
|
|
|
double Input::getMouseY()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-02-27 21:07:43 +08:00
|
|
|
|
return (double)s_MousePosition.y;
|
2018-01-30 16:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-07 16:37:12 +08:00
|
|
|
|
Point Input::getMousePos()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-02-27 21:07:43 +08:00
|
|
|
|
return Point((double)s_MousePosition.x, (double)s_MousePosition.y);
|
2018-01-30 16:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-27 21:07:43 +08:00
|
|
|
|
double Input::getMouseDeltaX()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-02-27 21:07:43 +08:00
|
|
|
|
return (double)s_MouseState.lX;
|
2018-01-30 16:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-27 21:07:43 +08:00
|
|
|
|
double Input::getMouseDeltaY()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-02-27 21:07:43 +08:00
|
|
|
|
return (double)s_MouseState.lY;
|
2018-01-30 16:45:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-27 21:07:43 +08:00
|
|
|
|
double Input::getMouseDeltaZ()
|
2018-01-30 16:45:38 +08:00
|
|
|
|
{
|
2018-02-27 21:07:43 +08:00
|
|
|
|
return (double)s_MouseState.lZ;
|
2018-05-22 00:36:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::addListener(const Function& func, const String& name, bool paused)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto listener = new (std::nothrow) Listener(func, name, paused);
|
|
|
|
|
|
s_vListeners.push_back(listener);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::pauseListener(const String& name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || name.isEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (listener->_name == name)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->_running = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::resumeListener(const String& name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || name.isEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (listener->_name == name)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->_running = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::stopListener(const String& name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || name.isEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (listener->_name == name)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->_stopped = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::pauseAllListeners()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->_running = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::resumeAllListeners()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->_running = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::stopAllListeners()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->_stopped = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::__updateListeners()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || Game::isPaused())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < s_vListeners.size(); ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto listener = s_vListeners[i];
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ<CDA3>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (listener->_stopped)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete listener;
|
|
|
|
|
|
s_vListeners.erase(s_vListeners.begin() + i);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
listener->update();
|
|
|
|
|
|
++i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Input::__clearListeners()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete listener;
|
|
|
|
|
|
}
|
|
|
|
|
|
s_vListeners.clear();
|
2018-01-30 16:45:38 +08:00
|
|
|
|
}
|