iw4x-client/src/Components/Modules/RawMouse.cpp

162 lines
3.4 KiB
C++
Raw Normal View History

2022-04-29 04:56:51 -04:00
#include <STDInclude.hpp>
namespace Components
{
2022-04-29 14:02:27 -04:00
Dvar::Var RawMouse::M_RawInput;
int RawMouse::MouseRawX = 0;
int RawMouse::MouseRawY = 0;
void RawMouse::IN_ClampMouseMove()
{
tagRECT rc;
tagPOINT curPos;
GetCursorPos(&curPos);
2022-05-02 22:32:15 -04:00
GetWindowRect(Window::GetWindow(), &rc);
2022-04-29 13:42:47 -04:00
auto isClamped = false;
if (curPos.x >= rc.left)
{
if (curPos.x >= rc.right)
{
curPos.x = rc.right - 1;
isClamped = true;
}
}
else
{
curPos.x = rc.left;
isClamped = true;
}
if (curPos.y >= rc.top)
{
if (curPos.y >= rc.bottom)
{
curPos.y = rc.bottom - 1;
isClamped = true;
}
}
else
{
curPos.y = rc.top;
isClamped = true;
}
if (isClamped)
{
SetCursorPos(curPos.x, curPos.y);
}
}
BOOL RawMouse::OnRawInput(LPARAM lParam, WPARAM)
2022-04-29 04:56:51 -04:00
{
2022-04-29 13:42:47 -04:00
auto dwSize = sizeof(RAWINPUT);
static BYTE lpb[sizeof(RAWINPUT)];
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
auto* raw = reinterpret_cast<RAWINPUT*>(lpb);
if (raw->header.dwType == RIM_TYPEMOUSE)
{
// Is there's really absolute mouse on earth?
if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
{
2022-04-29 14:02:27 -04:00
MouseRawX = raw->data.mouse.lLastX;
MouseRawY = raw->data.mouse.lLastY;
}
else
{
2022-04-29 14:02:27 -04:00
MouseRawX += raw->data.mouse.lLastX;
MouseRawY += raw->data.mouse.lLastY;
}
}
return TRUE;
}
void RawMouse::IN_RawMouseMove()
{
2022-04-29 13:42:47 -04:00
static auto r_fullscreen = Dvar::Var("r_fullscreen");
2022-05-02 22:32:15 -04:00
if (GetForegroundWindow() == Window::GetWindow())
{
2022-04-29 13:42:47 -04:00
if (r_fullscreen.get<bool>())
IN_ClampMouseMove();
2022-04-29 13:42:47 -04:00
static auto oldX = 0, oldY = 0;
2022-04-29 14:02:27 -04:00
auto dx = MouseRawX - oldX;
auto dy = MouseRawY - oldY;
2022-04-29 14:02:27 -04:00
oldX = MouseRawX;
oldY = MouseRawY;
// Don't use raw input for menu?
// Because it needs to call the ScreenToClient
tagPOINT curPos;
GetCursorPos(&curPos);
Game::s_wmv->oldPos = curPos;
2022-05-02 22:32:15 -04:00
ScreenToClient(Window::GetWindow(), &curPos);
2022-05-02 22:32:15 -04:00
auto recenterMouse = Game::CL_MouseEvent(curPos.x, curPos.y, dx, dy);
2022-05-02 22:32:15 -04:00
if (recenterMouse)
{
Game::IN_RecenterMouse();
}
}
2022-04-29 04:56:51 -04:00
}
void RawMouse::IN_RawMouse_Init()
{
2022-05-02 22:32:15 -04:00
if (Window::GetWindow() && RawMouse::M_RawInput.get<bool>())
{
#ifdef DEBUG
Logger::Print("Raw Mouse Init.\n");
#endif
2022-04-29 04:56:51 -04:00
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
Rid[0].usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE
Rid[0].dwFlags = RIDEV_INPUTSINK;
2022-05-02 22:32:15 -04:00
Rid[0].hwndTarget = Window::GetWindow();
2022-04-29 04:56:51 -04:00
RegisterRawInputDevices(Rid, ARRAYSIZE(Rid), sizeof(Rid[0]));
}
}
2022-04-29 04:56:51 -04:00
void RawMouse::IN_Init()
{
Game::IN_Init();
IN_RawMouse_Init();
}
void RawMouse::IN_MouseMove()
{
2022-04-29 14:02:27 -04:00
if (RawMouse::M_RawInput.get<bool>())
{
IN_RawMouseMove();
}
else
{
Game::IN_MouseMove();
}
}
2022-04-29 04:56:51 -04:00
RawMouse::RawMouse()
{
Utils::Hook(0x475E65, RawMouse::IN_MouseMove, HOOK_JUMP).install()->quick();
Utils::Hook(0x475E8D, RawMouse::IN_MouseMove, HOOK_JUMP).install()->quick();
Utils::Hook(0x467C03, RawMouse::IN_Init, HOOK_CALL).install()->quick();
Utils::Hook(0x64D095, RawMouse::IN_Init, HOOK_JUMP).install()->quick();
2022-04-29 13:42:47 -04:00
Dvar::OnInit([]()
{
RawMouse::M_RawInput = Dvar::Register<bool>("m_rawinput", true, Game::dvar_flag::DVAR_ARCHIVE, "Use raw mouse input, Improves accuracy & has better support for higher polling rates. Use in_restart to take effect if not enabled.");
2022-04-29 13:42:47 -04:00
});
Window::OnWndMessage(WM_INPUT, RawMouse::OnRawInput);
Window::OnCreate(RawMouse::IN_RawMouse_Init);
2022-04-29 04:56:51 -04:00
}
}