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

166 lines
3.4 KiB
C++
Raw Normal View History

2022-04-29 04:56:51 -04:00
#include <STDInclude.hpp>
namespace Components
{
Dvar::Var RawMouse::m_rawinput;
void RawMouse::IN_ClampMouseMove()
{
tagRECT rc;
tagPOINT curPos;
GetCursorPos(&curPos);
GetWindowRect(Game::g_wv->hWnd, &rc);
bool 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);
}
}
int RawMouse::mouseRawX = 0;
int RawMouse::mouseRawY = 0;
BOOL RawMouse::OnRawInput(LPARAM lParam, WPARAM)
2022-04-29 04:56:51 -04:00
{
UINT 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 Game::dvar_t* r_fullscreen = Game::Dvar_FindVar("r_fullscreen");
if (GetForegroundWindow() == Game::g_wv->hWnd)
{
if (r_fullscreen->current.enabled)
IN_ClampMouseMove();
static int oldX = 0, oldY = 0;
int dx = mouseRawX - oldX;
int dy = mouseRawY - oldY;
oldX = mouseRawX;
oldY = mouseRawY;
// Don't use raw input for menu?
// Because it needs to call the ScreenToClient
static tagPOINT curPos;
GetCursorPos(&curPos);
Game::s_wmv->oldPos = curPos;
ScreenToClient(Game::g_wv->hWnd, &curPos);
Game::g_wv->recenterMouse = Game::CL_MouseEvent(curPos.x, curPos.y, dx, dy);
if (Game::g_wv->recenterMouse)
{
Game::IN_RecenterMouse();
}
}
2022-04-29 04:56:51 -04:00
}
void RawMouse::IN_RawMouse_Init()
{
static bool init = false;
2022-04-29 04:56:51 -04:00
if (Game::g_wv->hWnd && !init && 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;
Rid[0].hwndTarget = Game::g_wv->hWnd;
2022-04-29 04:56:51 -04:00
RegisterRawInputDevices(Rid, ARRAYSIZE(Rid), sizeof(Rid[0]));
2022-04-29 04:56:51 -04:00
init = true;
}
}
2022-04-29 04:56:51 -04:00
void RawMouse::IN_Init()
{
Game::IN_Init();
IN_RawMouse_Init();
}
void RawMouse::IN_MouseMove()
{
if (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(0x475E9E, 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();
m_rawinput = Dvar::Register<bool>("m_rawinput", true, Game::dvar_flag::DVAR_ARCHIVE, "Use raw mouse input, use in_restart to take effect if not enabled.");
Window::OnWndMessage(WM_INPUT, RawMouse::OnRawInput);
2022-04-29 04:56:51 -04:00
Window::OnCreate(RawMouse::IN_RawMouse_Init);
2022-04-29 04:56:51 -04:00
}
}