aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2016-01-03 13:01:21 +0100
committerraysan5 <raysan5@gmail.com>2016-01-03 13:01:21 +0100
commitd32feaa6685584e9856aa94f4d5bf80b7f5b861c (patch)
treea2531dc7fc7baafc1ef649a73062b17e321de0a1 /src
parentf269fb46eaa446fd07baf672d6d7f97f5035e6c2 (diff)
downloadraylib-d32feaa6685584e9856aa94f4d5bf80b7f5b861c.tar.gz
raylib-d32feaa6685584e9856aa94f4d5bf80b7f5b861c.zip
Reviewed Android inputs and gestures system
Corrected Android processing for some inputs (BACK button, VOLUME buttons) Redesigned Gestures system (some work still required) SetEnabledGestures() - Only support desired gestures (requires some review)
Diffstat (limited to 'src')
-rw-r--r--src/core.c224
-rw-r--r--src/gestures.c332
-rw-r--r--src/gestures.h21
-rw-r--r--src/raylib.h20
4 files changed, 294 insertions, 303 deletions
diff --git a/src/core.c b/src/core.c
index acfc63d5..14510a1b 100644
--- a/src/core.c
+++ b/src/core.c
@@ -66,7 +66,7 @@
#include <jni.h> // Java native interface
#include <android/sensor.h> // Android sensors functions
#include <android/window.h> // Defines AWINDOW_FLAG_FULLSCREEN and others
- //#include <android_native_app_glue.h> // Defines basic app state struct and manages activity
+ #include <android_native_app_glue.h> // Defines basic app state struct and manages activity
#include <EGL/egl.h> // Khronos EGL library - Native platform display device control functions
#include <GLES2/gl2.h> // Khronos OpenGL ES 2.0 library
@@ -103,7 +103,6 @@
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define MAX_TOUCH_POINTS 256
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -121,7 +120,8 @@ static struct android_app *app; // Android activity
static struct android_poll_source *source; // Android events polling source
static int ident, events;
static bool windowReady = false; // Used to detect display initialization
-
+static bool appEnabled = true; // Used to detec if app is active
+static bool contextRebindRequired = false; // Used to know context rebind required
#elif defined(PLATFORM_RPI)
static EGL_DISPMANX_WINDOW_T nativeWindow; // Native window (graphic device)
@@ -149,6 +149,7 @@ static int gamepadStream = -1; // Gamepad device file descripto
static EGLDisplay display; // Native display device (physical screen connection)
static EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
static EGLContext context; // Graphic context, mode in which drawing can be done
+static EGLConfig config; // Graphic config
static uint64_t baseTime; // Base time measure for hi-res timer
static bool windowShouldClose = false; // Flag to set window for closing
#endif
@@ -254,10 +255,12 @@ static void TakeScreenshot(void);
#if defined(PLATFORM_ANDROID)
static void AndroidCommandCallback(struct android_app *app, int32_t cmd); // Process Android activity lifecycle commands
+static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs
#endif
#if defined(PLATFORM_WEB)
static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData);
+static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
#endif
//----------------------------------------------------------------------------------
@@ -293,9 +296,15 @@ void InitWindow(int width, int height, const char *title)
#endif
#if defined(PLATFORM_WEB)
- InitGesturesSystem();
-
emscripten_set_fullscreenchange_callback(0, 0, 1, EmscriptenFullscreenChangeCallback);
+
+ // NOTE: Some code examples
+ //emscripten_set_touchstart_callback(0, NULL, 1, Emscripten_HandleTouch);
+ //emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
+ emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenInputCallback);
+ emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback);
+ emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback);
+ emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback);
#endif
mousePosition.x = screenWidth/2;
@@ -350,24 +359,23 @@ void InitWindow(int width, int height, struct android_app *state)
//state->userData = &engine;
app->onAppCmd = AndroidCommandCallback;
-
- InitAssetManager(app->activity->assetManager);
+ app->onInputEvent = AndroidInputCallback;
- InitGesturesSystem(app);
+ InitAssetManager(app->activity->assetManager);
TraceLog(INFO, "Android app initialized successfully");
+ // Wait for window to be initialized (display and context)
while (!windowReady)
{
- // Wait for window to be initialized (display and context)
// Process events loop
while ((ident = ALooper_pollAll(0, NULL, &events,(void**)&source)) >= 0)
{
// Process this event
if (source != NULL) source->process(app, source);
- // Check if we are exiting
- if (app->destroyRequested != 0) windowShouldClose = true;
+ // NOTE: Never close window, native activity is controlled by the system!
+ //if (app->destroyRequested != 0) windowShouldClose = true;
}
}
}
@@ -1221,7 +1229,6 @@ static void InitDisplay(int width, int height)
};
EGLint numConfigs;
- EGLConfig config;
// Get an EGL display connection
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -1455,30 +1462,62 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
if (app->window != NULL)
{
- // Init device display (monitor, LCD, ...)
- InitDisplay(screenWidth, screenHeight);
+ if (contextRebindRequired)
+ {
+ // Reset screen scaling to full display size
+ EGLint displayFormat;
+ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &displayFormat);
+ ANativeWindow_setBuffersGeometry(app->window, renderWidth, renderHeight, displayFormat);
- // Init OpenGL graphics
- InitGraphics();
+ // Recreate display surface and re-attach OpenGL context
+ surface = eglCreateWindowSurface(display, config, app->window, NULL);
+ eglMakeCurrent(display, surface, surface, context);
- // Load default font for convenience
- // NOTE: External function (defined in module: text)
- LoadDefaultFont();
+ contextRebindRequired = false;
+ }
+ else
+ {
+ // Init device display (monitor, LCD, ...)
+ InitDisplay(screenWidth, screenHeight);
+
+ // Init OpenGL graphics
+ InitGraphics();
+
+ // Load default font for convenience
+ // NOTE: External function (defined in module: text)
+ LoadDefaultFont();
+
+ // TODO: GPU assets reload in case of lost focus (lost context)
+ // NOTE: This problem has been solved just unbinding and rebinding context from display
+ /*
+ if (assetsReloadRequired)
+ {
+ for (int i = 0; i < assetsCount; i++)
+ {
+ // TODO: Unload old asset if required
+
+ // Load texture again to pointed texture
+ (*textureAsset + i) = LoadTexture(assetPath[i]);
+ }
+ }
+ */
- // Init hi-res timer
- InitTimer();
+ // Init hi-res timer
+ InitTimer();
- // raylib logo appearing animation (if enabled)
- if (showLogo)
- {
- SetTargetFPS(60);
- LogoAnimation();
+ // raylib logo appearing animation (if enabled)
+ if (showLogo)
+ {
+ SetTargetFPS(60); // Not required on Android
+ LogoAnimation();
+ }
}
}
} break;
case APP_CMD_GAINED_FOCUS:
{
TraceLog(INFO, "APP_CMD_GAINED_FOCUS");
+ appEnabled = true;
//ResumeMusicStream();
} break;
case APP_CMD_PAUSE:
@@ -1489,11 +1528,18 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
{
//DrawFrame();
TraceLog(INFO, "APP_CMD_LOST_FOCUS");
+ appEnabled = false;
//PauseMusicStream();
} break;
case APP_CMD_TERM_WINDOW:
{
- // TODO: Do display destruction here? -> Yes but only display, don't free buffers!
+ // Dettach OpenGL context and destroy display surface
+ // NOTE 1: Detaching context before destroying display surface avoids losing our resources (textures, shaders, VBOs...)
+ // NOTE 2: In some cases (too many context loaded), OS could unload context automatically... :(
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(display, surface);
+
+ contextRebindRequired = true;
TraceLog(INFO, "APP_CMD_TERM_WINDOW");
} break;
@@ -1524,6 +1570,61 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
default: break;
}
}
+
+// Android: Get input events
+static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
+{
+ //http://developer.android.com/ndk/reference/index.html
+
+ int type = AInputEvent_getType(event);
+
+ if (type == AINPUT_EVENT_TYPE_MOTION)
+ {
+ touchPosition.x = AMotionEvent_getX(event, 0);
+ touchPosition.y = AMotionEvent_getY(event, 0);
+ }
+ else if (type == AINPUT_EVENT_TYPE_KEY)
+ {
+ int32_t keycode = AKeyEvent_getKeyCode(event);
+ //int32_t AKeyEvent_getMetaState(event);
+
+ //if (keycode == AKEYCODE_HOME) { }
+ //if (keycode == AKEYCODE_POWER) { }
+ if (keycode == AKEYCODE_BACK)
+ {
+ // Eat BACK_BUTTON, just do nothing... and don't let to be handled by OS!
+ return 1;
+ }
+ else if ((keycode == AKEYCODE_VOLUME_UP) || (keycode == AKEYCODE_VOLUME_DOWN))
+ {
+ // Set default OS behaviour
+ return 0;
+ }
+ }
+
+ int32_t action = AMotionEvent_getAction(event);
+ unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
+
+ GestureEvent gestureEvent;
+
+ // Register touch actions
+ if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_DOWN;
+ else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_UP;
+ else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_MOVE;
+
+ // Register touch points count
+ gestureEvent.pointCount = AMotionEvent_getPointerCount(event);
+
+ // Register touch points position
+ // NOTE: Only two points registered
+ gestureEvent.position[0] = (Vector2){ AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) };
+ gestureEvent.position[1] = (Vector2){ AMotionEvent_getX(event, 1), AMotionEvent_getY(event, 1) };
+
+ // Gesture data is sent to gestures system for processing
+ ProcessGestureEvent(gestureEvent);
+
+ return 0; // return 1;
+}
#endif
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
@@ -1613,9 +1714,8 @@ static bool GetMouseButtonStatus(int button)
static void PollInputEvents(void)
{
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
- // Touch events reading (requires gestures module)
- touchPosition = GetRawTouchPosition();
-
+
+ // TODO: Remove this requirement...
UpdateGestures();
#endif
@@ -1645,23 +1745,18 @@ static void PollInputEvents(void)
glfwPollEvents(); // Register keyboard/mouse events... and window events!
#elif defined(PLATFORM_ANDROID)
- // TODO: Check virtual keyboard (?)
-
// Poll Events (registered events)
- // TODO: Enable/disable activityMinimized to block activity if minimized
- //while ((ident = ALooper_pollAll(activityMinimized ? 0 : -1, NULL, &events,(void**)&source)) >= 0)
- while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
+ // NOTE: Activity is paused if not enabled (appEnabled)
+ while ((ident = ALooper_pollAll(appEnabled ? 0 : -1, NULL, &events,(void**)&source)) >= 0)
{
// Process this event
if (source != NULL) source->process(app, source);
- // Check if we are exiting
+ // NOTE: Never close window, native activity is controlled by the system!
if (app->destroyRequested != 0)
{
- // NOTE: Never close window, native activity is controlled by the system!
//TraceLog(INFO, "Closing Window...");
//windowShouldClose = true;
-
//ANativeActivity_finish(app->activity);
}
}
@@ -2035,6 +2130,59 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte
return 0;
}
+
+// Web: Get input events
+static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
+{
+ /*
+ for (int i = 0; i < touchEvent->numTouches; i++)
+ {
+ long x, y, id;
+
+ if (!touchEvent->touches[i].isChanged) continue;
+
+ id = touchEvent->touches[i].identifier;
+ x = touchEvent->touches[i].canvasX;
+ y = touchEvent->touches[i].canvasY;
+ }
+
+ printf("%s, numTouches: %d %s%s%s%s\n", emscripten_event_type_to_string(eventType), event->numTouches,
+ event->ctrlKey ? " CTRL" : "", event->shiftKey ? " SHIFT" : "", event->altKey ? " ALT" : "", event->metaKey ? " META" : "");
+
+ for(int i = 0; i < event->numTouches; ++i)
+ {
+ const EmscriptenTouchPoint *t = &event->touches[i];
+
+ printf(" %ld: screen: (%ld,%ld), client: (%ld,%ld), page: (%ld,%ld), isChanged: %d, onTarget: %d, canvas: (%ld, %ld)\n",
+ t->identifier, t->screenX, t->screenY, t->clientX, t->clientY, t->pageX, t->pageY, t->isChanged, t->onTarget, t->canvasX, t->canvasY);
+ }
+ */
+
+ GestureEvent gestureEvent;
+
+ // Register touch actions
+ if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) gestureEvent.touchAction = TOUCH_DOWN;
+ else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) gestureEvent.touchAction = TOUCH_UP;
+ else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) gestureEvent.touchAction = TOUCH_MOVE;
+
+ // Register touch points count
+ gestureEvent.pointCount = touchEvent->numTouches;
+
+ // Register touch points position
+ // NOTE: Only two points registered
+ // TODO: Touch data should be scaled accordingly!
+ //gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].canvasX, touchEvent->touches[0].canvasY };
+ //gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].canvasX, touchEvent->touches[1].canvasY };
+ gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].targetX, touchEvent->touches[0].targetY };
+ gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].targetX, touchEvent->touches[1].targetY };
+
+ touchPosition = gestureEvent.position[0];
+
+ // Gesture data is sent to gestures system for processing
+ ProcessGestureEvent(gestureEvent); // Process obtained gestures data
+
+ return 1;
+}
#endif
// Plays raylib logo appearing animation
diff --git a/src/gestures.c b/src/gestures.c
index adde85b9..88cdb528 100644
--- a/src/gestures.c
+++ b/src/gestures.c
@@ -42,23 +42,12 @@
#include <time.h> // Used for clock functions
#endif
-#if defined(PLATFORM_ANDROID)
- #include <jni.h> // Java native interface
- #include <android/sensor.h> // Android sensors functions
- #include <android/window.h> // Defines AWINDOW_FLAG_FULLSCREEN and others
-#endif
-
-#if defined(PLATFORM_WEB)
- #include <emscripten/emscripten.h>
- #include <emscripten/html5.h>
-#endif
-
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define FORCE_TO_SWIPE 20
#define TAP_TIMEOUT 300
-#define MAX_TOUCH_POINTS 4
+//#define MAX_TOUCH_POINTS 4
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -69,20 +58,6 @@ typedef enum {
TYPE_DUAL_INPUT
} GestureType;
-typedef enum {
- UP,
- DOWN,
- MOVE
-} ActionType;
-
-typedef struct {
- ActionType action;
- int pointCount;
- int pointerId[MAX_TOUCH_POINTS];
- Vector2 position[MAX_TOUCH_POINTS];
-} GestureEvent;
-
-
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
@@ -119,133 +94,24 @@ static float pinchDelta = 0; // Pinch delta displacement
static int previousGesture = GESTURE_NONE;
static int currentGesture = GESTURE_NONE;
-static unsigned int enabledGestures = 0; // TODO: Currently not in use...
-
-static Vector2 rawTouchPosition;
+// Enabled gestures flags, all gestures enabled by default
+static unsigned int enabledGestures = 0b0000011111111111;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-static void ProcessMotionEvent(GestureEvent event);
-
static void InitPinchGesture(Vector2 posA, Vector2 posB);
static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude);
static float VectorDistance(Vector2 v1, Vector2 v2);
static float VectorDotProduct(Vector2 v1, Vector2 v2);
static double GetCurrentTime();
-#if defined(PLATFORM_WEB)
-static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
-#endif
-
-#if defined(PLATFORM_ANDROID)
-static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event);
-#endif
-
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
-// Get touch position (could require further processing depending on display size)
-Vector2 GetRawTouchPosition(void)
-{
- return rawTouchPosition;
-}
-
-// Check if a gesture have been detected
-bool IsGestureDetected(void)
-{
- if (currentGesture != GESTURE_NONE) return true;
- else return false;
-}
-
-// Check gesture type
-int GetGestureType(void)
-{
- return currentGesture;
-}
-
-void SetGesturesEnabled(unsigned int gestureFlags)
-{
- enabledGestures = gestureFlags;
-}
-
-// Get drag intensity (pixels per frame)
-float GetGestureDragIntensity(void)
-{
- return intensity;
-}
-
-// Get drag angle
-// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
-float GetGestureDragAngle(void)
-{
- return angle;
-}
-
-// Get drag vector (between initial and final position)
-Vector2 GetGestureDragVector(void)
-{
- return dragVector;
-}
-
-// Hold time measured in frames
-int GetGestureHoldDuration(void)
-{
- return 0;
-}
-
-// Get magnitude between two pinch points
-float GetGesturePinchDelta(void)
-{
- return pinchDelta;
-}
-
-// Get angle beween two pinch points
-// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
-float GetGesturePinchAngle(void)
-{
- return 0;
-}
-
-#if defined(PLATFORM_WEB)
-// Init gestures system (web)
-void InitGesturesSystem(void)
-{
- // Init gestures system web (emscripten)
-
- // NOTE: Some code examples
- //emscripten_set_touchstart_callback(0, NULL, 1, Emscripten_HandleTouch);
- //emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
-
- emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenInputCallback);
- emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback);
- emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback);
- emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback);
-}
-#elif defined(PLATFORM_ANDROID)
-// Init gestures system (android)
-void InitGesturesSystem(struct android_app *app)
-{
- app->onInputEvent = AndroidInputCallback;
-
- // TODO: Receive frameBuffer data: displayWidth/displayHeight, renderWidth/renderHeight, screenWidth/screenHeight
-}
-#endif
-
-// Update gestures detected (must be called every frame)
-void UpdateGestures(void)
-{
- // NOTE: Gestures are processed through system callbacks on touch events
-
- if ((previousGesture == GESTURE_TAP) && (currentGesture == GESTURE_TAP)) currentGesture = GESTURE_HOLD;
- else if (currentGesture != GESTURE_HOLD) currentGesture = GESTURE_NONE;
-}
-
-//----------------------------------------------------------------------------------
-// Module specific Functions Definition
-//----------------------------------------------------------------------------------
-static void ProcessMotionEvent(GestureEvent event)
+// Process gesture event and translate it into gestures
+void ProcessGestureEvent(GestureEvent event)
{
// Resets
dragVector = (Vector2){ 0, 0 };
@@ -257,7 +123,7 @@ static void ProcessMotionEvent(GestureEvent event)
{
case TYPE_MOTIONLESS: // Detect TAP, DOUBLE_TAP and HOLD events
{
- if (event.action == DOWN)
+ if (event.touchAction == TOUCH_DOWN)
{
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
else
@@ -279,7 +145,7 @@ static void ProcessMotionEvent(GestureEvent event)
else currentGesture = GESTURE_TAP;
}
}
- else if (event.action == UP)
+ else if (event.touchAction == TOUCH_UP)
{
currentGesture = GESTURE_NONE;
@@ -297,7 +163,7 @@ static void ProcessMotionEvent(GestureEvent event)
eventTime = GetCurrentTime();
}
// Begin dragging
- else if (event.action == MOVE)
+ else if (event.touchAction == TOUCH_MOVE)
{
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
else
@@ -316,7 +182,7 @@ static void ProcessMotionEvent(GestureEvent event)
case TYPE_DRAG: // Detect DRAG and SWIPE events
{
// end of the drag
- if (event.action == UP)
+ if (event.touchAction == TOUCH_UP)
{
// Return Swipe if we have enough sensitivity
if (intensity > FORCE_TO_SWIPE)
@@ -334,14 +200,13 @@ static void ProcessMotionEvent(GestureEvent event)
gestureType = TYPE_MOTIONLESS;
}
// Update while we are dragging
- else if (event.action == MOVE)
+ else if (event.touchAction == TOUCH_MOVE)
{
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
else
{
lastDragPosition = endDragPosition;
-
- endDragPosition = rawTouchPosition;
+ endDragPosition = event.position[0];
//endDragPosition.x = AMotionEvent_getX(event, 0);
//endDragPosition.y = AMotionEvent_getY(event, 0);
@@ -359,7 +224,7 @@ static void ProcessMotionEvent(GestureEvent event)
} break;
case TYPE_DUAL_INPUT:
{
- if (event.action == UP)
+ if (event.touchAction == TOUCH_UP)
{
if (event.pointCount == 1)
{
@@ -368,7 +233,7 @@ static void ProcessMotionEvent(GestureEvent event)
}
gestureType = TYPE_MOTIONLESS;
}
- else if (event.action == MOVE)
+ else if (event.touchAction == TOUCH_MOVE)
{
// Adapt the ending position of the inputs
firstEndPinchPosition = event.position[0];
@@ -410,9 +275,78 @@ static void ProcessMotionEvent(GestureEvent event)
}
} break;
}
- //--------------------------------------------------------------------
}
+// Check if a gesture have been detected
+bool IsGestureDetected(void)
+{
+ if (currentGesture != GESTURE_NONE) return true;
+ else return false;
+}
+
+// Check gesture type
+int GetGestureType(void)
+{
+ // Get current gesture only if enabled
+ return (enabledGestures & currentGesture);
+}
+
+void SetGesturesEnabled(unsigned int gestureFlags)
+{
+ enabledGestures = enabledGestures | gestureFlags;
+}
+
+// Get drag intensity (pixels per frame)
+float GetGestureDragIntensity(void)
+{
+ return intensity;
+}
+
+// Get drag angle
+// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
+float GetGestureDragAngle(void)
+{
+ return angle;
+}
+
+// Get drag vector (between initial and final position)
+Vector2 GetGestureDragVector(void)
+{
+ return dragVector;
+}
+
+// Hold time measured in frames
+int GetGestureHoldDuration(void)
+{
+ return 0;
+}
+
+// Get magnitude between two pinch points
+float GetGesturePinchDelta(void)
+{
+ return pinchDelta;
+}
+
+// Get angle beween two pinch points
+// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
+float GetGesturePinchAngle(void)
+{
+ return 0;
+}
+
+// Update gestures detected (must be called every frame)
+void UpdateGestures(void)
+{
+ // NOTE: Gestures are processed through system callbacks on touch events
+
+ if ((previousGesture == GESTURE_TAP) && (currentGesture == GESTURE_TAP)) currentGesture = GESTURE_HOLD;
+ else if (currentGesture != GESTURE_HOLD) currentGesture = GESTURE_NONE;
+}
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
+
static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, float magnitude)
{
float angle;
@@ -520,103 +454,3 @@ static double GetCurrentTime()
return time;
}
-
-#if defined(PLATFORM_ANDROID)
-// Android: Get input events
-static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
-{
- int type = AInputEvent_getType(event);
-
- if (type == AINPUT_EVENT_TYPE_MOTION)
- {
- rawTouchPosition.x = AMotionEvent_getX(event, 0);
- rawTouchPosition.y = AMotionEvent_getY(event, 0);
- }
- else if (type == AINPUT_EVENT_TYPE_KEY)
- {
- int32_t keycode = AKeyEvent_getKeyCode(event);
- int32_t AKeyEvent_getMetaState(event);
-
- // If we are in active mode, we eat the back button and move into pause mode.
- // If we are already in pause mode, we allow the back button to be handled by the OS, which means we'll be shut down.
- if ((keycode == AKEYCODE_BACK)) // && mActiveMode)
- {
- //setActiveMode(false);
- //return 1;
- }
- }
-
- int32_t action = AMotionEvent_getAction(event);
- unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
-
- GestureEvent gestureEvent;
-
- // Action
- if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.action = DOWN;
- else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.action = UP;
- else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.action = MOVE;
-
- // Points
- gestureEvent.pointCount = AMotionEvent_getPointerCount(event);
-
- // Position
- gestureEvent.position[0] = (Vector2){ AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) };
- gestureEvent.position[1] = (Vector2){ AMotionEvent_getX(event, 1), AMotionEvent_getY(event, 1) };
-
- ProcessMotionEvent(gestureEvent);
-
- return 0; // return 1;
-}
-#endif
-
-#if defined(PLATFORM_WEB)
-// Web: Get input events
-static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
-{
- /*
- for (int i = 0; i < touchEvent->numTouches; i++)
- {
- long x, y, id;
-
- if (!touchEvent->touches[i].isChanged) continue;
-
- id = touchEvent->touches[i].identifier;
- x = touchEvent->touches[i].canvasX;
- y = touchEvent->touches[i].canvasY;
- }
-
- printf("%s, numTouches: %d %s%s%s%s\n", emscripten_event_type_to_string(eventType), event->numTouches,
- event->ctrlKey ? " CTRL" : "", event->shiftKey ? " SHIFT" : "", event->altKey ? " ALT" : "", event->metaKey ? " META" : "");
-
- for(int i = 0; i < event->numTouches; ++i)
- {
- const EmscriptenTouchPoint *t = &event->touches[i];
-
- printf(" %ld: screen: (%ld,%ld), client: (%ld,%ld), page: (%ld,%ld), isChanged: %d, onTarget: %d, canvas: (%ld, %ld)\n",
- t->identifier, t->screenX, t->screenY, t->clientX, t->clientY, t->pageX, t->pageY, t->isChanged, t->onTarget, t->canvasX, t->canvasY);
- }
- */
- GestureEvent gestureEvent;
-
- // Action
- if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) gestureEvent.action = DOWN;
- else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) gestureEvent.action = UP;
- else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) gestureEvent.action = MOVE;
-
- // Points
- gestureEvent.pointCount = touchEvent->numTouches;
-
- // Position
- //gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].canvasX, touchEvent->touches[0].canvasY };
- //gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].canvasX, touchEvent->touches[1].canvasY };
- gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].targetX, touchEvent->touches[0].targetY };
- gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].targetX, touchEvent->touches[1].targetY };
- printf("EVENT DETECTED!\n");
-
- rawTouchPosition = gestureEvent.position[0];
-
- ProcessMotionEvent(gestureEvent);
-
- return 1;
-}
-#endif \ No newline at end of file
diff --git a/src/gestures.h b/src/gestures.h
index 896f3028..b5cf2767 100644
--- a/src/gestures.h
+++ b/src/gestures.h
@@ -67,6 +67,17 @@ typedef enum {
GESTURE_PINCH_OUT = 1024
} Gestures;
+typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
+
+// Gesture events
+// NOTE: MAX_TOUCH_POINTS fixed to 4
+typedef struct {
+ int touchAction;
+ int pointCount;
+ int pointerId[4];
+ Vector2 position[4];
+} GestureEvent;
+
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
@@ -79,19 +90,11 @@ extern "C" { // Prevents name mangling of functions
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
-int GetTouchX(void); // Returns touch position X (relative to screen size)
-int GetTouchY(void); // Returns touch position Y (relative to screen size)
-Vector2 GetTouchPosition(void); // Returns touch position XY (relative to screen size)
-
-#if defined(PLATFORM_WEB)
-void InitGesturesSystem(void); // Init gestures system (web)
-#elif defined(PLATFORM_ANDROID)
-void InitGesturesSystem(struct android_app *app); // Init gestures system (android)
-#endif
void UpdateGestures(void); // Update gestures detected (must be called every frame)
bool IsGestureDetected(void); // Check if a gesture have been detected
int GetGestureType(void); // Get latest detected gesture
void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
+void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
float GetGestureDragIntensity(void); // Get gesture drag intensity
float GetGestureDragAngle(void); // Get gesture drag angle
diff --git a/src/raylib.h b/src/raylib.h
index 1113958d..864a240a 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -70,7 +70,7 @@
#endif
#if defined(PLATFORM_ANDROID)
- #include <android_native_app_glue.h> // Defines android_app struct
+ typedef struct android_app; // Define android_app struct (android_native_app_glue.h)
#endif
//----------------------------------------------------------------------------------
@@ -432,6 +432,17 @@ typedef enum {
GESTURE_PINCH_OUT = 1024
} Gestures;
+typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
+
+// Gesture events
+// NOTE: MAX_TOUCH_POINTS fixed to 4
+typedef struct {
+ int touchAction;
+ int pointCount;
+ int pointerId[4];
+ Vector2 position[4];
+} GestureEvent;
+
// Camera system modes
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
@@ -571,16 +582,11 @@ Vector2 GetTouchPosition(void); // Returns touch positio
//------------------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: gestures)
//------------------------------------------------------------------------------------
-Vector2 GetRawTouchPosition(void); // Get touch position (raw)
-#if defined(PLATFORM_WEB)
-void InitGesturesSystem(void); // Init gestures system (web)
-#elif defined(PLATFORM_ANDROID)
-void InitGesturesSystem(struct android_app *app); // Init gestures system (android)
-#endif
void UpdateGestures(void); // Update gestures detected (must be called every frame)
bool IsGestureDetected(void); // Check if a gesture have been detected
int GetGestureType(void); // Get latest detected gesture
void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
+void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
float GetGestureDragIntensity(void); // Get gesture drag intensity
float GetGestureDragAngle(void); // Get gesture drag angle