Accumulate subpixel mouse motion so motion is not lost.
authorBoris Gjenero <boris.gjenero@gmail.com>
Tue, 13 Sep 2016 00:03:45 -0700
changeset 10325743e0f5e8ace
parent 10324 efa3b17582ce
child 10326 b7059a6e0de7
Accumulate subpixel mouse motion so motion is not lost.

Previously when the canvas was scaled up and the pointer was locked,
motion corresponding to less than one pixel was lost. Therefore,
slow mouse motion resulted in no motion. This fixes that.
src/video/emscripten/SDL_emscriptenevents.c
     1.1 --- a/src/video/emscripten/SDL_emscriptenevents.c	Tue Sep 13 00:03:44 2016 -0700
     1.2 +++ b/src/video/emscripten/SDL_emscriptenevents.c	Tue Sep 13 00:03:45 2016 -0700
     1.3 @@ -301,25 +301,33 @@
     1.4  Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
     1.5  {
     1.6      SDL_WindowData *window_data = userData;
     1.7 -    int mx = mouseEvent->canvasX, my = mouseEvent->canvasY;
     1.8 +    int mx, my;
     1.9 +    static double residualx = 0, residualy = 0;
    1.10      EmscriptenPointerlockChangeEvent pointerlock_status;
    1.11  
    1.12 +    /* rescale (in case canvas is being scaled)*/
    1.13 +    double client_w, client_h, xscale, yscale;
    1.14 +    emscripten_get_element_css_size(NULL, &client_w, &client_h);
    1.15 +    xscale = window_data->window->w / (client_w * window_data->pixel_ratio);
    1.16 +    yscale = window_data->window->h / (client_h * window_data->pixel_ratio);
    1.17 +
    1.18      /* check for pointer lock */
    1.19      int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status);
    1.20      int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS  ? pointerlock_status.isActive : SDL_FALSE;
    1.21  
    1.22      if (isPointerLocked) {
    1.23 -        mx = mouseEvent->movementX;
    1.24 -        my = mouseEvent->movementY;
    1.25 +        residualx += mouseEvent->movementX * xscale;
    1.26 +        residualy += mouseEvent->movementY * yscale;
    1.27 +        /* Let slow sub-pixel motion accumulate. Don't lose it. */
    1.28 +        mx = residualx;
    1.29 +        residualx -= mx;
    1.30 +        my = residualy;
    1.31 +        residualy -= my;
    1.32 +    } else {
    1.33 +        mx = mouseEvent->canvasX * xscale;
    1.34 +        my = mouseEvent->canvasY * yscale;
    1.35      }
    1.36  
    1.37 -    /* rescale (in case canvas is being scaled)*/
    1.38 -    double client_w, client_h;
    1.39 -    emscripten_get_element_css_size(NULL, &client_w, &client_h);
    1.40 -
    1.41 -    mx = mx * (window_data->window->w / (client_w * window_data->pixel_ratio));
    1.42 -    my = my * (window_data->window->h / (client_h * window_data->pixel_ratio));
    1.43 -
    1.44      SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
    1.45      return 0;
    1.46  }