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 d92f993af8
commit 3e7d88ba20
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) // Event from the Mouse (ANGLE)
if(event == EventGDMouseMove) if(event == EventGDMouseMove)
{ {
#ifdef NL_OS_WINDOWS
CGDMouseMove* mouseEvent=(CGDMouseMove*)&event; CGDMouseMove* mouseEvent=(CGDMouseMove*)&event;
// Mouse acceleration // Mouse acceleration
sint dX = mouseEvent->X; sint dX = mouseEvent->X;
sint dY = ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y; sint dY = ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y;
updateFreeLookPos((float) dX, (float) dY); 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) // Event from the Mouse (MOVE)
else if(event == EventMouseMoveId) else if(event == EventMouseMoveId)

View file

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

View file

@ -431,6 +431,11 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
// The mouse may still "StandardMove" ie through a CEventMouseMove // The mouse may still "StandardMove" ie through a CEventMouseMove
// This can happens cause DirectInputDisabled, or because of the "Rotation Anti-Lag system" // 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 // 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; extern IMouseDevice *MouseDevice;
if (MouseDevice) if (MouseDevice)
{ {
@ -446,6 +451,35 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
EventsListener.updateFreeLookPos(dmpx, dmpy); 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 the mouse move on the axis X, with a CGDMouseMove
if(EventsListener.isMouseAngleX()) if(EventsListener.isMouseAngleX())