|
|
@@ -7,10 +7,8 @@
|
|
|
#include "Form.h"
|
|
|
#include "ScriptController.h"
|
|
|
#include <unistd.h>
|
|
|
-
|
|
|
#include <android/sensor.h>
|
|
|
#include <android_native_app_glue.h>
|
|
|
-
|
|
|
#include <android/log.h>
|
|
|
|
|
|
// Externally referenced global variables.
|
|
|
@@ -45,6 +43,24 @@ PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
|
|
|
PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
|
|
|
PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
|
|
|
|
|
|
+#define GESTURE_TAP_DURATION_MAX 200
|
|
|
+#define GESTURE_SWIPE_DURATION_MAX 400
|
|
|
+#define GESTURE_SWIPE_DISTANCE_MIN 50
|
|
|
+
|
|
|
+static std::bitset<3> __gestureEventsProcessed;
|
|
|
+
|
|
|
+struct TouchPointerData
|
|
|
+{
|
|
|
+ size_t pointerId;
|
|
|
+ bool pressed;
|
|
|
+ double time;
|
|
|
+ int x;
|
|
|
+ int y;
|
|
|
+};
|
|
|
+
|
|
|
+TouchPointerData __pointer0;
|
|
|
+TouchPointerData __pointer1;
|
|
|
+
|
|
|
namespace gameplay
|
|
|
{
|
|
|
|
|
|
@@ -579,50 +595,177 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
|
|
|
size_t pointerIndex;
|
|
|
size_t pointerId;
|
|
|
size_t pointerCount;
|
|
|
+ int x;
|
|
|
+ int y;
|
|
|
+
|
|
|
switch (action & AMOTION_EVENT_ACTION_MASK)
|
|
|
{
|
|
|
case AMOTION_EVENT_ACTION_DOWN:
|
|
|
- // Primary pointer down.
|
|
|
- pointerId = AMotionEvent_getPointerId(event, 0);
|
|
|
- gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0), pointerId);
|
|
|
- __primaryTouchId = pointerId;
|
|
|
+ {
|
|
|
+ pointerId = AMotionEvent_getPointerId(event, 0);
|
|
|
+ x = AMotionEvent_getX(event, 0);
|
|
|
+ y = AMotionEvent_getY(event, 0);
|
|
|
+
|
|
|
+ // Gesture handling
|
|
|
+ if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
|
|
|
+ __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
|
|
|
+ {
|
|
|
+ __pointer0.pressed = true;
|
|
|
+ __pointer0.time = Game::getInstance()->getAbsoluteTime();
|
|
|
+ __pointer0.pointerId = pointerId;
|
|
|
+ __pointer0.x = x;
|
|
|
+ __pointer0.y = y;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Primary pointer down.
|
|
|
+ gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, x, y, pointerId);
|
|
|
+ __primaryTouchId = pointerId;
|
|
|
+ }
|
|
|
break;
|
|
|
+
|
|
|
case AMOTION_EVENT_ACTION_UP:
|
|
|
- pointerId = AMotionEvent_getPointerId(event, 0);
|
|
|
- if (__multiTouch || __primaryTouchId == pointerId)
|
|
|
{
|
|
|
- gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0), pointerId);
|
|
|
+ pointerId = AMotionEvent_getPointerId(event, 0);
|
|
|
+ x = AMotionEvent_getX(event, 0);
|
|
|
+ y = AMotionEvent_getY(event, 0);
|
|
|
+
|
|
|
+ // Gestures
|
|
|
+ bool gestureDetected = false;
|
|
|
+ if ( __pointer0.pressed && __pointer0.pointerId == pointerId)
|
|
|
+ {
|
|
|
+ int deltaX = x - __pointer0.x;
|
|
|
+ int deltaY = y - __pointer0.y;
|
|
|
+
|
|
|
+ // Test for swipe
|
|
|
+ if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
|
|
|
+ gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_SWIPE_DURATION_MAX &&
|
|
|
+ (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
|
|
|
+ {
|
|
|
+ int direction = 0;
|
|
|
+ if ( abs(deltaX) > abs(deltaY) )
|
|
|
+ {
|
|
|
+ if (deltaX > 0)
|
|
|
+ direction = gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
|
|
|
+ else if (deltaX < 0)
|
|
|
+ direction = gameplay::Gesture::SWIPE_DIRECTION_LEFT;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (deltaY > 0)
|
|
|
+ direction = gameplay::Gesture::SWIPE_DIRECTION_UP;
|
|
|
+ else if (deltaY < 0)
|
|
|
+ direction = gameplay::Gesture::SWIPE_DIRECTION_DOWN;
|
|
|
+ }
|
|
|
+ gameplay::Game::getInstance()->gestureSwipeEvent(x, y, direction);
|
|
|
+ __pointer0.pressed = false;
|
|
|
+ gestureDetected = true;
|
|
|
+ }
|
|
|
+ else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
|
|
|
+ gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_TAP_DURATION_MAX)
|
|
|
+ {
|
|
|
+ gameplay::Game::getInstance()->gestureTapEvent(x, y);
|
|
|
+ __pointer0.pressed = false;
|
|
|
+ gestureDetected = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
|
|
|
+ {
|
|
|
+ gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, x, y, pointerId);
|
|
|
+ }
|
|
|
+ __primaryTouchId = -1;
|
|
|
}
|
|
|
- __primaryTouchId = -1;
|
|
|
break;
|
|
|
+
|
|
|
case AMOTION_EVENT_ACTION_POINTER_DOWN:
|
|
|
- // Non-primary pointer down.
|
|
|
- if (__multiTouch)
|
|
|
{
|
|
|
- pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
|
|
- pointerId = AMotionEvent_getPointerId(event, pointerIndex);
|
|
|
- gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
|
|
|
+ pointerId = AMotionEvent_getPointerId(event, 0);
|
|
|
+ x = AMotionEvent_getX(event, 0);
|
|
|
+ y = AMotionEvent_getY(event, 0);
|
|
|
+
|
|
|
+ // Gesture handling
|
|
|
+ if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
|
|
|
+ __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
|
|
|
+ {
|
|
|
+ __pointer1.pressed = true;
|
|
|
+ __pointer1.time = Game::getInstance()->getAbsoluteTime();
|
|
|
+ __pointer1.pointerId = pointerId;
|
|
|
+ __pointer1.x = x;
|
|
|
+ __pointer1.y = y;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Non-primary pointer down.
|
|
|
+ if (__multiTouch)
|
|
|
+ {
|
|
|
+ pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
|
|
+ pointerId = AMotionEvent_getPointerId(event, pointerIndex);
|
|
|
+ gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, x, y, pointerId);
|
|
|
+ }
|
|
|
}
|
|
|
break;
|
|
|
+
|
|
|
case AMOTION_EVENT_ACTION_POINTER_UP:
|
|
|
- pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
|
|
- pointerId = AMotionEvent_getPointerId(event, pointerIndex);
|
|
|
- if (__multiTouch || __primaryTouchId == pointerId)
|
|
|
{
|
|
|
- gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
|
|
|
+ pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
|
|
+ pointerId = AMotionEvent_getPointerId(event, 0);
|
|
|
+ x = AMotionEvent_getX(event, 0);
|
|
|
+ y = AMotionEvent_getY(event, 0);
|
|
|
+
|
|
|
+ bool gestureDetected = false;
|
|
|
+ if ( __pointer1.pressed && __pointer1.pointerId == pointerId)
|
|
|
+ {
|
|
|
+ int deltaX = x - __pointer1.x;
|
|
|
+ int deltaY = y - __pointer1.y;
|
|
|
+
|
|
|
+ // Test for swipe
|
|
|
+ if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
|
|
|
+ gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_SWIPE_DURATION_MAX &&
|
|
|
+ (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
|
|
|
+ {
|
|
|
+ int direction;
|
|
|
+ if (deltaX > 0)
|
|
|
+ direction |= gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
|
|
|
+ else if (deltaX < 0)
|
|
|
+ direction |= gameplay::Gesture::SWIPE_DIRECTION_LEFT;
|
|
|
+
|
|
|
+ if (deltaY > 0)
|
|
|
+ direction |= gameplay::Gesture::SWIPE_DIRECTION_UP;
|
|
|
+ else if (deltaY < 0)
|
|
|
+ direction |= gameplay::Gesture::SWIPE_DIRECTION_DOWN;
|
|
|
+
|
|
|
+ gameplay::Game::getInstance()->gestureSwipeEvent(x, y, direction);
|
|
|
+ __pointer1.pressed = false;
|
|
|
+ gestureDetected = true;
|
|
|
+ }
|
|
|
+ else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
|
|
|
+ gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_TAP_DURATION_MAX)
|
|
|
+ {
|
|
|
+ gameplay::Game::getInstance()->gestureTapEvent(x, y);
|
|
|
+ __pointer1.pressed = false;
|
|
|
+ gestureDetected = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
|
|
|
+ {
|
|
|
+ gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
|
|
|
+ }
|
|
|
+ if (__primaryTouchId == pointerId)
|
|
|
+ __primaryTouchId = -1;
|
|
|
}
|
|
|
- if (__primaryTouchId == pointerId)
|
|
|
- __primaryTouchId = -1;
|
|
|
break;
|
|
|
+
|
|
|
case AMOTION_EVENT_ACTION_MOVE:
|
|
|
- // ACTION_MOVE events are batched, unlike the other events.
|
|
|
- pointerCount = AMotionEvent_getPointerCount(event);
|
|
|
- for (size_t i = 0; i < pointerCount; ++i)
|
|
|
{
|
|
|
- pointerId = AMotionEvent_getPointerId(event, i);
|
|
|
- if (__multiTouch || __primaryTouchId == pointerId)
|
|
|
+ // ACTION_MOVE events are batched, unlike the other events.
|
|
|
+ pointerCount = AMotionEvent_getPointerCount(event);
|
|
|
+ for (size_t i = 0; i < pointerCount; ++i)
|
|
|
{
|
|
|
- gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
|
|
|
+ pointerId = AMotionEvent_getPointerId(event, i);
|
|
|
+ if (__multiTouch || __primaryTouchId == pointerId)
|
|
|
+ {
|
|
|
+ gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
@@ -1014,20 +1157,49 @@ bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheel
|
|
|
|
|
|
bool Platform::isGestureSupported(Gesture::GestureEvent evt)
|
|
|
{
|
|
|
- return false;
|
|
|
+ // Pinch currently not implemented
|
|
|
+ return evt == gameplay::Gesture::GESTURE_SWIPE || evt == gameplay::Gesture::GESTURE_TAP;
|
|
|
}
|
|
|
|
|
|
void Platform::registerGesture(Gesture::GestureEvent evt)
|
|
|
{
|
|
|
+ switch(evt)
|
|
|
+ {
|
|
|
+ case Gesture::GESTURE_ANY_SUPPORTED:
|
|
|
+ __gestureEventsProcessed.set();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Gesture::GESTURE_TAP:
|
|
|
+ case Gesture::GESTURE_SWIPE:
|
|
|
+ __gestureEventsProcessed.set(evt);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void Platform::unregisterGesture(Gesture::GestureEvent evt)
|
|
|
{
|
|
|
+ switch(evt)
|
|
|
+ {
|
|
|
+ case Gesture::GESTURE_ANY_SUPPORTED:
|
|
|
+ __gestureEventsProcessed.reset();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Gesture::GESTURE_TAP:
|
|
|
+ case Gesture::GESTURE_SWIPE:
|
|
|
+ __gestureEventsProcessed.set(evt, 0);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
|
|
|
{
|
|
|
- return false;
|
|
|
+ return __gestureEventsProcessed.test(evt);
|
|
|
}
|
|
|
|
|
|
unsigned int Platform::getGamepadsConnected()
|
|
|
@@ -1077,7 +1249,6 @@ float Platform::getGamepadJoystickAxisY(unsigned int gamepadHandle, unsigned int
|
|
|
|
|
|
void Platform::getGamepadJoystickAxisValues(unsigned int gamepadHandle, unsigned int joystickIndex, Vector2* outValue)
|
|
|
{
|
|
|
-
|
|
|
}
|
|
|
|
|
|
unsigned int Platform::getGamepadTriggerCount(unsigned int gamepadHandle)
|