158 lines
3.4 KiB
C++
158 lines
3.4 KiB
C++
#include <STDInclude.hpp>
|
|
|
|
namespace Components
|
|
{
|
|
Dvar::Var RawMouse::M_RawInput;
|
|
int RawMouse::MouseRawX = 0;
|
|
int RawMouse::MouseRawY = 0;
|
|
|
|
void RawMouse::IN_ClampMouseMove()
|
|
{
|
|
tagRECT rc;
|
|
tagPOINT curPos;
|
|
|
|
GetCursorPos(&curPos);
|
|
GetWindowRect(Window::GetWindow(), &rc);
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
MouseRawX = raw->data.mouse.lLastX;
|
|
MouseRawY = raw->data.mouse.lLastY;
|
|
}
|
|
else
|
|
{
|
|
MouseRawX += raw->data.mouse.lLastX;
|
|
MouseRawY += raw->data.mouse.lLastY;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void RawMouse::IN_RawMouseMove()
|
|
{
|
|
static auto r_fullscreen = Dvar::Var("r_fullscreen");
|
|
|
|
if (GetForegroundWindow() == Window::GetWindow())
|
|
{
|
|
if (r_fullscreen.get<bool>())
|
|
IN_ClampMouseMove();
|
|
|
|
static auto oldX = 0, oldY = 0;
|
|
|
|
auto dx = MouseRawX - oldX;
|
|
auto dy = MouseRawY - oldY;
|
|
|
|
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;
|
|
ScreenToClient(Window::GetWindow(), &curPos);
|
|
|
|
Gamepad::OnMouseMove(curPos.x, curPos.y, dx, dy);
|
|
auto recenterMouse = Game::CL_MouseEvent(curPos.x, curPos.y, dx, dy);
|
|
|
|
if (recenterMouse)
|
|
{
|
|
Game::IN_RecenterMouse();
|
|
}
|
|
}
|
|
}
|
|
|
|
void RawMouse::IN_RawMouse_Init()
|
|
{
|
|
if (Window::GetWindow() && RawMouse::M_RawInput.get<bool>())
|
|
{
|
|
Logger::Debug("Raw Mouse Init");
|
|
|
|
RAWINPUTDEVICE Rid[1];
|
|
Rid[0].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
|
|
Rid[0].usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE
|
|
Rid[0].dwFlags = RIDEV_INPUTSINK;
|
|
Rid[0].hwndTarget = Window::GetWindow();
|
|
|
|
RegisterRawInputDevices(Rid, ARRAYSIZE(Rid), sizeof(Rid[0]));
|
|
}
|
|
}
|
|
|
|
void RawMouse::IN_Init()
|
|
{
|
|
Game::IN_Init();
|
|
IN_RawMouse_Init();
|
|
}
|
|
|
|
void RawMouse::IN_MouseMove()
|
|
{
|
|
if (RawMouse::M_RawInput.get<bool>())
|
|
{
|
|
IN_RawMouseMove();
|
|
}
|
|
else
|
|
{
|
|
Game::IN_MouseMove();
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
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.");
|
|
|
|
Window::OnWndMessage(WM_INPUT, RawMouse::OnRawInput);
|
|
Window::OnCreate(RawMouse::IN_RawMouse_Init);
|
|
}
|
|
}
|