From 2852c02e0a37a36acf51db49e4909223f5782850 Mon Sep 17 00:00:00 2001 From: Sam Parkinson Date: Sun, 20 Dec 2015 19:33:12 +1100 Subject: [PATCH] Handle touch events Natively on Linux, using OpenRCT2 with touch is impossible because touch events are not handled by the game. They just don't do anything. This commit handles touch events. A single touch represents a press of the left mouse button. If it followed by another touch within 300ms, a right mouse button event is emitted. This timeout is like that of mobile web browsers [1]. [1] https://developers.google.com/web/updates/2013/12/300ms-tap-delay-gone-away?hl=en --- src/platform/platform.h | 4 ++++ src/platform/shared.c | 42 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/platform/platform.h b/src/platform/platform.h index 0aeac6d853..0d65b6c566 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -41,6 +41,8 @@ #define INVALID_HANDLE -1 +#define TOUCH_DOUBLE_TIMEOUT 300 + typedef struct { int width, height; } resolution; @@ -69,6 +71,8 @@ typedef struct { unsigned char left, middle, right, any; int wheel; int old; + bool touch, touchIsDouble; + unsigned int touchDownTimestamp; } openrct2_cursor; enum { diff --git a/src/platform/shared.c b/src/platform/shared.c index 08c3277b79..5fbeef3390 100644 --- a/src/platform/shared.c +++ b/src/platform/shared.c @@ -426,6 +426,7 @@ void platform_process_messages() gCursorState.middle &= ~CURSOR_CHANGED; gCursorState.right &= ~CURSOR_CHANGED; gCursorState.old = 0; + gCursorState.touch = false; while (SDL_PollEvent(&e)) { switch (e.type) { @@ -466,6 +467,13 @@ void platform_process_messages() gCursorState.x = (int)(e.motion.x / gConfigGeneral.window_scale); gCursorState.y = (int)(e.motion.y / gConfigGeneral.window_scale); break; + case SDL_FINGERMOTION: + RCT2_GLOBAL(0x0142406C, int) = (int)(e.tfinger.x / gConfigGeneral.window_scale); + RCT2_GLOBAL(0x01424070, int) = (int)(e.tfinger.y / gConfigGeneral.window_scale); + + gCursorState.x = (int)(e.tfinger.x / gConfigGeneral.window_scale); + gCursorState.y = (int)(e.tfinger.y / gConfigGeneral.window_scale); + break; case SDL_MOUSEWHEEL: if (gConsoleOpen) { console_scroll(e.wheel.y); @@ -492,6 +500,25 @@ void platform_process_messages() break; } break; + case SDL_FINGERDOWN: + RCT2_GLOBAL(0x01424318, int) = (int)(e.tfinger.x / gConfigGeneral.window_scale); + RCT2_GLOBAL(0x0142431C, int) = (int)(e.tfinger.y / gConfigGeneral.window_scale); + + gCursorState.touchIsDouble = (!gCursorState.touchIsDouble + && e.tfinger.timestamp - gCursorState.touchDownTimestamp < TOUCH_DOUBLE_TIMEOUT); + + if (gCursorState.touchIsDouble) { + store_mouse_input(3); + gCursorState.right = CURSOR_PRESSED; + gCursorState.old = 2; + } else { + store_mouse_input(1); + gCursorState.left = CURSOR_PRESSED; + gCursorState.old = 1; + } + gCursorState.touch = true; + gCursorState.touchDownTimestamp = e.tfinger.timestamp; + break; case SDL_MOUSEBUTTONUP: RCT2_GLOBAL(0x01424318, int) = (int)(e.button.x / gConfigGeneral.window_scale); RCT2_GLOBAL(0x0142431C, int) = (int)(e.button.y / gConfigGeneral.window_scale); @@ -511,6 +538,21 @@ void platform_process_messages() break; } break; + case SDL_FINGERUP: + RCT2_GLOBAL(0x01424318, int) = (int)(e.tfinger.x / gConfigGeneral.window_scale); + RCT2_GLOBAL(0x0142431C, int) = (int)(e.tfinger.y / gConfigGeneral.window_scale); + + if (gCursorState.touchIsDouble) { + store_mouse_input(4); + gCursorState.left = CURSOR_RELEASED; + gCursorState.old = 4; + } else { + store_mouse_input(2); + gCursorState.left = CURSOR_RELEASED; + gCursorState.old = 3; + } + gCursorState.touch = true; + break; case SDL_KEYDOWN: if (gTextInputCompositionActive) break;