Added basic raw input support

This commit is contained in:
Simon Lübeß
2021-03-04 13:05:26 +01:00
parent 08613b9e82
commit 4e377bb117
4 changed files with 197 additions and 1 deletions
+8
View File
@@ -6,6 +6,8 @@ namespace GlitchyEngine
{ {
public static class Input public static class Input
{ {
public static extern bool RawInput {get; set;}
public static extern bool IsKeyPressed(Key keycode); public static extern bool IsKeyPressed(Key keycode);
public static extern bool IsKeyReleased(Key keycode); public static extern bool IsKeyReleased(Key keycode);
public static extern bool IsKeyToggled(Key keycode); public static extern bool IsKeyToggled(Key keycode);
@@ -41,6 +43,12 @@ namespace GlitchyEngine
public static extern bool IsMouseButtonReleasiong(MouseButton button); public static extern bool IsMouseButtonReleasiong(MouseButton button);
public static extern Point GetMouseMovement(); public static extern Point GetMouseMovement();
/**
* Returns the raw mouse (that is the mouse movement taken direcly from the device instead of the movement processed by the OS).
* Requires RawInput to be true. If RawInput is false (or could not be initialized) this method will return the same value as GetMouseMovement();
*/
public static extern Int32_2 GetRawMouseMovement();
public static extern void NewFrame(); public static extern void NewFrame();
} }
} }
@@ -12,12 +12,30 @@ namespace GlitchyEngine
/// Windows (WinApi) specific implementation of the Input-class /// Windows (WinApi) specific implementation of the Input-class
extension Input extension Input
{ {
internal static bool sUseRawInput = true;
public override static bool RawInput
{
get => sUseRawInput;
set
{
if(sUseRawInput == value)
return;
sUseRawInput = value;
//if(sUseRawInput)
// TODO: init raw input
}
}
/// Represents the state of the input devices on the windows platform (WinApi that is). /// Represents the state of the input devices on the windows platform (WinApi that is).
struct WindowsInputState struct WindowsInputState
{ {
public int8[256] KeyStates; public int8[256] KeyStates;
public Point CursorPosition; public Point CursorPosition;
public Point CursorPositionDifference; public Point CursorPositionDifference;
public Int32_2 RawMovement;
} }
static WindowsInputState* CurrentState = new WindowsInputState() ~ delete _; static WindowsInputState* CurrentState = new WindowsInputState() ~ delete _;
@@ -152,6 +170,19 @@ namespace GlitchyEngine
public override static Point GetMouseMovement() => CurrentState.CursorPositionDifference; public override static Point GetMouseMovement() => CurrentState.CursorPositionDifference;
public override static Int32_2 GetRawMouseMovement()
{
if(sUseRawInput)
{
return CurrentState.RawMovement;
}
else
{
var v = GetMouseMovement();
return *(Int32_2*)&v;
}
}
//[CLink, CallingConvention(.Stdcall)] //[CLink, CallingConvention(.Stdcall)]
//static extern int16 GetKeyState(int32 keycode); //static extern int16 GetKeyState(int32 keycode);
@@ -160,6 +191,8 @@ namespace GlitchyEngine
[CLink, CallingConvention(.Stdcall)] [CLink, CallingConvention(.Stdcall)]
static extern IntBool ScreenToClient(HWnd hWnd, ref Point p); static extern IntBool ScreenToClient(HWnd hWnd, ref Point p);
internal static Int32_2 rawMovement;
public override static void NewFrame() public override static void NewFrame()
{ {
// Switch last and current states // Switch last and current states
@@ -192,6 +225,8 @@ namespace GlitchyEngine
// Calculate cursor movement // Calculate cursor movement
CurrentState.CursorPositionDifference = CurrentState.CursorPosition - LastState.CursorPosition; CurrentState.CursorPositionDifference = CurrentState.CursorPosition - LastState.CursorPosition;
CurrentState.RawMovement = rawMovement;
rawMovement = .Zero;
} }
} }
#endif #endif
@@ -9,6 +9,7 @@ using GlitchyEngine.Events;
using System.Diagnostics; using System.Diagnostics;
using GlitchyEngine.Math; using GlitchyEngine.Math;
using GlitchyEngine.Renderer; using GlitchyEngine.Renderer;
using DirectX.Windows.Winuser.RawInput;
using static System.Windows; using static System.Windows;
namespace GlitchyEngine namespace GlitchyEngine
@@ -215,6 +216,41 @@ namespace GlitchyEngine
LoadWindowRectangle(); LoadWindowRectangle();
Log.EngineLogger.Trace($"Created window \"{Title}\" ({Width}, {Height})"); Log.EngineLogger.Trace($"Created window \"{Title}\" ({Width}, {Height})");
if(Input.RawInput)
{
InitRawInput();
}
}
[CLink, CallingConvention(.Stdcall)]
static extern IntBool RegisterRawInputDevices(RAWINPUTDEVICE* rawInputDevices, uint32 numDevices, uint32 size);
private void InitRawInput()
{
RAWINPUTDEVICE[1] Rid;
Rid[0].UsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
Rid[0].Usage = 0x02; // HID_USAGE_GENERIC_MOUSE
Rid[0].Flags = 0;//RIDEV_NOLEGACY; // adds mouse and also ignores legacy mouse messages
Rid[0].Target = 0;
/*
Rid[1].UsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
Rid[1].Usage = 0x06; // HID_USAGE_GENERIC_KEYBOARD
Rid[1].Flags = RIDEV_NOLEGACY; // adds keyboard and also ignores legacy keyboard messages
Rid[1].Target = 0;
*/
if (!RegisterRawInputDevices(&Rid, Rid.Count, sizeof(RAWINPUTDEVICE)))
{
DirectX.Common.HResult errorCode = (.)GetLastError();
Log.EngineLogger.Error($"Failed to register raw input devices. Message({(int32)errorCode}):{errorCode}");
// Disable raw input
Input.RawInput = false;
}
else
{
Log.EngineLogger.Trace($"Registered raw input devices.");
}
} }
private bool _isResizingOrMoving; private bool _isResizingOrMoving;
@@ -438,11 +474,128 @@ namespace GlitchyEngine
return 0; return 0;
} }
// Raw Input
case 0x00FF: //WM_INPUT
{
uint32 dataSize = ?;
GetRawInputData((.)lParam, RID_INPUT, null, &dataSize, sizeof(RAWINPUTHEADER));
if (dataSize > 0)
{
uint8[] rawData = scope .[dataSize];
if (GetRawInputData((.)lParam, RID_INPUT, rawData.CArray(), &dataSize, sizeof(RAWINPUTHEADER)) == dataSize)
{
RAWINPUT* raw = (.)rawData.CArray();
if (raw.Header.Type == RIM_TYPEMOUSE)
{
int32 movementX = raw.Data.Mouse.lLastX;
int32 movementY = raw.Data.Mouse.lLastY;
// TODO: raw.Data.Mouse.usFlags defines whether movement is abosulte, relative, etc...
Input.[Friend]rawMovement += .(movementX, movementY);
/*
var event = scope MouseMovedEvent(movementX, movementY);
window._eventCallback(event);
// Convert button transition flags to a more manageable type
var buttonTransitions = (RawMouseButtonTransition)raw.Data.Mouse.DUMMYUNIONNAME.DUMMYSTRUCTNAME.usButtonFlags;
if(buttonTransitions.HasFlag(.LeftDown))
{
var buttonEvent = scope MouseButtonPressedEvent(.LeftButton);
window._eventCallback(buttonEvent);
}
else if(buttonTransitions.HasFlag(.LeftUp))
{
var buttonEvent = scope MouseButtonReleasedEvent(.LeftButton);
window._eventCallback(buttonEvent);
}
if(buttonTransitions.HasFlag(.RightDown))
{
var buttonEvent = scope MouseButtonPressedEvent(.RightButton);
window._eventCallback(buttonEvent);
}
else if(buttonTransitions.HasFlag(.RightUp))
{
var buttonEvent = scope MouseButtonReleasedEvent(.RightButton);
window._eventCallback(buttonEvent);
}
if(buttonTransitions.HasFlag(.MiddleDown))
{
var buttonEvent = scope MouseButtonPressedEvent(.MiddleButton);
window._eventCallback(buttonEvent);
}
else if(buttonTransitions.HasFlag(.MiddleUp))
{
var buttonEvent = scope MouseButtonReleasedEvent(.MiddleButton);
window._eventCallback(buttonEvent);
}
if(buttonTransitions.HasFlag(.XButton1Down))
{
var buttonEvent = scope MouseButtonPressedEvent(.XButton1);
window._eventCallback(buttonEvent);
}
else if(buttonTransitions.HasFlag(.XButton1Up))
{
var buttonEvent = scope MouseButtonReleasedEvent(.XButton1);
window._eventCallback(buttonEvent);
}
if(buttonTransitions.HasFlag(.XButton2Down))
{
var buttonEvent = scope MouseButtonPressedEvent(.XButton2);
window._eventCallback(buttonEvent);
}
else if(buttonTransitions.HasFlag(.XButton2Up))
{
var buttonEvent = scope MouseButtonReleasedEvent(.XButton2);
window._eventCallback(buttonEvent);
}
if(buttonTransitions.HasFlag(.MouseWheel))
{
int32 rotation = raw.Data.Mouse.DUMMYUNIONNAME.DUMMYSTRUCTNAME.usButtonData / WHEEL_DELTA;
var scrollEvent = scope MouseScrolledEvent(0, rotation);
window._eventCallback(scrollEvent);
}
if(buttonTransitions.HasFlag(.MouseHWheel))
{
int32 rotation = raw.Data.Mouse.DUMMYUNIONNAME.DUMMYSTRUCTNAME.usButtonData / WHEEL_DELTA;
var scrollEvent = scope MouseScrolledEvent(rotation, 0);
window._eventCallback(scrollEvent);
}
*/
}
}
}
}
} }
return DefWindowProcW(hwnd, uMsg, wParam, lParam); return DefWindowProcW(hwnd, uMsg, wParam, lParam);
} }
enum RawMouseButtonTransition
{
LeftDown = 0x0001,
LeftUp = 0x0002,
MiddleDown = 0x0010,
MiddleUp = 0x0020,
RightDown = 0x0004,
RightUp = 0x0008,
XButton1Down = 0x0040,
XButton1Up = 0x0080,
XButton2Down = 0x0100,
XButton2Up = 0x0200,
MouseWheel = 0x0400,
MouseHWheel = 0x0800
}
public override void Update() public override void Update()
{ {
Message message = .(); Message message = .();
+1 -1
View File
@@ -280,7 +280,7 @@ namespace Sandbox.VoxelFun
return; return;
} }
let mouseMovement = Input.GetMouseMovement(); let mouseMovement = Input.GetRawMouseMovement();
if(mouseMovement.X == 0 && mouseMovement.Y == 0) if(mouseMovement.X == 0 && mouseMovement.Y == 0)
return; return;