summaryrefslogtreecommitdiff
path: root/platform/windows
diff options
context:
space:
mode:
authorMikko Mustonen <mustonen.mikko@outlook.com>2018-07-27 19:32:27 +0300
committerMikko Mustonen <mustonen.mikko@outlook.com>2018-07-30 23:51:51 +0300
commitdcbbc445dba8a07ef6d6f5029a6e18372fe3201f (patch)
tree3881226035230eceaa0010cb77b02279a2d50451 /platform/windows
parent3f01f40e91c962b68fd18c0ca00144dfb6aee65f (diff)
Relative motion based on raw input for Windows
Diffstat (limited to 'platform/windows')
-rw-r--r--platform/windows/os_windows.cpp70
-rw-r--r--platform/windows/os_windows.h2
2 files changed, 72 insertions, 0 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index bd76db8796..986970d452 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -387,7 +387,63 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
input->set_mouse_in_window(false);
} break;
+ case WM_INPUT: {
+ if (mouse_mode != MOUSE_MODE_CAPTURED || !use_raw_input) {
+ break;
+ }
+
+ UINT dwSize;
+
+ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
+ LPBYTE lpb = new BYTE[dwSize];
+ if (lpb == NULL) {
+ return 0;
+ }
+
+ if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
+ OutputDebugString(TEXT("GetRawInputData does not return correct size !\n"));
+
+ RAWINPUT *raw = (RAWINPUT *)lpb;
+
+ if (raw->header.dwType == RIM_TYPEMOUSE) {
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ mm->set_control(control_mem);
+ mm->set_shift(shift_mem);
+ mm->set_alt(alt_mem);
+
+ mm->set_button_mask(last_button_state);
+
+ Point2i c(video_mode.width / 2, video_mode.height / 2);
+
+ // centering just so it works as before
+ POINT pos = { (int)c.x, (int)c.y };
+ ClientToScreen(hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+
+ mm->set_position(c);
+ mm->set_global_position(c);
+ input->set_mouse_position(c);
+ mm->set_speed(Vector2(0, 0));
+
+ if (raw->data.mouse.usFlags == 0) {
+ mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY));
+
+ } else if (raw->data.mouse.usFlags == 1) {
+ mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY) - last_absolute_position);
+ last_absolute_position = Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY);
+ }
+
+ if (window_has_focus && main_loop)
+ input->parse_input_event(mm);
+ }
+ delete[] lpb;
+ } break;
case WM_MOUSEMOVE: {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
+ break;
+ }
if (input->is_emulating_mouse_from_touch()) {
// Universal translation enabled; ignore OS translation
@@ -1066,6 +1122,20 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
return ERR_UNAVAILABLE;
}
+ use_raw_input = true;
+
+ RAWINPUTDEVICE Rid[1];
+
+ Rid[0].usUsagePage = 0x01;
+ Rid[0].usUsage = 0x02;
+ Rid[0].dwFlags = 0;
+ Rid[0].hwndTarget = 0;
+
+ if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) {
+ //registration failed.
+ use_raw_input = false;
+ }
+
pre_fs_valid = true;
if (video_mode.fullscreen) {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 69c7d851b8..30bb2327ed 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -125,6 +125,8 @@ class OS_Windows : public OS {
bool force_quit;
bool window_has_focus;
uint32_t last_button_state;
+ Vector2 last_absolute_position;
+ bool use_raw_input;
HCURSOR cursors[CURSOR_MAX] = { NULL };
CursorShape cursor_shape;