Skip to content

Commit

Permalink
Fixed touch normalized coordinates
Browse files Browse the repository at this point in the history
When converting normalized coordinates to pixel coordinates, the valid range is 0 to (width or height) - 1, and the pixel coordinate of width or height is past the edge of the window.

Fixes libsdl-org#2913
  • Loading branch information
slouken committed Nov 5, 2023
1 parent ff3c20a commit 9302d77
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 16 deletions.
30 changes: 24 additions & 6 deletions android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,24 @@ public boolean onKey(View v, int keyCode, KeyEvent event) {
return SDLActivity.handleKeyEvent(v, keyCode, event, null);
}

private float getNormalizedX(float x)
{
if (mWidth <= 1) {
return 0.5f;
} else {
return (x / (mWidth - 1));
}
}

private float getNormalizedY(float y)
{
if (mHeight <= 1) {
return 0.5f;
} else {
return (y / (mHeight - 1));
}
}

// Touch events
@Override
public boolean onTouch(View v, MotionEvent event) {
Expand Down Expand Up @@ -242,8 +260,8 @@ public boolean onTouch(View v, MotionEvent event) {
case MotionEvent.ACTION_MOVE:
for (i = 0; i < pointerCount; i++) {
pointerFingerId = event.getPointerId(i);
x = event.getX(i) / mWidth;
y = event.getY(i) / mHeight;
x = getNormalizedX(event.getX(i));
y = getNormalizedY(event.getY(i));
p = event.getPressure(i);
if (p > 1.0f) {
// may be larger than 1.0f on some devices
Expand All @@ -267,8 +285,8 @@ public boolean onTouch(View v, MotionEvent event) {
}

pointerFingerId = event.getPointerId(i);
x = event.getX(i) / mWidth;
y = event.getY(i) / mHeight;
x = getNormalizedX(event.getX(i));
y = getNormalizedY(event.getY(i));
p = event.getPressure(i);
if (p > 1.0f) {
// may be larger than 1.0f on some devices
Expand All @@ -281,8 +299,8 @@ public boolean onTouch(View v, MotionEvent event) {
case MotionEvent.ACTION_CANCEL:
for (i = 0; i < pointerCount; i++) {
pointerFingerId = event.getPointerId(i);
x = event.getX(i) / mWidth;
y = event.getY(i) / mHeight;
x = getNormalizedX(event.getX(i));
y = getNormalizedY(event.getY(i));
p = event.getPressure(i);
if (p > 1.0f) {
// may be larger than 1.0f on some devices
Expand Down
12 changes: 10 additions & 2 deletions src/video/emscripten/SDL_emscriptenevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,8 +759,16 @@ static EM_BOOL Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent
}

id = touchEvent->touches[i].identifier;
x = touchEvent->touches[i].targetX / client_w;
y = touchEvent->touches[i].targetY / client_h;
if (client_w <= 1) {
x = 0.5f;
} else {
x = touchEvent->touches[i].targetX / (client_w - 1);
}
if (client_h <= 1) {
y = 0.5f;
} else {
y = touchEvent->touches[i].targetY / (client_h - 1);
}

if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
SDL_SendTouch(0, deviceId, id, window_data->window, SDL_TRUE, x, y, 1.0f);
Expand Down
4 changes: 2 additions & 2 deletions src/video/n3ds/SDL_n3dstouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
internally in a portrait disposition so the
GSP_SCREEN constants are flipped.
*/
#define TOUCHSCREEN_SCALE_X 1.0f / GSP_SCREEN_HEIGHT_BOTTOM
#define TOUCHSCREEN_SCALE_Y 1.0f / GSP_SCREEN_WIDTH
#define TOUCHSCREEN_SCALE_X 1.0f / (GSP_SCREEN_HEIGHT_BOTTOM - 1)
#define TOUCHSCREEN_SCALE_Y 1.0f / (GSP_SCREEN_WIDTH - 1)

void N3DS_InitTouch(void)
{
Expand Down
14 changes: 12 additions & 2 deletions src/video/vita/SDL_vitatouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,18 @@ void VITA_PollTouch(void)

void VITA_ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port)
{
float x = (vita_x - area_info[port].x) / area_info[port].w;
float y = (vita_y - area_info[port].y) / area_info[port].h;
float x, y;

if (area_info[port].w <= 1) {
x = 0.5f;
} else {
x = (vita_x - area_info[port].x) / (area_info[port].w - 1);
}
if (area_info[port].h <= 1) {
y = 0.5f;
} else {
y = (vita_y - area_info[port].y) / (area_info[port].h - 1);
}

x = SDL_max(x, 0.0);
x = SDL_min(x, 1.0);
Expand Down
14 changes: 12 additions & 2 deletions src/video/wayland/SDL_waylandevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,8 +953,18 @@ static void touch_handler_down(void *data, struct wl_touch *touch, uint32_t seri
window_data = (SDL_WindowData *)wl_surface_get_user_data(surface);

if (window_data) {
const float x = wl_fixed_to_double(fx) / window_data->wl_window_width;
const float y = wl_fixed_to_double(fy) / window_data->wl_window_height;
float x, y;

if (window_data->wl_window_width <= 1) {
x = 0.5f;
} else {
x = wl_fixed_to_double(fx) / (window_data->wl_window_width - 1);
}
if (window_data->wl_window_height <= 1) {
y = 0.5f;
} else {
y = wl_fixed_to_double(fy) / (window_data->wl_window_height - 1);
}

SDL_SendTouch(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(intptr_t)touch,
(SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f);
Expand Down
14 changes: 12 additions & 2 deletions src/video/windows/SDL_windowsevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

for (i = 0; i < num_inputs; ++i) {
PTOUCHINPUT input = &inputs[i];
const int w = (rect.right - rect.left);
const int h = (rect.right - rect.left);

const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource);

Expand All @@ -1430,8 +1432,16 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}

/* Get the normalized coordinates for the window */
x = (float)(input->x - rect.left) / (rect.right - rect.left);
y = (float)(input->y - rect.top) / (rect.bottom - rect.top);
if (w <= 1) {
x = 0.5f;
} else {
x = (float)(input->x - rect.left) / (w - 1);
}
if (h <= 1) {
y = 0.5f;
} else {
y = (float)(input->y - rect.top) / (h - 1);
}

/* FIXME: Should we use the input->dwTime field for the tick source of the timestamp? */
if (input->dwFlags & TOUCHEVENTF_DOWN) {
Expand Down

0 comments on commit 9302d77

Please sign in to comment.