From 1d52985943d102b321c631bc4d24cca8ad0f651e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cemal=20G=C3=B6n=C3=BClta=C5=9F?= <45357531+cemalgnlts@users.noreply.github.com> Date: Thu, 16 May 2024 13:01:27 +0300 Subject: [PATCH] [rcore_web] Relative mouse mode issues. (#3940) * [rcore_web] Relative mouse mode issues. * Review formatting. --- .gitignore | 3 +++ src/platforms/rcore_web.c | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 6ff0e234..eeb1ed09 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,9 @@ packages/ *.so.* *.dll +# Emscripten +emsdk + # Ignore wasm data in examples/ examples/**/*.wasm examples/**/*.data diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 9328b8c9..afe8adfb 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -100,6 +100,8 @@ static const char cursorLUT[11][12] = { "not-allowed" // 10 MOUSE_CURSOR_NOT_ALLOWED }; +Vector2 lockedMousePos = { 0 }; + //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- @@ -131,6 +133,7 @@ static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUi static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData); // Emscripten input callback events +static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData); static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData); static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPointerlockChangeEvent *pointerlockChangeEvent, void *userData); static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); @@ -862,6 +865,8 @@ void SetMousePosition(int x, int y) CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y }; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; + if (CORE.Input.Mouse.cursorHidden) lockedMousePos = CORE.Input.Mouse.currentPosition; + // NOTE: emscripten not implemented glfwSetCursorPos(platform.handle, CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y); } @@ -1270,6 +1275,9 @@ int InitPlatform(void) emscripten_set_click_callback("#canvas", NULL, 1, EmscriptenMouseCallback); emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenPointerlockCallback); + // Following the mouse delta when the mouse is locked + emscripten_set_mousemove_callback("#canvas", NULL, 1, EmscriptenMouseMoveCallback); + // Support touch events emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback); emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback); @@ -1477,9 +1485,13 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int // GLFW3 Cursor Position Callback, runs on mouse move static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) { - CORE.Input.Mouse.currentPosition.x = (float)x; - CORE.Input.Mouse.currentPosition.y = (float)y; - CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + // If the pointer is not locked, follow the position + if (!CORE.Input.Mouse.cursorHidden) + { + CORE.Input.Mouse.currentPosition.x = (float)x; + CORE.Input.Mouse.currentPosition.y = (float)y; + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + } #if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES) // Process mouse events as touches to be able to use mouse-gestures @@ -1505,6 +1517,18 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) #endif } +static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) +{ + // To emulate the GLFW_RAW_MOUSE_MOTION property. + if (CORE.Input.Mouse.cursorHidden) + { + CORE.Input.Mouse.previousPosition.x = lockedMousePos.x - mouseEvent->movementX; + CORE.Input.Mouse.previousPosition.y = lockedMousePos.y - mouseEvent->movementY; + } + + return 1; // The event was consumed by the callback handler +} + // GLFW3 Scrolling Callback, runs on mouse wheel static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset) { @@ -1598,6 +1622,12 @@ static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPoin { CORE.Input.Mouse.cursorHidden = EM_ASM_INT( { if (document.pointerLockElement) return 1; }, 0); + if (CORE.Input.Mouse.cursorHidden) + { + lockedMousePos = CORE.Input.Mouse.currentPosition; + CORE.Input.Mouse.previousPosition = lockedMousePos; + } + return 1; // The event was consumed by the callback handler }