mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
reduced win32 raw mouse input latency and added cl_drawMouseLag
This commit is contained in:
parent
f9d4056e41
commit
e4062a6c90
10 changed files with 78 additions and 42 deletions
|
@ -56,6 +56,8 @@ fix: if requesting a resolution too high for the display, the image would be off
|
|||
|
||||
chg: updated mouse input for better grab (de-)activation and fixed window dragging not working
|
||||
|
||||
chg: reduced raw mouse input latency and added cl_drawMouseLag
|
||||
|
||||
|
||||
Linux:
|
||||
|
||||
|
|
|
@ -295,6 +295,7 @@ void CL_MouseEvent( int dx, int dy, int time )
|
|||
VM_Call( cgvm, CG_MOUSE_EVENT, dx, dy );
|
||||
cl.mouseDx[cl.mouseIndex] += dx;
|
||||
cl.mouseDy[cl.mouseIndex] += dy;
|
||||
cl.mouseTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,6 +455,7 @@ static usercmd_t CL_CreateCmd()
|
|||
|
||||
// get basic movement from mouse
|
||||
CL_MouseMove( &cmd );
|
||||
cl.userCmdTime = Sys_Milliseconds();
|
||||
|
||||
// get basic movement from joystick
|
||||
CL_JoystickMove( &cmd );
|
||||
|
@ -865,6 +867,8 @@ void CL_InitInput()
|
|||
Cmd_AddCommand ("+mlook", IN_MLookDown);
|
||||
Cmd_AddCommand ("-mlook", IN_MLookUp);
|
||||
|
||||
Cvar_Get( "cl_drawMouseLag", "0", 0 );
|
||||
|
||||
m_speed = Cvar_Get( "m_speed", "8", CVAR_ARCHIVE );
|
||||
m_accel = Cvar_Get( "m_accel", "0", CVAR_ARCHIVE );
|
||||
m_limit = Cvar_Get( "m_limit", "0", CVAR_ARCHIVE );
|
||||
|
|
|
@ -215,6 +215,39 @@ void SCR_Init()
|
|||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static void SCR_DrawStats( float x, float y, float w, float h, int value )
|
||||
{
|
||||
if ( value < 0 || value >= 100 )
|
||||
SCR_DrawString( x, y, w, h, " ?", qfalse );
|
||||
else
|
||||
SCR_DrawString( x, y, w, h, va( "%3d", value ), qfalse );
|
||||
}
|
||||
|
||||
|
||||
static void SCR_DrawInputStats( int stats, float x, float y, float w, float h, const char* header )
|
||||
{
|
||||
SCR_DrawString( x, y, w, h, header, qfalse );
|
||||
x += 5.0f * w;
|
||||
SCR_DrawStats( x, y, w, h, stats );
|
||||
}
|
||||
|
||||
|
||||
static void SCR_DrawMouseInputLatencies()
|
||||
{
|
||||
if ( !cls.cgameStarted || cls.state != CA_ACTIVE ||
|
||||
!Cvar_VariableIntegerValue( "cl_drawMouseLag" ) )
|
||||
return;
|
||||
|
||||
float x = 10, y = 10, w = 16, h = 24;
|
||||
SCR_AdjustFrom640( &x, &y, 0, 0 );
|
||||
SCR_DrawString( x, y, w, h, "mouse lag [ms]", qfalse );
|
||||
y += 30;
|
||||
SCR_DrawInputStats( cl.userCmdTime - cl.mouseTime, x, y, w, h, "netw" );
|
||||
y += 30;
|
||||
SCR_DrawInputStats( re_cameraMatrixTime - cl.mouseTime, x, y, w, h, "draw" );
|
||||
}
|
||||
|
||||
|
||||
// this will be called twice if rendering in stereo mode
|
||||
|
||||
static void SCR_DrawScreenField( stereoFrame_t stereoFrame )
|
||||
|
@ -283,6 +316,8 @@ static void SCR_DrawScreenField( stereoFrame_t stereoFrame )
|
|||
VM_Call( uivm, UI_REFRESH, cls.realtime );
|
||||
}
|
||||
|
||||
SCR_DrawMouseInputLatencies();
|
||||
|
||||
// console draws next
|
||||
Con_DrawConsole();
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ typedef struct {
|
|||
|
||||
int mouseDx[2], mouseDy[2]; // added to by mouse events
|
||||
int mouseIndex;
|
||||
int mouseTime; // when the last mouse input was sampled, for cl_drawMouseLag
|
||||
int joystickAxis[MAX_JOYSTICK_AXIS]; // set by joystick events
|
||||
|
||||
// cgame communicates a few values to the client system
|
||||
|
@ -116,6 +117,7 @@ typedef struct {
|
|||
usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds
|
||||
int cmdNumber; // incremented each frame, because multiple
|
||||
// frames may need to be packed into a single packet
|
||||
int userCmdTime; // when the last usercmd_t was generated, for cl_drawMouseLag
|
||||
|
||||
outPacket_t outPackets[PACKET_BACKUP]; // information about each packet we have sent out
|
||||
|
||||
|
|
|
@ -708,7 +708,7 @@ int Com_HashKey(char *string, int maxlen);
|
|||
int Com_Filter( const char* filter, const char* name );
|
||||
int Com_FilterPath( const char* filter, const char* name );
|
||||
int Com_RealTime(qtime_t *qtime);
|
||||
qbool Com_SafeMode();
|
||||
qbool Com_SafeMode();
|
||||
|
||||
void Com_StartupVariable( const char *match );
|
||||
// checks for and removes command line "+set var arg" constructs
|
||||
|
|
|
@ -1272,6 +1272,9 @@ static void R_DebugGraphics()
|
|||
}
|
||||
|
||||
|
||||
int re_cameraMatrixTime;
|
||||
|
||||
|
||||
// a view may be either the actual camera view, or a mirror / remote location
|
||||
|
||||
void R_RenderView( const viewParms_t* parms )
|
||||
|
@ -1289,6 +1292,7 @@ void R_RenderView( const viewParms_t* parms )
|
|||
int firstLitSurf = tr.refdef.numLitSurfs;
|
||||
|
||||
// set viewParms.world
|
||||
re_cameraMatrixTime = Sys_Milliseconds();
|
||||
R_RotateForViewer();
|
||||
|
||||
R_SetupFrustum();
|
||||
|
|
|
@ -158,8 +158,6 @@ typedef struct {
|
|||
qbool (*inPVS)( const vec3_t p1, const vec3_t p2 );
|
||||
|
||||
void (*TakeVideoFrame)( int h, int w, byte* captureBuffer, byte *encodeBuffer, qbool motionJpeg );
|
||||
// drakkar
|
||||
void (*WindowFocus)(qbool focus);
|
||||
} refexport_t;
|
||||
|
||||
//
|
||||
|
@ -223,4 +221,8 @@ typedef struct {
|
|||
// if the module can't init to a valid rendering state, it will return NULL
|
||||
const refexport_t* GetRefAPI( const refimport_t* rimp );
|
||||
|
||||
|
||||
extern int re_cameraMatrixTime; // when the final model-view matrix is computed, for cl_drawMouseLag
|
||||
|
||||
|
||||
#endif // __TR_PUBLIC_H
|
||||
|
|
|
@ -29,7 +29,6 @@ struct Mouse {
|
|||
virtual qbool Activate( qbool active );
|
||||
virtual void OnWindowMoved() {}
|
||||
virtual void Shutdown() {}
|
||||
virtual void Read( int* mx, int* my ) = 0;
|
||||
virtual qbool ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam ) { return qfalse; } // returns true if the event was handled
|
||||
|
||||
Mouse() : active(qfalse), wheel(0) {}
|
||||
|
@ -78,10 +77,7 @@ void Mouse::UpdateWheel( int delta )
|
|||
struct rawmouse_t : public Mouse {
|
||||
virtual qbool Init();
|
||||
virtual qbool Activate( qbool active );
|
||||
virtual void Read( int* mx, int* my );
|
||||
virtual qbool ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
int x, y;
|
||||
};
|
||||
|
||||
static rawmouse_t rawmouse;
|
||||
|
@ -109,14 +105,6 @@ qbool rawmouse_t::Activate( qbool active )
|
|||
}
|
||||
|
||||
|
||||
void rawmouse_t::Read( int* mx, int* my )
|
||||
{
|
||||
*mx = rawmouse.x;
|
||||
*my = rawmouse.y;
|
||||
rawmouse.x = rawmouse.y = 0;
|
||||
}
|
||||
|
||||
|
||||
// MSDN says you have to always let DefWindowProc run for WM_INPUT
|
||||
// regardless of whether you process the message or not, so ALWAYS return false here
|
||||
|
||||
|
@ -138,8 +126,10 @@ qbool rawmouse_t::ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam )
|
|||
if ( (ri.header.dwType != RIM_TYPEMOUSE) || (ri.data.mouse.usFlags != MOUSE_MOVE_RELATIVE) )
|
||||
return qfalse;
|
||||
|
||||
rawmouse.x += ri.data.mouse.lLastX;
|
||||
rawmouse.y += ri.data.mouse.lLastY;
|
||||
const int dx = (int)ri.data.mouse.lLastX;
|
||||
const int dy = (int)ri.data.mouse.lLastY;
|
||||
if (dx != 0 || dy != 0)
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_MOUSE, dx, dy, 0, NULL );
|
||||
|
||||
if (!ri.data.mouse.usButtonFlags) // no button or wheel transitions
|
||||
return qfalse;
|
||||
|
@ -173,12 +163,12 @@ qbool rawmouse_t::ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam )
|
|||
struct winmouse_t : public Mouse {
|
||||
virtual qbool Activate( qbool active );
|
||||
virtual void OnWindowMoved();
|
||||
virtual void Read( int* mx, int* my );
|
||||
virtual qbool ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
void UpdateWindowCenter();
|
||||
|
||||
int window_center_x, window_center_y;
|
||||
qbool active;
|
||||
};
|
||||
|
||||
static winmouse_t winmouse;
|
||||
|
@ -197,9 +187,11 @@ void winmouse_t::UpdateWindowCenter()
|
|||
}
|
||||
|
||||
|
||||
qbool winmouse_t::Activate(qbool active)
|
||||
qbool winmouse_t::Activate( qbool _active )
|
||||
{
|
||||
if (!active)
|
||||
active = _active;
|
||||
|
||||
if (!_active)
|
||||
return qtrue;
|
||||
|
||||
UpdateWindowCenter();
|
||||
|
@ -215,21 +207,23 @@ void winmouse_t::OnWindowMoved()
|
|||
}
|
||||
|
||||
|
||||
void winmouse_t::Read( int* mx, int* my )
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos( &p );
|
||||
*mx = p.x - window_center_x;
|
||||
*my = p.y - window_center_y;
|
||||
SetCursorPos( window_center_x, window_center_y );
|
||||
}
|
||||
|
||||
|
||||
qbool winmouse_t::ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if ( !active )
|
||||
return qfalse;
|
||||
|
||||
#define QUEUE_WM_BUTTON( qbutton, mask ) \
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, qbutton, (wParam & mask), 0, NULL );
|
||||
|
||||
POINT p;
|
||||
GetCursorPos( &p );
|
||||
const int dx = p.x - window_center_x;
|
||||
const int dy = p.y - window_center_y;
|
||||
if (dx != 0 || dy != 0) {
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_MOUSE, dx, dy, 0, NULL );
|
||||
SetCursorPos( window_center_x, window_center_y );
|
||||
}
|
||||
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
|
@ -408,14 +402,6 @@ void IN_Frame()
|
|||
}
|
||||
|
||||
IN_Activate( qtrue );
|
||||
|
||||
int mx, my;
|
||||
mouse->Read( &mx, &my );
|
||||
|
||||
if ( !mx && !my )
|
||||
return;
|
||||
|
||||
Sys_QueEvent( 0, SE_MOUSE, mx, my, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ typedef struct
|
|||
qbool isMinimized;
|
||||
|
||||
// when we get a windows message, we store the time off
|
||||
// so keyboard processing can know the exact time of an event
|
||||
unsigned sysMsgTime;
|
||||
// using Sys_Milliseconds
|
||||
int sysMsgTime;
|
||||
|
||||
RECT monitorRects[MAX_MONITOR_COUNT];
|
||||
HMONITOR hMonitors[MAX_MONITOR_COUNT];
|
||||
|
|
|
@ -35,7 +35,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include <VersionHelpers.h>
|
||||
|
||||
|
||||
WinVars_t g_wv;
|
||||
WinVars_t g_wv;
|
||||
|
||||
|
||||
static qbool win_timePeriodActive = qfalse;
|
||||
|
@ -471,7 +471,8 @@ sysEvent_t Sys_GetEvent()
|
|||
}
|
||||
|
||||
// save the msg time, because wndprocs don't have access to the timestamp
|
||||
g_wv.sysMsgTime = msg.time;
|
||||
// msg.time seems to use values from GetTickCount
|
||||
g_wv.sysMsgTime = Sys_Milliseconds();
|
||||
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage( &msg );
|
||||
|
|
Loading…
Reference in a new issue