Fixed: #972 Do not reset mouse position to implement FreeLook (IDriver::InterfaceVersion = 0x66)

This commit is contained in:
rti 2010-06-11 15:04:10 +02:00
parent d74bf9a642
commit 610a04982f
16 changed files with 260 additions and 129 deletions

View file

@ -413,6 +413,12 @@ public:
//
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager();
/**
* wrapper for IEventEmitter::emulateMouseRawMode()
*/
virtual void emulateMouseRawMode(bool enable);
virtual uint getDoubleClickDelay(bool hardwareMouse);
/// show cursor if b is true, or hide it if b is false

View file

@ -571,6 +571,11 @@ public:
*/
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0;
/**
* wrapper for IEventEmitter::emulateMouseRawMode()
*/
virtual void emulateMouseRawMode(bool enable) = 0;
// get delay used for mouse double click
virtual uint getDoubleClickDelay(bool hardwareMouse) = 0;

View file

@ -49,7 +49,19 @@ public:
* \param server
*/
virtual void submitEvents(CEventServer & server, bool allWindows) = 0;
/**
* Instruct the event emitter to send CGDMouseMove instead of CEventMouseMove.
*
* On windows, the mouse device can be set into RawMode. Using this mode,
* CGDMouseMove events (only containing the raw movement delta) are emitted
* instead of the normal CEventMouseMove events (containing the mouse position).
*
* On Linux and Mac OS X, there is no MouseDevice implementation, all the
* events are created by the event emitter. So the event emitter has to
* emulate the mouse raw mode.
*/
virtual void emulateMouseRawMode(bool) = 0;
};

View file

@ -99,6 +99,9 @@ public:
* Return true if the message must be trapped, false if DefWindowProc must be called afterwards
*/
bool processMessage (HWND hWnd, uint32 msg, WPARAM wParam, LPARAM lParam, CEventServer *server=NULL);
void emulateMouseRawMode(bool enable);
private:
CWinEventServer _InternalServer;
HWND _HWnd;

View file

@ -34,7 +34,7 @@ namespace NL3D
{
// ***************************************************************************
const uint32 IDriver::InterfaceVersion = 0x65; // Added nlWindow patch.
const uint32 IDriver::InterfaceVersion = 0x66; // added IEventEmitter::emulateMouseRawMode(bool)
// ***************************************************************************
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )

View file

@ -89,6 +89,9 @@ void release();
void submitEvents(NLMISC::CEventServer& server,
bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter);
/// mac specific stuff while calling CCocoaEventEmitter::emulateMouseRawMode()
void emulateMouseRawMode(bool enable);
}}
#endif

View file

@ -19,6 +19,7 @@
#include "cocoa_adapter.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#include "nel/3d/driver.h"
#include "cocoa_event_emitter.h"
@ -33,11 +34,13 @@
namespace NL3D { namespace MAC {
static NSApplication* g_app = nil;
static NSAutoreleasePool* g_pool = nil;
static CocoaWindow* g_window = nil;
static CocoaOpenGLView* g_glview = nil;
static NSOpenGLContext* g_glctx = nil;
static NSApplication* g_app = nil;
static NSAutoreleasePool* g_pool = nil;
static CocoaWindow* g_window = nil;
static CocoaOpenGLView* g_glview = nil;
static NSOpenGLContext* g_glctx = nil;
static bool g_emulateRawMode = false;
#define UGLY_BACKBUFFER_SIZE_WORKAROUND
@ -77,13 +80,17 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
/*
TODO use show and resizable flags
*/
/*
TODO add menu, on quit send EventDestroyWindowId
*/
// create a cocoa window with the size provided by the mode parameter
g_window = [[CocoaWindow alloc]
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
styleMask:NSTitledWindowMask | NSResizableWindowMask |
NSClosableWindowMask | NSMiniaturizableWindowMask
backing:NSBackingStoreBuffered
styleMask:NSTitledWindowMask | NSResizableWindowMask |
NSClosableWindowMask | NSMiniaturizableWindowMask
backing:NSBackingStoreBuffered
defer:NO];
if(!g_window)
@ -130,7 +137,7 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
// enable mouse move events, NeL wants them
[g_window setAcceptsMouseMovedEvents:YES];
// there are no overlapping subview, so we can use the magical optimization!
// there are no overlapping subviews, so we can use the magical optimization!
[g_window useOptimizedDrawing:YES];
// create a opengl context for the view
@ -139,7 +146,7 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
if(!g_glctx)
nlerror("cannot create context");
// make the views opengl context the currrent one
// make the view's opengl context the currrent one
[g_glctx makeCurrentContext];
// put the window to the front and make it the key window
@ -178,9 +185,6 @@ bool setMode(const GfxMode& mode)
// leave fullscreen mode, enter windowed mode
if(mode.Windowed && [g_glview isInFullScreenMode])
{
// pull the view back from fullscreen restoring window options
[g_glview exitFullScreenModeWithOptions:nil];
// disable manual setting of back buffer size, cocoa handles this
// automatically as soon as the view gets resized
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
@ -189,6 +193,9 @@ bool setMode(const GfxMode& mode)
if(error != kCGLNoError)
nlerror("cannot disable kCGLCESurfaceBackingSize (%s)",
CGLErrorString(error));
// pull the view back from fullscreen restoring window options
[g_glview exitFullScreenModeWithOptions:nil];
}
// enter fullscreen, leave windowed mode
@ -205,20 +212,21 @@ bool setMode(const GfxMode& mode)
// put the view in fullscreen mode, hiding the dock but enabling the menubar
// to pop up if the mouse hits the top screen border.
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
/*
TODO check if simply using NSView enterFullScreenMode is a good idea.
the context can be set to full screen as well, performance differences?
*/
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:
NSApplicationPresentationHideDock |
NSApplicationPresentationAutoHideMenuBar],
NSFullScreenModeApplicationPresentationOptions, nil]];
/*
TODO check if simply using NSView enterFullScreenMode is a good idea.
the context can be set to full screen as well, performance differences?
*/
}
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
// due to the back buffer size reading problem, just store the size
// due to a back buffer size reading problem, just store the size
g_bufferSize[0] = mode.Width;
g_bufferSize[1] = mode.Height;
#endif
@ -240,13 +248,18 @@ void getWindowSize(uint32 &width, uint32 &height)
// not the one from the window.
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
// in fullscreen mode
if([g_glview isInFullScreenMode])
{
// use the size stored in setMode()
width = g_bufferSize[0];
height = g_bufferSize[1];
}
// in windowed mode
else
{
// use the size of the view
NSRect rect = [g_glview frame];
width = rect.size.width;
height = rect.size.height;
@ -264,7 +277,7 @@ void getWindowSize(uint32 &width, uint32 &height)
nlerror("cannot check kCGLCESurfaceBackingSize state (%s)",
CGLErrorString(error));
// if in fullscreen mode
// if in fullscreen mode (only in fullscreen back buffer sizing is used)
if(surfaceBackingSizeSet)
{
/*
@ -341,20 +354,13 @@ void swapBuffers()
void setCapture(bool b)
{
/*
TODO implement capture cursor, no need to fake using pull back to 0.5 / 0.5
set a flag and then act accordingly in event loop?
// no screen bounds...
void CGGetLastMouseDelta(CGMouseDelta* deltaX, CGMouseDelta* deltaY);
*/
nlwarning("not implemented");
// no need to capture
}
void showCursor(bool b)
{
// Mac OS manages a show/hide counter for the cursor, so hiding the cursor
// twice requires two calls to show to make the cursor visible again.
// twice requires two calls to "show" to make the cursor visible again.
// Since other platforms seem to not do this, the functionality is masked here
// by only calling hide if the cursor is visible and only calling show if
// the cursor was hidden.
@ -379,6 +385,10 @@ void showCursor(bool b)
void setMousePos(float x, float y)
{
/*
TODO FIXME for windows placed on non primary monitor
*/
// CG wants absolute coordinates related to screen top left
CGFloat fromScreenLeft = 0.0;
CGFloat fromScreenTop = 0.0;
@ -571,7 +581,7 @@ NLMISC::TKeyButton modifierFlagsToNelKeyButton(unsigned int modifierFlags)
bool isTextKeyEvent(NSEvent* event)
{
// if there are no characters provided with this event, is is not a text event
// if there are no characters provided with this event, it is not a text event
if([[event characters] length] == 0)
return false;
@ -621,6 +631,11 @@ bool isTextKeyEvent(NSEvent* event)
return false;
}
void emulateMouseRawMode(bool enable)
{
g_emulateRawMode = enable;
}
void submitEvents(NLMISC::CEventServer& server,
bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter)
{
@ -641,8 +656,6 @@ void submitEvents(NLMISC::CEventServer& server,
if(!event)
break;
// NSLog(@"%@", event);
// get the views size
NSRect rect = [g_glview frame];
@ -651,7 +664,7 @@ void submitEvents(NLMISC::CEventServer& server,
float mouseX = event.locationInWindow.x / (float)rect.size.width;
float mouseY = event.locationInWindow.y / (float)rect.size.height;
// if the mouse event was placed on the window's titlebar, ignore it
// if the mouse event was placed on the window's titlebar, don't tell NeL :)
if(mouseY > 1.0 && event.type != NSKeyDown && event.type != NSKeyUp)
{
[g_app sendEvent:event];
@ -662,58 +675,106 @@ void submitEvents(NLMISC::CEventServer& server,
switch(event.type)
{
case NSLeftMouseDown:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseDown(
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
}
break;
case NSLeftMouseUp:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseUp(
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
break;
break;
}
case NSRightMouseDown:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseDown(
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
break;
break;
}
case NSRightMouseUp:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseUp(
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
break;
break;
}
case NSMouseMoved:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseMove(
mouseX, mouseY, (NLMISC::TMouseButton)0 /* modifiers */, eventEmitter));
break;
case NSLeftMouseDragged:
/*
TODO modifiers with mouse events
*/
// nldebug("mouse left drag %f %f", mouseX, mouseY);
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
if(g_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove(
eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY);
server.postEvent(new NLMISC::CEventMouseMove(
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
break;
case NSRightMouseDragged:break;
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
(NLMISC::TMouseButton)0 /* modifiers */, eventEmitter);
server.postEvent(nelEvent);
break;
}
case NSLeftMouseDragged:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseMove(
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
if(g_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove(
eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
NLMISC::leftButton /* modifiers */, eventEmitter);
server.postEvent(nelEvent);
break;
}
case NSRightMouseDragged:
{
/*
TODO modifiers with mouse events
*/
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
if(g_emulateRawMode)
nelEvent = new NLMISC::CGDMouseMove(
eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY);
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
NLMISC::rightButton /* modifiers */, eventEmitter);
server.postEvent(nelEvent);
break;
}
case NSMouseEntered:break;
case NSMouseExited:break;
case NSKeyDown:
{
// push the key press event to the event server
server.postEvent(new NLMISC::CEventKeyDown(
virtualKeycodeToNelKey([event keyCode]),
@ -735,14 +796,17 @@ void submitEvents(NLMISC::CEventServer& server,
NLMISC::noKeyButton,
eventEmitter));
}
break;
break;
}
case NSKeyUp:
{
// push the key release event to the event server
server.postEvent(new NLMISC::CEventKeyUp(
virtualKeycodeToNelKey([event keyCode]),
modifierFlagsToNelKeyButton([event modifierFlags]),
eventEmitter));
break;
break;
}
case NSFlagsChanged:break;
case NSAppKitDefined:break;
case NSSystemDefined:break;
@ -762,9 +826,11 @@ void submitEvents(NLMISC::CEventServer& server,
case NSEventTypeBeginGesture:break;
case NSEventTypeEndGesture:break;
default:
{
nlwarning("Unknown event type. dropping.");
// NSLog(@"%@", event);
break;
break;
}
}
[g_app sendEvent:event];

View file

@ -27,4 +27,10 @@ void CCocoaEventEmitter::submitEvents(CEventServer & server, bool allWindows)
NL3D::MAC::submitEvents(server, allWindows, this);
}
void CCocoaEventEmitter::emulateMouseRawMode(bool enable)
{
// just forwarding to our cocoa adapter
NL3D::MAC::emulateMouseRawMode(enable);
}
}

View file

@ -26,6 +26,7 @@ class CCocoaEventEmitter : public IEventEmitter
{
public:
virtual void submitEvents(CEventServer & server, bool allWindows);
virtual void emulateMouseRawMode(bool enable);
};
}

View file

@ -29,7 +29,7 @@
namespace NLMISC {
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY)
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY), _emulateRawMode(false)
{
_im = 0;
_ic = 0;
@ -83,6 +83,19 @@ void CUnixEventEmitter::submitEvents(CEventServer & server, bool allWindows)
}
}
void CUnixEventEmitter::emulateMouseRawMode(bool enable)
{
_emulateRawMode = enable;
if(_emulateRawMode)
{
XWindowAttributes xwa;
XGetWindowAttributes(_dpy, _win, &xwa);
XWarpPointer(_dpy, None, _win, None, None, None, None,
(xwa.width / 2), (xwa.height / 2));
}
}
#ifndef AltMask
# ifdef NL_OS_MAC
# define AltMask (8192)
@ -120,6 +133,9 @@ TKey getKeyFromKeycode (uint keycode)
switch (keycode)
{
#ifdef NL_OS_MAC
/*
TODO use key mapping from driver/opengl/mac/cocoa_adapter.mm
*/
case 0x12: return Key1;
case 0x13: return Key2;
case 0x14: return Key3;
@ -316,6 +332,9 @@ TKey getKeyFromKeySym (KeySym keysym)
void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
{
XWindowAttributes xwa;
XGetWindowAttributes (_dpy, _win, &xwa);
switch (event.type)
{
Case(ReparentNotify)
@ -325,8 +344,6 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
Case(ButtonPress)
{
//nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y);
XWindowAttributes xwa;
XGetWindowAttributes (_dpy, _win, &xwa);
float fX = (float) event.xbutton.x / (float) xwa.width;
float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
TMouseButton button=getMouseButton(event.xbutton.state);
@ -353,8 +370,6 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
Case(ButtonRelease)
{
//nlinfo("%d %d %d", event.xbutton.button, event.xbutton.x, event.xbutton.y);
XWindowAttributes xwa;
XGetWindowAttributes (_dpy, _win, &xwa);
float fX = (float) event.xbutton.x / (float) xwa.width;
float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
switch(event.xbutton.button)
@ -373,13 +388,36 @@ void CUnixEventEmitter::processMessage (XEvent &event, CEventServer &server)
}
Case(MotionNotify)
{
XWindowAttributes xwa;
XGetWindowAttributes (_dpy, _win, &xwa);
float fX = (float) event.xbutton.x / (float) xwa.width;
float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
if ((fX == 0.5f) && (fY == 0.5f)) break;
TMouseButton button=getMouseButton (event.xbutton.state);
server.postEvent (new CEventMouseMove (fX, fY, button, this));
// if raw mode should be emulated
if(_emulateRawMode)
{
// when we just wrapped back the pointer to 0.5 / 0.5, ignore event
if(event.xbutton.x == xwa.width / 2 && event.xbutton.y == xwa.height / 2)
break;
// post a CGDMouseMove with the movement delta to the event server
server.postEvent(
new CGDMouseMove(this, NULL /* no mouse device */,
event.xbutton.x - (xwa.width / 2),
(xwa.height / 2) - event.xbutton.y));
// move the pointer back to the center of the window
XWarpPointer(_dpy, None, _win, None, None, None, None,
(xwa.width / 2), (xwa.height / 2));
}
// if in normal mouse mode
else
{
// get the relative mouse position
float fX = (float) event.xbutton.x / (float) xwa.width;
float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
// post a normal mouse move event to the event server
server.postEvent (new CEventMouseMove (fX, fY, button, this));
}
break;
}
Case(KeyPress)

View file

@ -22,6 +22,7 @@
#include "nel/misc/types_nl.h"
#include "nel/misc/event_emitter.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#ifdef NL_OS_UNIX
@ -54,6 +55,8 @@ public:
*/
virtual void submitEvents(CEventServer & server, bool allWindows);
virtual void emulateMouseRawMode(bool);
public:
void processMessage (XEvent &event, CEventServer &server);
@ -65,6 +68,7 @@ private:
TKey _PreviousKey;
XIM _im;
XIC _ic;
bool _emulateRawMode;
};

View file

@ -34,6 +34,7 @@
#include "nel/3d/water_pool_manager.h"
#include "nel/3d/u_camera.h"
#include "nel/misc/hierarchical_timer.h"
#include "nel/misc/event_emitter.h"
using namespace NLMISC;
@ -1594,6 +1595,11 @@ NLMISC::IKeyboardDevice *CDriverUser::enableLowLevelKeyboard(bool enable)
return _Driver->enableLowLevelKeyboard(enable);
}
void CDriverUser::emulateMouseRawMode(bool enable)
{
_Driver->getEventEmitter()->emulateMouseRawMode(enable);
}
uint CDriverUser::getDoubleClickDelay(bool hardwareMouse)
{
NL3D_HAUTO_UI_DRIVER;

View file

@ -52,6 +52,13 @@ void CWinEventEmitter::submitEvents(CEventServer & server, bool allWindows)
_InternalServer.pump (allWindows);
}
/*------------------------------------------------------------------*\
emulateMouseRawMode()
\*------------------------------------------------------------------*/
void CWinEventEmitter::emulateMouseRawMode(bool enable)
{
nlerror("no raw mode emulation on windows, the CDIMouse has a real raw mode");
}
/*------------------------------------------------------------------*\
processMessage()

View file

@ -145,16 +145,11 @@ void CEventsListener::operator()(const CEvent& event)
// Event from the Mouse (ANGLE)
if(event == EventGDMouseMove)
{
#ifdef NL_OS_WINDOWS
CGDMouseMove* mouseEvent=(CGDMouseMove*)&event;
// Mouse acceleration
sint dX = mouseEvent->X;
sint dY = ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y;
updateFreeLookPos((float) dX, (float) dY);
#else
// just to make sure that there is no game device implementation un unix
nlerror("not expecting EventGDMouseMove on unix");
#endif
}
// Event from the Mouse (MOVE)
else if(event == EventMouseMoveId)

View file

@ -198,20 +198,24 @@ void UpdateMouse ()
// Raw mode
if (MouseDevice)
{
MouseDevice->setMessagesMode(IMouseDevice::RawMode);
MouseDevice->setMouseAcceleration(ClientCfg.FreeLookAcceleration);
}
else
{
// no mouse device implementation on X11 and Cocoa, emulate raw mode
Driver->emulateMouseRawMode(true);
}
}
else
{
// Get the driver size
uint32 width, height;
Driver->getWindowSize(width, height);
// Set the mouse properties
if (MouseDevice)
{
// Get the driver size
uint32 width, height;
Driver->getWindowSize(width, height);
MouseDevice->setMessagesMode(IMouseDevice::NormalMode);
MouseDevice->setMouseMode(IMouseDevice::XAxis, IMouseDevice::Clamped);
MouseDevice->setMouseMode(IMouseDevice::YAxis, IMouseDevice::Clamped);
@ -221,6 +225,11 @@ void UpdateMouse ()
MouseDevice->setMouseSpeed(MouseCursorSpeed);
MouseDevice->setMouseAcceleration(MouseCursorAcceleration);
}
else
{
// no mouse device implementation on X11 and Cocoa, emulate raw mode
Driver->emulateMouseRawMode(false);
}
}
if (!IsSystemCursorCaptured())
{
@ -249,13 +258,6 @@ void SetMouseFreeLook ()
}
UpdateMouse ();
}
#ifdef NL_OS_UNIX
// on X11 and cocoa the mouse needs to get pulled into the middle each update,
// else the cursor would reach the border of the window / desktop
// and freelook would hang
Driver->setMousePos(0.5f, 0.5f);
#endif
}
//*********************************************************************************
@ -404,6 +406,9 @@ bool IsSystemCursorCaptured()
#ifdef NL_OS_WINDOWS
return GetCapture() == Driver->getDisplay();
#else
/*
TODO there should be a way to ask the driver if capturing is on or off
*/
return MouseCapture;
#endif
}

View file

@ -427,72 +427,46 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
dx = 0.0f;
dy = 0.0f;
// The mouse may still "StandardMove" ie through a CEventMouseMove
// This can happens cause DirectInputDisabled, or because of the "Rotation Anti-Lag system"
// which start to rotate before the mouse is hid and message mode passed to RawMode
// This can happens cause DirectInputDisabled, or because of the
// "Rotation Anti-Lag system" which start to rotate before the mouse is hid
// and message mode passed to RawMode
//
// If we are not on Windows; on X11 there is always StandardMove/CEventMouseMove.
// Currently, there is only a direct input IMouseDevice, not available on X11.
// On X11 and Cocoa, there is no MouseDevice, do it without.
#ifdef NL_OS_WINDOWS
extern IMouseDevice *MouseDevice;
if (MouseDevice)
{
if( EventsListener.getMousePosX() != _LastFrameMousePosX ||
EventsListener.getMousePosY() != _LastFrameMousePosY )
{
float dmpx= EventsListener.getMousePosX() - _LastFrameMousePosX;
float dmpy= EventsListener.getMousePosY() - _LastFrameMousePosY;
// simulate mickeys mode
MouseDevice->convertStdMouseMoveInMickeys(dmpx, dmpy);
if(ClientCfg.FreeLookInverted) dmpy = -dmpy;
// update free look
EventsListener.updateFreeLookPos(dmpx, dmpy);
}
}
#else
// On X11 and Mac, do the thing without IMouseDevice implementation
// if the mouse position changed
if( EventsListener.getMousePosX() != _LastFrameMousePosX ||
EventsListener.getMousePosY() != _LastFrameMousePosY )
{
float dmpx, dmpy;
// On X11 and Cocoa in free look mode, the mouse is pulled back to (0.5, 0.5)
// every update to prevent reaching a border and get stuck.
if(IsMouseFreeLook())
{
/*
TODO on X11, use setCapture to not fake it, capture on mac?
*/
dmpx = EventsListener.getMousePosX() - 0.5;
dmpy = EventsListener.getMousePosY() - 0.5;
}
else
{
dmpx = EventsListener.getMousePosX() - _LastFrameMousePosX;
dmpy = EventsListener.getMousePosY() - _LastFrameMousePosY;
}
// TODO: read desktop mouse speed value on X11 and Cocoa
// implement X11MouseDevice/CocoaMouseDevice?
dmpx *= 450.0f;
dmpy *= 450.0f;
// get the mouse movement delta
float dmpx= EventsListener.getMousePosX() - _LastFrameMousePosX;
float dmpy= EventsListener.getMousePosY() - _LastFrameMousePosY;
// simulate mickeys mode if there is a mouse device
if (MouseDevice)
MouseDevice->convertStdMouseMoveInMickeys(dmpx, dmpy);
else
{
dmpx *= (float)Driver->getWindowWidth();
dmpy *= (float)Driver->getWindowHeight();
}
// handle inverted mouse, if enabled
if(ClientCfg.FreeLookInverted) dmpy = -dmpy;
// update free look
EventsListener.updateFreeLookPos(dmpx, dmpy);
}
#endif
// If the mouse move on the axis X, with a CGDMouseMove
if(EventsListener.isMouseAngleX())
dx = -EventsListener.getMouseAngleX ();
// If the mouse move on the axis Y, with a CGDMouseMove
if(EventsListener.isMouseAngleY())
dy = EventsListener.getMouseAngleY ();
}