Skip to content

Commit

Permalink
Accumulate subpixel mouse motion so motion is not lost.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dreamlayers committed Sep 13, 2016
1 parent 443998f commit a20c40c
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions src/video/emscripten/SDL_emscriptenevents.c
Expand Up @@ -301,25 +301,33 @@ EM_BOOL
Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
{
SDL_WindowData *window_data = userData;
int mx = mouseEvent->canvasX, my = mouseEvent->canvasY;
int mx, my;
static double residualx = 0, residualy = 0;
EmscriptenPointerlockChangeEvent pointerlock_status;

/* rescale (in case canvas is being scaled)*/
double client_w, client_h, xscale, yscale;
emscripten_get_element_css_size(NULL, &client_w, &client_h);
xscale = window_data->window->w / (client_w * window_data->pixel_ratio);
yscale = window_data->window->h / (client_h * window_data->pixel_ratio);

/* check for pointer lock */
int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status);
int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS ? pointerlock_status.isActive : SDL_FALSE;

if (isPointerLocked) {
mx = mouseEvent->movementX;
my = mouseEvent->movementY;
residualx += mouseEvent->movementX * xscale;
residualy += mouseEvent->movementY * yscale;
/* Let slow sub-pixel motion accumulate. Don't lose it. */
mx = residualx;
residualx -= mx;
my = residualy;
residualy -= my;
} else {
mx = mouseEvent->canvasX * xscale;
my = mouseEvent->canvasY * yscale;
}

/* rescale (in case canvas is being scaled)*/
double client_w, client_h;
emscripten_get_element_css_size(NULL, &client_w, &client_h);

mx = mx * (window_data->window->w / (client_w * window_data->pixel_ratio));
my = my * (window_data->window->h / (client_h * window_data->pixel_ratio));

SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
return 0;
}
Expand Down

0 comments on commit a20c40c

Please sign in to comment.