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
This commit is contained in:
Sam Parkinson 2015-12-20 19:33:12 +11:00
parent 229abec6bf
commit 2852c02e0a
2 changed files with 46 additions and 0 deletions

View File

@ -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 {

View File

@ -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;