mirror of
https://github.com/mrxenginner/reVC.git
synced 2026-10-10 03:43:04 +08:00
SDL2: drain event queue every frame + relative mouse mode during gameplay (#49)
This commit is contained in:
@@ -890,6 +890,11 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
|
||||
return state;
|
||||
}
|
||||
|
||||
#ifdef LIBRW_SDL2
|
||||
bool _InputMouseIsRelative(void);
|
||||
void _InputConsumeMouseRelative(int *dx, int *dy);
|
||||
#endif
|
||||
|
||||
void CPad::UpdateMouse()
|
||||
{
|
||||
#if defined RW_D3D9 || defined RWLIBS
|
||||
@@ -942,8 +947,13 @@ void CPad::UpdateMouse()
|
||||
double xpos = 1.0f, ypos;
|
||||
glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
|
||||
#endif
|
||||
#ifdef LIBRW_SDL2
|
||||
if (!_InputMouseIsRelative() && xpos == 0)
|
||||
return;
|
||||
#else
|
||||
if (xpos == 0.f)
|
||||
return;
|
||||
#endif
|
||||
|
||||
int32 signX = 1;
|
||||
int32 signy = 1;
|
||||
@@ -958,8 +968,20 @@ void CPad::UpdateMouse()
|
||||
|
||||
PCTempMouseControllerState.Clear();
|
||||
|
||||
#ifdef LIBRW_SDL2
|
||||
if (_InputMouseIsRelative()) {
|
||||
// true relative deltas from the motion events; polled positions are
|
||||
// confined and stall at window/monitor edges
|
||||
int dx, dy;
|
||||
_InputConsumeMouseRelative(&dx, &dy);
|
||||
PCTempMouseControllerState.x = (float)(signX * dx);
|
||||
PCTempMouseControllerState.y = (float)(signy * dy);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
PCTempMouseControllerState.x = (float)(signX * (xpos - PSGLOBAL(lastMousePos.x)));
|
||||
PCTempMouseControllerState.y = (float)(signy * (ypos - PSGLOBAL(lastMousePos.y)));
|
||||
}
|
||||
#ifdef LIBRW_SDL2
|
||||
PCTempMouseControllerState.LMB = !!(mouseState & SDL_BUTTON(1));
|
||||
PCTempMouseControllerState.RMB = !!(mouseState & SDL_BUTTON(3));
|
||||
|
||||
+57
-4
@@ -784,6 +784,24 @@ bool _InputMouseNeedsExclusive()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Relative mouse support: the game derives deltas from polled positions,
|
||||
// but confined positions stall at window/monitor edges. Accumulate the true
|
||||
// deltas from the motion events instead; the game consumes them once per frame.
|
||||
static bool mouseRelativeMode = false;
|
||||
static int mouseRelX = 0, mouseRelY = 0;
|
||||
|
||||
bool _InputMouseIsRelative(void)
|
||||
{
|
||||
return mouseRelativeMode;
|
||||
}
|
||||
|
||||
void _InputConsumeMouseRelative(int *dx, int *dy)
|
||||
{
|
||||
*dx = mouseRelX;
|
||||
*dy = mouseRelY;
|
||||
mouseRelX = mouseRelY = 0;
|
||||
}
|
||||
|
||||
void psPostRWinit(void)
|
||||
{
|
||||
RwVideoMode vm;
|
||||
@@ -1268,9 +1286,12 @@ cursorEnterCB(int entered) {
|
||||
PSGLOBAL(cursorIsInWindow) = !!entered;
|
||||
}
|
||||
|
||||
void
|
||||
windowFocusCB(int focused) {
|
||||
void windowFocusCB(int focused) {
|
||||
WindowFocused = !!focused;
|
||||
if (!focused) {
|
||||
// deltas accumulated while unfocused must not fire on refocus
|
||||
mouseRelX = mouseRelY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1281,14 +1302,18 @@ windowIconifyCB(int iconified) {
|
||||
void inputEventHandler() {
|
||||
SDL_Event event;
|
||||
|
||||
if (SDL_PollEvent(&event)) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN: /* fall-through */
|
||||
case SDL_KEYUP:
|
||||
keypressCB(event.key.keysym.sym, event.type, 0);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION: cursorCB(event.motion.x, event.motion.y); break;
|
||||
case SDL_MOUSEMOTION:
|
||||
cursorCB(event.motion.x, event.motion.y);
|
||||
mouseRelX += event.motion.xrel;
|
||||
mouseRelY += event.motion.yrel;
|
||||
break;
|
||||
case SDL_MOUSEWHEEL: scrollCB(event.wheel.x, event.wheel.y); break;
|
||||
|
||||
// note that SDL_CONTROLLERDEVICEADDED/REMOVED exists, but it did not work for me
|
||||
@@ -1313,6 +1338,34 @@ void inputEventHandler() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Grab the mouse during gameplay (GLFW_CURSOR_DISABLED equivalent):
|
||||
// relative motion + pointer confinement, so the hidden cursor can't
|
||||
// wander off to another monitor or stall at the window edge.
|
||||
// The frontend needs absolute positions, so keep it free there.
|
||||
bool wantRelative = gGameState == GS_PLAYING_GAME &&
|
||||
!FrontEndMenuManager.m_bMenuActive && !WindowIconified;
|
||||
if (wantRelative != mouseRelativeMode) {
|
||||
if (SDL_SetRelativeMouseMode(wantRelative ? SDL_TRUE : SDL_FALSE) == 0) {
|
||||
mouseRelativeMode = wantRelative;
|
||||
mouseRelX = mouseRelY = 0;
|
||||
if (wantRelative) {
|
||||
PSGLOBAL(cursorIsInWindow) = true;
|
||||
} else {
|
||||
int x, y;
|
||||
SDL_GetMouseState(&x, &y);
|
||||
PSGLOBAL(lastMousePos.x) = x;
|
||||
PSGLOBAL(lastMousePos.y) = y;
|
||||
}
|
||||
} else {
|
||||
// switch failed: never leave the menu with a grabbed pointer and
|
||||
// garbage coordinates — release the grab and fall back to polling
|
||||
SDL_SetWindowGrab(PSGLOBAL(window), SDL_FALSE);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
mouseRelativeMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user