diff --git a/src/gestures.c b/src/gestures.c index 86cd2ce17..278f48eed 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -1,652 +1,3468 @@ -/********************************************************************************************** -* -* raylib Gestures System - Gestures Detection and Usage Functions (Android and HTML5) -* -* Copyright (c) 2015 Marc Palau and Ramon Santamaria -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -//#define GESTURES_STANDALONE // NOTE: To use the gestures module as standalone lib, just uncomment this line - -#if defined(GESTURES_STANDALONE) - #include "gestures.h" -#else - #include "raylib.h" // Required for typedef(s): Vector2, Gestures -#endif - -#include // malloc(), free() -#include // printf(), fprintf() -#include // Used for ... -#include // Defines int32_t, int64_t - -#if defined(_WIN32) - //#define WIN32_LEAN_AND_MEAN - //#include // ISSUE: Rectangle redeclared, CloseWindow/ShowCursor conflicting types -int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); -int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); -#elif defined(__linux) - #include // Declares storage size of ‘now’ - #include // Used for clock functions -#endif - -#if defined(PLATFORM_ANDROID) - #include // Java native interface - #include // Android sensors functions - #include // Defines AWINDOW_FLAG_FULLSCREEN and others -#endif - -#if defined(PLATFORM_WEB) - #include - #include -#endif - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -#define FORCE_TO_SWIPE 20 -#define TAP_TIMEOUT 300 -#define MAX_TOUCH_POINTS 4 - -//---------------------------------------------------------------------------------- -// Types and Structures Definition -//---------------------------------------------------------------------------------- -typedef enum { - TYPE_MOTIONLESS, - TYPE_DRAG, - 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 -//---------------------------------------------------------------------------------- -static GestureType gestureType = TYPE_MOTIONLESS; -static double eventTime = 0; -//static int32_t touchId; // Not used... - -// Tap gesture variables -static Vector2 initialTapPosition = { 0, 0 }; - -// Double Tap gesture variables -static bool doubleTapping = false; -static bool untap = false; // Check if recently done a tap - -// Drag gesture variables -static Vector2 initialDragPosition = { 0, 0 }; -static Vector2 endDragPosition = { 0, 0 }; -static Vector2 lastDragPosition = { 0, 0 }; -static Vector2 dragVector = { 0, 0 }; - -static float magnitude = 0; // Distance traveled dragging -static float angle = 0; // Angle direction of the drag -static float intensity = 0; // How fast we did the drag (pixels per frame) -static int draggingTimeCounter = 0; // Time that have passed while dragging - -// Pinch gesture variables -static Vector2 firstInitialPinchPosition = { 0, 0 }; -static Vector2 secondInitialPinchPosition = { 0, 0 }; -static Vector2 firstEndPinchPosition = { 0, 0 }; -static Vector2 secondEndPinchPosition = { 0, 0 }; -static float pinchDelta = 0; // Pinch delta displacement - -// Detected gestures -static int previousGesture = GESTURE_NONE; -static int currentGesture = GESTURE_NONE; - -static unsigned int enabledGestures = 0; // TODO: Currently not in use... - -static Vector2 rawTouchPosition; - -//---------------------------------------------------------------------------------- -// 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) -{ - // Resets - dragVector = (Vector2){ 0, 0 }; - pinchDelta = 0; - - previousGesture = currentGesture; - - switch (gestureType) - { - case TYPE_MOTIONLESS: // Detect TAP, DOUBLE_TAP and HOLD events - { - if (event.action == DOWN) - { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - // Set the press position - initialTapPosition = event.position[0]; - - // If too much time have passed, we reset the double tap - if (GetCurrentTime() - eventTime > TAP_TIMEOUT) untap = false; - - // If we are in time, we detect the double tap - if (untap) doubleTapping = true; - - // Update our event time - eventTime = GetCurrentTime(); - - // Set hold - if (doubleTapping) currentGesture = GESTURE_DOUBLETAP; - else currentGesture = GESTURE_TAP; - } - } - else if (event.action == UP) - { - currentGesture = GESTURE_NONE; - - // Detect that we are tapping instead of holding - if (GetCurrentTime() - eventTime < TAP_TIMEOUT) - { - if (doubleTapping) untap = false; - else untap = true; - } - - // Tap finished - doubleTapping = false; - - // Update our event time - eventTime = GetCurrentTime(); - } - // Begin dragging - else if (event.action == MOVE) - { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - // Set the drag starting position - initialDragPosition = initialTapPosition; - endDragPosition = initialDragPosition; - - // Initialize drag - draggingTimeCounter = 0; - gestureType = TYPE_DRAG; - currentGesture = GESTURE_NONE; - } - } - } break; - case TYPE_DRAG: // Detect DRAG and SWIPE events - { - // end of the drag - if (event.action == UP) - { - // Return Swipe if we have enough sensitivity - if (intensity > FORCE_TO_SWIPE) - { - if (angle < 30 || angle > 330) currentGesture = GESTURE_SWIPE_RIGHT; // Right - else if (angle > 60 && angle < 120) currentGesture = GESTURE_SWIPE_UP; // Up - else if (angle > 150 && angle < 210) currentGesture = GESTURE_SWIPE_LEFT; // Left - else if (angle > 240 && angle < 300) currentGesture = GESTURE_SWIPE_DOWN; // Down - } - - magnitude = 0; - angle = 0; - intensity = 0; - - gestureType = TYPE_MOTIONLESS; - } - // Update while we are dragging - else if (event.action == MOVE) - { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - lastDragPosition = endDragPosition; - - endDragPosition = rawTouchPosition; - - //endDragPosition.x = AMotionEvent_getX(event, 0); - //endDragPosition.y = AMotionEvent_getY(event, 0); - - // Calculate attributes - dragVector = (Vector2){ endDragPosition.x - lastDragPosition.x, endDragPosition.y - lastDragPosition.y }; - magnitude = sqrt(pow(endDragPosition.x - initialDragPosition.x, 2) + pow(endDragPosition.y - initialDragPosition.y, 2)); - angle = CalculateAngle(initialDragPosition, endDragPosition, magnitude); - intensity = magnitude / (float)draggingTimeCounter; - - currentGesture = GESTURE_DRAG; - draggingTimeCounter++; - } - } - } break; - case TYPE_DUAL_INPUT: - { - if (event.action == UP) - { - if (event.pointCount == 1) - { - // Set the drag starting position - initialTapPosition = event.position[0]; - } - gestureType = TYPE_MOTIONLESS; - } - else if (event.action == MOVE) - { - // Adapt the ending position of the inputs - firstEndPinchPosition = event.position[0]; - secondEndPinchPosition = event.position[1]; - - // If there is no more than two inputs - if (event.pointCount == 2) - { - // Calculate distances - float initialDistance = VectorDistance(firstInitialPinchPosition, secondInitialPinchPosition); - float endDistance = VectorDistance(firstEndPinchPosition, secondEndPinchPosition); - - // Calculate Vectors - Vector2 firstTouchVector = { firstEndPinchPosition.x - firstInitialPinchPosition.x, firstEndPinchPosition.y - firstInitialPinchPosition.y }; - Vector2 secondTouchVector = { secondEndPinchPosition.x - secondInitialPinchPosition.x, secondEndPinchPosition.y - secondInitialPinchPosition.y }; - - // Detect the pinch gesture - if (VectorDotProduct(firstTouchVector, secondTouchVector) < -0.5) pinchDelta = initialDistance - endDistance; - else pinchDelta = 0; - - // Pinch gesture resolution - if (pinchDelta != 0) - { - if (pinchDelta > 0) currentGesture = GESTURE_PINCH_IN; - else currentGesture = GESTURE_PINCH_OUT; - } - } - else - { - // Set the drag starting position - initialTapPosition = event.position[0]; - - gestureType = TYPE_MOTIONLESS; - } - - // Readapt the initial position of the inputs - firstInitialPinchPosition = firstEndPinchPosition; - secondInitialPinchPosition = secondEndPinchPosition; - } - } break; - } - //-------------------------------------------------------------------- -} - -static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, float magnitude) -{ - float angle; - - // Calculate arcsinus of the movement - angle = asin((finalPosition.y - initialPosition.y)/magnitude); - angle *= RAD2DEG; - - // Calculate angle depending on the sector - if ((finalPosition.x - initialPosition.x) >= 0) - { - // Sector 4 - if ((finalPosition.y - initialPosition.y) >= 0) - { - angle *= -1; - angle += 360; - } - // Sector 1 - else angle *= -1; - } - else - { - // Sector 3 - if ((finalPosition.y - initialPosition.y) >= 0) angle += 180; - // Sector 2 - else - { - angle *= -1; - angle = 180 - angle; - } - } - - return angle; -} - -static void InitPinchGesture(Vector2 posA, Vector2 posB) -{ - initialDragPosition = (Vector2){ 0, 0 }; - endDragPosition = (Vector2){ 0, 0 }; - lastDragPosition = (Vector2){ 0, 0 }; - - // Initialize positions - firstInitialPinchPosition = posA; - secondInitialPinchPosition = posB; + + + + + + + + + + - firstEndPinchPosition = firstInitialPinchPosition; - secondEndPinchPosition = secondInitialPinchPosition; - // Resets - magnitude = 0; - angle = 0; - intensity = 0; + raylib/gestures.c at develop · raysan5/raylib + + + + + + + + + + + + + + + + + + + + - gestureType = TYPE_DUAL_INPUT; -} + + -static float VectorDistance(Vector2 v1, Vector2 v2) -{ - float result; + - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; + - result = sqrt(dx*dx + dy*dy); - return result; -} + + -static float VectorDotProduct(Vector2 v1, Vector2 v2) -{ - float result; - float v1Module = sqrt(v1.x*v1.x + v1.y*v1.y); - float v2Module = sqrt(v2.x*v2.x + v2.y*v2.y); + + + + + + + + + + + + + - Vector2 v1Normalized = { v1.x / v1Module, v1.y / v1Module }; - Vector2 v2Normalized = { v2.x / v2Module, v2.y / v2Module }; - result = v1Normalized.x*v2Normalized.x + v1Normalized.y*v2Normalized.y; - - return result; -} - -static double GetCurrentTime() -{ - double time = 0; -#if defined(_WIN32) -/* - // NOTE: Requires Windows.h - FILETIME tm; - GetSystemTimePreciseAsFileTime(&tm); - ULONGLONG nowTime = ((ULONGLONG)tm.dwHighDateTime << 32) | (ULONGLONG)tm.dwLowDateTime; // Time provided in 100-nanosecond intervals - time = ((double)nowTime/10000000.0); // time in seconds -*/ -/* - double pcFreq = 0.0; - __int64 counterStart = 0; // In C99 defined a standard 64-bit integer type named int64_t and unsigned version uint64_t in stdint.h. + + + + + + + + + + + + + + + + Skip to content + - //int64_t or uint64_t is type defined as long long or unsigned long long in C99's stdint.h. - //LARGE_INTEGER li; // Represents a 64-bit signed integer value - //li.QuadPart // A signed 64-bit integer - unsigned long long int li; // __int64, same as long long - if(!QueryPerformanceFrequency(&li)) return 0; - - pcFreq = (double)(li)/1000.0; - - QueryPerformanceCounter(&li); - counterStart = li; - - unsigned long long int tm; - QueryPerformanceCounter(&tm); - time = (double)(tm - counterStart)/pcFreq; -*/ - unsigned long long int tm, tf; - time = (double)(QueryPerformanceCounter(&tm)/QueryPerformanceFrequency(&tf)); // time in seconds -#endif - -#if defined(__linux) - // NOTE: Only for Linux-based systems - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time provided in nanoseconds + + + + + + + + + + +
+ +
+
+ + +
+
+
+ +
+ +
+ + +
    + +
  • +
    + +
    + + + + Watch + + + + +
    + +
    +
    +
    +
  • + +
  • - 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; - } +
    + +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + +
    + +
  • +
+ +

+ + /raylib + + + + + +

+ +
+
+
+ +
+
+
+ + + +
+ +
+

HTTPS clone URL

+
+ + + + +
+
+ + +
+

SSH clone URL

+
+ + + + +
+
+ + +
+

Subversion checkout URL

+
+ + + + +
+
+ + + +
You can clone with +
,
, or
. + + + +
+ + + Clone in Desktop + + + + + Download ZIP + +
+
+
+ + + + + + + +
- 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" : ""); +
+ + + +
+ +
+ + + + +
+ + +
+ + +
+ Fetching contributors… +
+ +
+ + Cannot retrieve contributors at this time +
+
+
+
+
+ +
+ Raw + Blame + History +
+ + + + + +
+ +
+ +
+ +
+ 651 lines (535 sloc) + + 22.4 KB +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
/**********************************************************************************************
*
* raylib Gestures System - Gestures Detection and Usage Functions (Android and HTML5)
*
* Copyright (c) 2015 Marc Palau and Ramon Santamaria
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
+
//#define GESTURES_STANDALONE // NOTE: To use the gestures module as standalone lib, just uncomment this line
+
#if defined(GESTURES_STANDALONE)
#include "gestures.h"
#else
#include "raylib.h" // Required for typedef(s): Vector2, Gestures
#endif
+
#include <stdlib.h> // malloc(), free()
#include <stdio.h> // printf(), fprintf()
#include <math.h> // Used for ...
#include <stdint.h> // Defines int32_t, int64_t
+
#if defined(_WIN32)
//#define WIN32_LEAN_AND_MEAN
//#include <Windows.h> // ISSUE: Rectangle redeclared, CloseWindow/ShowCursor conflicting types
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
#elif defined(__linux)
#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
+
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef enum {
TYPE_MOTIONLESS,
TYPE_DRAG,
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
//----------------------------------------------------------------------------------
static GestureType gestureType = TYPE_MOTIONLESS;
static double eventTime = 0;
//static int32_t touchId; // Not used...
+
// Tap gesture variables
static Vector2 initialTapPosition = { 0, 0 };
+
// Double Tap gesture variables
static bool doubleTapping = false;
static bool untap = false; // Check if recently done a tap
+
// Drag gesture variables
static Vector2 initialDragPosition = { 0, 0 };
static Vector2 endDragPosition = { 0, 0 };
static Vector2 lastDragPosition = { 0, 0 };
static Vector2 dragVector = { 0, 0 };
+
static float magnitude = 0; // Distance traveled dragging
static float angle = 0; // Angle direction of the drag
static float intensity = 0; // How fast we did the drag (pixels per frame)
static int draggingTimeCounter = 0; // Time that have passed while dragging
+
// Pinch gesture variables
static Vector2 firstInitialPinchPosition = { 0, 0 };
static Vector2 secondInitialPinchPosition = { 0, 0 };
static Vector2 firstEndPinchPosition = { 0, 0 };
static Vector2 secondEndPinchPosition = { 0, 0 };
static float pinchDelta = 0; // Pinch delta displacement
+
// Detected gestures
static int previousGesture = GESTURE_NONE;
static int currentGesture = GESTURE_NONE;
+
static unsigned int enabledGestures = 0; // TODO: Currently not in use...
+
static Vector2 rawTouchPosition;
+
//----------------------------------------------------------------------------------
// 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)
{
// Resets
dragVector = (Vector2){ 0, 0 };
pinchDelta = 0;
previousGesture = currentGesture;
switch (gestureType)
{
case TYPE_MOTIONLESS: // Detect TAP, DOUBLE_TAP and HOLD events
{
if (event.action == DOWN)
{
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
else
{
// Set the press position
initialTapPosition = event.position[0];
// If too much time have passed, we reset the double tap
if (GetCurrentTime() - eventTime > TAP_TIMEOUT) untap = false;
// If we are in time, we detect the double tap
if (untap) doubleTapping = true;
// Update our event time
eventTime = GetCurrentTime();
// Set hold
if (doubleTapping) currentGesture = GESTURE_DOUBLETAP;
else currentGesture = GESTURE_TAP;
}
}
else if (event.action == UP)
{
currentGesture = GESTURE_NONE;
+
// Detect that we are tapping instead of holding
if (GetCurrentTime() - eventTime < TAP_TIMEOUT)
{
if (doubleTapping) untap = false;
else untap = true;
}
// Tap finished
doubleTapping = false;
+
// Update our event time
eventTime = GetCurrentTime();
}
// Begin dragging
else if (event.action == MOVE)
{
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
else
{
// Set the drag starting position
initialDragPosition = initialTapPosition;
endDragPosition = initialDragPosition;
// Initialize drag
draggingTimeCounter = 0;
gestureType = TYPE_DRAG;
currentGesture = GESTURE_NONE;
}
}
} break;
case TYPE_DRAG: // Detect DRAG and SWIPE events
{
// end of the drag
if (event.action == UP)
{
// Return Swipe if we have enough sensitivity
if (intensity > FORCE_TO_SWIPE)
{
if (angle < 30 || angle > 330) currentGesture = GESTURE_SWIPE_RIGHT; // Right
else if (angle > 60 && angle < 120) currentGesture = GESTURE_SWIPE_UP; // Up
else if (angle > 150 && angle < 210) currentGesture = GESTURE_SWIPE_LEFT; // Left
else if (angle > 240 && angle < 300) currentGesture = GESTURE_SWIPE_DOWN; // Down
}
magnitude = 0;
angle = 0;
intensity = 0;
gestureType = TYPE_MOTIONLESS;
}
// Update while we are dragging
else if (event.action == MOVE)
{
if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]);
else
{
lastDragPosition = endDragPosition;
endDragPosition = rawTouchPosition;
//endDragPosition.x = AMotionEvent_getX(event, 0);
//endDragPosition.y = AMotionEvent_getY(event, 0);
// Calculate attributes
dragVector = (Vector2){ endDragPosition.x - lastDragPosition.x, endDragPosition.y - lastDragPosition.y };
magnitude = sqrt(pow(endDragPosition.x - initialDragPosition.x, 2) + pow(endDragPosition.y - initialDragPosition.y, 2));
angle = CalculateAngle(initialDragPosition, endDragPosition, magnitude);
intensity = magnitude / (float)draggingTimeCounter;
currentGesture = GESTURE_DRAG;
draggingTimeCounter++;
}
}
} break;
case TYPE_DUAL_INPUT:
{
if (event.action == UP)
{
if (event.pointCount == 1)
{
// Set the drag starting position
initialTapPosition = event.position[0];
}
gestureType = TYPE_MOTIONLESS;
}
else if (event.action == MOVE)
{
// Adapt the ending position of the inputs
firstEndPinchPosition = event.position[0];
secondEndPinchPosition = event.position[1];
// If there is no more than two inputs
if (event.pointCount == 2)
{
// Calculate distances
float initialDistance = VectorDistance(firstInitialPinchPosition, secondInitialPinchPosition);
float endDistance = VectorDistance(firstEndPinchPosition, secondEndPinchPosition);
+
// Calculate Vectors
Vector2 firstTouchVector = { firstEndPinchPosition.x - firstInitialPinchPosition.x, firstEndPinchPosition.y - firstInitialPinchPosition.y };
Vector2 secondTouchVector = { secondEndPinchPosition.x - secondInitialPinchPosition.x, secondEndPinchPosition.y - secondInitialPinchPosition.y };
+
// Detect the pinch gesture
if (VectorDotProduct(firstTouchVector, secondTouchVector) < -0.5) pinchDelta = initialDistance - endDistance;
else pinchDelta = 0;
// Pinch gesture resolution
if (pinchDelta != 0)
{
if (pinchDelta > 0) currentGesture = GESTURE_PINCH_IN;
else currentGesture = GESTURE_PINCH_OUT;
}
}
else
{
// Set the drag starting position
initialTapPosition = event.position[0];
gestureType = TYPE_MOTIONLESS;
}
// Readapt the initial position of the inputs
firstInitialPinchPosition = firstEndPinchPosition;
secondInitialPinchPosition = secondEndPinchPosition;
}
} break;
}
//--------------------------------------------------------------------
}
+
static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, float magnitude)
{
float angle;
// Calculate arcsinus of the movement
angle = asin((finalPosition.y - initialPosition.y)/magnitude);
angle *= RAD2DEG;
// Calculate angle depending on the sector
if ((finalPosition.x - initialPosition.x) >= 0)
{
// Sector 4
if ((finalPosition.y - initialPosition.y) >= 0)
{
angle *= -1;
angle += 360;
}
// Sector 1
else angle *= -1;
}
else
{
// Sector 3
if ((finalPosition.y - initialPosition.y) >= 0) angle += 180;
// Sector 2
else
{
angle *= -1;
angle = 180 - angle;
}
}
return angle;
}
+
static void InitPinchGesture(Vector2 posA, Vector2 posB)
{
initialDragPosition = (Vector2){ 0, 0 };
endDragPosition = (Vector2){ 0, 0 };
lastDragPosition = (Vector2){ 0, 0 };
+
// Initialize positions
firstInitialPinchPosition = posA;
secondInitialPinchPosition = posB;
firstEndPinchPosition = firstInitialPinchPosition;
secondEndPinchPosition = secondInitialPinchPosition;
// Resets
magnitude = 0;
angle = 0;
intensity = 0;
+
gestureType = TYPE_DUAL_INPUT;
}
+
static float VectorDistance(Vector2 v1, Vector2 v2)
{
float result;
+
float dx = v2.x - v1.x;
float dy = v2.y - v1.y;
+
result = sqrt(dx*dx + dy*dy);
+
return result;
}
+
static float VectorDotProduct(Vector2 v1, Vector2 v2)
{
float result;
+
float v1Module = sqrt(v1.x*v1.x + v1.y*v1.y);
float v2Module = sqrt(v2.x*v2.x + v2.y*v2.y);
Vector2 v1Normalized = { v1.x / v1Module, v1.y / v1Module };
Vector2 v2Normalized = { v2.x / v2Module, v2.y / v2Module };
result = v1Normalized.x*v2Normalized.x + v1Normalized.y*v2Normalized.y;
+
return result;
}
+
static double GetCurrentTime()
{
double time = 0;
#if defined(_WIN32)
/*
// NOTE: Requires Windows.h
FILETIME tm;
GetSystemTimePreciseAsFileTime(&tm);
ULONGLONG nowTime = ((ULONGLONG)tm.dwHighDateTime << 32) | (ULONGLONG)tm.dwLowDateTime; // Time provided in 100-nanosecond intervals
time = ((double)nowTime/10000000.0); // time in seconds
*/
/*
double pcFreq = 0.0;
__int64 counterStart = 0; // In C99 defined a standard 64-bit integer type named int64_t and unsigned version uint64_t in stdint.h.
//int64_t or uint64_t is type defined as long long or unsigned long long in C99's stdint.h.
//LARGE_INTEGER li; // Represents a 64-bit signed integer value
//li.QuadPart // A signed 64-bit integer
unsigned long long int li; // __int64, same as long long
if(!QueryPerformanceFrequency(&li)) return 0;
pcFreq = (double)(li)/1000.0;
QueryPerformanceCounter(&li);
counterStart = li;
unsigned long long int tm;
QueryPerformanceCounter(&tm);
time = (double)(tm - counterStart)/pcFreq;
*/
unsigned long long int tm, tf;
time = (double)(QueryPerformanceCounter(&tm)/QueryPerformanceFrequency(&tf)); // time in seconds
#endif
+
#if defined(__linux)
// NOTE: Only for Linux-based systems
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time provided in nanoseconds
time = ((double)nowTime/1000000.0); // time in miliseconds
#endif
+
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 key = AKeyEvent_getKeyCode(event);
//int32_t AKeyEvent_getMetaState(event);
//int32_t code = AKeyEvent_getKeyCode((const AInputEvent *)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 ((code == 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
+ +
+ +
+ +Jump to Line + + +
+
+ +
+
+ + +
+ +
+ +
+ + - 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 +
+ + + Something went wrong with that request. Please try again. +
+ + + + + + + + + + diff --git a/src/makefile b/src/makefile index 5f7a9e17b..3cb237e6c 100644 --- a/src/makefile +++ b/src/makefile @@ -1,192 +1,1551 @@ -#************************************************************************************************** -# -# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten) -# -# Copyright (c) 2014 Ramon Santamaria (@raysan5) -# -# This software is provided "as-is", without any express or implied warranty. In no event -# will the authors be held liable for any damages arising from the use of this software. -# -# Permission is granted to anyone to use this software for any purpose, including commercial -# applications, and to alter it and redistribute it freely, subject to the following restrictions: -# -# 1. The origin of this software must not be misrepresented; you must not claim that you -# wrote the original software. If you use this software in a product, an acknowledgment -# in the product documentation would be appreciated but is not required. -# -# 2. Altered source versions must be plainly marked as such, and must not be misrepresented -# as being the original software. -# -# 3. This notice may not be removed or altered from any source distribution. -# -#************************************************************************************************** - -# define raylib platform to compile for -# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB -PLATFORM ?= PLATFORM_DESKTOP - -# determine PLATFORM_OS in case PLATFORM_DESKTOP selected -ifeq ($(PLATFORM),PLATFORM_DESKTOP) - # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows - ifeq ($(OS),Windows_NT) - PLATFORM_OS=WINDOWS - else - UNAMEOS:=$(shell uname) - ifeq ($(UNAMEOS),Linux) - PLATFORM_OS=LINUX - else - ifeq ($(UNAMEOS),Darwin) - PLATFORM_OS=OSX - endif - endif - endif -endif - -# define raylib graphics api depending on selected platform -ifeq ($(PLATFORM),PLATFORM_RPI) - # define raylib graphics api to use (on RPI, OpenGL ES 2.0 must be used) - GRAPHICS = GRAPHICS_API_OPENGL_ES2 -else - # define raylib graphics api to use (OpenGL 1.1 by default) - GRAPHICS ?= GRAPHICS_API_OPENGL_11 - #GRAPHICS = GRAPHICS_API_OPENGL_33 # Uncomment to use OpenGL 3.3 -endif -ifeq ($(PLATFORM),PLATFORM_WEB) - GRAPHICS = GRAPHICS_API_OPENGL_ES2 -endif - -# NOTE: makefiles targets require tab indentation - -# define compiler: gcc for C program, define as g++ for C++ -ifeq ($(PLATFORM),PLATFORM_WEB) - # define emscripten compiler - CC = emcc -else - # define default gcc compiler - CC = gcc -endif - -# define compiler flags: -<<<<<<< HEAD -# -O1 defines optimization level -# -Wall turns on most, but not all, compiler warnings -# -std=c99 defines C language mode (standard C from 1999 revision) -# -std=gnu99 defines C language mode (GNU C from 1999 revision) -# -fgnu89-inline declaring inline functions support (GCC optimized, faster) -CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -======= -# -O2 defines optimization level -# -Wall turns on most, but not all, compiler warnings -# -std=c99 use standard C from 1999 revision -ifeq ($(PLATFORM),PLATFORM_RPI) - CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -else - CFLAGS = -O1 -Wall -std=gnu99 -endif ->>>>>>> refs/remotes/raysan5/master - -#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes - -# define any directories containing required header files -ifeq ($(PLATFORM),PLATFORM_RPI) - INCLUDES = -I. -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -else - INCLUDES = -I. -I../src -# external libraries headers -# GLFW3 - INCLUDES += -I../external/glfw3/include -# GLEW - INCLUDES += -I../external/glew/include -# OpenAL Soft - INCLUDES += -I../external/openal_soft/include -endif - -# define all object files required -OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o - -# typing 'make' will invoke the first target entry in the file, -# in this case, the 'default' target entry is raylib -default: raylib - -# compile raylib library -raylib: $(OBJS) -ifeq ($(PLATFORM),PLATFORM_WEB) - emcc -O1 $(OBJS) -o libraylib.bc -else - ar rcs libraylib.a $(OBJS) -endif - -# compile core module -# emcc core.c -o core.bc -DPLATFORM_DESKTOP -core.o: core.c - $(CC) -c core.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) - -# compile rlgl module -rlgl.o: rlgl.c - $(CC) -c rlgl.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) - -# compile raymath module -raymath.o: raymath.c - $(CC) -c raymath.c $(CFLAGS) $(INCLUDES) - -# compile shapes module -shapes.o: shapes.c - $(CC) -c shapes.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) - -# compile textures module -textures.o: textures.c - $(CC) -c textures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) - -# compile text module -text.o: text.c - $(CC) -c text.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) - -# compile models module -models.o: models.c - $(CC) -c models.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) - -# compile audio module -audio.o: audio.c - $(CC) -c audio.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) - -# compile stb_vorbis library -stb_vorbis.o: stb_vorbis.c - $(CC) -c stb_vorbis.c -O1 $(INCLUDES) -D$(PLATFORM) - -# compile utils module -utils.o: utils.c - $(CC) -c utils.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) - -# compile camera module -camera.o: camera.c - $(CC) -c camera.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) - -# compile gestures module -gestures.o: gestures.c - $(CC) -c gestures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) - -# clean everything -clean: -ifeq ($(PLATFORM),PLATFORM_DESKTOP) - ifeq ($(PLATFORM_OS),OSX) - rm -f *.o libraylib.a - else - ifeq ($(PLATFORM_OS),LINUX) - find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f - else - del *.o libraylib.a - endif - endif -endif -ifeq ($(PLATFORM),PLATFORM_RPI) - rm -f *.o libraylib.a -endif -ifeq ($(PLATFORM),PLATFORM_WEB) - del *.o libraylib.bc -endif - @echo Cleaning done - -# instead of defining every module one by one, we can define a pattern -# this pattern below will automatically compile every module defined on $(OBJS) -#%.o : %.c -# $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) + + + + + + + + + + + + + raylib/makefile at develop · raysan5/raylib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + + + + + + + +
+ +
+
+ + +
+
+
+ +
+ +
+ + +
    + +
  • +
    + +
    + + + + Watch + + + + +
    + +
    +
    +
    +
  • + +
  • + +
    + +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + +
    + +
  • +
+ +

+ + /raylib + + + + + +

+ +
+
+
+ +
+
+
+ + + +
+ +
+

HTTPS clone URL

+
+ + + + +
+
+ + +
+

SSH clone URL

+
+ + + + +
+
+ + +
+

Subversion checkout URL

+
+ + + + +
+
+ + + +
You can clone with +
,
, or
. + + + +
+ + + Clone in Desktop + + + + + Download ZIP + +
+
+
+ + + + + + + +
+ +
+ + + +
+ +
+ + + + +
+ + +
+ + +
+ Fetching contributors… +
+ +
+ + Cannot retrieve contributors at this time +
+
+
+
+
+ +
+ Raw + Blame + History +
+ + + + + +
+ +
+ +
+ +
+ 182 lines (156 sloc) + + 5.78 KB +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#**************************************************************************************************
#
# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten)
#
# Copyright (c) 2014 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
#
# Permission is granted to anyone to use this software for any purpose, including commercial
# applications, and to alter it and redistribute it freely, subject to the following restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not claim that you
# wrote the original software. If you use this software in a product, an acknowledgment
# in the product documentation would be appreciated but is not required.
#
# 2. Altered source versions must be plainly marked as such, and must not be misrepresented
# as being the original software.
#
# 3. This notice may not be removed or altered from any source distribution.
#
#**************************************************************************************************
+
# define raylib platform to compile for
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
PLATFORM ?= PLATFORM_DESKTOP
+
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
else
UNAMEOS:=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
else
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
endif
endif
endif
endif
+
# define raylib graphics api depending on selected platform
ifeq ($(PLATFORM),PLATFORM_RPI)
# define raylib graphics api to use (on RPI, OpenGL ES 2.0 must be used)
GRAPHICS = GRAPHICS_API_OPENGL_ES2
else
# define raylib graphics api to use (OpenGL 1.1 by default)
GRAPHICS ?= GRAPHICS_API_OPENGL_11
#GRAPHICS = GRAPHICS_API_OPENGL_33 # Uncomment to use OpenGL 3.3
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif
+
# NOTE: makefiles targets require tab indentation
+
# define compiler: gcc for C program, define as g++ for C++
ifeq ($(PLATFORM),PLATFORM_WEB)
# define emscripten compiler
CC = emcc
else
# define default gcc compiler
CC = gcc
endif
+
# define compiler flags:
# -O1 defines optimization level
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -fgnu89-inline declaring inline functions support (GCC optimized, faster)
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline
+
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
+
# define any directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI)
INCLUDES = -I. -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads
else
INCLUDES = -I. -I../src
# external libraries headers
# GLFW3
INCLUDES += -I../external/glfw3/include
# GLEW
INCLUDES += -I../external/glew/include
# OpenAL Soft
INCLUDES += -I../external/openal_soft/include
endif
+
# define all object files required
OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o
+
# typing 'make' will invoke the first target entry in the file,
# in this case, the 'default' target entry is raylib
default: raylib
+
# compile raylib library
raylib: $(OBJS)
ifeq ($(PLATFORM),PLATFORM_WEB)
emcc -O1 $(OBJS) -o libraylib.bc
else
ar rcs libraylib.a $(OBJS)
endif
+
# compile core module
# emcc core.c -o core.bc -DPLATFORM_DESKTOP
core.o: core.c
$(CC) -c core.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+
# compile rlgl module
rlgl.o: rlgl.c
$(CC) -c rlgl.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+
# compile raymath module
raymath.o: raymath.c
$(CC) -c raymath.c $(CFLAGS) $(INCLUDES)
+
# compile shapes module
shapes.o: shapes.c
$(CC) -c shapes.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+
# compile textures module
textures.o: textures.c
$(CC) -c textures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+
# compile text module
text.o: text.c
$(CC) -c text.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+
# compile models module
models.o: models.c
$(CC) -c models.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+
# compile audio module
audio.o: audio.c
$(CC) -c audio.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
# compile stb_vorbis library
stb_vorbis.o: stb_vorbis.c
$(CC) -c stb_vorbis.c -O1 $(INCLUDES) -D$(PLATFORM)
+
# compile utils module
utils.o: utils.c
$(CC) -c utils.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
+
# compile camera module
camera.o: camera.c
$(CC) -c camera.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
+
# compile gestures module
gestures.o: gestures.c
$(CC) -c gestures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
+
# clean everything
clean:
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),OSX)
rm -f *.o libraylib.a
else
ifeq ($(PLATFORM_OS),LINUX)
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
else
del *.o libraylib.a
endif
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
rm -f *.o libraylib.a
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
del *.o libraylib.bc
endif
@echo Cleaning done
+
# instead of defining every module one by one, we can define a pattern
# this pattern below will automatically compile every module defined on $(OBJS)
#%.o : %.c
# $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+ +
+ +
+ +Jump to Line + + +
+
+ +
+
+ + +
+ +
+ +
+ + + + + + + +
+ + + Something went wrong with that request. Please try again. +
+ + + + + + + + + +