mirror of
https://github.com/yawut/SDL.git
synced 2026-08-22 08:45:31 -05:00
WinRT: added support for SDL_SetRelativeMouseMode
This commit is contained in:
@@ -33,6 +33,7 @@ SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::Devices::Input;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::Foundation;
|
||||
@@ -42,7 +43,8 @@ using namespace concurrency;
|
||||
SDL_WinRTApp::SDL_WinRTApp() :
|
||||
m_windowClosed(false),
|
||||
m_windowVisible(true),
|
||||
m_sdlWindowData(NULL)
|
||||
m_sdlWindowData(NULL),
|
||||
m_useRelativeMouseMode(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -82,6 +84,10 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window)
|
||||
window->PointerMoved +=
|
||||
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);
|
||||
|
||||
// Retrieves relative-only mouse movements:
|
||||
Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
|
||||
ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
|
||||
|
||||
window->KeyDown +=
|
||||
ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);
|
||||
|
||||
@@ -167,6 +173,68 @@ void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
|
||||
{
|
||||
if (m_sdlWindowData && m_useRelativeMouseMode) {
|
||||
// DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows
|
||||
// Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs'
|
||||
// MouseDelta field often reports very large values. More information
|
||||
// on this can be found at the following pages on MSDN:
|
||||
// - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8
|
||||
// - https://connect.microsoft.com/VisualStudio/Feedback/details/756515
|
||||
//
|
||||
// The values do not appear to be as large when running on some systems,
|
||||
// most notably a Surface RT. Furthermore, the values returned by
|
||||
// CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved
|
||||
// method, do not ever appear to be large, even when MouseEventArgs'
|
||||
// MouseDelta is reporting to the contrary.
|
||||
//
|
||||
// On systems with the large-values behavior, it appears that the values
|
||||
// get reported as if the screen's size is 65536 units in both the X and Y
|
||||
// dimensions. This can be viewed by using Windows' now-private, "Raw Input"
|
||||
// APIs. (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.)
|
||||
//
|
||||
// MSDN's documentation on MouseEventArgs' MouseDelta field (at
|
||||
// http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ),
|
||||
// does not seem to indicate (to me) that its values should be so large. It
|
||||
// says that its values should be a "change in screen location". I could
|
||||
// be misinterpreting this, however a post on MSDN from a Microsoft engineer (see:
|
||||
// http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ),
|
||||
// indicates that these values are in DIPs, which is the same unit used
|
||||
// by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint
|
||||
// property. See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx
|
||||
// for details.)
|
||||
//
|
||||
// To note, PointerMoved events are sent a 'RawPosition' value (via the
|
||||
// CurrentPoint property in MouseEventArgs), however these do not seem
|
||||
// to exhibit the same large-value behavior.
|
||||
//
|
||||
// The values passed via PointerMoved events can't always be used for relative
|
||||
// mouse motion, unfortunately. Its values are bound to the cursor's position,
|
||||
// which stops when it hits one of the screen's edges. This can be a problem in
|
||||
// first person shooters, whereby it is normal for mouse motion to travel far
|
||||
// along any one axis for a period of time. MouseMoved events do not have the
|
||||
// screen-bounding limitation, and can be used regardless of where the system's
|
||||
// cursor is.
|
||||
//
|
||||
// One possible workaround would be to programmatically set the cursor's
|
||||
// position to the screen's center (when SDL's relative mouse mode is enabled),
|
||||
// however Windows RT does not yet seem to have the ability to set the cursor's
|
||||
// position via a public API. Win32 did this via an API call, SetCursorPos,
|
||||
// however WinRT makes this function be private. Apps that use it won't get
|
||||
// approved for distribution in the Windows Store. I've yet to be able to find
|
||||
// a suitable, store-friendly counterpart for WinRT.
|
||||
//
|
||||
// There may be some room for a workaround whereby OnPointerMoved's values
|
||||
// are compared to the values from OnMouseMoved in order to detect
|
||||
// when this bug is active. A suitable transformation could then be made to
|
||||
// OnMouseMoved's values. For now, however, the system-reported values are sent
|
||||
// without transformation.
|
||||
//
|
||||
SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 1, args->MouseDelta.X, args->MouseDelta.Y);
|
||||
}
|
||||
}
|
||||
|
||||
// Applies necessary geometric transformations to raw cursor positions:
|
||||
Point SDL_WinRTApp::TransformCursor(Point rawPosition)
|
||||
{
|
||||
@@ -182,7 +250,7 @@ Point SDL_WinRTApp::TransformCursor(Point rawPosition)
|
||||
|
||||
void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
|
||||
{
|
||||
if (m_sdlWindowData)
|
||||
if (m_sdlWindowData && ! m_useRelativeMouseMode)
|
||||
{
|
||||
Point transformedPoint = TransformCursor(args->CurrentPoint->Position);
|
||||
SDL_SendMouseMotion(m_sdlWindowData->sdlWindow, 0, (int)transformedPoint.X, (int)transformedPoint.Y);
|
||||
@@ -456,6 +524,11 @@ bool SDL_WinRTApp::HasSDLWindowData() const
|
||||
return (m_sdlWindowData != NULL);
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::SetRelativeMouseMode(bool enable)
|
||||
{
|
||||
m_useRelativeMouseMode = enable;
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData)
|
||||
{
|
||||
m_sdlWindowData = windowData;
|
||||
|
||||
@@ -25,6 +25,7 @@ internal:
|
||||
void PumpEvents();
|
||||
const SDL_WindowData * GetSDLWindowData() const;
|
||||
bool HasSDLWindowData() const;
|
||||
void SetRelativeMouseMode(bool enable);
|
||||
void SetSDLWindowData(const SDL_WindowData * windowData);
|
||||
void UpdateWindowFramebuffer(SDL_Surface * surface, SDL_Rect * rects, int numrects);
|
||||
void ResizeMainTexture(int w, int h);
|
||||
@@ -42,6 +43,7 @@ protected:
|
||||
void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
||||
void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
||||
void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
||||
void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
|
||||
void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
|
||||
void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
|
||||
|
||||
@@ -50,6 +52,7 @@ private:
|
||||
bool m_windowClosed;
|
||||
bool m_windowVisible;
|
||||
const SDL_WindowData* m_sdlWindowData;
|
||||
bool m_useRelativeMouseMode;
|
||||
};
|
||||
|
||||
ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
|
||||
|
||||
@@ -108,12 +108,12 @@ WINRT_ShowCursor(SDL_Cursor * cursor)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//static int
|
||||
//WINRT_SetRelativeMouseMode(SDL_bool enabled)
|
||||
//{
|
||||
// //return -1;
|
||||
// return 0;
|
||||
//}
|
||||
static int
|
||||
WINRT_SetRelativeMouseMode(SDL_bool enabled)
|
||||
{
|
||||
SDL_WinRTGlobalApp->SetRelativeMouseMode(enabled ? true : false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WINRT_InitMouse(_THIS)
|
||||
@@ -131,7 +131,7 @@ WINRT_InitMouse(_THIS)
|
||||
mouse->ShowCursor = WINRT_ShowCursor;
|
||||
mouse->FreeCursor = WINRT_FreeCursor;
|
||||
//mouse->WarpMouse = WINRT_WarpMouse;
|
||||
//mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; // DLudwig: 'relative mouse mode' support is pending
|
||||
mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode;
|
||||
|
||||
SDL_SetDefaultCursor(WINRT_CreateDefaultCursor());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user