Patrick Baggett implemented relative mouse mode on Win32
Here is my first rough attempt. "testrelative" feels right to me, but I'd like it someone else tested this, especially compared to Linux/OSX. The "Ctrl+r" to switch between relative and normal mouse movements seems to work flawlessly. With relative mouse movement, the only way to change focus is via keyboard. I'm not sure if that is the correct approach, but that would seem to be the most useful mode for games. Still, if my assumption is wrong, I can fix that no problem.
This commit is contained in:
parent
540577559f
commit
c7a5aa5128
3 changed files with 82 additions and 3 deletions
|
@ -30,7 +30,7 @@
|
|||
#define UNICODE 1
|
||||
#endif
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */
|
||||
#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
|
|
@ -173,6 +173,24 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
if (SDL_GetKeyboardFocus() != data->window) {
|
||||
SDL_SetKeyboardFocus(data->window);
|
||||
}
|
||||
|
||||
if(SDL_GetMouse()->relative_mode) {
|
||||
LONG cx, cy;
|
||||
RECT rect;
|
||||
GetWindowRect(hwnd, &rect);
|
||||
|
||||
cx = (rect.left + rect.right) / 2;
|
||||
cy = (rect.top + rect.bottom) / 2;
|
||||
|
||||
/* Make an absurdly small clip rect */
|
||||
rect.left = cx-1;
|
||||
rect.right = cx+1;
|
||||
rect.top = cy-1;
|
||||
rect.bottom = cy+1;
|
||||
|
||||
ClipCursor(&rect);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Update keyboard state
|
||||
*/
|
||||
|
@ -191,6 +209,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if(SDL_GetMouse()->relative_mode)
|
||||
break;
|
||||
#ifdef _WIN32_WCE
|
||||
/* transform coords for VGA, WVGA... */
|
||||
{
|
||||
|
@ -208,6 +228,25 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_INPUT:
|
||||
{
|
||||
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
|
||||
RAWINPUT inp;
|
||||
UINT size = sizeof(inp);
|
||||
GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
|
||||
|
||||
/* Mouse data */
|
||||
if(inp.header.dwType == RIM_TYPEMOUSE)
|
||||
{
|
||||
RAWMOUSE* mouse = &inp.data.mouse;
|
||||
|
||||
if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE)
|
||||
SDL_SendMouseMotion(data->window, 1, (int)mouse->lLastX, (int)mouse->lLastY);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
break;
|
||||
|
|
|
@ -140,8 +140,48 @@ WIN_WarpMouse(SDL_Window * window, int x, int y)
|
|||
static int
|
||||
WIN_SetRelativeMouseMode(SDL_bool enabled)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
return -1;
|
||||
RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */
|
||||
HWND hWnd;
|
||||
hWnd = GetActiveWindow();
|
||||
|
||||
rawMouse.hwndTarget = hWnd;
|
||||
if(!enabled) {
|
||||
rawMouse.dwFlags |= RIDEV_REMOVE;
|
||||
rawMouse.hwndTarget = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* (Un)register raw input for mice */
|
||||
if(RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) {
|
||||
|
||||
/* Only return an error when registering. If we unregister and fail, then
|
||||
it's probably that we unregistered twice. That's OK. */
|
||||
if(enabled) {
|
||||
SDL_Unsupported();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(enabled) {
|
||||
LONG cx, cy;
|
||||
RECT rect;
|
||||
GetWindowRect(hWnd, &rect);
|
||||
|
||||
cx = (rect.left + rect.right) / 2;
|
||||
cy = (rect.top + rect.bottom) / 2;
|
||||
|
||||
/* Make an absurdly small clip rect */
|
||||
rect.left = cx-1;
|
||||
rect.right = cx+1;
|
||||
rect.top = cy-1;
|
||||
rect.bottom = cy+1;
|
||||
|
||||
ClipCursor(&rect);
|
||||
}
|
||||
else
|
||||
ClipCursor(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue