From 3e7d88ba20fbb5add2c7bb72dc856ab43acc9d9c Mon Sep 17 00:00:00 2001 From: vl Date: Wed, 19 May 2010 11:04:40 +0200 Subject: [PATCH] Fixed: #917 X11 Free Look and Cam Look support (by rti) --- code/ryzom/client/src/events_listener.cpp | 5 +++ code/ryzom/client/src/input.cpp | 36 +++++++++++++------ .../ryzom/client/src/motion/user_controls.cpp | 34 ++++++++++++++++++ 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/code/ryzom/client/src/events_listener.cpp b/code/ryzom/client/src/events_listener.cpp index 82b01271d..91379c8ca 100644 --- a/code/ryzom/client/src/events_listener.cpp +++ b/code/ryzom/client/src/events_listener.cpp @@ -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) diff --git a/code/ryzom/client/src/input.cpp b/code/ryzom/client/src/input.cpp index e8c8f8762..404fcd323 100644 --- a/code/ryzom/client/src/input.cpp +++ b/code/ryzom/client/src/input.cpp @@ -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 } diff --git a/code/ryzom/client/src/motion/user_controls.cpp b/code/ryzom/client/src/motion/user_controls.cpp index 020d21182..465748d8b 100644 --- a/code/ryzom/client/src/motion/user_controls.cpp +++ b/code/ryzom/client/src/motion/user_controls.cpp @@ -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())