diff options
author | Mikko Mustonen <mustonen.mikko@outlook.com> | 2018-07-27 19:32:27 +0300 |
---|---|---|
committer | Mikko Mustonen <mustonen.mikko@outlook.com> | 2018-07-30 23:51:51 +0300 |
commit | dcbbc445dba8a07ef6d6f5029a6e18372fe3201f (patch) | |
tree | 3881226035230eceaa0010cb77b02279a2d50451 /platform/windows | |
parent | 3f01f40e91c962b68fd18c0ca00144dfb6aee65f (diff) |
Relative motion based on raw input for Windows
Diffstat (limited to 'platform/windows')
-rw-r--r-- | platform/windows/os_windows.cpp | 70 | ||||
-rw-r--r-- | platform/windows/os_windows.h | 2 |
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; |