Merge branch 'SDL2_RelMouse' into 'master'

SDL2: Relative mouse mode

See merge request !206
This commit is contained in:
Monster Iestyn 2017-09-04 15:11:50 -04:00
commit 017df6cd75
1 changed files with 57 additions and 21 deletions

View File

@ -107,6 +107,9 @@ static SDL_bool disable_mouse = SDL_FALSE;
// first entry in the modelist which is not bigger than MAXVIDWIDTHxMAXVIDHEIGHT // first entry in the modelist which is not bigger than MAXVIDWIDTHxMAXVIDHEIGHT
static INT32 firstEntry = 0; static INT32 firstEntry = 0;
// Total mouse motion X/Y offsets
static INT32 mousemovex = 0, mousemovey = 0;
// SDL vars // SDL vars
static SDL_Surface *vidSurface = NULL; static SDL_Surface *vidSurface = NULL;
static SDL_Surface *bufSurface = NULL; static SDL_Surface *bufSurface = NULL;
@ -119,7 +122,8 @@ static Uint8 BitsPerPixel = 16;
Uint16 realwidth = BASEVIDWIDTH; Uint16 realwidth = BASEVIDWIDTH;
Uint16 realheight = BASEVIDHEIGHT; Uint16 realheight = BASEVIDHEIGHT;
static SDL_bool mousegrabok = SDL_TRUE; static SDL_bool mousegrabok = SDL_TRUE;
#define HalfWarpMouse(x,y) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2)) static SDL_bool wrapmouseok = SDL_FALSE;
#define HalfWarpMouse(x,y) if (wrapmouseok) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2))
static SDL_bool videoblitok = SDL_FALSE; static SDL_bool videoblitok = SDL_FALSE;
static SDL_bool exposevideo = SDL_FALSE; static SDL_bool exposevideo = SDL_FALSE;
static SDL_bool usesdl2soft = SDL_FALSE; static SDL_bool usesdl2soft = SDL_FALSE;
@ -158,7 +162,7 @@ static INT32 windowedModes[MAXWINMODES][2] =
static void Impl_VideoSetupSDLBuffer(void); static void Impl_VideoSetupSDLBuffer(void);
static void Impl_VideoSetupBuffer(void); static void Impl_VideoSetupBuffer(void);
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
static void Impl_SetWindowName(const char *title); //static void Impl_SetWindowName(const char *title);
static void Impl_SetWindowIcon(void); static void Impl_SetWindowIcon(void);
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
@ -348,6 +352,8 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
static void SDLdoUngrabMouse(void) static void SDLdoUngrabMouse(void)
{ {
SDL_SetWindowGrab(window, SDL_FALSE); SDL_SetWindowGrab(window, SDL_FALSE);
wrapmouseok = SDL_FALSE;
SDL_SetRelativeMouseMode(SDL_FALSE);
} }
void SDLforceUngrabMouse(void) void SDLforceUngrabMouse(void)
@ -355,6 +361,8 @@ void SDLforceUngrabMouse(void)
if (SDL_WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO && window != NULL) if (SDL_WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO && window != NULL)
{ {
SDL_SetWindowGrab(window, SDL_FALSE); SDL_SetWindowGrab(window, SDL_FALSE);
wrapmouseok = SDL_FALSE;
SDL_SetRelativeMouseMode(SDL_FALSE);
} }
} }
@ -603,36 +611,43 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type)
static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
{ {
event_t event;
int wwidth, wheight;
if (USE_MOUSEINPUT) if (USE_MOUSEINPUT)
{ {
SDL_GetWindowSize(window, &wwidth, &wheight);
if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window)) if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window))
{ {
SDLdoUngrabMouse(); SDLdoUngrabMouse();
return; return;
} }
// If using relative mouse mode, don't post an event_t just now,
// add on the offsets so we can make an overall event later.
if (SDL_GetRelativeMouseMode())
{
if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window)
{
mousemovex += evt.xrel;
mousemovey += -evt.yrel;
SDL_SetWindowGrab(window, SDL_TRUE);
}
return;
}
// If the event is from warping the pointer to middle
// of the screen then ignore it.
if ((evt.x == realwidth/2) && (evt.y == realheight/2)) if ((evt.x == realwidth/2) && (evt.y == realheight/2))
{ {
return; return;
} }
else
{
event.data2 = (INT32)lround((evt.xrel) * ((float)wwidth / (float)realwidth));
event.data3 = (INT32)lround(-evt.yrel * ((float)wheight / (float)realheight));
}
event.type = ev_mouse;
// Don't send an event_t if not in relative mouse mode anymore,
// just grab and set relative mode
// this fixes the stupid camera jerk on mouse entering bug
// -- Monster Iestyn
if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window) if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window)
{ {
D_PostEvent(&event);
SDL_SetWindowGrab(window, SDL_TRUE); SDL_SetWindowGrab(window, SDL_TRUE);
HalfWarpMouse(wwidth, wheight); if (SDL_SetRelativeMouseMode(SDL_TRUE) == 0) // already warps mouse if successful
wrapmouseok = SDL_TRUE; // TODO: is wrapmouseok or HalfWarpMouse needed anymore?
} }
} }
} }
@ -780,13 +795,15 @@ void I_GetEvent(void)
SDL_Event evt; SDL_Event evt;
// We only want the first motion event, // We only want the first motion event,
// otherwise we'll end up catching the warp back to center. // otherwise we'll end up catching the warp back to center.
int mouseMotionOnce = 0; //int mouseMotionOnce = 0;
if (!graphics_started) if (!graphics_started)
{ {
return; return;
} }
mousemovex = mousemovey = 0;
while (SDL_PollEvent(&evt)) while (SDL_PollEvent(&evt))
{ {
switch (evt.type) switch (evt.type)
@ -799,8 +816,9 @@ void I_GetEvent(void)
Impl_HandleKeyboardEvent(evt.key, evt.type); Impl_HandleKeyboardEvent(evt.key, evt.type);
break; break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
if (!mouseMotionOnce) Impl_HandleMouseMotionEvent(evt.motion); //if (!mouseMotionOnce)
mouseMotionOnce = 1; Impl_HandleMouseMotionEvent(evt.motion);
//mouseMotionOnce = 1;
break; break;
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
@ -823,6 +841,20 @@ void I_GetEvent(void)
} }
} }
// Send all relative mouse movement as one single mouse event.
if (mousemovex || mousemovey)
{
event_t event;
int wwidth, wheight;
SDL_GetWindowSize(window, &wwidth, &wheight);
//SDL_memset(&event, 0, sizeof(event_t));
event.type = ev_mouse;
event.data1 = 0;
event.data2 = (INT32)lround(mousemovex * ((float)wwidth / (float)realwidth));
event.data3 = (INT32)lround(mousemovey * ((float)wheight / (float)realheight));
D_PostEvent(&event);
}
// In order to make wheels act like buttons, we have to set their state to Up. // In order to make wheels act like buttons, we have to set their state to Up.
// This is because wheel messages don't have an up/down state. // This is because wheel messages don't have an up/down state.
gamekeydown[KEY_MOUSEWHEELDOWN] = gamekeydown[KEY_MOUSEWHEELUP] = 0; gamekeydown[KEY_MOUSEWHEELDOWN] = gamekeydown[KEY_MOUSEWHEELUP] = 0;
@ -836,7 +868,9 @@ void I_StartupMouse(void)
return; return;
if (!firsttimeonmouse) if (!firsttimeonmouse)
{
HalfWarpMouse(realwidth, realheight); // warp to center HalfWarpMouse(realwidth, realheight); // warp to center
}
else else
firsttimeonmouse = SDL_FALSE; firsttimeonmouse = SDL_FALSE;
if (cv_usemouse.value) if (cv_usemouse.value)
@ -1184,7 +1218,7 @@ INT32 VID_SetMode(INT32 modeNum)
} }
vid.modenum = -1; vid.modenum = -1;
} }
Impl_SetWindowName("SRB2 "VERSIONSTRING); //Impl_SetWindowName("SRB2 "VERSIONSTRING);
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
@ -1267,14 +1301,16 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
return SDL_TRUE; return SDL_TRUE;
} }
/*
static void Impl_SetWindowName(const char *title) static void Impl_SetWindowName(const char *title)
{ {
if (window != NULL) if (window == NULL)
{ {
return; return;
} }
SDL_SetWindowTitle(window, title); SDL_SetWindowTitle(window, title);
} }
*/
static void Impl_SetWindowIcon(void) static void Impl_SetWindowIcon(void)
{ {