Raw mouse input support (#798)

* mouse raw input test

* fixes

* focus fix

* input buffering fix

* remove multiplyer

* use raw input for mouse capture only & compatability fix

* fix

* clang format

* small moving around

---------

Co-authored-by: lilacLunatic <8488221+lilacLunatic@users.noreply.github.com>
This commit is contained in:
lightmanLP
2025-02-20 20:36:26 -05:00
committed by GitHub
co-authored by lilacLunatic
parent 204c62f785
commit 6f1461e6b7
+43 -11
View File
@@ -44,6 +44,13 @@
#define NANOSECOND_IN_SECOND 1000000000
#define _100NANOSECONDS_IN_SECOND 10000000
#ifndef HID_USAGE_PAGE_GENERIC
#define HID_USAGE_PAGE_GENERIC ((unsigned short)0x01)
#endif
#ifndef HID_USAGE_GENERIC_MOUSE
#define HID_USAGE_GENERIC_MOUSE ((unsigned short)0x02)
#endif
using namespace Microsoft::WRL; // For ComPtr
static struct {
@@ -93,6 +100,8 @@ static struct {
LARGE_INTEGER previous_present_time;
bool is_mouse_captured;
bool in_focus;
RAWINPUTDEVICE raw_input_device[1];
POINT raw_mouse_delta_buf;
void (*on_fullscreen_changed)(bool is_now_fullscreen);
bool (*on_key_down)(int scancode);
@@ -425,6 +434,19 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
case WM_MOUSEWHEEL:
dxgi.mouse_wheel[1] = GET_WHEEL_DELTA_WPARAM(w_param) / WHEEL_DELTA;
break;
case WM_INPUT: {
if (dxgi.is_mouse_captured && dxgi.in_focus) {
uint32_t size = sizeof(RAWINPUT);
static RAWINPUT raw[sizeof(RAWINPUT)];
GetRawInputData((HRAWINPUT)l_param, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER));
if (raw->header.dwType == RIM_TYPEMOUSE) {
dxgi.raw_mouse_delta_buf.x += raw->data.mouse.lLastX;
dxgi.raw_mouse_delta_buf.y += raw->data.mouse.lLastY;
}
}
break;
}
case WM_DROPFILES:
DragQueryFileA((HDROP)w_param, 0, fileName, 256);
Ship::Context::GetInstance()->GetConsoleVariables()->SetString(CVAR_DROPPED_FILE, fileName);
@@ -527,6 +549,13 @@ void gfx_dxgi_init(const char* game_name, const char* gfx_api_name, bool start_i
}
DragAcceptFiles(dxgi.h_wnd, TRUE);
// Mouse init
dxgi.raw_input_device[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
dxgi.raw_input_device[0].usUsage = HID_USAGE_GENERIC_MOUSE;
dxgi.raw_input_device[0].dwFlags = RIDEV_INPUTSINK;
dxgi.raw_input_device[0].hwndTarget = dxgi.h_wnd;
RegisterRawInputDevices(dxgi.raw_input_device, 1, sizeof(dxgi.raw_input_device[0]));
}
static void gfx_dxgi_set_fullscreen_changed_callback(void (*on_fullscreen_changed)(bool is_now_fullscreen)) {
@@ -572,19 +601,22 @@ static void gfx_dxgi_get_mouse_pos(int32_t* x, int32_t* y) {
}
static void gfx_dxgi_get_mouse_delta(int32_t* x, int32_t* y) {
if (dxgi.is_mouse_captured && dxgi.in_focus) {
POINT p;
GetCursorPos(&p);
ScreenToClient(dxgi.h_wnd, &p);
int32_t centerX, centerY;
centerX = dxgi.current_width / 2;
centerY = dxgi.current_height / 2;
*x = p.x - centerX;
*y = p.y - centerY;
SetCursorPos(dxgi.posX + centerX, dxgi.posY + centerY);
} else {
if (!dxgi.in_focus) {
*x = 0;
*y = 0;
} else if (dxgi.is_mouse_captured) {
*x = dxgi.raw_mouse_delta_buf.x;
*y = dxgi.raw_mouse_delta_buf.y;
dxgi.raw_mouse_delta_buf.x = 0;
dxgi.raw_mouse_delta_buf.y = 0;
} else {
static int32_t prev_x = 0, prev_y = 0;
int32_t current_x, current_y;
gfx_dxgi_get_mouse_pos(&current_x, &current_y);
*x = current_x - prev_x;
*y = current_y - prev_y;
prev_x = current_x;
prev_y = current_y;
}
}