Fixed: #917 X11 Free Look and Cam Look support (by rti)

This commit is contained in:
vl 2010-05-19 11:04:40 +02:00
parent 1fec532b3f
commit 8c7a9b6516
3 changed files with 65 additions and 10 deletions

View file

@ -145,11 +145,16 @@ 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

@ -65,6 +65,11 @@ bool SetMousePosFirstTime = true;
// mask for mouse buttons that are known to be down
uint DownMouseButtons = 0;
#ifdef NL_OS_UNIX
// on X11, store whether the mouse was captured or not
bool MouseCapture = false;
#endif
//////////////
// FUNCTION //
//////////////
@ -244,6 +249,13 @@ void SetMouseFreeLook ()
}
UpdateMouse ();
}
#ifdef NL_OS_UNIX
// on X11 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
}
//*********************************************************************************
@ -360,24 +372,28 @@ void CaptureSystemCursor()
HWND drvWnd = (HWND) Driver->getDisplay();
if (!drvWnd) return;
SetCapture(drvWnd);
#else
// on X11, set driver mouse capture on and store it locally as well
Driver->setCapture(MouseCapture = true);
#endif
}
//*********************************************************************************
void ReleaseSystemCursor()
{
if (!IsSystemCursorCaptured()) return;
#ifdef NL_OS_WINDOWS
if (IsSystemCursorCaptured())
// if hardware mouse and not in client area, then force to update its aspect by updating its pos
if (!IsSystemCursorInClientArea())
{
// if hardware mouse and not in client area, then force to update its aspect by updating its pos
if (!IsSystemCursorInClientArea())
{
// force update
ShowCursor(FALSE);
ShowCursor(TRUE);
}
ReleaseCapture();
// force update
ShowCursor(FALSE);
ShowCursor(TRUE);
}
ReleaseCapture();
#else
// on X11, set driver mouse capture off and store it locally as well
Driver->setCapture(MouseCapture = false);
#endif
}
@ -388,7 +404,7 @@ bool IsSystemCursorCaptured()
#ifdef NL_OS_WINDOWS
return GetCapture() == (HWND) Driver->getDisplay();
#else
return false;
return MouseCapture;
#endif
}

View file

@ -431,6 +431,11 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
// 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
//
// 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.
#ifdef NL_OS_WINDOWS
extern IMouseDevice *MouseDevice;
if (MouseDevice)
{
@ -446,6 +451,35 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
EventsListener.updateFreeLookPos(dmpx, dmpy);
}
}
#else
// On X11, do the thing without IMouseDevice implementation
if( EventsListener.getMousePosX() != _LastFrameMousePosX ||
EventsListener.getMousePosY() != _LastFrameMousePosY )
{
float dmpx, dmpy;
// On X11 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())
{
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 / implement X11MouseDevice
dmpx *= 450.0f;
dmpy *= 450.0f;
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())