2022-04-29 16:56:51 +08:00
# include <STDInclude.hpp>
2022-12-26 13:07:24 +01:00
# include "Gamepad.hpp"
# include "RawMouse.hpp"
2022-04-29 16:56:51 +08:00
namespace Components
{
2022-04-30 02:02:27 +08:00
Dvar : : Var RawMouse : : M_RawInput ;
int RawMouse : : MouseRawX = 0 ;
int RawMouse : : MouseRawY = 0 ;
2022-04-29 22:26:14 +08:00
void RawMouse : : IN_ClampMouseMove ( )
{
tagRECT rc ;
tagPOINT curPos ;
GetCursorPos ( & curPos ) ;
2022-05-03 10:32:15 +08:00
GetWindowRect ( Window : : GetWindow ( ) , & rc ) ;
2022-04-30 01:42:47 +08:00
auto isClamped = false ;
2022-04-29 22:26:14 +08:00
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 16:56:51 +08:00
{
2022-04-30 01:42:47 +08:00
auto dwSize = sizeof ( RAWINPUT ) ;
2022-04-29 22:26:14 +08:00
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-30 02:02:27 +08:00
MouseRawX = raw - > data . mouse . lLastX ;
MouseRawY = raw - > data . mouse . lLastY ;
2022-04-29 22:26:14 +08:00
}
else
{
2022-04-30 02:02:27 +08:00
MouseRawX + = raw - > data . mouse . lLastX ;
MouseRawY + = raw - > data . mouse . lLastY ;
2022-04-29 22:26:14 +08:00
}
}
return TRUE ;
}
void RawMouse : : IN_RawMouseMove ( )
{
2022-04-30 01:42:47 +08:00
static auto r_fullscreen = Dvar : : Var ( " r_fullscreen " ) ;
2022-04-29 22:26:14 +08:00
2022-05-03 10:32:15 +08:00
if ( GetForegroundWindow ( ) = = Window : : GetWindow ( ) )
2022-04-29 22:26:14 +08:00
{
2022-04-30 01:42:47 +08:00
if ( r_fullscreen . get < bool > ( ) )
2022-12-26 13:07:24 +01:00
{
2022-04-29 22:26:14 +08:00
IN_ClampMouseMove ( ) ;
2022-12-26 13:07:24 +01:00
}
2022-04-29 22:26:14 +08:00
2022-04-30 01:42:47 +08:00
static auto oldX = 0 , oldY = 0 ;
2022-04-29 22:26:14 +08:00
2022-04-30 02:02:27 +08:00
auto dx = MouseRawX - oldX ;
auto dy = MouseRawY - oldY ;
2022-04-29 22:26:14 +08:00
2022-04-30 02:02:27 +08:00
oldX = MouseRawX ;
oldY = MouseRawY ;
2022-04-29 22:26:14 +08:00
// Don't use raw input for menu?
// Because it needs to call the ScreenToClient
2022-05-03 10:11:02 +08:00
tagPOINT curPos ;
2022-04-29 22:26:14 +08:00
GetCursorPos ( & curPos ) ;
Game : : s_wmv - > oldPos = curPos ;
2022-05-03 10:32:15 +08:00
ScreenToClient ( Window : : GetWindow ( ) , & curPos ) ;
2022-04-29 22:26:14 +08:00
2022-05-04 20:15:17 +02:00
Gamepad : : OnMouseMove ( curPos . x , curPos . y , dx , dy ) ;
2022-05-03 10:32:15 +08:00
auto recenterMouse = Game : : CL_MouseEvent ( curPos . x , curPos . y , dx , dy ) ;
2022-04-29 22:26:14 +08:00
2022-05-03 10:32:15 +08:00
if ( recenterMouse )
2022-04-29 22:26:14 +08:00
{
Game : : IN_RecenterMouse ( ) ;
}
}
2022-04-29 16:56:51 +08:00
}
2022-04-29 22:26:14 +08:00
void RawMouse : : IN_RawMouse_Init ( )
{
2022-12-26 13:07:24 +01:00
if ( Window : : GetWindow ( ) & & M_RawInput . get < bool > ( ) )
2022-04-29 22:26:14 +08:00
{
2022-06-12 23:07:53 +02:00
Logger : : Debug ( " Raw Mouse Init " ) ;
2022-04-29 16:56:51 +08:00
2022-04-29 22:26:14 +08: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-03 10:32:15 +08:00
Rid [ 0 ] . hwndTarget = Window : : GetWindow ( ) ;
2022-04-29 16:56:51 +08:00
2022-04-29 22:26:14 +08:00
RegisterRawInputDevices ( Rid , ARRAYSIZE ( Rid ) , sizeof ( Rid [ 0 ] ) ) ;
}
}
2022-04-29 16:56:51 +08:00
2022-04-29 22:26:14 +08:00
void RawMouse : : IN_Init ( )
{
Game : : IN_Init ( ) ;
IN_RawMouse_Init ( ) ;
}
void RawMouse : : IN_MouseMove ( )
{
2022-12-26 13:07:24 +01:00
if ( M_RawInput . get < bool > ( ) )
2022-04-29 22:26:14 +08:00
{
IN_RawMouseMove ( ) ;
}
else
{
Game : : IN_MouseMove ( ) ;
}
}
2022-04-29 16:56:51 +08:00
RawMouse : : RawMouse ( )
{
2022-12-26 13:07:24 +01:00
Utils : : Hook ( 0x475E65 , IN_MouseMove , HOOK_JUMP ) . install ( ) - > quick ( ) ;
Utils : : Hook ( 0x475E8D , IN_MouseMove , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2022-04-29 22:26:14 +08:00
2022-12-26 13:07:24 +01:00
Utils : : Hook ( 0x467C03 , IN_Init , HOOK_CALL ) . install ( ) - > quick ( ) ;
Utils : : Hook ( 0x64D095 , IN_Init , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2022-04-29 22:26:14 +08:00
2022-12-26 13:07:24 +01:00
M_RawInput = Dvar : : Register < bool > ( " m_rawinput " , true , Game : : DVAR_ARCHIVE , " Use raw mouse input, Improves accuracy & has better support for higher polling rates " ) ;
2022-04-29 22:26:14 +08:00
2022-12-26 13:07:24 +01:00
Window : : OnWndMessage ( WM_INPUT , OnRawInput ) ;
Window : : OnCreate ( IN_RawMouse_Init ) ;
2022-04-29 16:56:51 +08:00
}
}