mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Added basic raw input support
This commit is contained in:
@@ -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 = .();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user