Implement RawInput (WIP)
This commit is contained in:
@@ -174,7 +174,9 @@ void InputSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* m
|
||||
void Mouse::OnMouseMoved(const Float2& newPosition)
|
||||
{
|
||||
_prevState.MousePosition = newPosition;
|
||||
_prevState.MouseWasReset = true;
|
||||
_state.MousePosition = newPosition;
|
||||
_state.MouseWasReset = true;
|
||||
}
|
||||
|
||||
void Mouse::OnMouseDown(const Float2& position, const MouseButton button, Window* target)
|
||||
@@ -221,6 +223,14 @@ void Mouse::OnMouseMove(const Float2& position, Window* target)
|
||||
e.MouseData.Position = position;
|
||||
}
|
||||
|
||||
void Mouse::OnMouseMoveDelta(const Vector2& delta, Window* target)
|
||||
{
|
||||
Event& e = _queue.AddOne();
|
||||
e.Type = EventType::MouseMoveDelta;
|
||||
e.Target = target;
|
||||
e.MouseData.Position = delta;
|
||||
}
|
||||
|
||||
void Mouse::OnMouseLeave(Window* target)
|
||||
{
|
||||
Event& e = _queue.AddOne();
|
||||
@@ -245,6 +255,7 @@ void Mouse::ResetState()
|
||||
_state.Clear();
|
||||
}
|
||||
|
||||
#include "Engine/Core/Log.h"
|
||||
bool Mouse::Update(EventQueue& queue)
|
||||
{
|
||||
// Move the current state to the previous
|
||||
@@ -256,6 +267,7 @@ bool Mouse::Update(EventQueue& queue)
|
||||
|
||||
// Handle events
|
||||
_state.MouseWheelDelta = 0;
|
||||
_state.MouseDelta = Vector2::Zero;
|
||||
for (int32 i = 0; i < _queue.Count(); i++)
|
||||
{
|
||||
const Event& e = _queue[i];
|
||||
@@ -286,6 +298,11 @@ bool Mouse::Update(EventQueue& queue)
|
||||
_state.MousePosition = e.MouseData.Position;
|
||||
break;
|
||||
}
|
||||
case EventType::MouseMoveDelta:
|
||||
{
|
||||
_state.MouseDelta += e.MouseData.Position;
|
||||
break;
|
||||
}
|
||||
case EventType::MouseLeave:
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
MouseDoubleClick,
|
||||
MouseWheel,
|
||||
MouseMove,
|
||||
MouseMoveDelta,
|
||||
MouseLeave,
|
||||
TouchDown,
|
||||
TouchMove,
|
||||
|
||||
@@ -24,6 +24,16 @@ public:
|
||||
/// </summary>
|
||||
Float2 MousePosition;
|
||||
|
||||
/// <summary>
|
||||
/// The mouse position delta.
|
||||
/// </summary>
|
||||
Vector2 MouseDelta;
|
||||
|
||||
/// <summary>
|
||||
/// Set when application moved the mouse.
|
||||
/// </summary>
|
||||
bool MouseWasReset;
|
||||
|
||||
/// <summary>
|
||||
/// The mouse wheel delta.
|
||||
/// </summary>
|
||||
@@ -73,7 +83,7 @@ public:
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE Float2 GetPositionDelta() const
|
||||
{
|
||||
return _state.MousePosition - _prevState.MousePosition;
|
||||
return _state.MouseDelta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -158,6 +168,13 @@ public:
|
||||
/// <param name="target">The target window to receive this event, otherwise input system will pick the window automatically.</param>
|
||||
void OnMouseMove(const Float2& position, Window* target = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Called when mouse moves.
|
||||
/// </summary>
|
||||
/// <param name="position">The mouse position.</param>
|
||||
/// <param name="target">The target window to receive this event, otherwise input system will pick the window automatically.</param>
|
||||
void OnMouseMoveDelta(const Vector2& delta, Window* target = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Called when mouse leaves the input source area.
|
||||
/// </summary>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Engine/Input/Gamepad.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Core/Math/Int2.h"
|
||||
#include "../Win32/IncludeWindowsHeaders.h"
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
@@ -107,12 +108,36 @@ namespace WindowsInputImpl
|
||||
bool XInputGamepads[XUSER_MAX_COUNT] = { false };
|
||||
WindowsMouse* Mouse = nullptr;
|
||||
WindowsKeyboard* Keyboard = nullptr;
|
||||
bool RawInput = true;
|
||||
}
|
||||
|
||||
#include <hidusage.h>
|
||||
void WindowsInput::Init()
|
||||
{
|
||||
Input::Mouse = WindowsInputImpl::Mouse = New<WindowsMouse>();
|
||||
Input::Keyboard = WindowsInputImpl::Keyboard = New<WindowsKeyboard>();
|
||||
|
||||
if (WindowsInputImpl::RawInput)
|
||||
{
|
||||
RAWINPUTDEVICE Rid[2];
|
||||
|
||||
// register mouse
|
||||
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
|
||||
Rid[0].dwFlags = (RIDEV_NOLEGACY*0); // adds mouse and also ignores legacy mouse messages
|
||||
Rid[0].hwndTarget = 0;
|
||||
|
||||
// register keyboard
|
||||
Rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
Rid[1].usUsage = HID_USAGE_GENERIC_KEYBOARD;
|
||||
Rid[1].dwFlags = (RIDEV_NOLEGACY*0); // adds keyboard and also ignores legacy keyboard messages
|
||||
Rid[1].hwndTarget = 0;
|
||||
|
||||
if (!RegisterRawInputDevices(Rid, 2, sizeof(Rid[0])))
|
||||
{
|
||||
//registration failed. Call GetLastError for the cause of the error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsInput::Update()
|
||||
@@ -138,6 +163,8 @@ void WindowsInput::Update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle raw input device detection here
|
||||
}
|
||||
|
||||
bool WindowsInput::WndProc(Window* window, Windows::UINT msg, Windows::WPARAM wParam, Windows::LPARAM lParam)
|
||||
@@ -149,6 +176,76 @@ bool WindowsInput::WndProc(Window* window, Windows::UINT msg, Windows::WPARAM wP
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnRawInput(Vector2 mousePosition, Window* window, HRAWINPUT input)
|
||||
{
|
||||
uint32 dataSize;
|
||||
static BYTE* dataBuffer = nullptr;
|
||||
static uint32 dataBufferSize = 0;
|
||||
|
||||
GetRawInputData(input, RID_INPUT, nullptr, &dataSize, sizeof(RAWINPUTHEADER));
|
||||
if (dataSize > dataBufferSize)
|
||||
{
|
||||
if (dataBuffer != nullptr)
|
||||
delete[] dataBuffer;
|
||||
dataBuffer = new BYTE[dataSize];
|
||||
dataBufferSize = dataSize;
|
||||
}
|
||||
|
||||
GetRawInputData(input, RID_INPUT, dataBuffer, &dataSize, sizeof(RAWINPUTHEADER));
|
||||
|
||||
if (((RAWINPUT*)dataBuffer)->header.dwType == RIM_TYPEKEYBOARD)
|
||||
{
|
||||
RAWKEYBOARD rawKeyboard = ((RAWINPUT*)dataBuffer)->data.keyboard;
|
||||
|
||||
if ((rawKeyboard.Flags & RI_KEY_BREAK) != 0)
|
||||
Input::Keyboard->OnKeyUp(static_cast<KeyboardKeys>(rawKeyboard.VKey), window);
|
||||
else
|
||||
Input::Keyboard->OnKeyDown(static_cast<KeyboardKeys>(rawKeyboard.VKey), window);
|
||||
}
|
||||
else if (((RAWINPUT*)dataBuffer)->header.dwType == RIM_TYPEMOUSE)
|
||||
{
|
||||
const RAWMOUSE rawMouse = ((RAWINPUT*)dataBuffer)->data.mouse;
|
||||
Vector2 mousePos;
|
||||
if ((rawMouse.usFlags & MOUSE_MOVE_ABSOLUTE) != 0)
|
||||
{
|
||||
const bool virtualDesktop = (rawMouse.usFlags & MOUSE_VIRTUAL_DESKTOP) != 0;
|
||||
const int width = GetSystemMetrics(virtualDesktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
|
||||
const int height = GetSystemMetrics(virtualDesktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
|
||||
mousePos = Vector2(Int2(
|
||||
static_cast<int>((rawMouse.lLastX / 65535.0f) * width),
|
||||
static_cast<int>((rawMouse.lLastY / 65535.0f) * height)));
|
||||
|
||||
Input::Mouse->OnMouseMove(mousePos, window);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: This is wrong. The current mouse position does not include
|
||||
// delta movement accumulated during this frame.
|
||||
mousePos = mousePosition;
|
||||
|
||||
const Vector2 mouseDelta(Int2(rawMouse.lLastX, rawMouse.lLastY));
|
||||
mousePos += mouseDelta;
|
||||
|
||||
if (!mouseDelta.IsZero())
|
||||
{
|
||||
//Input::Mouse->OnMouseMove(mousePos, window);
|
||||
Input::Mouse->OnMouseMoveDelta(mouseDelta, window);
|
||||
}
|
||||
}
|
||||
|
||||
if ((rawMouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) != 0)
|
||||
Input::Mouse->OnMouseDown(mousePos, MouseButton::Left, window);
|
||||
if ((rawMouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) != 0)
|
||||
Input::Mouse->OnMouseUp(mousePos, MouseButton::Left, window);
|
||||
if ((rawMouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) != 0)
|
||||
Input::Mouse->OnMouseDown(mousePos, MouseButton::Right, window);
|
||||
if ((rawMouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) != 0)
|
||||
Input::Mouse->OnMouseUp(mousePos, MouseButton::Right, window);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowsKeyboard::WndProc(Window* window, const Windows::UINT msg, Windows::WPARAM wParam, Windows::LPARAM lParam)
|
||||
{
|
||||
bool result = false;
|
||||
@@ -197,6 +294,21 @@ bool WindowsMouse::WndProc(Window* window, const UINT msg, WPARAM wParam, LPARAM
|
||||
{
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if (!WindowsInputImpl::RawInput)
|
||||
{
|
||||
static Vector2 lastPos = mousePos;
|
||||
if (_state.MouseWasReset)
|
||||
{
|
||||
lastPos = _state.MousePosition;
|
||||
_state.MouseWasReset = false;
|
||||
}
|
||||
|
||||
Vector2 deltaPos = mousePos - lastPos;
|
||||
if (!deltaPos.IsZero())
|
||||
OnMouseMoveDelta(deltaPos, window);
|
||||
lastPos = mousePos;
|
||||
}
|
||||
|
||||
OnMouseMove(mousePos, window);
|
||||
result = true;
|
||||
break;
|
||||
@@ -293,6 +405,11 @@ bool WindowsMouse::WndProc(Window* window, const UINT msg, WPARAM wParam, LPARAM
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
case WM_INPUT:
|
||||
{
|
||||
result = OnRawInput(_state.MousePosition, window, reinterpret_cast<HRAWINPUT>(lParam));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user